我有这个函数我写的非常慢,因为php不能很好地处理递归。我正在尝试将其转换为while循环,但我无法绕过如何做到这一点。
有人能给我一些提示吗?
public function findRoute($curLoc, $distanceSoFar, $expectedValue) {
$this->locationsVisited[$curLoc] = true;
$expectedValue += $this->locationsArray[$curLoc]*$distanceSoFar;
$at_end = true;
for($i = 1; $i < $this->numLocations; $i++) {
if($this->locationsVisited[$i] == false) {
$at_end = false;
if($expectedValue < $this->bestEV)
$this->findRoute($i, $distanceSoFar + $this->distanceArray[$curLoc][$i], $expectedValue);
}
}
$this->locationsVisited[$curLoc] = false;
if($at_end) {
if($expectedValue < $this->bestEV) {
$this->bestEV = $expectedValue;
}
}
}
答案 0 :(得分:7)
我不打算转换你的代码,但你可以通过创建一个堆栈将一个recusive函数转换为迭代函数:
$stack= array();
而不是调用$this->findroute()
,而是将参数推送到此堆栈:
$stack[] = array($i, $distanceSoFar + $this->distanceArray[$curLoc][$i], $expectedValue);
现在将函数中的所有内容基本上包围在一个while循环中,在启动它之后排空堆栈:
while ($stack) {
// Do stuff you already do in your function here
答案 1 :(得分:2)
您可以使用堆栈存储当前状态,将递归函数转换为迭代函数。查看array_push()
和array_pop()
。
答案 2 :(得分:0)
一眼我不认为递归是你的问题,是的,它在PHP中很慢,但看起来你的价值超过你需要的值,将值放在一个堆栈中,或几个堆栈并处理它们,可能很好。
自定义排序功能一直帮助我解决这类问题。
function sort_by_visited($x,$y)
{
return ($this->locationsVisited[$x] > $this->locationsVisited[$y]) ? -1 : 1;
}
uasort($locationsVisited,'sort_by_visited');
这将优先考虑堆栈顶部的所有未访问位置。
答案 3 :(得分:0)
这看起来像是在尝试找到遍历图表中一系列节点的最佳路径。
我猜你没有学过计算机科学,因为“旅行推销员”问题是人工智能的原型。当然,因此,它有自己的维基百科页面:
http://en.wikipedia.org/wiki/Travelling_salesman_problem
抱歉 - 但是从递归到迭代函数的交换不会让它更快(“php不能很好地处理递归。” - 你能为这个断言提供参考)。如果您需要更快的解决方案,那么您需要查看非穷举/模糊方法。
下进行。