ไม่มีคำตอบใดที่ชัดเจนหรือเรียบง่ายเป็นพิเศษ
นี่คือวิธีการง่ายๆที่ชัดเจนซึ่งรับประกันได้ว่าจะได้ผล
collect_normalize_probabilitiesใช้พจนานุกรมp
ที่จับคู่สัญลักษณ์กับความน่าจะเป็นหรือความถี่ มันแสดงรายการสิ่งที่สามารถใช้งานได้ซึ่งจะทำการเลือก
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
อัตราผลตอบแทน:
>>> accumulate_normalize_values( { 'a': 100, 'b' : 300, 'c' : 400, 'd' : 200 } )
[('a', 0.1), ('c', 0.5), ('b', 0.8), ('d', 1.0)]
ทำไมมันถึงได้ผล
สะสมขั้นตอนที่จะเปิดแต่ละสัญลักษณ์ลงในช่วงเวลาระหว่างตัวเองและสัญลักษณ์ความน่าจะเป็นก่อนหรือความถี่ (หรือ 0 ในกรณีของสัญลักษณ์แรก) ช่วงเวลาเหล่านี้สามารถใช้เพื่อเลือกจาก (และตัวอย่างการแจกแจงที่ให้มา) โดยเพียงแค่ก้าวผ่านรายการจนกระทั่งตัวเลขสุ่มในช่วง 0.0 -> 1.0 (เตรียมไว้ก่อนหน้านี้) น้อยกว่าหรือเท่ากับจุดสิ้นสุดของช่วงเวลาของสัญลักษณ์ปัจจุบัน
การทำให้เป็นมาตรฐานทำให้เราหลุดพ้นจากความต้องการที่จะทำให้แน่ใจว่าทุกอย่างรวมเป็นมูลค่าบางอย่าง หลังจากการทำให้เป็นมาตรฐาน "เวกเตอร์" ของความน่าจะเป็นจะรวมเป็น 1.0
ส่วนที่เหลือของรหัสสำหรับการเลือกและสร้างตัวอย่างยาวโดยพลการจากการกระจายอยู่ด้านล่าง:
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
การใช้งาน:
>>> 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()
? คุณสร้างรายการหลักด้วยจำนวนครั้งที่เหมาะสมและเลือกหนึ่งรายการ นี่เป็นคำถามที่ซ้ำกันแน่นอน