我有一个程序可以计算某种投注的各种指标,例如EV,获胜机会等等。我还想要的是衡量投注“差异多大”的指标。而我明确指出的是:“经过多次重复下注后,你将有多少时间用完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
答案 0 :(得分:0)
如果我正确地阅读了您的问题,您可以通过多种不同的方式下注并赢得&#34;或者&#34;输掉&#34;。我相信你首先需要确定每次输赢的适当分配函数。然后,您需要将这些函数中的每一个作为一个独立变量进行评估,并确定一个代表您的函数集合的分布函数。简而言之,您需要找到这组概率函数的联合密度函数。这不是一个简单的操作,尽管有几种方法可以解决它。您使用的确切方法取决于每个结果所代表的分布函数的类型以及这些函数的行为。
这不是一个简单的操作,你可能更容易(但更慢)从经验方法中去做。
答案 1 :(得分:0)
你提出的问题听起来并不像我所知道的那种“差异”,所以我只能把它搁置一边。此外,我将假设您的问题具体关于计算资金耗尽的可能性,而不是关于一般统计计算(这将太宽泛)。< / p>
对于n
投注和m
结果,有一种确定性方法可以在时间内解决此问题:
假设我们最初有A
个m
个结果数组,每个结果的相关概率p
和货币变化 y
(支付减去初始存款)。按y
排序此数组。
从数组的 end 开始计算累积概率。最后应该加1。
使用n, X
调用例程,其中n
是剩余投注数,X
是当前预算。
如果n = 1
使用二进制搜索,请找到i
索引A[i:] >= -X
。这是玩家能负担得起的最昂贵的结果。返回此指数的累积概率。
如果n > 1
,请为输出概率保留变量S
,并将其初始化为0.从上面开始,对于A[i] >= -X
的所有值,如上所述:
n - 1, X + A[j].y
。A[j].p
并添加到S
。S
。以上内容可能会让您感到困惑。该算法探讨了所有可能的方式下注n
次而没有用完资金,并以连续投注独立为由积累其概率。
请注意,这是 1减去您想要的数量(超出预算的概率);计算这个数量的原因是,因为我们在预算范围内,我们可以花费的金额总是从上面限制,这意味着我们需要测试的案例更少。
编辑:示例实施:
struct outcome
{
double prob; // probability "p"
int change; // change in money "y"
};
// search for the most expensive bet
static size_t search_smallest(const vector<outcome> & out, int X)
{
size_t left = 0, right = out.size();
while (left < right)
{
size_t i = (left + right) / 2;
if (out[i].change >= -X)
right = i;
else
left = i + 1;
}
return left;
}
// compute the probability that it is enough
static double prob_enough(unsigned n, int X,
const vector<outcome> & out, const vector<double> & probs)
{
if (X <= 0) return 0.0;
if (n <= 1) {
size_t i = search_smallest(out, X);
return (i < out.size()) ? probs[i] : 0.0;
}
double S = 0.0;
for (size_t i = out.size(); i > 0; i--)
{
if (out[i - 1].change < -X) break;
S += out[i - 1].prob * prob_enough(n - 1, X + out[i - 1].change, out, probs);
}
return S;
}
int main()
{
int n, X;
// input number of bets and budget
// ...
vector<outcome> out_list;
// input different outcomes and fill out_list
// ...
// sort out_list with respect to y
sort(out_list.begin(), out_list.end(),
[](const outcome & a, const outcome & b) { return a.change < b.change; });
// create cumulative list
vector<double> prob_list(out_list.size());
{
double c = 0.0;
for (size_t i = out_list.size(); i > 0; i--)
{
c += out_list[i - 1].prob;
prob_list[i - 1] = c;
}
}
double prob_runout = 1.0 - prob_enough(n, X, out_list, prob_list);
}
测试用例:
X = 7, n = 3
Outcome no. | 1 2 3
-----------------------------------
Change (y) | -10 1 2
Probability (p) | 0.5 0.4 0.1
--> prob_runout = 0.83
确认 - 在所有投注完成之前用尽的不同方式:
Outcomes | Probability
----------|---------------------
[1, ., .] | 0.5 = 0.5
[2, 1, .] | 0.4*0.5 = 0.2
[3, 1, .] | 0.1*0.5 = 0.05
[2, 2, .] | 0.4*0.4*0.5 = 0.08
Total = 0.83