将递归函数转换为非递归函数

时间:2014-01-08 14:35:59

标签: java recursion

是否可以将函数go转换为非递归函数?一些提示或启动草图将非常有用

public static TSPSolution solve(CostMatrix _cm, TSPPoint start, TSPPoint[] points, long seed) {
    TSPSolution sol = TSPSolution.randomSolution(start, points, seed, _cm);
    double t = initialTemperature(sol, 1000);
    int frozen = 0;
    System.out.println("-- Simulated annealing started with initial temperature " + t + " --");
    return go(_cm, sol, t, frozen);
}

private static TSPSolution go(CostMatrix _cm, TSPSolution solution, double t, int frozen) {
    if (frozen >= 3) {
        return solution;
    }
    i++;

    TSPSolution bestSol = solution;
    System.out.println(i + ": " + solution.fitness() + " " + solution.time() + " "
            + solution.penalty() + " " + t);
    ArrayList<TSPSolution> nHood = solution.nHood();

    int attempts = 0;
    int accepted = 0;

    while (!(attempts == 2 * nHood.size() || accepted == nHood.size()) && attempts < 500) {
        TSPSolution sol = nHood.get(rand.nextInt(nHood.size()));
        attempts++;

        double deltaF = sol.fitness() - bestSol.fitness();
        if (deltaF < 0 || Math.exp(-deltaF / t) > Math.random()) {
            accepted++;
            bestSol = sol;
            nHood = sol.nHood();
        }
    }

    frozen = accepted == 0 ? frozen + 1 : 0;

    double newT = coolingSchedule(t);

    return go(_cm, bestSol, newT, frozen);

}

3 个答案:

答案 0 :(得分:4)

这很简单,因为它是尾递归的:递归调用和放大之间没有代码。函数返回什么。因此,一旦循环结束,您可以将go的正文包裹在循环while (frozen<3)return solution中。并使用参数的赋值替换递归调用:solution=bestSol; t=newT;

答案 1 :(得分:2)

你需要考虑两件事:

  1. 每一步都有哪些变化?
  2. 算法什么时候结束?
  3. 答案答案应该是

    1. bestSolsolution),newTt),frozenfrozen
    2. frozen >= 3为真时
    3. 因此,最简单的方法就是将整个函数包含在

      之类的内容中
      while (frozen < 3) {
          ...
          ...
          ...
      
          frozen = accepted == 0 ? frozen + 1 : 0;
          //double newT = coolingSchedule(t);
          t = coolingSchedule(t);
          solution = bestSol;
      }
      

答案 2 :(得分:1)

根据经验,迭代递归函数的最简单方法是将第一个元素加载到Stack上,而不是调用递归,而是将结果添加到Stack中。

例如:

public Item recursive(Item myItem)
{
    if(myItem.GetExitCondition().IsMet()
    {
        return myItem;
    }
    ... do stuff ...
    return recursive(myItem);
}

会变成:

public Item iterative(Item myItem)
{
    Stack<Item> workStack = new Stack<>();
    while (!workStack.isEmpty())
    {
        Item workItem = workStack.pop()
        if(myItem.GetExitCondition().IsMet()
        {
            return workItem;
        }
        ... do stuff ...
        workStack.put(workItem)
    }
    // No solution was found (!).
    return myItem;
}

此代码未经测试,可能(读取:确实)包含错误。它可能甚至不能编译,但应该给你一个大致的想法。