递归循环

Recursive loops

问题是 return 如果您从 10,000 开始,需要达到 20,000,并且您每次下注 1,000(在达到 0 之前达到 20,000 的概率)。您有 50-50 的输赢变化。

public static double roulette( double start, double end, double bet) {

    if (start >= end) return 1;
    if (start <= 0) return 0;

        return .5*roulette(start+2*bet,end,bet) + .5*roulette(start-bet,end,bet);
}

但它陷入了无限循环,因为一些递归调用将再次开始。就好像我打了一个开始 = 11,000 的电话,它会回到 10,000 并创建一个循环。我该如何防止这种情况?

这是一个建议的迭代解决方案(我将实施留给您):

为了缩短它,让我们找到 roulette(10,20,1)(相当于您的 roulette(10000,20000,1000))。让我们用 r(10).

表示 roulette(10,20,1)

现在,让我们计算 r(i),其中 i0 变为 20

  • r(0) = 0 - 即如果您没钱就没有机会赢。
  • r(20) = 1 - 因为这意味着你赢了。

现在让我们计算其他 r(i)s:

  • r(1) = 0.5 * r(2) + 0.5 * r(0) = 0.5 * r(2) + 0 = 1/2 * r(2)

  • r(2) = 0.5 * r(3) + 0.5 * r(1) = 0.5 * r(3) + 0.5 * (0.5 * r(2))

这意味着

  • r(2) = 2/3 * r(3)

如果你继续这些计算,你会发现

  • r(3) = 3/4 * r(4)
  • r(4) = 4/5 * r(5)

...

  • r(18) = 18/19 * r(19)
  • r(19) = 19/20 * r(20) = 19/20 * 1 = 19/20

既然我们找到了r(19),我们可以找到r(18):

  • r(18) = 18/19 * 19/20 = 18/20
  • r(17) = 17/18 * r(18) = 17/18 * 18/20 = 17/20

...

  • r(10) = 10/20 = 0.5

因此,如果您从 10000 开始,需要达到 20000,并且每次下注 1000,那么您有 50% 的机会达到 20000。

正如我在评论中提到的,概率是所有以 start >= endleft < 0 结束的概率的总和。

static double roulette(double start, double end, double bet, int left) {
    if (start >= end && left >= 0)
        return 1; // you definitely win.
    if (start < bet || left < 0)
        return 0; // you cannot win.
    double win = 0.5 * roulette(start + bet, end, bet, left - 1);
    double lose = 0.5 * roulette(start - bet, end, bet, left - 1);
    return win + lose; // you get a 0.5-0.5 to win or lose.
}

例如,假设 start 是 100,end 是 200,bet 是 50。 如果总数为2,则只有一种方式:100->150->200,即0.25的概率。但如果总数为4,则可以有以下几种中奖方式:100->150->200、100->150->100->150->200、100->50->100->150-> 200。获胜的概率是 0.375.

关于 "probability of reaching 20,000 before you get to 0" 的特定查询,这可以作为 Random Walk over a one dimensional graph 解决,如解释的那样:

"If a and b are positive integers, then the expected number of steps until a one-dimensional simple random walk starting at 0 first hits b or −a is ab. The probability that this walk will hit b before −a is b/(a+b), which can be derived from the fact that simple random walk is a martingale."

给定,行走原点 = 10000,a=10000(距 0 的距离),b=10000(距 20000 的距离),& 步长 =1000: 在 -a = 10000/(10000 + 10000) = 1/2 之前到达 b 的概率。

不确定这是否是您想要实现的全部内容,这将是一行 return 语句。

另一方面,给定的实现最终将探索整个 space 可能的解决方案(即达到 0 或 20000 的所有可能方式)。请参阅 RandomWalk.pdf 中的概率和帕斯卡三角形部分,了解此时间及其长 运行 时间的增长模式。您的实施已开始沿着帕斯卡三角形最右边的分支/对角线探索,并继续探索所有可能的分支。

相反,另一种方法是尝试实现一种方法,该方法计算第一次达到 20000(或 0)的概率(并非以所有可能的方式)然后中断。选择向右(赢)还是向左(输)分支 at random。在几个 运行 秒内对数字进行平均,这应该非常接近概率,如上计算的 ~1/2。

有趣的是,n 步后随机游走的预期距离 = sqrt(n)。这可用于估计正确实现的算法达到 20000 或 0 所需的迭代次数或递归调用次数(复杂性)。 在这种情况下,距离 n = ((20000-10000)/1000) = 10,平均需要大约 n*n = 100 步/迭代。