在递归中求和

时间:2013-05-10 23:06:04

标签: java recursion

在递归中求和:它是否总是产生StackOverflow错误?

public final static float getAlpha(int t, int i, int N, float[] P, float[][] B, float[][] A, int[] O)
{
    float alpha;
    if (t==1)
    {
        alpha = P[i] * B[i][O[0] - 1];
    }
    else
    {
        float sum = 0;
        int k;
        for (k=0; k < N; k++){
            sum = sum + (getAlpha(t-1, k, N, P, B, A, O) * A[k][i]);
        }
        alpha = sum * B[i][O[0] - 1];
    }
    return alpha;
}

我收到该行的错误:

sum = sum + (getAlpha(t-1, k, N, P, B, A, O) * A[k][i]);

有没有创意解决方案?

3 个答案:

答案 0 :(得分:2)

我建议使用动态编程方法。这种方式永远不会计算第二次的值,您也不必担心堆栈溢出。

通过N数组创建一个t。

所以Array[i][0] = P[i] * B[i][O[0] - 1]

从这里你总结前一行的所有元素并乘以A[k][i] and B[i][O[0] - 1],其中k是前一列的行的索引,i是索引。当前列的一行。

对于最终结果,您需要使用最初调用它的i值。

这样您只需进行2*t次乘法和t*N*N求和。显着低于你现在正在做的事情。

如果您需要实际实施方面的帮助,您应该查看veterbi算法。它非常相似。

答案 1 :(得分:0)

显然你的t非常大(或者有一个错误,它小于1)。

所以,除非你可以重写这个函数以使尾递归(很难,因为递归发生在循环中),并且你正在运行正确类型的JVM进行尾递归(只有少数实际做),递归解决方案总是会溢出堆栈。

此时,我建议尝试以迭代方式重写它。这可能意味着从下往上开始,并将中间值存储在数组中。

答案 2 :(得分:0)

在我看来,你不必要地反复重新计算相同的值。您的递归遵循树模式,其中每个分支都是相同的,并且这些分支的每个子分支都是相同的,等等。因此,所涉及的计算量指数大于它应该的大小。