【问题标题】:Find all paths between two vertices (nodes) in a graph using Python使用 Python 查找图中两个顶点(节点)之间的所有路径
【发布时间】:2012-12-14 17:17:19
【问题描述】:

我有以下 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 中的相同问题有解决方案

【问题讨论】:

  • 这更像是一个基于算法的问题,您是否在 google 上搜索过?
  • 是的,我一直在寻找任何可以解决问题的算法。我发现了很多,我找不到一个可以使用无向图来找到两个节点之间的所有路径的。例如:所有最短路径、BFS、DFS 等。它们都使用有向边作为问题中的边。
  • 为什么不使用现有的解决方案,例如networkxigraph,或者您只想使用您的代码?
  • @Namit Kewat,老实说,我没有尝试 networkx 或 igraph,因为在我的搜索中,我在他们的文档中找不到任何算法线索来查找无向图中的所有路径。
  • 查看这篇文章以获得解决方案;它同时使用igraphnetworkx 模块:stackoverflow.com/questions/2606018/…

标签: java python graph python-2.7 graph-algorithm


【解决方案1】:

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

【讨论】:

  • 我试过你的方法,效果很好。但我真正想要的是为这个任务修改算法本身。我是图论的新手,但是寻找这个问题的解决方案让我有机会了解不同的图算法。
【解决方案2】:

每种算法都适用于特定的数据结构和该数据结构所表示的明确图。特定的数据结构也是表示特定类型图形的好选择。

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

在您的情况下,将行 for link_node in graph[last_node]: 替换为一些更复杂的表达式,该表达式遍历整个邻接列表。

编辑: 我想到了另一个想法,您也可以即时“预处理”您的图表。我的意思是,每当您的算法涉及边缘 'A' -> 'B' 时,它也会将边缘 'B' -> 'A' 添加到您的图表中。一个缺点是如果已经添加了一些边,您需要额外的数据结构来保存信息,相反,您必须只添加有趣的边。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    相关资源
    最近更新 更多