ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python-查找树中两个节点之间的(保证唯一)路径

2019-10-30 10:58:58  阅读:453  来源: 互联网

标签:graph-traversal networkx python


我有一个(可能)简单的图形遍历问题.我是使用networkx作为图形数据结构的图形新手.我的图总是这样:

             0
      1              8
   2     3       9      10
 4  5   6 7    11 12  13  14

我需要返回从根节点到给定节点的路径(例如,path(0,11)应该返回[0,8,9,11]).

我有一个解决方案,它通过传递一个列表来工作,该列表会随着树的移动而增大和缩小,以跟踪路径的样子,最终在找到目标节点时返回:

def VisitNode(self, node, target, path):
    path.append(node)
    # Base case. If we found the target, then notify the stack that we're done.
    if node == target:
        return True
    else:
        # If we're at a leaf and it isn't the target, then pop the leaf off
        # our path (backtrack) and notify the stack that we're still looking
        if len(self.neighbors(node)) == 0:
            path.pop()
            return False
        else:
            # Sniff down the next available neighboring node
            for i in self.neighbors_iter(node):
                # If this next node is the target, then return the path 
                # we've constructed so far
                if self.VisitNode(i, target, path):
                    return path
            # If we've gotten this far without finding the target, 
            # then this whole branch is a dud. Backtrack
            path.pop()

我感到骨子里没有必要传递这个“路径”列表…我应该能够使用调用堆栈来跟踪该信息,但是我不知道如何…有人可以启发一下我如何使用堆栈来递归地解决路径问题?

解决方法:

通过在失败时返回None,在成功时返回部分路径,可以避免绕过路径.这样,您无需保留从根到当前节点的某种“面包屑路径”,而是仅在找到目标后才构造从目标到根的路径.未经测试的代码:

def VisitNode(self, node, target):
    # Base case. If we found the target, return target in a list
    if node == target:
        return [node]

    # If we're at a leaf and it isn't the target, return None 
    if len(self.neighbors(node)) == 0:
        return None

    # recursively iterate over children
    for i in self.neighbors_iter(node):
        tail = self.VisitNode(i, target)
        if tail: # is not None
            return [node] + tail # prepend node to path back from target
    return None #none of the children contains target

我不知道您正在使用的图形库,但是我假设即使叶子也包含neighbours_iter方法,该方法显然不应该为叶子产生任何子级.在这种情况下,您可以省略对叶子的显式检查,从而使其变得更短:

def VisitNode(self, node, target):
    # Base case. If we found the target, return target in a list
    if node == target:
        return [node]
    # recursively iterate over children
    for i in self.neighbors_iter(node):
        tail = self.VisitNode(i, target)
        if tail: # is not None
            return [node] + tail # prepend node to path back from target
    return None # leaf node or none of the child contains target

我还删除了其他else语句,因为如果要从函数返回,则在true的内部.这是常见的refactering pattern(有些老派人士不喜欢).这消除了一些不必要的缩进.

标签:graph-traversal,networkx,python
来源: https://codeday.me/bug/20191030/1967329.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有