【问题标题】:Trying to iterate through a graph breadth first in Python尝试首先在 Python 中遍历图宽度
【发布时间】:2016-08-01 15:05:19
【问题描述】:

在我的代码中,我实际上是在尝试创建数据流网络的实现。虽然我如何做这件事的特殊性并不是特别重要,但我需要一些帮助来使程序以广度优先的方式遍历图表。 当我使用我的代码执行此操作时:

def traverse(self):
    source = self._nodelist[0]
    self.sand_pile(source)
    return

def sand_pile(self, start):
    for sink in start._sinks:
        //ALGORITHM FOR SENDING DATA HERE
    for s in start._sinks:
        self.sand_pile(s)
    return

编译器正确地首先通过第一个节点和它的接收器广度,但是当它继续对接收器重复该过程时,它开始首先进入深度。

另一种解释方式如下:如果图的源有两个或三个sink,每个sink都有两个或三个自己的sink,编译器会将它们全部打印出来并成功将值传递给它们,但随后将继续深入其他节点,直到到达终点。我的逻辑哪里出错了?

附:如果我没有很好地解释任何事情,请发表评论以便我澄清。

【问题讨论】:

    标签: python data-transfer


    【解决方案1】:

    您在方法中混合了 BFS(广度优先搜索)和 DFS(深度优先搜索)。

    在您的sand_pile 方法中发送数据时,您会水平迭代当前节点的所有子节点,这可能是您实现 BFS 的方法。但是,一旦第一级子节点(或 sinks 在您的情况下)完成,您将在每个子节点上执行 recursion 步骤。这实质上会产生这样的架构:

    • 在级别 0(根节点)上的节点上启动 sand_pile
    • 将数据分发给级别 1 上的所有子级
    • 1 级别的第一个子级开始sand_pile
    • 将数据分发给级别 2 上的所有子级
    • ...继续使用离线数据分布进行 DFS

    缺陷在于,您为 BFS 使用了递归。

    您可以对 DFS 使用递归下降(即 stack-like 迭代),但对于 BFS,您应该创建一个包含所需顺序的所有节点的缓冲区(即 queue-喜欢迭代)

    然后步骤可以如下所示

    1. 获取树的最大深度
    2. 对于每个深度级别,将驻留在该级别上的所有节点放入一个列表中
    3. 连接所有列表以获得类似[lvl0_node0, lvl1_node0, lvl1_node1, lvl1_node2, lvl2_node_0, ..., lvlN_nodeM] 的内容
    4. 遍历该队列

    【讨论】:

    • 嘿伙计,谢谢你的回答。但它有一个问题。当我尝试在更复杂的图表上执行此操作时,其中一个节点可能位于“多个”级别,显然我遇到了问题。我不会每次都分配这些假设级别,那么是否有解决此问题的替代方法?
    • 如果一个节点可能是多个级别的一部分(即它在您的节点列表中出现多次),您可能需要携带一个 visited 列表。完成后只需将每个节点的引用推入其中,并在对任何其他节点执行操作之前检查此列表。
    猜你喜欢
    • 2019-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多