欢迎光临散文网 会员登陆 & 注册

由“赛尔号超阴间BOSS”关卡引来的思考,通过马尔可夫链计算通关的期望天数

2023-08-24 16:25 作者:彡清欢  | 我要投稿

之前看评论区觉得很难算,先用模拟值跑了一遍。今天受到启发,发现也没那么难算。
首先亮python代码:

import math

import numpy as np

from scipy.special import comb


def transition_probability(current_on, num_toggled):

    """计算给定当前开启的开关数量和操控的开关数量后的转移概率分布"""

    prob_dist = [0] * 10


    # 每种情况下,计算有多少种方式选择开和关的开关

    for k in range(num_toggled + 1):

        num_on = k

        num_off = num_toggled - k

       

        if num_on <= current_on and num_off <= 9 - current_on:

            ways_to_pick_on = comb(current_on, num_on)

            ways_to_pick_off = comb(9 - current_on, num_off)

           

            total_ways = ways_to_pick_on * ways_to_pick_off

           

            prob = total_ways / comb(9, num_toggled)

           

            if current_on - num_on + num_off <= 9:

                prob_dist[current_on - num_on + num_off] += prob


    return prob_dist


def build_matrix():

    matrix = np.zeros((10, 10))

    for current_on in range(10):

        for num_toggled in range(1, 4):

            transitions = transition_probability(current_on, num_toggled)

            matrix[current_on] += transitions

    return matrix / 3  # 除以3是因为我们随机选择操控1到3个开关


matrix = build_matrix()

print(matrix)


# 使用前面得到的转移矩阵

matrix = build_matrix()


def expected_days_to_all_on():

    # 初始化一个9x9的矩阵,对应从0到8个开关打开的状态

    A = np.eye(9) - matrix[:-1, :-1]

   

    # 我们从所有状态要加1天到下一个状态,所以初始化为1

    b = np.ones(9)

   

    # 解Ax = b的方程组来得到期望值

    E = np.linalg.solve(A, b)

   

    # 我们只关心从0个开关打开的状态开始所需的期望天数

    return E[0]


average_days = expected_days_to_all_on()

average_days_required = math.ceil(average_days / 10)

print(f"通关的期望天数:{average_days_required}")

运行结果:
[[0.         0.33333333 0.33333333 0.33333333 0.         0.
  0.         0.         0.         0.        ]
 [0.03703704 0.07407407 0.40740741 0.25925926 0.22222222 0.
  0.         0.         0.         0.        ]
 [0.00925926 0.10185185 0.12962963 0.42592593 0.19444444 0.13888889
  0.         0.         0.         0.        ]
 [0.00396825 0.02777778 0.18253968 0.16666667 0.40079365 0.13888889
  0.07936508 0.         0.         0.        ]
 [0.         0.01587302 0.05555556 0.26719577 0.18518519 0.34391534
  0.09259259 0.03968254 0.         0.        ]
 [0.         0.         0.03968254 0.09259259 0.34391534 0.18518519
  0.26719577 0.05555556 0.01587302 0.        ]
 [0.         0.         0.         0.07936508 0.13888889 0.40079365
  0.16666667 0.18253968 0.02777778 0.00396825]
 [0.         0.         0.         0.         0.13888889 0.19444444
  0.42592593 0.12962963 0.10185185 0.00925926]
 [0.         0.         0.         0.         0.         0.22222222
  0.25925926 0.40740741 0.07407407 0.03703704]
 [0.         0.         0.         0.         0.         0.
  0.33333333 0.33333333 0.33333333 0.        ]]
通关的期望天数:53

思考过程:
以下把翻牌替换成开关

对于这个问题,我们有9个开关,每个开关可以处于两种状态:开或关。因此,总共有2^9=512种可能的配置。

当我们谈论转移矩阵时,我们要考虑从每种配置(当前状态)转移到每种其他配置(下一个状态)的概率。

所以,我们的矩阵有512行和512列:

  • 512行:代表所有可能的当前配置。

  • 512列:代表从当前配置可能转移到的所有其他配置。

因此,完整的转移矩阵是一个2^9×2^9,也就是512×512的矩阵。

简单地说,矩阵的每一行代表一种可能的初始配置,而该行的每一列则代表从那个初始配置转移到每种其他配置的概率。

换一个思路

如果我们只考虑开关为开的状态的数量,那么我们可以将状态简化为一个从0到9的整数,其中整数表示当前为开的开关的数量。这样,我们只需要一个10×10的转移矩阵,求解出概率就可以计算天数了。

由ChatGPT3.5协作完成,优化思路灵感来源@xzip7775

以上。

由“赛尔号超阴间BOSS”关卡引来的思考,通过马尔可夫链计算通关的期望天数的评论 (共 条)

分享到微博请遵守国家法律