深度优先搜索:错误的迭代 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 结果顺序的主要内容,如果未能解决你的问题,请参考以下文章

深度优先搜索 DFS 学习笔记

dfs(深度优先搜索)

深度优先搜索小结

深度优先搜索小结

BFS/DFS 广度/深度优先搜索

栈和深度优先搜索(DFS)