I have a possible solution for the following question, but not sure if correct:
Assume we have already found a minimum spanning tree T for a weighted, undirected graph G = (V,E). We would like to be able to efficiently update T should G be altered slightly.
An edge is added to G to produce a new graph. Give an algorithm that uses T to find a minimum spanning tree for the new graph in O(|V|) time.
My algorithm:
for each vertex do
if smallest edge not in T then
replace this edge with existing edge in T
break
end if
end for
I do not have much experience in writing pseudocode, so my algorithm might be over-simplified or incorrect. Please correct me if I am wrong. Thanks!
Don't know if your algorithm is correct, but it doesn't seem O(|V|) at least, because getting the "smallest edge not in T" of a vertex cannot be done in O(1).
The most usual way to add an edge e=(u, v) into a MST T is:
Run a BFS in T from u to v to detect the edge with maximum value in that path. (O(|V|))
If that edge's weight is greater than the weight of the edge you're trying to add, remove that old edge and add the new one. Otherwise, do nothing, because the new edge would not improve the MST. (O(1)).
The rationale behind this solution is that simply adding the edge into T would create exactly one cycle, and to restore the MST property you have to remove the edge with maximum value from that cycle.
Yes, your algorithm seems to be correct. I would amend your pseudocode to clarify that "if smallest incident edge not in T then" so that your new algorithm is this:
for each vertex do
if smallest incident edge not in T then
replace this edge with existing edge in T
break
end if
end for
Proof by contradiction:
There exist two cases: the new edge is either in the MST or it isn't. For the case that it is: Suppose that the algorithm does not replace an edge in T. This must mean that all edges in T are smaller than other edges that are incident on the same vertex. This is a contradiction because that means the new edge is not in the MST of T.
The proof for the other case is a trivially similar proof by contradiction.
Related
I'm attempting ch23 in CLRS on MSTs, here's a question:
Given a graph G and a minimum spanning tree T , suppose that we decrease the weight of one of the edges not in T . Give an algorithm for finding the minimum spanning tree in the modified graph.
A solution I found was to add this new changed edge in T, then exactly one simple cycle is created in T, traverse this cycle and delete the max-weight edge in this cycle, voila, the new updated MST is found!
My question is, how do I only traverse nodes on this simple-cycle? Since DFS/BFS traversals might go out of the cycle if I, say, start the traversal in T from one endpoint of this newly added edge in T.
One solution I could think of was to find the biconnected components in T after adding the new edge. Only one BCC will be found, which is this newly formed simple-cycle, then I can put in a special condition in my DFS code saying to only traverse edges/nodes in this BCC, and once a back-edge is found, stop the traversal.
Edit: graph G is connected and undirected btw
Your solution is basically good. To make it more formal you can use Tarjan's bridge-finding algorithm
This algorithm find the cut-edges (aka bridges) in the graph in linear time. Consider E' to be the cut-edges set. It is easy to prove that every edge in E' can not be on circle. So, E / E' are must be the cycle in the graph.
You can use hash-map or array build function to find the difference between your E and the cut-edges set
From here you can run simple for-loop to find the max weight edge which you want to remove.
Hope that help!
Suppose that a graph G has a minimum spanning tree already computed. How can we quickly update the minimum tree if we add a new vertex and incident edges to G.
My initial solution is to choose the new added edge who has least weight and then add this edge to the tree already computed. But it seems this solution is wrong. Can someone give me some tips on this question? Thanks
Adding the minimum weight edge will give wrong results because now you have extra edges and more than one edge out of them can be a part of the new MST. See the image for example.
You can use Prim's algorithm. Just take into account the previous MST edges and the new edges while running the algorithm.
This will work because if you run Prims on the whole new graph then also all the edges that it will add will be from old MST or new edges. You can use any other MST finding algorithm as well like Kruskal considering the above said edges.
We know the original graph and the original MST. Now we change an edge's weight in the graph. Beside the Prim and the Kruskal, is there any way we can generate the new MST from the old one?
Here's how I would do it:
If the changed edge is in the original MST:
If its weight was reduced, then of course it must be in the new MST.
If its weight was increased, then delete it from the original MST and look for the lowest-weight edge that connects the two subtrees that remain (this could select the original edge again). This can be done efficiently in a Kruskal-like way by building up a disjoint-set data structure to hold the two subtrees, and sorting the remaining edges by weight: select the first one with endpoints in different sets. If you know a way of quickly deleting an edge from a disjoint-set data structure, and you built the original MST using Kruskal's algorithm, then you can avoid recomputing them here.
Otherwise:
If its weight was increased, then of course it will remain outside the MST.
If its weight was reduced, add it to the original MST. This will create a cycle. Scan the cycle, looking for the heaviest edge (this could select the original edge again). Delete this edge. If you will be performing many edge mutations, cycle-finding may be sped up by calculating all-pairs shortest paths using the Floyd-Warshall algorithm. You can then find all edges in the cycle by initially leaving the new edge out, and looking for the shortest path in the MST between its two endpoints (there will be exactly one such path).
Besides linear-time algorithm, proposed by j_random_hacker, you can find a sub-linear algorithm in this book: "Handbook of Data Structures and Applications" (Chapter 36) or in these papers: Dynamic graphs, Maintaining Minimum Spanning Trees in Dynamic Graphs.
You can change the problem a little while the result is same.
Get the structure of the original MST, run DFS from each vertice and
you can get the maximum weighted edge in the tree-path between each
vertice-pair. The complexity of this step is O(N ^ 2)
Instead of changing one edge's weight to w, we can assume we are
adding a new edge (u,v) into the original MST whose weight is w. The
adding edge would make a loop on the tree and we should cut one edge
on the loop to generate a new MST. It's obviously that we can only
compare the adding edge with the maximum edge in the path(a,b), The
complexity of this step is O(1)
Devise an algorithm that takes a weighted graph G and finds the
smallest change in the cost to a non-MST edge that would cause a change in the
minimum spanning tree of G.
My solution so far (need suggestions):
To make a change to the MST, we need to change the weight of a non-MST edge s.t. it is one less than the maximum edge in the path of its start vertex and end vertex in the MST.
So we can start by walking the edges of MST, and for every vertex, check if there is a non-MST edge. If there is, a bfs to reach the edge's end point (in the MST) can be done. The non-MST edge weight must be updated to one less than the maximum edge weight in the path.
This would cause the non-MST edge to be included in the MST and the previous maximum edge to be removed from MST.
Can someone tell if this solution is correct ? Thanks.
You found the idea.
However, your answer needs to be tuned to show that you want to find the minimum change and not that you want to modify each non-MST edge you come across in your walk.
If this is a school question, you will also be asked to provide a proof of corectness. in order to build it, I would suggest to rely on Kruskal's proof, and to explain why your change would have Kruskal choose the modified edge instead of that other max-weight edge from the path.
I have an idea. So basically, we can follow the idea of the Kruskal algorithm. So if we want the MST to change, then there must be one time when the Krukal algorithm doen't choose the edge in the original MST. That edge must be the edge whose cost we are going to modify. So the algorithm is pretty clear. Follow the Kruskal algorithm, every time when we want to select a new edge e, we keep searching according to the Kruskal algorithm and find another edge e' that still doen't create a cycle. Then we calculate the minimum change in cost:w(e')-w(e)-1 .(I am not sure if the cost if limited to be an interger or not). Simply select the minimum change from above.
Can anyone think of a way to modify Kruskal's algorithm for a minimum spanning tree so that it must include a certain edge (u,v)?
I might be confusing, but as far as I remember, kruskal can handle negative weights,so you can give this edge -infinity weight.
Of course it won't actually be -infinity, but a number low enough
to be significant enough that it cannot be ignored, something like -1 * sigma(|weight(e)|) for each e in E.
If you can modify the graph structure, you could remove vertices u and v, and replace them with a new vertex w that has the edges u and v used to have. In the case of duplicate edges, pick the one with the smallest weight.
Provided that we know the edge weight of (u,v), we can also simply add it to the front of our sorted list of edge weights (as Kruskal sorts the edge weights in increasing order). In this case, the edge (u,v) will be the first edge included in our tree and Kruskal will run normally, finding the spanning tree of minimum weight with (u,v).