Change to non-MST edge in graph to change MST - algorithm

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.

Related

Dijkstra with Parallel edges and self-loop

If I have a weighted undirected Graph with no negative weights, but can contain multiple edges between vertex and self-loops, Can I run Dijkstra algorithm without problem to find the minimum path between a source and a destination or exists a counterexample?
My guess is that there is not problem, but I want to be sure.
If you're going to run Dijkstra's algorithm without making any changes to he graph, there's a chance that you'll not get the shortest path between source and destination.
For example, consider S and O. Now, finding the shortest path really depends on which edge is being being traversed when you want to push O to the queue. If your code picks edge with weight 1, you're fine. But if your code picks the edge with weight 8, then your algorithm is going to give you the wrong answer.
This means that the algorithm's correctness is now dependent on the order of edges entered in the adjacency list of the source node.
You can trivially transform your graph to one without single-edge loops and parallel edges.
With single-edge loops you need to check whether their weight is negative or non-negative. If the weight is negative, there obviously is no shortest path, as you can keep spinning in place and reduce your path length beyond any limit. If however the weight is positive, you can throw that edge away, as no shortest path can go through that edge.
A zero-weight edge would create a similar problem than any zero-weight loop: there will be not one but an infinite number of shortest paths, going through the same loop over and over again. In these cases the sensible thing is again to remove the edge from the graph.
Out of the parallel edges you can throw away all but the one with the lowest weight. The reasoning for this is equally simple: if there was a shortest path going through an edge A that has a parallel edge B with lower weight, you could construct an even shorter path by simply replacing A with B. Therefore no shortest path can go through A.
It just needs a minor variation. If there are multiple edges directed from u to v and each edge has a different weight, you can either:
Pick the weight with least edge for relaxation; or
Run relaxation for each edge.
Both of the above will have the same complexity although the constant factors in #2 will have higher values.
In any case you'll need to make sure that you evaluate all edges between u and v before moving to the next adjacent node of u.
I don't think it will create any kind of problem.As the dijkstra algorithm will use priority queue ,so offcourse minimum value will get update first.

Update minimum spanning tree if edge is added

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.

Algorithm to cover all edges given starting node

Working on an algorithm for a game I am developing with a friend and we got stuck. Currently, we have a cyclic undirected graph, and we are trying to find the quickest path from starting node S that covers every edge. We are not looking for a tour and there can be repeated edges.
Any ideas on an algorithm or approximation? I'm sure this problem is NP-hard, but I don't believe it's TSP.
Route Inspection
This is known as the route inspection problem and it does have a polynomial solution.
The basic idea (see the link for more details) is that it is easy to solve for an Eulerian path (where we visit every edge once), but an Eulerian path is only possible for certain graphs.
In particular, a graph has to be connected and have either 0 or 2 vertices of odd degree.
However, it is possible to generalise this for other graphs by adding additional edges in the cheapest way that will produce a graph that does have an Eulerian path. (Note that we have added more edges so we may travel multiple times over edges in the original graph.)
The way of choosing the best way to add additional edges is a maximal matching problem that can be solved in O(n^3).
P.S.
Concidentally I wrote a simple demo earlier today (link to game) for a planar max-cut problem. The solution to this turns out to be based on exactly the same route inspection problem :)
EDIT
I just spotted from the comments that in your particular case your graph may be a tree.
If so, then I believe the answer is much simpler as you just need to do a DFS over the tree making sure to visit the shallowest subtree first.
For example, suppose you have a tree with edges S->A and S->A->B. S has two subtrees, and you should visit A first because it is shallower.
The total edges visited will equal the number of edges visited in a full DFS, minus the depth of the last leaf visited, which is why to minimise the total edges you want to maximise the depth of the last leaf, and hence visit the shallowest subtree first.
This is somewhat like the Eulerian Path. The main distinction is that there may be dead-ends and you may be able to modify the algorithm to suit your needs. Pruning dead-ends is one option or you may be able to reduce the graph into a number of connected components.
DFS will work here. However you must have a good evaluation function to prun the branch early. Otherwise you can not solve this problem fast. You can refer to my discussion and implementation in Java here http://www.capacode.com/?p=650
Detail of my evaluation function
My first try is if the length of the current path plus the distance from U to G is not shorter than the minimum length (stored in minLength variable) we found, we will not visit U next because it can not lead a shorter path.
Actually, the above evaluation function is not efficient because it only works when we already visit most of the cities. We need to compute more precise the minimum length to reach G with all cities visited.
Assume s is the length from S to U, from U to visit G and pass all cities, the length is at least s’ = s + ∑ minDistance(K) where K is an unvisited city and different from U; minDistance(K) is the minimum distance from K to an unvisited state. Basically, for each unvisited state, we assume that we can reach that city with the shortest edge. Note that those shortest edges may not compose a valid path. Then, we will not visit U if s’ ≥ minLength.
With that evaluation function, my program can handle the problem with 20 cities within 1 second. I also add another optimization to improve the performance more. Before running the program, I use greedy algorithm to get a good value for minLength. Specifically, for each city, we will visit the nearest city next. The reason is when we have a smaller minLength, we can prun more.

How to get the new MST from the old one if one edge in the graph changes its weight?

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)

What modifications could you make to a graph to allow Dijkstra's algorithm to work on it?

So I've been thinking, without resorting to another algorithm, what modifications could you make to a graph to allow Dijkstra's algorithm to work on it, and still get the correct answer at the end of the day? If it's even possible at all?
I first thought of adding a constant equal to the most negative weight to all weights, but I found that that will mess up everthing and change the original single source path.
Then, I thought of traversing through the graph, putting all weights that are less than zero into an array or somwthing of the sort and then multiplying it by -1. I think his would work (disregarding running time constraints) but maybe I'm looking at the wrong way.
EDIT:
Another idea. How about permanently setting all negative weights to infinity. that way ensuring that they are ignored?
So I just want to hear some opinions on this; what do you guys think?
Seems you looking for something similar to Johnson's algorithm:
First, a new node q is added to the graph, connected by zero-weight edges to each of the other nodes.
Second, the Bellman–Ford algorithm is used, starting from the new vertex q, to find for each vertex v the minimum weight h(v) of a path
from q to v. If this step detects a negative cycle, the algorithm is
terminated.
Next the edges of the original graph are reweighted using the values computed by the Bellman–Ford algorithm: an edge from u to v,
having length w(u,v), is given the new length w(u,v) + h(u) − h(v).
Finally, q is removed, and Dijkstra's algorithm is used to find the shortest paths from each node s to every other vertex in the
reweighted graph.
By any algorithm, you should check for negative cycles, and if there isn't negative cycle, find the shortest path.
In your case you need to run Dijkstra's algorithm one time. Also note that in Johnson's algorithm semi Bellman–Ford algorithm runs just for new added node. (not all vertices).

Resources