传统思路抽取小球
RW_draw.py
import random
import numpy as np
ball_name = {
0: '红',
1: '白'
}
box1 = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] # 5,5
box2 = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1] # 3,7
box3 = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1] # 6,4
box4 = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1] # 8,2
def draw_balls(times=0):
box_id = random.randint(1, 4) # 第一次抽
nextbox_id = 0
ball_list = []
box_list = []
while times > 0: # 抽取次数
box_list.append(box_id) # 添加 box_id
# 随机抽球的id,只执行4种情况的1个 可以放在外边
ball_id = random.randint(0, 9)
# 根据 box_id 判断 nextbox_id, 并根据 ball_id 随机抽球
if box_id == 1: # 下个盒子一定是 2
nextbox_id = 2
ball_list.append(box1[ball_id])
if box_id == 2 or box_id == 3: # 0.4/0.6 概率 左/右边的盒子
nextbox_id = np.random.choice([box_id - 1, box_id + 1], p=[0.4, 0.6])
if box_id == 2:
ball_list.append(box2[ball_id])
else:
ball_list.append(box3[ball_id])
if box_id == 4: # 各以0.5的概率留在 4 或移到 3
nextbox_id = np.random.choice([3, 4], p=[0.5, 0.5])
ball_list.append(box4[ball_id])
# 更新 box 为 nextbox
box_id = nextbox_id
times -= 1
ball_list = [ball_name[i] for i in ball_list]
# box_list 状态序列
# ball_list 观测序列
for val in zip(box_list, ball_list):
print(val)
draw_balls(5)
马尔可夫 状态转移概率 思路
Markov_draw.py
import numpy as np
ball_name = {
0: '红',
1: '白'
}
box1 = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] # 5,5
box2 = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1] # 3,7
box3 = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1] # 6,4
box4 = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1] # 8,2
# Markov draw
# 初始概率分布
init_P = np.array([
0.25, 0.25, 0.25, 0.25
]).T
# 状态转移矩阵
state_P = np.array([
[0, 1, 0, 0], # 不同盒子选择下一个盒子的概率
[0.4, 0, 0.6, 0],
[0, 0.4, 0, 0.6],
[0, 0, 0.5, 0.5]
])
# 观测概率分布
observe_P = np.array([
[0.5, 0.5], # 不同盒子抓到 红/白球的概率
[0.3, 0.7],
[0.6, 0.4],
[0.8, 0.2]
])
# 状态转移矩阵发现 next_P === init_P, [0.25, 0.25, 0.25, 0.25]
# next_P = state_P @ init_P
# 所以无论怎样选择 最后抽到 红/白球的概率时恒定的 [0.55 0.45]
ball_P = state_P @ init_P @ observe_P # 前两项乘积属于隐藏状态,三项乘积是观测状态
def draw_balls(times=0):
ball_list = []
while times > 0:
color_id = np.random.choice([0, 1], p=ball_P)
ball_list.append(ball_name[color_id])
times -= 1
return ball_list
# 示例抽取结果
target = ['红', '红', '白', '白', '红']
while True:
ball_list = draw_balls(5)
print(ball_list)
if ball_list == target:
break
-
next_P = state_P @ init_P === init_P
[0.25, 0.25, 0.25, 0.25] - 所以无论怎样选择 最后抽到 红/白球的概率时恒定的 [0.55 0.45]
网友评论