递归循环

时间:2018-01-18 06:53:45

标签: java recursion infinite-loop probability

问题是返回概率,如果你从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);
}

但它会陷入无限循环,因为一些递归调用会再次启动。就像我点击一个start = 11,000的调用一样,它将返回10,000并创建一个循环。我该如何防止这种情况?

3 个答案:

答案 0 :(得分:1)

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

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

现在,让我们计算r(i) i020的位置。

  • 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。

答案 1 :(得分:1)

关于“在达到0之前达到20,000的概率”的具体查询,这可以解释为Random Walk over a one dimensional graph,如下所述:

  

“如果a和b是正整数,那么直到从0开始的一维简单随机游动首先击中b或-a的预期步数是ab。这个步行在-a之前击中b的概率是b /(a + b),这可以从简单随机游走是鞅的事实中得出。“

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

不确定这是否是您想要实现的所有内容,这将是一行返回语句。

另一方面,给定的实现将最终探索可能解决方案的整个空间(即,达到0或20000的所有可能方式)。请参阅概率&amp; RandomWalk.pdf中的Pascal三角形截面,用于此&amp;的增长模式。它的运行时间很长。你的实现已经开始沿着pascal三角形的最右边的分支/对角线进行探索。继续探索所有可能的分支。

相反,替代方案可以是尝试实现一种方法来计算第一次达到20000(或0)的概率(并且不是以所有可能的方式)&amp;然后休息。选择向右(赢)或左分支(亏损)at random。在几次运行中平均数字&amp;它应该非常接近概率,如上所计算的~1 / 2。

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

答案 2 :(得分:0)

正如我在评论中提到的,概率是所有概率的总和,最终得到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- &GT; 100-&GT; 150-&GT; 200。获胜的概率是0.375。