是否可以将函数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);
}
答案 0 :(得分:4)
这很简单,因为它是尾递归的:递归调用和放大之间没有代码。函数返回什么。因此,一旦循环结束,您可以将go
的正文包裹在循环while (frozen<3)
和return solution
中。并使用参数的赋值替换递归调用:solution=bestSol; t=newT;
。
答案 1 :(得分:2)
你需要考虑两件事:
答案答案应该是
bestSol
(solution
),newT
(t
),frozen
(frozen
)frozen >= 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;
}
此代码未经测试,可能(读取:确实)包含错误。它可能甚至不能编译,但应该给你一个大致的想法。