• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            ?? 生成無重復(fù)的隨機(jī)數(shù),注意,是不重復(fù)的序列.
            ?? 通常的生成隨機(jī)數(shù)的做法是不考慮重復(fù)的,因?yàn)榧词怪貜?fù)也屬于概率意義上的正常情況.但某些情況下需要不重復(fù)的隨機(jī)數(shù)據(jù),怎么辦呢?
            ?? 我想從大方向上來說,應(yīng)該只有兩個(gè)方法.要么犧牲時(shí)間要么犧牲空間.講得不對(duì)或不完整,大家一定要指出來啊,謝謝.

            ?? 注意,下面均以在101~200的范圍內(nèi)(設(shè)為b[100],它實(shí)際上是附加空間),從中產(chǎn)生10個(gè)不重復(fù)的隨機(jī)數(shù)(設(shè)為a[10]).
            ??
            一.犧牲時(shí)間為代價(jià)
            ?? 這種方法不需要附加空間b數(shù)組.
            ?? 要產(chǎn)生一定范圍內(nèi)不可重復(fù)的隨機(jī)數(shù),把曾經(jīng)生成的隨機(jī)數(shù)保存起來作為歷史數(shù)據(jù)。產(chǎn)生一個(gè)新的隨機(jī)數(shù)后在歷史數(shù)據(jù)搜索,若找到就重新產(chǎn)生一個(gè)新的再重復(fù)數(shù)據(jù)搜索;否則就認(rèn)為已經(jīng)找到了一個(gè)新的不同隨機(jī)數(shù)。
            ?? 可以預(yù)見,每個(gè)新產(chǎn)生的隨機(jī)數(shù)都要與前面所有的數(shù)比較.若重復(fù),舍棄,再產(chǎn)生;否則,產(chǎn)生下一個(gè).平均耗時(shí)n的平方量級(jí).
            ?? 粗看起來,上面的程序似乎沒有什么問題,在執(zhí)行過程中程序也能夠通過。但,仔細(xì)分析我們就會(huì)發(fā)現(xiàn)問題出在一個(gè)新產(chǎn)生的隨機(jī)數(shù)是否已經(jīng)存在的判定上。既然是隨機(jī)數(shù),那么從數(shù)學(xué)的角度來說在概率上,每次產(chǎn)生的隨機(jī)數(shù) r就有可能相同,盡管這種可能性很小,但確是一個(gè)邏輯性與正確性的問題。因此,每次產(chǎn)生的新的隨機(jī)數(shù)r都有可能是數(shù)組random的前i-1個(gè)數(shù)中的某一個(gè),也就是說程序在運(yùn)行過程中由此可能會(huì)導(dǎo)致死循環(huán)!
            ??? 有人可能會(huì)爭(zhēng)辯說,這種概率很小嘛,幾乎為零.的確,但我要問,算法的五大特性是什么,其中兩大特性就是:確定性和有窮性.
            ??? 所以,怎么解決?犧牲空間.(稍后介紹)

            二.犧牲空間為代價(jià)
            ?? 以下方法需要附加空間b數(shù)組.
            ?? (1)將范圍數(shù)組b[100](b[i]=100+i,不妨設(shè)數(shù)組下標(biāo)從1開始)的每個(gè)元素設(shè)置一個(gè)標(biāo)志位flag.初始均為flag=0;若某元素被選入到a數(shù)組中,則flag=1;顯然,以后再選到重復(fù)元素可以立刻判定是否已選.這不正是以空間換時(shí)間嗎?
            ?? 但是仍然有一個(gè)很嚴(yán)重的問題,在小規(guī)模輸入下,無疑它的表現(xiàn)是不錯(cuò)的.但現(xiàn)在舉一個(gè)失敗的例子.
            ?? 在1~65536之間,選擇65500個(gè)不重復(fù)的隨機(jī)數(shù).看看后面的隨機(jī)數(shù),比如第65500個(gè)數(shù)(最后一個(gè)),它要在剩下的36個(gè)數(shù)中選擇才會(huì)有flag=0(根本不知道這36個(gè)數(shù)是什么);哼哼,概率36/65536.越到后面,隨機(jī)數(shù)越難產(chǎn)生,空間也換不了時(shí)間.
            ?? 改進(jìn):先在1~65536之間隨機(jī)選取36個(gè)數(shù),刪除.將剩下的65500個(gè)數(shù)依次賦值給a[65500],然后打亂順序即可,如下偽碼:

            1 for ?i?←? 1 ?to?length[a]
            2 ??? do ?j?←?random()? // 隨機(jī)產(chǎn)生一個(gè)a數(shù)組的下標(biāo)

            3 ??????exchange?a[i]←→a[j] // 交換a[i]與a[j]
            4

            ? 當(dāng)范圍數(shù)組與目標(biāo)數(shù)組的大小非常接近時(shí),上述算法非常有效,建議采用.

            ? (2)問題的最終解決.
            ?? 仍以最開始的那個(gè)例子來說,初始數(shù)組b[i]=100+i,a數(shù)組空.
            ?? 每次隨機(jī)生成數(shù)組b的一個(gè)下標(biāo)subscript,然后取出它所對(duì)應(yīng)的數(shù)據(jù)a[subscript],記下來.然后將數(shù)組b的最后一個(gè)數(shù)b[length]放到下標(biāo)subscript的位置,同時(shí)將數(shù)組a長(zhǎng)度減1。盡管前若干次生成的下標(biāo)subscript隨機(jī)數(shù)有可能相同,但,因?yàn)槊恳淮味及炎詈笠粋€(gè)數(shù)填到取出的位置,因此,相同下標(biāo)subscript對(duì)應(yīng)的數(shù)卻絕不會(huì)相同,每一次取出的數(shù)都不會(huì)一樣,這樣,就保證了算法的確定性、有效性、有窮性.
            ? 偽碼算法如下:

            ?1 lower?←? 101
            ?2 upper?←? 200
            ?3 for ?i?←? 1 ?to?upper - lower + 1
            ?4 ???? do ?b[i] = lower + i - 1
            ?5 for ?i← 1 ?to?length[a]
            ?6 ???? do ?subscript? = ?( int )(length[b] * Rnd? + ?lower) // 隨機(jī)產(chǎn)生b數(shù)組的一個(gè)下標(biāo),Rnd產(chǎn)生0~1隨機(jī)數(shù)

            ?7 ???????temp?←?b[subscript]
            ?8
            ???????b[subscript]?←?b[length[b]]
            ?9 ???????length[b] --
            ;
            10 ???????a[i] =
            temp;
            11

            ? 這個(gè)算法我認(rèn)為是很不錯(cuò)的.
            ?
            如果大家有更好的想法解決不重復(fù)的隨機(jī)數(shù),歡迎探討!

            posted on 2006-11-12 12:05 哈哈 閱讀(4308) 評(píng)論(12)  編輯 收藏 引用

            評(píng)論:
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2006-12-05 18:23 | 沐楓
            你的方法1)因?yàn)樾枰4骐S機(jī)數(shù)歷史數(shù)據(jù),因此仍然是需要空間消耗的。而且空間消耗與方法2)比起來,沒區(qū)別。

            --
            至于方法2)的交換方法,VS2005中的std::random_shuffle函數(shù)就是這么做的。

              回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2006-12-05 22:27 | pengkuny
            @沐楓
            方法1)中,歷史數(shù)據(jù)不算附加空間吧
            比如從0~10000000000中隨機(jī)選6個(gè)數(shù),
            a[6]不算附加空間,b[10000000000]才是

            至于VS2005中的std::random_shuffle函數(shù),非常謝謝,原來有這樣的函數(shù),那太好了.  回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2007-01-19 15:13 | null
            二(1)處有誤,“若某元素被選入到a數(shù)組中,則flag=1;顯然,以后再選到重復(fù)元素可以立刻判定是否已選.這不正是以空間換時(shí)間嗎?”,在概率下有可能存在一直生成樹組b的且flag為1的下標(biāo)而導(dǎo)致死循環(huán),與一同。
            二(2)中有筆誤,“同時(shí)將數(shù)組a長(zhǎng)度減1。盡管”該處a應(yīng)為b。  回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2007-01-19 16:38 | Dain
            我知道c/cpp中可以產(chǎn)生隨機(jī)種子,在用rand函數(shù),就避免了重復(fù)
            srand((unsigned)time(NULL));
            rand();  回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2007-01-19 20:20 | pengkuny
            @null
            null說得不錯(cuò)
            二(1)確實(shí)沒有達(dá)到有窮性,只是使得"判定是否重復(fù)"的時(shí)間為常數(shù)
            二(2)中筆誤已改正.謝謝@Dain
              回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2007-01-19 20:22 | pengkuny
            @Dain
            撒種srand可以避免程序每次運(yùn)行時(shí)數(shù)據(jù)一樣(畢竟系統(tǒng)采用偽隨機(jī)方法)
            只不過和本文討論的不是一回事  回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2007-05-13 11:32 | Stupidmxx
            m序列可能可以做到生成不重復(fù)隨機(jī)序列  回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2007-05-13 12:02 | pengkuny
            @Stupidmxx
            請(qǐng)問什么是m序列?它是怎么生成不重復(fù)隨機(jī)序列的  回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2007-05-24 23:45 | Stupidmxx
            小m序列,沒記錯(cuò)的話是先找到個(gè)本原多項(xiàng)式,然后得到相應(yīng)的線性移位寄存器,再不斷的異或+移位生成的。呵呵,老師講的時(shí)候我就只記得它的性質(zhì),具體細(xì)節(jié)沒搞清楚。博主有興趣不妨baidu之。  回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2007-05-25 01:50 | pengkuny
            @Stupidmxx
            查過了,就是線性同余法.模為m.
            如Xi = 65539Xi (mod 2^31),65539=2^16+3,左移16位并相加3次.

            最終,它還是偽隨機(jī),電腦也正是這么實(shí)現(xiàn)的.

              回復(fù)  更多評(píng)論
              
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2007-07-17 03:56 | touzani
            # re: 生成無重復(fù)的隨機(jī)數(shù) 2009-05-16 17:05 | 土豆
            試過 ,很好的方法~  回復(fù)  更多評(píng)論
              

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久久久人妻精品一区二区三区| 伊人久久综在合线亚洲2019| 亚洲色欲久久久久综合网| 精品无码久久久久久久动漫| 色99久久久久高潮综合影院 | 狠狠久久亚洲欧美专区| 久久国产午夜精品一区二区三区| 久久久久久国产a免费观看不卡 | 久久婷婷国产综合精品| 久久中文娱乐网| 亚洲欧洲日产国码无码久久99 | 色综合久久中文字幕综合网| 日韩乱码人妻无码中文字幕久久| 国产AV影片久久久久久| 一本久道久久综合狠狠爱| 久久免费小视频| 久久亚洲精品中文字幕| 欧美久久天天综合香蕉伊| 成人久久精品一区二区三区| 久久久午夜精品| 久久久WWW成人免费毛片| 99国产欧美精品久久久蜜芽| 久久午夜夜伦鲁鲁片免费无码影视| 久久精品国产91久久综合麻豆自制| 亚洲国产天堂久久综合| 久久综合日本熟妇| 99久久精品国产一区二区蜜芽 | 精产国品久久一二三产区区别| 国产精品免费久久久久电影网| 久久精品国产99国产精偷 | 亚洲乱码日产精品a级毛片久久| 国产一级做a爰片久久毛片| 亚洲国产欧美国产综合久久| 久久精品一区二区三区中文字幕 | 久久这里只有精品久久| 久久99久久99精品免视看动漫| 无码专区久久综合久中文字幕| 久久亚洲精品无码aⅴ大香| 久久综合九色综合网站| 99蜜桃臀久久久欧美精品网站| 久久久久久国产a免费观看黄色大片|