Không có câu trả lời nào là đặc biệt rõ ràng hoặc đơn giản.
Dưới đây là một phương pháp rõ ràng, đơn giản được đảm bảo để làm việc.
tích lũy_n normalize_probabilities lấy một từ điển p
ánh xạ các ký hiệu theo xác suất HOẶC tần số. Nó đưa ra danh sách các bộ dữ liệu có thể sử dụng để lựa chọn.
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
Sản lượng:
>>> accumulate_normalize_values( { 'a': 100, 'b' : 300, 'c' : 400, 'd' : 200 } )
[('a', 0.1), ('c', 0.5), ('b', 0.8), ('d', 1.0)]
Tại sao nó hoạt động
Bước tích lũy biến mỗi ký hiệu thành một khoảng giữa chính nó và xác suất hoặc tần số ký hiệu trước đó (hoặc 0 trong trường hợp ký hiệu đầu tiên). Các khoảng này có thể được sử dụng để chọn từ (và do đó lấy mẫu phân phối được cung cấp) bằng cách chỉ cần bước qua danh sách cho đến khi số ngẫu nhiên trong khoảng 0,0 -> 1,0 (được chuẩn bị trước đó) nhỏ hơn hoặc bằng điểm cuối khoảng của ký hiệu hiện tại.
Việc chuẩn hóa giải phóng chúng ta khỏi nhu cầu đảm bảo mọi thứ tổng hợp đến một giá trị nào đó. Sau khi chuẩn hóa, "vectơ" của xác suất tính tổng thành 1.0.
Phần còn lại của mã để chọn và tạo mẫu dài tùy ý từ phân phối bên dưới:
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
Sử dụng :
>>> 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()
? Bạn xây dựng danh sách tổng thể với số lần xuất hiện thích hợp và chọn một lần xuất hiện. Đây là một câu hỏi trùng lặp, tất nhiên.