關於根據機率來隨機sampling according to probability distribution

問題

基本問題是這樣的:當咱們扔一個骰子的時候是等機率的出現數字。那這個問題容易模擬。但咱們能不能模擬不等機率的骰子呢。git

思路

最簡單

給定一組序列 l = [(4,0.4),(3,0.3),(2,0.2),(1,0.1)]。github

對應數字:出現機率dom

基於此最簡單的思路 看代碼。code

def random_distr(l):
    r = random.uniform(0, sum([x[1] for x in l]))
    s = 0
    for num,(item, prob) in enumerate(l):
        s += prob
        if s >= r:
            return num
    return l[-1]

思路很明確了。隨機一個數n(假定0-1之間),而後從0開始加l的機率指導大於n爲止。orm

弊端get

這個方法的複雜度是 空間複雜度是O(N),時間複雜度是O(N)。顯然不是最好解。it

提高時間複雜度。

很容易想到的思路是將機率映射到key。就是尋找機率分母的最小公倍數lcm。io

如: (4,4),(3,3),(2,2),(1,1) ps:10是明顯的lcm。form

那麼對應到key 就是方法

4444 333 22 1

那麼對於該問題用一個dict,[1..10]爲key,以上爲value。那麼隨機的過程變爲,隨機一個數(1-10),而後找到對應的value。此時時間複雜度 爲O(1),空間複雜度最好O(N),最壞則O(最小公倍數) 。

提高空間複雜度。

這裏別人提出了個二維的維度來思考問題。

好比權重爲 10,20,30,40. key 爲ABCD.

則爲

10  AAAAAAAAAA
20  BBBBBBBBBB BBBBBBBBBB
30  CCCCCCCCCC CCCCCCCCCC CCCCCCCCCC
40  DDDDDDDDDD DDDDDDDDDD DDDDDDDDDD DDDDDDDDDD

分割並從新安排後。

AAAAAAAAAA DDDDDDDDDDDDDDD  -- 10 A + 15 D = 40% A + 60% D
BBBBBBBBBBBBBBBBBBBB DDDDD  -- 20 B + 5 D  = 80% B + 20% D
CCCCCCCCCCCCCCCCCCCCCCCCC   -- 25 C        = 100% C
DDDDDDDDDDDDDDDDDDDD CCCCC  -- 20 D + 5 C  = 80% D + 20% C

那麼隨機的過程變爲了,隨機一個數字 n 好比1,隨機一個0-1的機率x。那麼若是x > 0.4 ,則爲d,若是小於則爲a。

這樣空間負責爲O(N),時間複雜度爲O(1).

參考:
http://www.keithschwarz.com/darts-dice-coins/

代碼連接:

https://github.com/BigAN/sampling-according-to-probability-distributio...

相關文章
相關標籤/搜索