Markov 盒子和球模型 李航 P173

2019-03-28  本文已影响0人  谢小帅

传统思路抽取小球
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
上一篇 下一篇

猜你喜欢

热点阅读