-1

我有一个程序可以计算某种赌注的各种指标,例如 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
4

2 回答 2

0

如果我正确阅读了您的问题,那么您的赌注有多种“赢”或“输”的方式。我相信您首先需要确定每次输赢的适当分布函数。然后,您需要将这些函数中的每一个作为自变量进行评估,并确定代表您的函数集合的分布函数。总之,你需要找到这组概率函数的联合密度函数。这不是一个简单的操作,尽管有几种方法可以解决。您使用的确切方法取决于每个结果所表示的分布函数的类型,以及这些函数的行为。

这不是一个简单的操作,并且可能更容易(但更慢)从你正在做的经验方法中进行。

于 2018-03-12T16:30:14.787 回答
0

你提出的问题听起来不像我所知道的任何“差异”衡量标准,所以我只能搁置这个问题。另外,我会假设您的问题专门关于计算用完钱的概率,而不是关于一般统计计算(这太广泛了)。


对于n赌注和m结果,有一种确定性的方法可以及时解决这个问题在此处输入图像描述

  1. 假设我们最初有一系列A结果m,每个结果都有相关的概率p货币变化 y(支出减去初始存款)。对这个数组进行排序y

  2. 计算从数组末尾开始的累积概率。最后加起来应该是1。

  3. 用 调用例程n, X,其中n是剩余投注数,X是当前预算。

  4. 如果,使用二分搜索,找到这样n = 1的索引。这是玩家能够承受的最昂贵的结果。返回此索引处的累积概率。iA[i:] >= -X

  5. 如果n > 1,为输出概率保留一个变量S,并将其初始化为 0。对于上述所有值,从末尾开始A[i] >= -X

    • 从 (3) 开始,使用预算执行递归调用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
于 2018-03-12T21:33:02.450 回答