我花了幾天時間試圖弄清楚這一點并查找教程,但到目前為止我發現的一切似乎都接近我需要的,但沒有給出我需要的結果。
我有一個產生單個字母的設備,AF。為簡單起見,您可以將其視為帶有字母的骰子。每次使用時,它總是會產生一個且只有一個字母。然而,它有一個主要區別:每個字母可以有不同的已知被選中概率:
A: 25%
B: 5%
C: 20%
D: 15%
E: 20%
F: 15%
這些概率在所有嘗試中保持不變。
此外,在我“成功”之前,我必須積累一個特定的組合:
As needed: 1
Bs needed: 3
Cs needed: 0
Ds needed: 1
Es needed: 2
Fs needed: 3
我需要找到要累積的這種字母組合必須發生的字母選擇(即滾動/試驗/嘗試)的平均數量。任何單個結果的字母數量超過所需數量是完全可以的,但只有當每個字母至少被選擇了最少次數時,才算成功。
我已經查看了很多關于多項概率分布和類似內容的教程,但我還沒有找到任何解釋如何為這樣的場景找到平均試驗次數的東西。請清楚地解釋答案,因為我不是統計專家。
uj5u.com熱心網友回復:
除了Severin 的回答,邏輯上對我來說看起來不錯,但評估成本可能很高(即無限的階乘總和)。讓我提供一些直覺,應該給出一個很好的近似值。
一次考慮每個類別。請參閱此數學 stackexchange 問題/答案。您將獲得每個類別(i)的k次成功的預期投擲次數可以計算為k(i)/ P(i):
Given,
p(A): 25% ; Expected number of tosses to get 1 A = 1/ 0.25 = 4
p(B): 5% ; Expected number of tosses to get 3 B's = 3/ 0.05 = 60
p(C): 20% ; Expected number of tosses to get 0 C = 0/ 0.20 = 0
p(D): 15% ; Expected number of tosses to get 1 D = 1/ 0.15 = 6.67 ~ 7
p(E): 20% ; Expected number of tosses to get 2 E's = 2/ 0.20 = 10
p(F): 15% ; Expected number of tosses to get 3 F's = 3/ 0.15 = 20
您知道獲得 3 個 B 是您的瓶頸,您可以預期平均 60 次投擲來完成您的場景。
uj5u.com熱心網友回復:
好吧,最少的投擲次數是 10。平均值是無限的總和
A=10?P(在 10 內完成) 11?P(在 11 內完成) 12?P(在 12 內完成) ...
對于 P(done in 10),我們可以使用多項式
P(10)=Pm(1,3,0,1,2,3|probs),其中 probs=[.25, .05, .20, .15, .20, .15]
對于 P(11),你還有一個投擲,你可以像這樣分配
P(11)=Pm(2,3,0,1,2,3|probs) Pm(1,4,0??,1,2,3|probs) Pm(1,3,0,2,2 ,3|概率) Pm(1,3,0,1,3,3|概率) Pm(1,3,0,1,2,4|概率)
對于 P(12),您必須再分配 2 次投擲。請注意,有一些無法獲得的 throws 組合,例如 Pm(2,3,0,2,2,3|probs),因為您必須提前停止
等等等等
uj5u.com熱心網友回復:
您的程序可以描述為具有有限數量狀態和吸收狀態的馬爾可夫鏈。
到達吸收狀態之前的步數稱為擊球時間。從馬爾可夫鏈的轉移矩陣可以很容易地計算出預期的命中時間。
列舉所有可能的狀態(a、b、c、d、e、f)。僅考慮有限數量的狀態,因為“b >= 3”實際上與“b = 3”等相同。狀態總數為
(1 1)*(3 1)*(0 1)*(2 1)*(3 1) = 192。確保在您的列舉中,起始狀態 (0, 0, 0, 0, 0, 0) 排在第一位,索引為 0,吸收狀態 (1, 3, 0, 1, 2, 3) 排在最后。
建立轉移矩陣
P。它是一個方陣,每個狀態有一行和一列。矩陣中的條目P[i, j]給出了擲骰子時從一個狀態i到另一個狀態的概率j。每行最多應有 6 個非零條目。例如,如果
i是狀態指數(1, 0, 0, 1, 2, 2)和狀態j指數(1, 1, 0, 1, 2, 2),那么P[i, j]= 滾動面 B 的概率 = 0.05。另一個例子:如果i是狀態的指數(1,3,0,0,0,0),則P[i,i]=滾動A、B或C的概率=0.25 0.05 0.2=0.5。呼叫
Q去掉 的最后一行最后一列得到的方陣P。呼叫
I與 相同維度的單位矩陣Q。計算矩陣
M = (I - Q)^-1,其中^-1是矩陣求逆。在矩陣
M中,條目是從狀態開始時,在吸收狀態之前達到M[i, j]該狀態的預期次數。ji由于我們的實驗從狀態 0 開始,我們對矩陣 M 的第 0 行特別感興趣。
矩陣 M 的第 0 行之和是在吸收狀態之前達到的預期狀態總數。這正是我們尋求的答案:達到吸收狀態的步數。
要了解為什么會這樣,您應該閱讀有關馬爾可夫鏈的課程!也許是這個:詹姆斯·諾里斯關于馬爾可夫鏈的課程筆記。關于“命中次數”(即達到目標狀態之前的步數的名稱)的章節是第 1.3 章。
下面是python中的一個實作。
from itertools import product, accumulate
from operator import mul
from math import prod
import numpy as np
dice_weights = [0.25, 0.05, 0.2, 0.15, 0.2, 0.15]
targets = [1, 3, 0, 1, 2, 3]
def get_expected_n_trials(targets, dice_weights):
states = list(product(*(range(n 1) for n in targets)))
base = list(accumulate([n 1 for n in targets[:0:-1]], mul, initial=1))[::-1]
lookup = dict(map(reversed, enumerate(states)))
P = np.zeros((len(states), len(states)))
for i, s in enumerate(states):
a,b,c,d,e,f = s
for f, p in enumerate(dice_weights):
#j = index of state reached from state i when rolling face f
j = i base[f] * (s[f] < targets[f])
j1 = lookup[s[:f] (min(s[f] 1, targets[f]),) s[f 1:]]
if (j != j1):
print(i, s, f, ' --> ' , j, j1)
assert(j == j1)
P[i,j] = p
Q = P[:-1, :-1]
I = np.identity(len(states)-1)
M = np.linalg.inv(I - Q)
return M[0,:].sum()
print(get_expected_n_trials(targets, dice_weights))
# 61.28361802372382
代碼說明:
- 首先,我們使用笛卡爾積構建狀態串列
itertools.product - 對于給定的狀態
i和模具面f,我們需要j在添加 f 時計算 = 從 i 到達的狀態。我有兩種計算方法, asj = i base[f] * (s[f] < targets[f])或 asj = lookup[s[:f] (min(s[f] 1, targets[f]),) s[f 1:]]。因為我很偏執,所以我用兩種方法計算了它,并檢查了兩種方法是否給出了相同的結果。但你只需要一種方式。j1 = ...如果需要,您可以洗掉行assert(j == j1)。 - 矩陣
P開始填充零,我們每行最多填充六個單元格,P[i, j] = p其中p是滾動面的概率f。 - 然后我們計算矩陣
Q,M正如我上面指出的那樣。 - 我們回傳第一行所有單元格的總和
M。
為了幫助您更好地了解正在發生的事情,我鼓勵您檢查所有變數的值。例如,您可以替換return M[0, :].sum()為return states, base, lookup, P, Q, I, M然后寫入states, base, lookup, P, Q, I, M = get_expected_n_trials(targets, dice_weights)python 互動式 shell,以便您可以單獨查看變數。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/471329.html
上一篇:如何在Linux中計算浮點數?
