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

时间:2012-12-14 17:17:20

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

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

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

每种算法都使用特定的数据结构,并具有该数据结构所代表的明确图形。此外,特定的数据结构是表示特定类型图表的不错选择。

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

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

修改 我想到了另一个想法,您也可以即时“预处理”您的图表。我的意思是每当你的算法到达边缘'A' - > 'B'它增加边'B' - >您的图表也是'A'。一个缺点是你需要额外的数据结构,如果已经添加了一些边缘,则保存信息,相反,你只需要添加有趣的边缘。