递归函数需要很长时间才能运行

时间:2010-12-10 16:12:45

标签: java

我描述了我的代码,发现我的程序花了大约85%的时间执行这个特定的递归函数。该函数旨在计算在给定初始位置(x,y)的情况下到达马尔可夫链中的一组状态的概率。

private static boolean condition(int n){
    int i = 0;
    while ( n >= i){
        if( n == i*4 || n == (i*4 - 1))
            return true;
            i++;
        }
    return false;
}

public static double recursiveVal(int x, int y, double A, double B){

    if(x> 6 && (x- 2 >= y)){ return 1;}
    if(y> 6 && (y- 2 >= x)){ return 0;}
    if(x> 5 && y> 5 && x== y){ return (A*(1-B) / (1 -(A*B) - ((1-A)*(1-B))));}

    if(condition(x+ y)){
        return (recursiveVal(x+1, y,A,B)*A + recursiveVal(x, y+1,A,B)*(1-A));
    }
    else{
        return (recursiveVal(x+1, y,A,B)*(1-B) + recursiveVal(x,y+1,A,B)*B);
    }
}

我曾被告知,99%的递归函数可以被while循环替换。我做这件事虽然困难。有谁知道如何改进执行时间或将其重写为迭代循环?

由于

4 个答案:

答案 0 :(得分:7)

您可以尝试使用一种名为memoization的技术,该技术基本上会缓存先前为递归调用计算的结果。

作为旁注,我建议稍微重新格式化您的代码。这是yoru代码的简化版本。

private static boolean condition(int n){
    for (int i = 0; i <= n; i++)
        if(n == i*4 || n == (i * 4 - 1))
            return true;
    return false;
}

public static double recursiveVal(int x, int y, double A, double B){

    if (x > 6 && (x - 2 >= y))
        return 1;

    if (y > 6 && (y - 2 >= x))
        return 0;

    if(x > 5 && y > 5 && x == y)
        return A*(1-B) / (1 -(A*B) - ((1-A)*(1-B)));

    double val1 = recursiveVal(x+1, y, A, B);
    double val2 = recursiveVal(x, y+1, A, B);

    return condition(x + y)
        ? A * val1 + val2 * (1-A)
        : (1-B) * val1 + B * val2; 
}

答案 1 :(得分:0)

要将其转换为迭代形式,请注意您正在计算两个(离散)变量的函数。您可以使用表来存储函数的值,并按特定顺序填写表,以便在需要时已经计算出所需的值。 (在这种情况下,来自xy)的较高值。

在这种情况下,边界情况(对应于原始递归中的基本情况)是:

f(7, y..5), f(8, 6)
f(x..5, 7), f(6, 8)
f(7, 7)

然后我们填写f(7, 6)f(6, 7),然后“向下”继续 - 即     f(6,6),f(5,6)... f(x,6),f(6,5),f(5,5)... f(x,5)... f( x,y)。

请注意,看起来像函数调用语法的对应于表查找(它实际上转换为数组语法)。

答案 2 :(得分:0)

如果要将递归函数重构为迭代函数,步骤如下:

  

1)确定递归的基本情况。达到基本情况时,会导致递归结束。每个递归必须具有已定义的基本情况。此外,每个递归调用必须在基本情况下取得进展(否则将无限执行递归调用)。
  2)实现一个循环,迭代直到达到基本情况   3)在基础案例方面取得进展。将新参数发送到循环顶部而不是递归方法。

答案 3 :(得分:0)

如何尝试理解它正在做什么可以使代码更快/更简单......

这种方法试图确定'n'是4的倍数还是n + 1是4的倍数。这可以写得更短。

private static boolean condition(int n){
    return (n+1) & 3 <= 1;
}