【发布时间】:2012-04-09 19:57:58
【问题描述】:
public List<Location2D> Path(Location2D start, Location2D goal)
{
openset = new List<NodeInfo>(); // The set of tentative nodes to be evaluated, initially containing the start node.
closedset = new List<NodeInfo>(); // The set of nodes already evaluated.
path = new List<Location2D>(); // The path result.
came_from = new Dictionary<Location2D, Location2D>();
NodeInfo Start = new NodeInfo();
Start.SetLoction(start.X, start.Y);
Start.H = GetHValue(start, goal);
openset.Add(Start);
while (openset.Count > 0) { // while openset is not empty
NodeInfo current = CheckBestNode(); //the node in openset having the lowest f_score[] value
if (current.Location.Equals(goal)) {
ReconstructPathRecursive(current.Location);
return path;
}
for (int i = 0; i < 8; i++) { // neighbor nodes.
NodeInfo neighbor = new NodeInfo();
neighbor.SetLoction((ushort)(current.Location.X + ArrayX[i]), (ushort)(current.Location.Y + ArrayY[i]));
bool tentative_is_better = false;
if (closedset.Contains(neighbor))
continue;
if (!map.Cells[neighbor.Location.X, neighbor.Location.Y].Walkable) { closedset.Add(neighbor); continue; }
Double tentative_g_score = current.G + DistanceBetween(current.Location, neighbor.Location);
if (!openset.Contains(neighbor)) {
openset.Add(neighbor);
neighbor.H = GetHValue(neighbor.Location, goal);
tentative_is_better = true;
} else if (tentative_g_score < neighbor.G) {
tentative_is_better = true;
} else {
tentative_is_better = false;
}
if (tentative_is_better) {
came_from[neighbor.Location] = current.Location;
neighbor.G = tentative_g_score;
}
}
}
return null;
}
private void ReconstructPathRecursive(Location2D current_node)
{
Location2D temp;
if (came_from.TryGetValue(current_node, out temp)) {
path.Add(temp);
ReconstructPathRecursive(temp);
} else {
path.Add(current_node);
}
}
所以我正在实施 A* 算法,当它找到目标时,它会转到 ReconstructPathRecursive
然后应用程序崩溃并抛出此异常An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll
和This thread is stopped with only external code frames on the call stack. External code frames are typically from framework code but can also include other optimized modules which are loaded in the target process.
知道怎么了!
【问题讨论】:
-
某处可能存在无限递归,请检查您的基本情况。
-
came_from.TryGetValue(current_node, out temp))总是返回 true 吗?如果是这样,你肯定有堆栈溢出。检查路径中是否有循环。 -
无限递归的原因可能是图中的循环;您可能可以通过使用调试器单步执行代码来非常快速地识别问题。
-
ReconstructPathRecursive 方法看起来相当简单。添加一些调试语句,例如打印递归数,甚至更好 - 打印 ReconstructPathRecursive 走过的路径。从一个小测试用例开始,你会发现递归循环正在吃掉你的堆栈。