我有一个程序可以计算某种赌注的各种指标,例如 EV、获胜机会等。我还想要衡量赌注的“方差”程度。我的明确意思是:“重复下注 n 次后,你用完 X 现金的概率是多少。” 我目前通过运行模拟来做到这一点,但这非常慢。我正在寻找一种更直接的数学/计算解决方案来做到这一点。
赌注不仅有两个结果。它有一个失败状态和任何给定数量的获胜状态,具有不同的概率和不同的支出,数据都可供程序使用。
这就是我目前使用模拟的方式:
Function GetOutcomeList() As List(Of Integer)
Dim result As New List(Of Integer)
For i = 1 To combos
Dim addcount As Integer = Math.Round((windistribution(i, 0, 1) / winchance(0)) * 500000)
For j = 1 To addcount
result.Add(windistribution(i, 0, 0))
Next
Next
Return result
End Function
上面的函数填充一个列表,以便从该列表中随机选择的任何元素都将具有与其相应概率相同的被选择机会。
Function GetVarianceMetric(bankroll As Integer) As Double
Dim simcount As Integer = 4000
Dim numofgames As Integer = bankroll / (bet ^ 0.6)
Dim simspassed As Integer = 0
Dim outcomeList As List(Of Integer) = GetOutcomeList()
For sims = 1 To simcount
Dim cash As Double = bankroll
For i = 1 To numofgames
Dim roll As Double = generator.NextDouble
cash -= bet
If roll <= winchance(0) AndAlso cash >= 0 Then
cash += outcomelist(generator.Next(1, outcomelist.Count))
ElseIf cash <= 0 Then
Exit For
End If
Next
If cash > 0 Then
simspassed += 1
End If
Next
Return (simspassed / simcount) * 100
End Function
以下是我尝试实施 meowgoesthedog 解决方案的尝试,但在处理更多赌注/结果时,它最终比我的 monte carlo 解决方案慢得多:
Structure OutCome
Dim prob As Double
Dim cashChange As Integer
End Structure
Function GetNewVarianceMetric(bankroll As Integer) As Double
Dim n As Integer = 10
Dim out_list(winstates) As OutCome
Dim taken(winstates) As Boolean
For i = 0 To winstates - 1
Dim biggest() As Integer = {0, 0}
For j = 1 To winstates
If taken(j) = False AndAlso (windistribution(j, 0, 0) - betsize) >= biggest(1) Then
biggest(1) = windistribution(j, 0, 0)
biggest(0) = j
End If
Next
Dim oc As New OutCome
oc.cashChange = windistribution(biggest(0), 0, 0) - betsize
oc.prob = windistribution(biggest(0), 0, 1)
out_list(i) = oc
taken(biggest(0)) = True
Next
Dim ocLose As New OutCome
ocLose.cashChange = -betsize
ocLose.prob = 1 - winchance(0)
out_list(winstates) = ocLose
Dim prob_list(winstates) As Double
Dim c As Double = 0
For i = winstates To 0 Step -1
c += out_list(i).prob
prob_list(i) = c
Next
Dim prob_runout As Double = prob_enough(n, bankroll, out_list, prob_list) * 100
Return prob_runout
End Function
Function prob_enough(n As Integer, x As Integer, out() As OutCome, probs() As Double) As Double
If x <= 0 Then
Return 0
End If
If n <= 1 Then
Dim i As Integer = search_smallest(out, x)
If (i < winstates) Then
Return probs(i)
Else
Return 0
End If
End If
Dim S As Double = 0
For i = winstates To 0 Step -1
If out(i).cashChange < -x Then
Exit For
End If
S += out(i).prob * prob_enough(n - 1, x + out(i).cashChange, out, probs)
Next
Return S
End Function
Function search_smallest(out() As OutCome, x As Integer) As Integer
Dim left As Integer = 0
Dim right As Integer = winstates
While left < right
Dim i As Integer = (left + right) / 2
If out(i).cashChange >= -x Then
right = i
Else
left = i + 1
End If
End While
Return left
End Function