这可能是一个问题,可能没有最佳解决方案。假设我有一个有向图,不知道它是否有任何循环(循环检测将是这个问题的一个方面)。给定一组顶点(可能是数百万个顶点),我需要计算给定图形的所有唯一对之间的所有不同路径(没有重复顶点的路径)。我该如何处理这种情况?
让我们看一下蛮力的方式来做到这一点:
从图表中计算所有可能的对。
对于每对图形,使用DFS获取从Source到的所有路径 目的地。
人们可以指出一些可能出现问题的事情吗?让我们以这种方式思考问题,找到地球上所有城市之间所有不同路径的计算挑战是什么,如果有人甚至试图解决这个问题,那么人们会从哪里开始?
编辑:所呈现的一些算法产生O(n!)阶乘时间的结果。对于处理资源有限的单台机器而言,这有点令人生畏。有没有人知道map-reduce技术可以将图遍历的问题分解成更小的块?
答案 0 :(得分:3)
您是否认为可以存在多少这样的路径?
在具有V顶点的图中,您有大约V ^ 2个不同的对。让我们想象一下最糟糕的情况,你有一个完整的图形(每一对之间存在边缘)。路径可以包含1个边和V-1边之间的任何位置,因为您不允许路径中有重复的顶点。
在每对顶点之间:
鉴于此,我们知道最多有V ^ 2 *和{i = 1 - > V-1}(prod {k = 1 - > i-1}(V-k-1))具有V个顶点的图的总路径。
因此,路径的总数是P(V)= V ^ 2 * sum {i = 1 - > V-1}(prod {k = 1 - > i-1}(V-k-1))= V ^ 2 * sum {i = 1 - > V-1}(O(V ^ V))= O(V ^ 3 * V ^ V)= O(V!)。现在想象一个理想的世界,你可以在恒定的时间内计算每条路径。你的算法需要运行O(1 * V!)= O(V!)时间,这是不合时宜的。
可能有一种算法可以在不枚举路径的情况下对路径进行计数,从而获得更高效的算法。
答案 1 :(得分:3)
Floyd-Warshall泛化得到了粗略的路径近似:
procedure FloydWarshall ()
for k := 1 to n
for i := 1 to n
for j := 1 to n
path[i][j] = path[i][j] + path[i][k]*path[k][j]
这是一个关于如何扩展它的非常粗略的想法。免责声明 - 这不是具体的 - 这是非常手工波浪,但希望它不仅仅是混乱。它有助于理解算法的工作原理。它从图的邻接矩阵开始。在每次迭代k中,我们说从i到j的路径数等于从i到j的先前迭代中的路径数加上从i到j经过k的路径数。
因此,将图形中断为大小为k x k的n个任意子邻接矩阵,在它们中的每一个上计算。现在,您可以通过在组合矩阵上重新计算上面的部分内容来获得路径数并开始组合子系统。即,我们只需要在重新组合时重新计算k的n / 2值。我找到了这个,看起来像一个类似的方向http://theory.stanford.edu/~oldham/publications/generalized/asgsp.pdf。
答案 2 :(得分:0)
This SO page描述了一种用于打印任意两个顶点之间的所有非循环路径的DFS方法 - 它还包括java代码。您可以修改它以查找所有顶点对的所有此类路径,但这不是 计算 所有顶点之间所有路径的最有效方式。