简体   繁体   English

图中的路径数

[英]number of paths in graph

how could the number of paths in a directed graph calculated? 如何计算有向图中的路径数? Are there any algorithms for this purpose? 有没有为此目的的算法?

Best wishes 最好的祝愿

EDIT : The graph is not a tree. 编辑 :图表不是树。

Let A be the adjacency matrix of a graph G . A是图G的邻接矩阵。 Then A^n (ie A multiplied n times with itself) has the following interesting property: 然后A^n (即A与自身相乘n次)具有以下有趣的属性:

The entry at position (i,j) of A^n equals the number of different paths of length n from vertex i to vertex j . A^n位置(i,j)处的条目等于从顶点i到顶点j的长度为n的不同路径的数量。

Hence: 因此:

  • represent the graph as an adjacency matrix A 将图表表示为邻接矩阵A
  • multiply A it with itself repeatedly until you get bored A它自身,直到你觉得无聊
  • in each step: compute the sum of all matrix elements and add it to the result, starting at 0 在每个步骤中:计算所有矩阵元素的总和,并将其添加到结果中,从0开始

It might be wise to first check whether G contains a cycle, because in this case it contains infinitely many paths. 首先检查G是否包含循环可能是明智的,因为在这种情况下它包含无限多个路径。 In order to detect cycles, set all edge weights to -1 and use Bellman-Ford. 为了检测周期,将所有边缘权重设置为-1并使用Bellman-Ford。

All the search hits I see are for the number of paths from a given node to another given node. 我看到的所有搜索命中都是针对从给定节点到另一个给定节点的路径数。 But here's an algorithm that should find the total number of paths anywhere in the graph, for any acyclic digraph. 但是这里有一个算法可以找到图中任何地方的路径总数,对于任何非循环有向图。 (If there are cycles, there are an infinite number of paths unless you specify that certain repetitive paths are excluded.) (如果存在循环,则除非您指定排除某些重复路径,否则会有无限数量的路径。)

Label each node with the number of paths which end at that node: 使用在该节点结束的路径数标记每个节点:

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

Now just add the labels on all nodes. 现在只需在所有节点上添加标签。

If you don't want to count "length zero" paths, subtract the number of nodes. 如果您不想计算“长度为零”路径,请减去节点数。

You can use depth-first search . 您可以使用深度优先搜索 However, you don't terminate the search when you find a path from start to destination, the way depth-first search normally does. 但是,当您找到从开始到目的地的路径时,您不会终止搜索,这是深度优先搜索通常的方式。 Instead, you just add to the count of paths and return from that node as if it were a dead end. 相反,您只需添加路径计数并从该节点返回,就好像它是一个死胡同。 This is probably not the fastest method, but it should work. 这可能不是最快的方法,但应该可行。

You could also potentially use breadth-first search, but then you need to work out a way to pass information on path counts forward (or backwards) through the tree as you search it. 您还可以使用广度优先搜索,但是您需要找到一种方法,在搜索时通过树向前(或向后)传递路径计数信息。 If you could do that, it'd probably be much faster. 如果你能做到这一点,它可能要快得多。

Assuming the graph is acyclic (a DAG), you can make a topological sorting of the vertices and than do dynamic programming to compute the number of distinct paths. 假设图是非循环的(DAG),您可以对顶点进行拓扑排序,然后进行动态编程以计算不同路径的数量。 If you want to print all the paths, there is not much use in discussing big O notation since the number of paths can be exponential on the number of vertices. 如果要打印所有路径,则在讨论大O表示法时没有多大用处,因为路径数可以是顶点数的指数。

Pseudo-code: 伪代码:

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

Edit: Bug on the code 编辑:代码上的错误

admat gives the length 1 paths between vertices; admat给出顶点之间的长度为1的路径;

admat^2 gives the length 2 paths between vertices; admat^2给出顶点之间的长度为2的路径;

admat^3 gives the length 3 paths between vertices; admat^3给出顶点之间的3条路径;

Spot the pattern yet ? 发现模式了吗?

I don't believe there's anything faster than traversing the graph, starting at the root. 从根本开始,我认为没有什么比遍历图表更快的了。

In pseudo-code - 在伪代码中 -

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

}

If it is realy a tree, the number of paths equals the number of nodes-1 if you count paths to internal nodes. 如果它确实是一棵树,那么如果计算到内部节点的路径,则路径数等于节点数-1。 If you only count paths to leaves, the number of paths equals the number of leaves. 如果只计算叶子的路径,则路径数等于叶子数。 So the fact that we're talking about trees simplifies matters to just counting nodes or leaves. 因此,我们谈论树木这一事实简化了计算节点或叶子的问题。 A simple BFS or DFS algorithm will suffice. 一个简单的BFS或DFS算法就足够了。

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

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

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