由“賽爾號超陰間BOSS”關(guān)卡引來的思考,通過馬爾可夫鏈計算通關(guān)的期望天數(shù)

之前看評論區(qū)覺得很難算,先用模擬值跑了一遍。今天受到啟發(fā),發(fā)現(xiàn)也沒那么難算。
首先亮python代碼:

import math
import numpy as np
from scipy.special import comb
def transition_probability(current_on, num_toggled):
? ? """計算給定當前開啟的開關(guān)數(shù)量和操控的開關(guān)數(shù)量后的轉(zhuǎn)移概率分布"""
? ? prob_dist = [0] * 10
? ? # 每種情況下,計算有多少種方式選擇開和關(guān)的開關(guān)
? ? 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個開關(guān)
matrix = build_matrix()
print(matrix)
# 使用前面得到的轉(zhuǎn)移矩陣
matrix = build_matrix()
def expected_days_to_all_on():
? ? # 初始化一個9x9的矩陣,對應(yīng)從0到8個開關(guān)打開的狀態(tài)
? ? A = np.eye(9) - matrix[:-1, :-1]
? ?
? ? # 我們從所有狀態(tài)要加1天到下一個狀態(tài),所以初始化為1
? ? b = np.ones(9)
? ?
? ? # 解Ax = b的方程組來得到期望值
? ? E = np.linalg.solve(A, b)
? ?
? ? # 我們只關(guān)心從0個開關(guān)打開的狀態(tài)開始所需的期望天數(shù)
? ? return E[0]
average_days = expected_days_to_all_on()
average_days_required = math.ceil(average_days / 10)
print(f"通關(guān)的期望天數(shù):{average_days_required}")

運行結(jié)果:
[[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.??????? ]]
通關(guān)的期望天數(shù):53

思考過程:
以下把翻牌替換成開關(guān)
對于這個問題,我們有9個開關(guān),每個開關(guān)可以處于兩種狀態(tài):開或關(guān)。因此,總共有2^9=512種可能的配置。
當我們談?wù)撧D(zhuǎn)移矩陣時,我們要考慮從每種配置(當前狀態(tài))轉(zhuǎn)移到每種其他配置(下一個狀態(tài))的概率。
所以,我們的矩陣有512行和512列:
512行:代表所有可能的當前配置。
512列:代表從當前配置可能轉(zhuǎn)移到的所有其他配置。
因此,完整的轉(zhuǎn)移矩陣是一個2^9×2^9,也就是512×512的矩陣。
簡單地說,矩陣的每一行代表一種可能的初始配置,而該行的每一列則代表從那個初始配置轉(zhuǎn)移到每種其他配置的概率。
換一個思路
如果我們只考慮開關(guān)為開的狀態(tài)的數(shù)量,那么我們可以將狀態(tài)簡化為一個從0到9的整數(shù),其中整數(shù)表示當前為開的開關(guān)的數(shù)量。這樣,我們只需要一個10×10的轉(zhuǎn)移矩陣,求解出概率就可以計算天數(shù)了。


由ChatGPT3.5協(xié)作完成,優(yōu)化思路靈感來源@xzip7775
以上。