一、算法原理:
参考博客:https://blog.csdn.net/haolexiao/article/details/65157026
论文地址:http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.675.8158&rep=rep1&type=pdf
二、代码实现:
import numpy as np
def alias_table(prob_table):
n = len(prob_table)
prob_norm = np.array(prob_table) * n
small, large = [], []
for i, prob in enumerate(prob_norm):
if prob < 1:
small.append(i)
else:
large.append(i)
accept, alias = [0] * n, [0] * n
while small and large:
small_idx, large_idx = small.pop(), large.pop()
#存放第i列对应的事件i的概率;
accept[small_idx] = prob_norm[small_idx]
#存放不是事件i的另外事件的标号;
alias[small_idx] = large_idx
prob_norm[large_idx] = prob_norm[large_idx] - (1 - prob_norm[small_idx])
if prob_norm[large_idx] < 1.0:
small.append(large_idx)
else:
large.append(large_idx)
while small:
small_idx = small.pop()
accept[small_idx] = 1
while large:
large_idx = large.pop()
accept[large_idx] = 1
return accept, alias
def alias_sample(accept, alias):
n = len(accept)
i = int(np.random.random() * n)
r = np.random.random()
if r < accept[i]:
return i
else:
return alias[i]
prob_table = [1/2,1/3,1/12,1/12]
ac, a = alias_table(prob_table)
i = alias_sample(ac, a)
print(i)