Bu cevapların hiçbiri özellikle açık veya basit değil.
İşte çalışması garantili net, basit bir yöntem.
biriktirmek_normalize_probabilities , p
sembolleri olasılık VEYA frekanslara eşleyen bir sözlük alır . Seçim yapılabilecek kullanılabilir tuplelar listesini çıkarır.
def accumulate_normalize_values(p):
pi = p.items() if isinstance(p,dict) else p
accum_pi = []
accum = 0
for i in pi:
accum_pi.append((i[0],i[1]+accum))
accum += i[1]
if accum == 0:
raise Exception( "You are about to explode the universe. Continue ? Y/N " )
normed_a = []
for a in accum_pi:
normed_a.append((a[0],a[1]*1.0/accum))
return normed_a
Verim:
>>> accumulate_normalize_values( { 'a': 100, 'b' : 300, 'c' : 400, 'd' : 200 } )
[('a', 0.1), ('c', 0.5), ('b', 0.8), ('d', 1.0)]
Neden işe yarıyor
Birikim aşaması (birinci sembolün halinde veya 0) kendisi ve önceki semboller olasılık ya da frekans arasında bir aralık her bir sembol döner. Bu aralıklar, 0.0 -> 1.0 aralığındaki rastgele sayı (daha önce hazırlanmış olan) mevcut sembolün aralığının bitiş noktasına eşit veya daha az olana kadar basitçe listede adım adım ilerleyerek arasından seçim yapmak (ve böylece sağlanan dağıtımı örneklemek) için kullanılabilir.
Normalleştirme bazı değere her şeyin meblağlar yapmak gerek bizi serbest bırakır. Normalleştirmeden sonra olasılıkların "vektörü" toplamı 1.0'a çıkar.
Kodun kalan seçimi ve dağılımından bir isteğe bağlı olarak uzun bir örnek oluşturmak için aşağıdaki gibidir:
def select(symbol_intervals,random):
print symbol_intervals,random
i = 0
while random > symbol_intervals[i][1]:
i += 1
if i >= len(symbol_intervals):
raise Exception( "What did you DO to that poor list?" )
return symbol_intervals[i][0]
def gen_random(alphabet,length,probabilities=None):
from random import random
from itertools import repeat
if probabilities is None:
probabilities = dict(zip(alphabet,repeat(1.0)))
elif len(probabilities) > 0 and isinstance(probabilities[0],(int,long,float)):
probabilities = dict(zip(alphabet,probabilities)) #ordered
usable_probabilities = accumulate_normalize_values(probabilities)
gen = []
while len(gen) < length:
gen.append(select(usable_probabilities,random()))
return gen
Kullanım:
>>> gen_random (['a','b','c','d'],10,[100,300,400,200])
['d', 'b', 'b', 'a', 'c', 'c', 'b', 'c', 'c', 'c'] #<--- some of the time
random.choice()
? Ana listeyi uygun sayıda oluşumla oluşturursunuz ve birini seçersiniz. Bu elbette yinelenen bir sorudur.