經典演算法 隨機數生成

2021-10-13 16:10:34 字數 2585 閱讀 4844

3. 解法二

4. 總結

tkinter庫的那篇部落格(python筆記:視覺化介面寫作嘗試)真的是寫的我心力憔悴啊,其實東西並不難,就是多,然後一開始又沒有找到比較靠譜的官方文件,搞得我沒寫乙個元件的應用就得去看原始碼,然後自己寫**嘗試,搞得累的半死。

所以,這裡,就讓我們來看一下另外一道經典的演算法題:隨機數生成問題好了。

隨機數生成這個經典演算法題我相信大部分人都知道,尤其刷過leetcode或者有過面試經歷的,無非就是給定乙個隨機數生成器,然後取生成另乙個範圍內的隨機數。

乙個典型的例子就是使用rand7生成rand10

因此,這裡,我們就以rand7生成rand10為例進行討論,考察一下有哪些實現思路,並對其進行一定的拓展延伸。

顯然的,如果用乙個範圍更大的隨機數生成器去生成乙個更小範圍的隨機數生成器是非常簡單的一件事,比如使用rand7()來生成rand5(),就可以使用下述方法:

def

rand5()

:while

true

: seed = rand7(

)if seed <=5:

return seed

顯然,如此一來乙個1到5的隨機數生成器就完成了,當然,效率上會略有損失,每乙個隨機數的生成所需要的rand7()的期望執行次數為1.4次,當時整體而言,這個值都不會高於2,因此,事實上大生成小的問題總是簡單的。

那麼,針對小生成大的問題,事實上也同樣可以嘗試將其拆解為大生成小的問題進行解決。

一種比較簡單的思路就是,由於10=2

×5

10 = 2 \times 5

10=2×5

,因此,我們可以使用rand7()構造兩個rand5()生成器,然後合併成乙個rand10()生成器。

給出python**實現如下:

def

rand2()

:while

true

: seed = rand7(

)if seed !=7:

return seed %2+

1def

rand10()

:return5*

(rand2()-

1)+ rand5(

)

其中,rand5()我們已經在上述內容中進行了介紹,這裡我們就不再多做說明了。

可以看到,整體而言,每一次隨機數生成所需要呼叫的rand7()的期望次數為7/6

+7/5

≃2.57

7/6+7/5\simeq 2.57

7/6+7/

5≃2.

57。但是上述演算法的限制也十分的明顯,需要目標範圍可以進行因式分解為兩個小數的乘積,否則就無法原模原樣地照抄上述的演算法,比如rand11(),就無法採用分解的方式進行求解。

但是,這個問題也不是無解,上述相同的思路只要稍作調整,我們還是可以進行求解的。

可以看到,在上述演算法中,最為核心的地方在於將問題從乙個小生成大的問題轉換為乙個大生成小的問題。

而具體的實現方式上,上述思路採用的是大拆小的模型,將目標範圍通過因式分解的方式拆分為若干個概率相同且可以被當前隨機數生成覆蓋的子範圍,從而進行求解。

但是上述方法受限於拆分過程必須是拆分為等概率的幾個子範圍,即是說必須是因式分解可分的,但是如果目標範圍是乙個質數或者因子中存在乙個數大於當前的隨機數生成器,上述思路就會失效。

不過,我們可以將上述拆分的思路反著來,不是縮減目標範圍,而是將當前隨機數生成器進行等比例放大,使之可以覆蓋住目標範圍。

而放大的方式就是就是通過k進製的方式,不斷地將其擴大k倍,那樣的話就可以等概率地覆蓋新的範圍內的所有值。

給出python**實現如下:

def

rand10()

:while

true

: seed =

(rand7()-

1)*7

+ rand7(

)if seed <=40:

return seed %10+

1

同樣的,我們同樣分析可得,上述演算法的期望值2×(

49/40)

=2.45

2\times(49/40)=2.45

2×(49/

40)=

2.45

。可以看到,通過這種方式,我們就可以將問題不受限制的擴充套件到任意情況當中。

綜上,我們給出了一道經典演算法題——隨機數生成問題的解答,並對其進行了一定的拓展,將其拓展到了任意兩個隨機數相互轉換的問題,具體而言,可以拆解為大生成小以及小生成大的問題。

其中,針對大生成小的我們沒有詳細的討論,因為事實上這還是比較明顯的。

而對小生成大的問題,其核心的處理思想事實上也都是將其轉換為大生成小的問題,我們具體給出了兩種常見的實現方法,分別是分解目標範圍以及擴充套件已有生成範圍的方式。

隨機數生成演算法

看到一些介紹隨機數生成演算法的文章,收集下來,有空深入了解下。c語言中偽隨機數生成演算法實際上是採用了 線性同餘法 具體的計算如下 xi xi 1 a c mod m 其中a,c,m都是常數 一般會取質數 當c 0時,叫做乘同餘法。srand 函式置的seed實際上會作為x0被代入上式中,然後每次呼...

隨機數生成演算法

這兩天沒事,就寫了寫數學課上老師說的那個 蒲豐投針實驗 的程式。接觸到了一些隨機數生成方面的東西,寫出來跟大家分享一下。對於計算機生成隨機數這個東西,以前有過一些淺顯的認識。只知道計算機不能生成真正的隨機數,只能用一定的方法來模擬隨機數,叫做偽隨機數。比如c語言裡面的rand 函式,就是乙個偽隨機數...

solitidy 生成隨機數演算法

引用fomo3d的空投機制就是這中演算法。以太坊 生成乙個5位的隨機數 uint256 winningnum uint256 keccak256 abi.encodepacked block.timestamp add block.difficulty add uint256 keccak256 a...