【问题标题】:Convert recursive function into the non-recursive function将递归函数转换为非递归函数
【发布时间】:2014-01-08 22:54:08
【问题描述】:

是否可以将函数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);

}

【问题讨论】:

  • 是的。所有递归方法都可以是非递归方法,反之亦然。

标签: java recursion


【解决方案1】:

这很简单,因为它是尾递归的:递归调用和函数返回的内容之间没有代码。因此,您可以将go 的主体包裹在循环while (frozen&lt;3) 中,并在循环结束后包裹return solution。并将递归调用替换为对参数的赋值:solution=bestSol; t=newT;

【讨论】:

    【解决方案2】:

    你需要考虑两件事:

    1. 每一步都有哪些变化?
    2. 算法什么时候结束?

    答案应该是

    1. bestSol (solution), newT (t), frozen (frozen)
    2. frozen &gt;= 3 为真时

    所以,最简单的方法就是将整个函数包含在类似

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

    【讨论】:

      【解决方案3】:

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

      例如:

      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;
      }
      

      此代码未经测试,可能(阅读:确实)包含错误。它甚至可能无法编译,但应该会给您一个大致的概念。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 2016-01-06
        • 1970-01-01
        • 2019-09-14
        • 2021-07-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多