I have found this paper so far. Is it outdated? Are there any faster and better implementations?
By the way, Wikipedia says that there can be n^n-2 spanning trees in a undirected graph. How many spanning trees can be in a directed graph?
If you use terms from paper you mentioned and you define spanning tree of directed graph as tree rooted in vertex r, having unique path from r to any other vertex then:
It's obvious that worst case when directed graph has the greatest number of the spanning trees is complete graph (there are a->b and b->a edges for any pair).
If we "forget" about directions we will get n^{n-2} spanning trees as in case of undirected graphs. For any of this spanning trees we have n options to choose a root, and this choice define uniquely define directions of edges we need to use. Not hard to see, that all trees we get are spanning, unique and there are no nother options. So we get n^{n-1} spanning trees. Strict proof will take time, I hope that simple explanation is enough.
So this task will take exponential time depend from vertex count in worst case. Considering the size of output (all spanning trees), I conclude that for arbitrary graph, algorithm can not be significantly faster and better. I think you need to somehow reformulate your original problem to not deal with all spanning trees, and may be search only needed by some criteria.
for undirected graph only....
n^n-2 spanning tress are possible for only complete graph....to find total number of spanning trees of any graph u can apply this method.....
find the adjacency matrix of the graph.
if column values are represented by 'i' and row entries by 'j' then...
if i=j...then the value will be the degree of vertex
suppose,there is a single edge between vertex v1 and v2 then the value of matrix entry will be -1......7 if there are two edges then it will be -2...& so on...
after constructing adjacency matrix....exclude any row and column...i.e, Nth row and Nth column....
answer will be the total number of spanning tress.
Related
I want to compute the complete set of spanning trees for a graph. The graphs I'm working with are small (usually less than 10 nodes).
I see functionality for computing the minimum spanning tree with igraph:
library(igraph)
g <- sample_gnp(100, 3/100)
g_mst <- mst(g)
and I see a previous StackOverflow post that described how to compute a spanning tree using a breadth-first search. The code below is adapted from the accepted answer:
r <- graph.bfs(g, root=1, neimode='all', order = TRUE, father = TRUE)
h <- graph(rbind(r$order, r$father[r$order, na_ok = TRUE])[,-1], directed = FALSE)
However, I don't know how to adapt this to compute multiple spanning trees. How would one adapt this code to compute all spanning trees? I'm thinking that one piece of this would be to loop through each node to use as the "root" of each tree, but I don't think that takes me all the way there (since there could still be multiple spanning trees associated with a given root node).
EDIT
The end-goal is to compute the distortion of a graph, which is defined as follows (link, see page 5):
Consider any spanning tree T on a graph G, and compute the average distance t = E[HT] on T between any two nodes that share a link in G. The distortion measures how T distorts links in G, i.e. it measures how many extra hops are required to go from one side of a link in G to the other, if we are restricted to using T. The distortion is defined [13] to be the smallest such average over all possible Ts. Intuitively distortion measures how tree-like a graph is.
[13] R. G. H. Tagmunarunkit and S. Jamin, “Network topology generators: degree-based vs. structural,” in SIGMCOMM, 2002.
I don't think you will find a function to do that on an R package.
There are n^{n-2} spanning trees on a graph (according to the Cayley's formula). Even on your graph with 10 nodes, there may exist 1,000,000,000 different spanning trees, which is a big number.
Furthermore, the problem of counting or enumerating all spanning trees of a given graph is #P-Complete, which is as harder as NP-Complete problems.
If you are really willing to do that, I recommend dropping R and start using C or C++, which can compute your problem much faster than any R code can do.
Have a look on this paper for a survey on algorithms for computing all spanning trees of a connected graph (which I think is your case).
My problem is a generalization of a task solved by [Blossom algorithm] by Edmonds. The original task is the following: given a complete graph with weighted undirected edges, find a set of edges such that
1) every vertex of the graph is adjacent to only one edge from this set (i.e. vertices are grouped into pairs)
2) sum over weights of edges in this set is minimal.
Now, I would like to modify the first goal into
1') vertices are grouped into sets of 3 vertices (or in general, d vertices), and leave condition 2) unchanged.
My questions:
Do you know if this 'generalised' problem has a name?
Do you know about an algorithm solving it in number of steps being polynomial of number of vertices (like Blossom algorithm for an original problem)? I don't see a straightforward generalisation of Blossom algorithm, as it is based on looking for augmenting paths on a graph compressed to a bipartite graph (and uses here Hungarian algorithm). But augmenting paths do not seem to point to groups of vertices different than pairs.
Best regards,
Paweł
I am revising for a test and came across two questions relating to minimal spanning trees in graphs that I am unsure of and want to test my answers against.
The first one asks: if a graph has multiple minimal spanning trees, will Kruskal and Prim’s minimal spanning tree algorithms generate the same tree? I am thinking that they won’t necessarily because the algorithms are different. Kruskal relies on the edges being sorted by weight, whilst Prim doesn’t, so they could start at different vertices, thus generating different trees.
The second question asks: if a graph has multiple minimal spanning trees, how should Kruskal’s algorithm be adapted to generate all of these? I am thinking that one needs to allow for either a looping structure through the vertices so that the start vertex changes each time because the edges values may be the same. Thus generate trees by taking each of the vertices in turn as start vertex. In other words, sort by vertex numbering as well, not by edge weight alone.
If a graph has multiple minimal spanning trees, will Kruskal and Prim’s minimal spanning tree algorithms generate the same tree?
No, it is not necessary for the Prims and Kruskals algorithms to generate the same MST. A graph can have many MSTs and both algorithms can generate different ones. But the edge types of the two MSTs will necessarily be the same. ie, if you make a multiset of the edges of the two MSTs, then the two multisets will definitely be equal. You can find a proof of this here
If a graph has multiple minimal spanning trees, how should Kruskal’s algorithm be adapted to generate all of these?
There seems to be no direct reduction of the kruskal's MST algorithm to find all the MSTs in the graph. Your best bet will be
Step1 : Sort the edges of the graph as done in kruskals.
Step2 : Now for each edge in the sorted list, two things can happen. Either the edge is in an MST or it is not. So for each edge in the sorted list, we will go over these two cases and create two new Union-Find data structures and recurse on other edges.
pseudocode:
Step1: sort edges in ascending order
Step2: now call printAllMsts(0, new UnionFind(V))
void printAllMsts(int edgeNum, UnionFind U){
if(edgeNum == edges.length){ // If no more edges to add
if(U.numEdges == V-1){ // If U has V-1 edges, then we have an MST
printMst();
}
return;
}
if(edges[edgeNum+1] == edges[edgeNum]){
printAllMsts(edgeNum+1, U); // when E is not taken in the MST
}
edge E = edges[edgeNum];
If(E can be a part of some MST){
UnionFind newU = new UnionFind(U);
newU.add(E);
}
printAllMsts(edgeNum+1, newU);
}
The running time of the algorithm will depend on the number and type of edges in the graph. The worst case input for the problem will be when all the edges in the graph are of the same length. The running time is atleast O(V*numberOfMsts) because whenever there is a possibility of different MSTs, the current Union-Find data structure is cloned which takes O(V) time.
I'm trying to test some models of graph partitioning (these come from the real world, where a graph slowly self-partitions). To do this, I need to be able to uniformly randomly partition this graph into contiguous components (we are given the graph is initially connected, as well). Were the contiguity criterion not required I believe this would be the problem of randomly partitioning a set, which can be combinatorially analyzed. Does anyone know of any way to randomly partition graphs into subgraphs (i.e. randomly sample one partition), or, if no such method is known, to randomly sample a set of elements? The method of randomizing the number of partitions and then randomizing membership won't work because there are different numbers of possible partitions for each partition size.
You have to differentiate edge-cut partitioning and vertex-cut partitioning, where you divide the graph along the edges or vertices. This significantly impacts your problem as the number of different vertex-cuts is much larger than the number of edge-cuts. The reason is that you exclusively assign edges to partitions in vertex-cut - as opposed to edge-cut where you assign vertices to partitions - and there are much more edges than vertices (e.g. O(n^2) edges for n vertices). Hence, the combinatorially larger vertex-cut leads to a larger number of subgraphs that have to be checked for connectivity. A naive method for randomization is to enumerate all partitionings, iteratively select one partitioning, and check connectivity of all subgraphs in the selected partitioning. Then you just take the first one. In this case, all solutions have equal probability (uniformly random).
I have come across the same problem in work I am doing. I have two solutions to randomly partition a graph into m contiguous components:
Spanning Tree Approach. Randomly choose a spanning tree of your graph (e.g. Using Wilson's algorithm which chooses uniformly amongst all spanning trees). Then randomly select m-1 edges (without replacements) and remove them from the spanning tree. This will give m components which are each connected in the original graph.
Edge contraction approach. Randomly choose an edge and contract it, renaming the (new) vertex as the union of the two previous vertices. Repeat until you have only m vertices left. Identify each vertex with the subset of (original) vertices that were contracted into it.
I don't want to find all the minimum spanning trees but I want to know how many of them are there, here is the method I considered:
Find one minimum spanning tree using prim's or kruskal's algorithm and then find the weights of all the spanning trees and increment the running counter when it is equal to the weight of minimum spanning tree.
I couldn't find any method to find the weights of all the spanning trees and also the number of spanning trees might be very large, so this method might not be suitable for the problem.
As the number of minimum spanning trees is exponential, counting them up wont be a good idea.
All the weights will be positive.
We may also assume that no weight will appear more than three times in the graph.
The number of vertices will be less than or equal to 40,000.
The number of edges will be less than or equal to 100,000.
There is only one minimum spanning tree in the graph where the weights of vertices are different. I think the best way of finding the number of minimum spanning tree must be something using this property.
EDIT:
I found a solution to this problem, but I am not sure, why it works. Can anyone please explain it.
Solution: The problem of finding the length of a minimal spanning tree is fairly well-known; two simplest algorithms for finding a minimum spanning tree are Prim's algorithm and Kruskal's algorithm. Of these two, Kruskal's algorithm processes edges in increasing order of their weights. There is an important key point of Kruskal's algorithm to consider, though: when considering a list of edges sorted by weight, edges can be greedily added into the spanning tree (as long as they do not connect two vertices that are already connected in some way).
Now consider a partially-formed spanning tree using Kruskal's algorithm. We have inserted some number of edges with lengths less than N, and now have to choose several edges of length N. The algorithm states that we must insert these edges, if possible, before any edges with length greater than N. However, we can insert these edges in any order that we want. Also note that, no matter which edges we insert, it does not change the connectivity of the graph at all. (Let us consider two possible graphs, one with an edge from vertex A to vertex B and one without. The second graph must have A and B as part of the same connected component; otherwise the edge from A to B would have been inserted at one point.)
These two facts together imply that our answer will be the product of the number of ways, using Kruskal's algorithm, to insert the edges of length K (for each possible value of K). Since there are at most three edges of any length, the different cases can be brute-forced, and the connected components can be determined after each step as they would be normally.
Looking at Prim's algorithm, it says to repeatedly add the edge with the lowest weight. What happens if there is more than one edge with the lowest weight that can be added? Possibly choosing one may yield a different tree than when choosing another.
If you use prim's algorithm, and run it for every edge as a starting edge, and also exercise all ties you encounter. Then you'll have a Forest containing all minimum spanning trees Prim's algorithm is able to find. I don't know if that equals the forest containing all possible minimum spanning trees.
This does still come down to finding all minimum spanning trees, but I can see no simple way to determine whether a different choice would yield the same tree or not.
MST and their count in a graph are well-studied. See for instance: http://www14.informatik.tu-muenchen.de/konferenzen/Jass08/courses/1/pieper/Pieper_Paper.pdf.