繁体   English   中英

图中的路径数

[英]number of paths in graph

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

最好的祝愿

编辑 :图表不是树。

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

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

因此:

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

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

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

使用在该节点结束的路径数标记每个节点:

 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.) 

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

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

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

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

假设图是非循环的(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

编辑:代码上的错误

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

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

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

发现模式了吗?

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

在伪代码中 -

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

}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM