深度优先搜索:错误的迭代 DFS 结果顺序
Posted
技术标签:
【中文标题】深度优先搜索:错误的迭代 DFS 结果顺序【英文标题】:Depth-First Search : Wrong Iterative DFS results order 【发布时间】:2016-05-17 09:59:02 【问题描述】:我正在尝试使用 DFS 算法对我的等距矩形进行排序。 递归版本完美运行。 这是我的实现:
if (node.discovered)
return;
node.discovered = true;
for (var i:int = 0, length:int = node.behindNodes.length; i < length; i++)
var currentNode:IsoNode = node.behindNodes[i];
if (!currentNode.discovered)
visitNode(currentNode, container);
container.addChild(node);
然而,到处张贴的**迭代**算法(例如:https://en.wikipedia.org/wiki/Depth-first_search)给了我绝对错误的顺序。 这是我的实现:
if (node.discovered)
return;
var stack:Vector.<IsoNode> = new <IsoNode>[node];
while (stack.length)
var currentNode:IsoNode = stack.pop();
if (currentNode.discovered)
continue;
currentNode.discovered = true;
for (var i:int = 0, length:int = currentNode.behindNodes.length; i < length; i++)
var behindNode:IsoNode = currentNode.behindNodes[i];
if (!behindNode.discovered)
stack.push(behindNode);
container.addChild(currentNode);
似乎它试图首先放置父节点而不是子节点 链的尽头
为什么这个版本的算法甚至存在?感觉这是原算法的半反版。
我该如何解决?如何使它返回与递归版本相同的结果?因为乍一看似乎我需要向这个版本提供完全形成的堆栈(而不是使用算法本身),但这没有任何意义!
排序的想法是按正确的顺序获取等距节点 - 从最远到最近。每个节点都保存着后面节点的信息。
所以基本上我们有图表
node_1->()
node_2->(node_3)
node_3->(node_1)
递归版本示例:正确顺序:node_1 node_3 node_2
(来源:yiffa.net)
迭代版本示例:不正确顺序:node_1 node_2 node_3
(来源:yiffa.net)
【问题讨论】:
@VC.One 为什么 MATLAB 标签适用于此?我对类 C 的代码理解得很好,但我不会涉足这片代码的海洋(我的意思是真的,键盘回调?),甚至没有预期和接收输出的示例。 没有必要深入研究所有这些代码。仅在前两个片段中。它们是在 Internet 上发现的两种最常见的 DFS 实现。但是我无法处理为什么使用相同的输入它们的输出不同。在我看来像是某种残酷的玩笑 @VC.One 我理解 MATLAB 就好了。我不知道为什么在回答有关 AS-3 或图形算法的问题时会有所不同。 我删除了 MATLAB 标签为 MATLAB != C,所以不要添加它。不妨将其标记为 java、python、C++ 和 ruby,以便从可能熟悉或不熟悉该概念的人那里获得更多观点。 @VC.One 正确地人们期望当它有那个标签时问题与 MATLAB 相关。毕竟这就是它的目的。 “数学家”将跟随标签“数学”,所以那里没有问题。 【参考方案1】:我不想接受我的答案,因为我可能对那个常见的迭代 DFS 有误。
我想,我自己想通了如何正确模拟这个算法的堆栈。
这是我的代码:
if (node.discovered)
return;
var currentNode:IsoNode = node;
currentNode.discovered = true;
var discoveredStack:Vector.<IsoNode> = new <IsoNode>[currentNode];
while (discoveredStack.length)
currentNode = discoveredStack[discoveredStack.length - 1];
while (currentNode.behindNodes.length)
var behindNode:IsoNode = currentNode.behindNodes.pop();
if (!behindNode.discovered)
behindNode.discovered = true;
discoveredStack.push(behindNode);
currentNode = behindNode;
container.addChild(discoveredStack.pop());
无论如何,对我来说,算法是迭代还是递归都没有关系。如果算法相同且输入相同,则它必须返回相同的结果。否则它是一个不同的算法。
如果有人能判断我是对是错,那就太好了。
【讨论】:
"如果算法相同且输入相同,则必须返回相同的结果。"你这么自信地说。也许您可以给我们一个示例输入以及相应的正确和错误输出。以上是关于深度优先搜索:错误的迭代 DFS 结果顺序的主要内容,如果未能解决你的问题,请参考以下文章