這是Python cookbook的示例
1 def random_pick(some_list,probabilities): 2 x=random.uniform(0,1) 3 cumulative_probability=0.0 4 for item,item_probability in zip(some_list,probabilities): 5 cumulative_probability+=item_probability 6 if x < cumulative_probability: break 7 return item
什么意思呢?
random.uniform(0,1)->生成0.0到1.0之間的偽隨機數,之后循環元素及其概率,計算累積概率.
如:random_pick([1,2,3,4],[0.1,0.2,0.3,0.4])
當x處於0.0到0.1之間,則輸出1
當x處於0.1到0.3之間,則輸出2
...........
在這里可以做個測試:
def test_random(nu): a=[1,2,3,4] b=[0.1,0.2,0.3,0.4] re=dict(zip(a,[0]*4)) for x in xrange(nu): result=random_pick(a,b) re[result]+=1 for v,value in re.iteritems(): re[v]=float(value)/nu return re print test_random(100000)
結果:
{
1
:
0.099250000000000005
,
2
:
0.19950999999999999
,
3
:
0.30030000000000001
,
4
:
0.40094000000000002
}
|
另一個有點類似的任務是根據一個非負整數的序列所定義的權重進行隨機擷取---基於機會,而不是概率
import random def random_picks(sequence,relative_odds): table=[z for x,y in zip(sequence,relative_odds) for z in [x]*y] while True: yield random.choice(table) x=random_picks('ciao',[1,1,3,2]) import itertools print ''.join(itertools.islice(x,8))
輸出:
oooocaco
|
這里我們也做個測試:
result=''.join(itertools.islice(x,100000)) c=result.count('c') i=result.count('i') a=result.count('a') o=result.count('o') min=min(c,i,a,o) print float(c)/min,':',float(i)/min,':',float(a)/min,':',float(o)/min
輸出:
1.0
:
1.0210748156
:
3.00316122234
:
2.00070249385
|
這兩個例子有什么區別呢?
第一個例子要求som_list的長度和probabilities的長度一致,以及所有元素的概率相加為1.0
而第二個例子需要非負整數.

