图论:寻找'n'长度的所有可能路径(有一些约束)

时间:2015-06-22 20:29:53

标签: python algorithm recursion graph-algorithm

我的一位朋友给了我一个样本挑战问题。我想听听一些关于如何最好地寻找解决方案的建议。

问题涉及计算在网格状量表上遍历一系列点的所有可能模式。我将简单地给出一个数字'n',表示我必须移动多少次,并且我必须确定我可以遍历网格移动n次的方式的数量。起点可以是任何一点,所以我必须在每个起点上运行我的计算,我的答案是每个起点的结果总和。

对于编程而言,我仍然是一个初学者,关于如何处理这个问题,我最好的猜测是使用图论。我首先创建了一个图表来表示节点及其邻居。我故意模糊地留下这个问题,因为我想学习如何解决这些问题而不是让一些专家为我解决整个事情。下面是我在Python 3(字典)中的图表的示例表示。

graph = {'a':['b','c']
         'b':['a','e','f']
         'c':['a','d']
         'd':['c']
         'e':['b','g'] and etc. 

我的真实图表显着更大,每个节点通常至少有3-4个邻居。让我们假设给定的'n'是6,这意味着我需要返回所有可能涉及移动6次的有效路径。我被允许重新访问节点,因此有效路径可能只是a-b-a-b-a-b。 “有效”路径的另一个例子是a-b-a-c-d-c或e-b-a-c-a-b,因为我们可以从任何起点开始。

我对如何最好地解决这个问题感到有点失落。递归已经超出我的想法作为一种可能的解决方案,我遍历所有可能的路径并在每次点击路径的“结束”时递增计数器。我考虑的另一个可能的解决方案是在每个节点上,计算可能的移动并将其与运行的计数相乘。例如,从'a'开始,我有两个动作。如果我导航到'b',我有3个动作。如果我导航到'c',我有2个动作。此时,我有1 * 3 * 2的动作。这可能是一个完全错误的方法......只是我的想法。

实际问题是对某些节点的约束要复杂得多(你可以访问它的次数,如果某个节点的某个序列被先前击中则禁止访问它的规则等)但是我现在将省略细节。我要说的是,鉴于这些约束,我的算法必须知道以前的访问节点模式是什么。例如,在第5步,我必须能够随时参考前4个动作。

我很想听听您如何最好地解决我上面概述的“更简单”问题的建议。

2 个答案:

答案 0 :(得分:1)

查看深度优先搜索(DFS)。就在我的脑海中:使用递归DFS,使用计数器来保存在'n'移动后找到的每个节点。您需要构建给定数据的无向图表示,以便您可以在图上运行DFS算法。

答案 1 :(得分:1)

这是您提供的最简单的答案。一旦你以“过渡地图”的形式绘制了图表。 (这可以只是一个字典,就像你已经显示的那样),然后下面的代码就可以了:

def myDFS(trans_dict,start,length,paths,path=[]): 
    path=path+[start] 
    if len(path)==length:
        paths.append(path) 
    else:
        for node in trans_dict[start]:
            myDFS(trans_dict,node,length,paths,path)

如果您想要使用给定长度的路径遍历地图的方式数量,则只需len(paths)

示例:

trans_dict = {0:[1,2],1:[2,3],2:[0,3],3:[3]}
paths = []
length = 3

for a in trans_dict:
    myDFS(trans_dict,a,length,paths)

print paths # [[0, 1, 2], [0, 1, 3], [0, 2, 0], [0, 2, 3], [1, 2, 0], [1, 2, 3], [1, 3, 3], [2, 0, 1], [2, 0, 2], [2, 3, 3], [3, 3, 3]]
print len(paths) # 11

答案的灵感来自于此问答:trying to find all the path in a graph using DFS recursive in Python