繁体   English   中英

使用Python查找图形中两个顶点(节点)之间的所有路径

[英]Find all paths between two vertices (nodes) in a graph using Python

我有以下Python代码,它可与有向图完美配合。 我的问题是如何以忽略边缘方向的方式修改代码,以找到所有路径。

例如,如果我们具有以下连接:

1-> 2

3-> 2

我的代码不会返回1到3之间的路径,这是按预期的方向。 但是在忽略边缘方向的情况下,代码应找到从1到3的路径。

我希望代码忽略方向,并找到两个给定节点之间的所有路径。

我尝试了所提出的解决方案,它确实很好用,解决方案是:“ 最简单的解决方案可能是通过为图中的每个A-> B添加圆弧B-> A来预处理图形。

我真正想要的是修改算法本身以按原样处理图形。

Python代码:

# a sample graph
graph = {'A': ['B', 'C','E'],
             'B': ['A','C', 'D'],
             'C': ['D'],
             'D': ['C'],
             'E': ['F','D'],
             'F': ['C']}

class MyQUEUE: # just an implementation of a queue

    def __init__(self):
        self.holder = []

    def enqueue(self,val):
        self.holder.append(val)

    def dequeue(self):
        val = None
        try:
            val = self.holder[0]
            if len(self.holder) == 1:
                self.holder = []
            else:
                self.holder = self.holder[1:]   
        except:
            pass

        return val  

    def IsEmpty(self):
        result = False
        if len(self.holder) == 0:
            result = True
        return result


path_queue = MyQUEUE() # now we make a queue


def BFS(graph,start,end,q):

    temp_path = [start]

    q.enqueue(temp_path)

    while q.IsEmpty() == False:
        tmp_path = q.dequeue()
        last_node = tmp_path[len(tmp_path)-1]
        #print tmp_path
        if last_node == end:
            print "VALID_PATH : ",tmp_path
        for link_node in graph[last_node]:
            if link_node not in tmp_path:
                new_path = []
                new_path = tmp_path + [link_node]
                q.enqueue(new_path)

BFS(graph,"A","D",path_queue)

-------------代码的输出-------------------

['A', 'B', 'D'] 
['A', 'C', 'D']
['A', 'E', 'D']
['A', 'B', 'C', 'D']
['A', 'E', 'F', 'C', 'D']

注意:我标记了Java,以防有人可以解决Java中的相同问题

最简单的解决方案可能是通过为图形中的每个A->B添加圆弧B->A来预处理图形。 然后,您应该能够按原样使用算法。

每种算法都使用特定的数据结构以及该数据结构表示的定图。 同样,特定的数据结构也是表示特定类型图形的不错选择。

例如,如果您有(如您所愿)具有代表有向图的邻接表,并且希望算法将其用作代表无向图的数据结构,则可以执行此操作,但这将非常无效,因为只是要找出节点之间是否存在边“ A”和节点“ B”意味着确定“ B”是否位于代表“ A”的相邻节点的行中,以及“ A”是否位于代表“ B”的相邻节点的行中。 因此,如果仅使用数据结构来标识与节点“ A”相邻的所有节点,而无需进行任何预处理,则需要花费一些时间来搜索完整的邻接表。

在您的情况下,这是用for link_node in graph[last_node]:替换行for link_node in graph[last_node]:用更复杂的表达式遍历整个邻接表。

编辑:我想到了另一个想法,您也可以即时“预处理”图形。 我的意思是,每当您的算法到达边'A'->'B'时,它也将边'B'->'A'添加到图形中。 缺点之一是您需要附加的数据结构,如果已经添加了某些边缘,则该数据结构将保留信息,相反,您仅需要添加有趣的边缘。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM