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开发者_Python百科.
Let A
be the adjacency matrix of a graph G
. Then A^n
(i.e. A
multiplied n
times with itself) has the following interesting property:
The entry at position (i,j)
of A^n
equals the number of different paths of length n
from vertex i
to vertex j
.
Hence:
- represent the graph as an adjacency matrix
A
- multiply
A
it with itself repeatedly until you get bored - in each step: compute the sum of all matrix elements and add it to the result, starting at 0
It might be wise to first check whether G contains a cycle, because in this case it contains infinitely many paths. In order to detect cycles, set all edge weights to -1 and use 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. 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.
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
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. 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.
admat
gives the length 1 paths between vertices;
admat^2
gives the length 2 paths between vertices;
admat^3
gives the length 3 paths between vertices;
Spot the pattern yet ?
If graph is not a tree, there will be infinite paths - walk a loop any times.
精彩评论