图中的路径数

时间:2011-01-08 18:20:32

标签: c++ algorithm boost graph

如何计算有向图中的路径数?有没有为此目的的算法?

祝福

编辑:图表不是树。

8 个答案:

答案 0 :(得分:3)

A成为图G的邻接矩阵。然后A^n(即A与自身相乘n次)具有以下有趣的属性:

(i,j)位置A^n的条目等于从顶点n到顶点i的不同长度j的路径数。

因此:

  • 将图表表示为邻接矩阵A
  • 反复将A与自身相乘,直至感到无聊
  • 在每个步骤中:计算所有矩阵元素的总和,并将其添加到结果中,从0
  • 开始

首先检查G是否包含循环可能是明智的,因为在这种情况下它包含无限多个路径。为了检测周期,将所有边权重设置为-1并使用Bellman-Ford。

答案 1 :(得分:1)

我看到的所有搜索命中都是针对从给定节点到另一个给定节点的路径数。但是这里有一个算法可以找到图中任何地方的路径总数,对于任何非循环有向图。 (如果存在循环,则除非您指定排除某些重复路径,否则会有无限数量的路径。)

使用以该节点结尾的路径数标记每个节点:

While not all nodes are labeled:
  Choose an unlabeled node with no unlabeled ancestors.
    (An implementation might here choose any node, and recursively
     process any unlabeled ancestors of that node first.)
  Label the node with one plus the sum of the labels on all ancestors.
    (If a node has no ancestors, its label is simply 1.)

现在只需在所有节点上添加标签。

如果您不想计算“长度为零”的路径,请减去节点数。

答案 2 :(得分:1)

您可以使用depth-first search。但是,当您找到从开始到目的地的路径时,您不会终止搜索,这是深度优先搜索通常的方式。相反,您只需添加路径计数并从该节点返回,就好像它是一个死路一样。这可能不是最快的方法,但它应该有效。

您还可以使用广度优先搜索,但是您需要找到一种方法,在搜索时通过树向前(或向后)传递路径计数信息。如果你能做到这一点,它可能会更快。

答案 3 :(得分:1)

假设图形是非循环的(DAG),您可以对顶点进行拓扑排序,然后进行动态编程以计算不同路径的数量。如果要打印所有路径,在讨论大O表示法时没有太大用处,因为路径数可以是顶点数的指数。

的伪代码:

paths := 0
dp[i] := 0, for all 0 <= i < n
compute topological sorting and store on ts
for i from n - 1 to 0
    for all edges (ts[i], v) // outbound edges from ts[i] 
        dp[ts[i]] := 1 + dp[ts[i]] + dp[v]
    paths := paths + dp[ts[i]]

print paths

修改:代码上的错误

答案 4 :(得分:0)

我认为没有什么比从根目录开始遍历图表更快的了。

在伪代码中 -

visit(node) {
  node.visited = true;
  for(int i = 0; i < node.paths.length; ++i) {
    ++pathCount;
    if (!node.paths[i].visited)
      visit(node.paths[i]);
  }

}

答案 5 :(得分:0)

如果它确实是一棵树,如果计算到内部节点的路径,则路径数等于节点数-1。如果只计算叶子的路径,则路径数等于叶子数。因此,我们谈论树木这一事实简化了计算节点或叶子的问题。一个简单的BFS或DFS算法就足够了。

答案 6 :(得分:0)

admat给出顶点之间的长度为1的路径;

admat^2给出顶点之间的长度为2的路径;

admat^3给出顶点之间的3条路径;

发现模式了吗?

答案 7 :(得分:-3)

如果图形不是树,则会有无限的路径 - 随时走一个循环。