1樓:_鈊_煩_薏亂
亂數是不重複的隨機數嗎?
很多演算法的每一個計算步驟都是固定的,而在下面我們要討論的概率演算法,允許演算法在執行的過程中隨機選擇下一個計算步驟。許多情況下,當演算法在執行過程中面臨一個選擇時,隨機性選擇常比最優選擇省時。因此概率演算法可在很大程度上降低演算法的複雜度。
概率演算法的一個基本特徵是對所求解問題的同一例項用同一概率演算法求解兩次可能得到完全不同的效果。這兩次求解問題所需的時間甚至所得到的結果可能會有相當大的差別。一般情況下,可將概率演算法大致分為四類:
數值概率演算法,蒙特卡羅(monte carlo)演算法,拉斯維加斯(las vegas)演算法和舍伍德(sherwood)演算法。
數值概率演算法常用於數值問題的求解。這類演算法所得到的往往是近似解。而且近似解的精度隨計算時間的增加不斷提高。
在許多情況下,要計算出問題的精確解是不可能或沒有必要的,因此用數值概率演算法可得到相當滿意的解。
蒙特卡羅演算法用於求問題的準確解。對於許多問題來說,近似解毫無意義。例如,一個判定問題其解為「是」或「否」,二者必居其一,不存在任何近似解答。
又如,我們要求一個整數的因子時所給出的解答必須是準確的,一個整數的近似因子沒有任何意義。用蒙特卡羅演算法能求得問題的一個解,但這個解未必是正確的。求得正確解的概率依賴於演算法所用的時間。
演算法所用的時間越多,得到正確解的概率就越高。蒙特卡羅演算法的主要缺點就在於此。一般情況下,無法有效判斷得到的解是否肯定正確。
拉斯維加斯演算法不會得到不正確的解,一旦用拉斯維加斯演算法找到一個解,那麼這個解肯定是正確的。但是有時候用拉斯維加斯演算法可能找不到解。與蒙特卡羅演算法類似。
拉斯維加斯演算法得到正確解的概率隨著它用的計算時間的增加而提高。對於所求解問題的任一例項,用同一拉斯維加斯演算法反覆對該例項求解足夠多次,可使求解失效的概率任意小。
舍伍德演算法總能求得問題的一個解,且所求得的解總是正確的。當一個確定性演算法在最壞情況下的計算複雜性與其在平均情況下的計算複雜性有較大差別時,可以在這個確定演算法中引入隨機性將它改造成一個舍伍德演算法,消除或減少問題的好壞例項間的這種差別。舍伍德演算法精髓不是避免演算法的最壞情況行為,而是設法消除這種最壞行為與特定例項之間的關聯性。
本文簡要的介紹一下數值概率演算法和舍伍德演算法。
首先來談談隨機數。隨機數在概率演算法設計中扮演著十分重要的角色。在現實計算機上無法產生真正的隨機數,因此在概率演算法中使用的隨機數都是一定程度上隨機的,即偽隨機數。
產生隨機數最常用的方法是線性同餘法。由線性同餘法產生的隨機序列a1,a2,...,an滿足
a0=d
an=(ban-1+c)mod m n=1,2.......
其中,b>=0, c>=0, d>=m。d稱為該隨機序列的種子。
下面我們建立一個隨機數類radomnumber,該類包含一個由使用者初始化的種子randseed。給定種子之後,既可產生與之相應的隨機數序列。randseed是一個無符號長整型數,既可由使用者指定也可由系統時間自動產生。
const unsigned long maxshort=65536l;
const unsigned long multiplier=1194211693l;
const unsigned long adder=12345l;
class randomnumber
; randomnumber::randomnumber(unsigned long s)
unsigned short randomnumber::random(unsigned long n)
double randomnumber::frandom(void)
函式random在每次計算時,用線性同餘式計算新的種子。它的高16位的隨機性較好,將randseed右移16位得到一個0-65535之間的隨機整數然後再將此隨機整數對映到0-n-1範圍內。
對於函式frandom,先用random(maxshort)產生一個0-(maxshort-1之間的整型隨機序列),將每個整型隨機數除以maxshort,就得到[0,1)區間中的隨機實數。
下面來看看數值概率演算法的兩個例子:
1.用隨機投點法計算π
設有一半徑為r的圓及其外切四邊形,如圖所示。向該正方形隨機投擲n個點。設落入圓內的點在正方形上均勻分佈,因而所投入點落入圓內的概率為 πr^2/4r^2,所以當n足夠大時,k與n之比就逼近這一概率,即π/4。
由此可得使用隨機投點法計算π值的數值概率演算法。具體實現時,只需要在第一次象限計算即可。
double darts(int n)
return 4*k/double(n);
} 再簡單舉個舍伍德演算法的例子。
我們在分析一個演算法在平均情況下的計算複雜性時,通常假定演算法的輸入資料服從某一特定的概率分佈。例如,在輸入資料是均勻分佈時,快速排序演算法所需的平均時間是o(n logn)。但是如果其輸入已經基本上排好序時,所用時間就大大增加了。
此時,可採用舍伍德演算法消除演算法所需計算時間與輸入例項間的這種聯絡。
在這裡,我們用舍伍德型選擇演算法隨機的選擇一個陣列元素作為劃分標準。這樣既能保證演算法的線性時間平均效能又避免了計算擬中位數的麻煩。非遞迴的舍伍德型演算法可描述如下:
template
type select(type a, int l, int r, int k)
if(j-l+1==k)
return pivot;
a[l]=a[j];
a[j]=pivot;
if(j-l+1
type select(type a, int n, int k)
平時我們一般開始考慮的是一個有著很好平均效能的選擇演算法,但在最壞情況下對某些例項演算法效率較低。這時候我們用概率演算法,將上述演算法改造成一個舍伍德型演算法,使得該演算法對任何例項均有效。
不過在有些情況下,所給的確定性演算法無法直接改造成舍伍德型演算法。這時候就可以藉助隨機預處理技術,不改變原有的確定性演算法,僅對其輸入進行隨機洗牌,同樣可以得到舍伍德演算法的效果。還是剛才的例子,換一種方法實現:
template
void shuffle(type a, int n) }
2樓:
自己程式設計序?程式執行步驟都是固定的
步驟一定,源數字一定,那麼結果當然還是一定的了不可能一個程式執行下去,自己變亂了,變得不可預知了,每次都得到不同的結果吧
要隨機數的話,總要從一個隨機的東西里面取一個出來吧,我是這麼認為的具體怎麼產生隨機數,那是數學問題了,而且,好像計算機裡得不到真正的隨機數
不用rand(),如何產生亂數?
3樓:匿名使用者
亂數是不重複的隨機數嗎?
很多演算法的每一個計算步驟都是固定的,而在下面我們要討論的概率演算法,允許演算法在執行的過程中隨機選擇下一個計算步驟。許多情況下,當演算法在執行過程中面臨一個選擇時,隨機性選擇常比最優選擇省時。因此概率演算法可在很大程度上降低演算法的複雜度。
概率演算法的一個基本特徵是對所求解問題的同一例項用同一概率演算法求解兩次可能得到完全不同的效果。這兩次求解問題所需的時間甚至所得到的結果可能會有相當大的差別。一般情況下,可將概率演算法大致分為四類:
數值概率演算法,蒙特卡羅(monte carlo)演算法,拉斯維加斯(las vegas)演算法和舍伍德(sherwood)演算法。
數值概率演算法常用於數值問題的求解。這類演算法所得到的往往是近似解。而且近似解的精度隨計算時間的增加不斷提高。
在許多情況下,要計算出問題的精確解是不可能或沒有必要的,因此用數值概率演算法可得到相當滿意的解。
蒙特卡羅演算法用於求問題的準確解。對於許多問題來說,近似解毫無意義。例如,一個判定問題其解為「是」或「否」,二者必居其一,不存在任何近似解答。
又如,我們要求一個整數的因子時所給出的解答必須是準確的,一個整數的近似因子沒有任何意義。用蒙特卡羅演算法能求得問題的一個解,但這個解未必是正確的。求得正確解的概率依賴於演算法所用的時間。
演算法所用的時間越多,得到正確解的概率就越高。蒙特卡羅演算法的主要缺點就在於此。一般情況下,無法有效判斷得到的解是否肯定正確。
拉斯維加斯演算法不會得到不正確的解,一旦用拉斯維加斯演算法找到一個解,那麼這個解肯定是正確的。但是有時候用拉斯維加斯演算法可能找不到解。與蒙特卡羅演算法類似。
拉斯維加斯演算法得到正確解的概率隨著它用的計算時間的增加而提高。對於所求解問題的任一例項,用同一拉斯維加斯演算法反覆對該例項求解足夠多次,可使求解失效的概率任意小。
舍伍德演算法總能求得問題的一個解,且所求得的解總是正確的。當一個確定性演算法在最壞情況下的計算複雜性與其在平均情況下的計算複雜性有較大差別時,可以在這個確定演算法中引入隨機性將它改造成一個舍伍德演算法,消除或減少問題的好壞例項間的這種差別。舍伍德演算法精髓不是避免演算法的最壞情況行為,而是設法消除這種最壞行為與特定例項之間的關聯性。
本文簡要的介紹一下數值概率演算法和舍伍德演算法。
首先來談談隨機數。隨機數在概率演算法設計中扮演著十分重要的角色。在現實計算機上無法產生真正的隨機數,因此在概率演算法中使用的隨機數都是一定程度上隨機的,即偽隨機數。
產生隨機數最常用的方法是線性同餘法。由線性同餘法產生的隨機序列a1,a2,...,an滿足
a0=d
an=(ban-1+c)mod m n=1,2.......
其中,b>=0, c>=0, d>=m。d稱為該隨機序列的種子。
下面我們建立一個隨機數類radomnumber,該類包含一個由使用者初始化的種子randseed。給定種子之後,既可產生與之相應的隨機數序列。randseed是一個無符號長整型數,既可由使用者指定也可由系統時間自動產生。
const unsigned long maxshort=65536l;
const unsigned long multiplier=1194211693l;
const unsigned long adder=12345l;
class randomnumber
; randomnumber::randomnumber(unsigned long s)
unsigned short randomnumber::random(unsigned long n)
double randomnumber::frandom(void)
函式random在每次計算時,用線性同餘式計算新的種子。它的高16位的隨機性較好,將randseed右移16位得到一個0-65535之間的隨機整數然後再將此隨機整數對映到0-n-1範圍內。
對於函式frandom,先用random(maxshort)產生一個0-(maxshort-1之間的整型隨機序列),將每個整型隨機數除以maxshort,就得到[0,1)區間中的隨機實數。
下面來看看數值概率演算法的兩個例子:
1.用隨機投點法計算π
設有一半徑為r的圓及其外切四邊形,如圖所示。向該正方形隨機投擲n個點。設落入圓內的點在正方形上均勻分佈,因而所投入點落入圓內的概率為 πr^2/4r^2,所以當n足夠大時,k與n之比就逼近這一概率,即π/4。
由此可得使用隨機投點法計算π值的數值概率演算法。具體實現時,只需要在第一次象限計算即可。
double darts(int n)
return 4*k/double(n);
} 再簡單舉個舍伍德演算法的例子。
我們在分析一個演算法在平均情況下的計算複雜性時,通常假定演算法的輸入資料服從某一特定的概率分佈。例如,在輸入資料是均勻分佈時,快速排序演算法所需的平均時間是o(n logn)。但是如果其輸入已經基本上排好序時,所用時間就大大增加了。
此時,可採用舍伍德演算法消除演算法所需計算時間與輸入例項間的這種聯絡。
在這裡,我們用舍伍德型選擇演算法隨機的選擇一個陣列元素作為劃分標準。這樣既能保證演算法的線性時間平均效能又避免了計算擬中位數的麻煩。非遞迴的舍伍德型演算法可描述如下:
template
type select(type a, int l, int r, int k)
if(j-l+1==k)
return pivot;
a[l]=a[j];
a[j]=pivot;
if(j-l+1
type select(type a, int n, int k)
平時我們一般開始考慮的是一個有著很好平均效能的選擇演算法,但在最壞情況下對某些例項演算法效率較低。這時候我們用概率演算法,將上述演算法改造成一個舍伍德型演算法,使得該演算法對任何例項均有效。
不過在有些情況下,所給的確定性演算法無法直接改造成舍伍德型演算法。這時候就可以藉助隨機預處理技術,不改變原有的確定性演算法,僅對其輸入進行隨機洗牌,同樣可以得到舍伍德演算法的效果。還是剛才的例子,換一種方法實現:
template
void shuffle(type a, int n) }
“專”是怎麼搞出來的啊
紫星寒冰 知道里有的使用者名稱前有 紅圈專家 和 綠圈專家 紅圈是專家知識團 見這裡 綠圈是專家 見這裡 只要你每週在某個欄位上升積分達到前五名,就會有一個專字現在改革了 是前五名 如何申請知識專家?欲申請成為知識專家的單位和個人請致信xuhe baidu.com,洽談合作事宜。請隨信提供專家姓名 ...
絲錐斷了怎麼搞出來,絲錐斷了怎麼辦?
海哥生活秀 絲錐斷了也別扔,用它製作一個小工具,螺絲生鏽卸不下來全靠它了 工業用品採購網 常規的處理絲錐 鑽頭等折斷在工件裡的方法無非是手工慢慢敲出 砸碎 氣焊後擰出 甚至酸腐蝕 火焰切割燒等方法,而且效果都不是很好。 苗賽兵 我們都用電火花機把絲錐打碎 專業真龍王 1盲孔的話 先讓絲錐退火然後拿比...
聖達菲1,8t發動機缸蓋螺絲斷了怎麼搞出來
只能用手搶鑽洗了,在用宮絲鑽牙,如果我的答案對你有所幫助,請設為最佳答案,謝謝。 是緊斷的還是鬆斷的,如果緊斷的把剛蓋取下來,用個尖嘴鉗,有很大機會取出來!汽車有問題,問汽車大師。4s店專業技師,10分鐘解決。 只有找專業取螺絲的,要用很厲害的轉花,轉出來的 汽車有問題,問汽車大師。4s店專業技師,...