Tricky algorithm for finding alternative route in graph with few added edges - algorithm

Okay, so I found this a bit tricky.
Basically, you have a directed graph (let's call it the base graph), that has some leaves and a node with 0 indegree that is called root. It may contain cycles.
From that base graph, a tree has been made, that contains the root and all leaves, and some connection between them. The nodes and edges that are not needed to connect the root to the leaves are left out.
Now imagine one or more edges in the tree "break", and can no longer be used. The problem now is to
a) If possible, find an alternative route(s) to the disconnected node(s), introducing as few previously unused edges from the base graph as possible.
b) If not possible, select which edges to "repair", repairing as few edges as possible to get all leaves connected again.
This is supposed to represent an electrical grid, and the breaks are power outages.
If just one edge is broken, it is easy enough. But say you have a graph with 100 leaves, 500 edges, and 50 edges break. Now to find which combination of adding previously unused edges from the base graph, and if necessary repairing some edges, to connect all leaves, seems like a very hard problem.
I imagined one could do some sort of brute force, where ALL combinations of unused edges, from using 1 to all of them, are tested. Or if repairs are needed, testing ALL combinations of repairs with all combinations of new edges. When the amount of edges get high, this seems to me very very inefficient.
My question is, does anyone have any smart ideas to how this could be done in a more efficient way? I hope I explained it well enough.

This is an NP-hard problem, and I'll explain why. Imagine that you have three layers of nodes: the root node, a layer of intermediate connecting nodes, and then a layer of leaf nodes. Edges go from root to intermediate nodes, and from an intermediate node to some subset of leaf nodes. Suppose you have some choice of intermediate nodes and edges to leaf nodes that gives you a connected tree graph, where each intermediate node has an edge to only one leaf node. Now imagine all edges in the reduced graph are removed. Then to find the minimum number of edges needed to add to repair the graph, this is equivalent to finding the minimum number of remaining intermediate nodes whose edges cover all of the leaf nodes. This is equivalent to the set cover problem for the leaf nodes http://en.wikipedia.org/wiki/Set_cover_problem and is NP-hard. Thus there is almost certainly no fast algorithm for your problem in the worst case (unless P = NP). Maybe if you bound the number of edges that are removed, you can come up with a polynomial time algorithm where the exponent in the polynomial depends (hopefully weakly) on how many edges were removed.

Seems like the start to a good efficient heuristic/solution would be to weight the edges. A couple simple approaches (not the most space efficient) as to how you could weight the edges based on the total number of edges are listed below.
If using any number of undamaged edges is better than using a single alternative edge and using any number of alternative edges is better than a single damaged edge.
Undamaged edge: 1
Alternative edge: E
Damaged edge: E^2
In the case of 100 vertices and 500 edges, alternative edges would be weighted as 500, while damaged edges would be weighted as 250000.
If using any number of undamaged edges is better than using a single alternative edge or a single damaged edge.
Undamaged edge: 1
Alternative/damaged edge: E
In the case of 100 vertices and 500 edges, alternative/damaged edges would be weighted as 500.
It seems like you then try a number of approaches to find either the exact solution or a heuristic result. The main suggestion I have for an algorithm is below.
Find the directed minimium spanning tree. If you use the weighting listed above, then I believe the result is optimum if I'm understanding things correctly.
Although, if you have intermediate nodes (nodes that are neither the root or a leaf), then this is likely to result in an overestimating heuristic. In which case, you might be able to get around it by running all pairs all shortest paths first and use the path costs for that as input for the directed minimium spanning tree algorithm, but that's probably a heuristic as well.

Related

How can I add resilience to a minimum spanning tree?

I have a complete, weighted, undirected graph. The edge weights are the cost of a connection between two nodes, so the minimum spanning tree is the subset of the edges with the lowest total cost such that the graph remains connected.
The MST must be connected at all times, but unfortunately the connections aren't very reliable, so I would like to add redundancy to this graph/network.
Is it possible to compute a subset of edges such that the total edge cost is minimised and edge-connectivity is over a certain minimum?
I can see how it would be possible by bruteforcing, but I was looking for something more practical. I haven't been able to find much about this problem, I think mainly because I don't posses the vocabulary necessary to search.
My current idea is:
Compute the MST
While the it is still below a certain connectivity
Find a node most below that connectivity
Activate that node's edge with the lowest weight
The reason I don't find all the nodes below a certain connectivity all at once is because activating an edge may give another one enough connectivity.
I'm pretty sure this does not yield 100% provably optimal networks, because with this method, it is possible to over-connect nodes (e.g. you activate k edges for a node, then another node activates more shared edges, making some of those k redundant). I hope that makes sense.
Any tips would be much appreciated!
The Wikipedia article on edge connected graphs ends with, A related problem: finding the minimum k-edge-connected spanning subgraph of G (that is: select as few as possible edges in G that your selection is k-edge-connected) is NP-hard for k >= 2. They then cite a 1979 paper that shows it.
Therefore I'd suggest taking a greedy approach, and tip-toeing away.

Maximal number of vertex pairs in undirected not weighted graph

Given undirected not weighted graph with any type of connectivity, i.e. it can contain from 1 to several components with or without single nodes, each node can have 0 to many connections, cycles are allowed (but no loops from node to itself).
I need to find the maximal amount of vertex pairs assuming that each vertex can be used only once, ex. if graph has nodes 1,2,3 and node 3 is connected to nodes 1 and 2, the answer is one (1-3 or 2-3).
I am thinking about the following approach:
Remove all single nodes.
Find the edge connected a node with minimal number of edges to node with maximal number of edges (if there are several - take any of them), count and remove this pair of nodes from graph.
Repeat step 2 while graph has connected nodes.
My questions are:
Does it provide maximal number of pairs for any case? I am
worrying about some extremes, like cycles connected with some
single or several paths, etc.
Is there any faster and correct algorithm?
I can use java or python, but pseudocode or just algo description is perfectly fine.
Your approach is not guaranteed to provide the maximum number of vertex pairs even in the case of a cycle-free graph. For example, in the following graph your approach is going to select the edge (B,C). After that unfortunate choice, there are no more vertex pairs to choose from, and therefore you'll end up with a solution of size 1. Clearly, the optimal solution contains two vertex pairs, and hence your approach is not optimal.
The problem you're trying to solve is the Maximum Matching Problem (not to be confused with the Maximal Matching Problem which is trivial to solve):
Find the largest subset of edges S such that no vertex is incident to more than one edge in S.
The Blossom Algorithm solves this problem in O(EV^2).
The way the algorithm works is not straightforward and it introduces nontrivial notions (like a contracted matching, forest expansions and blossoms) to establish the optimal matching. If you just want to use the algorithm without fully understanding its intricacies you can find ready-to-use implementations of it online (such as this Python implementation).

Will a standard Kruskal-like approach for MST work if some edges are fixed?

The problem: you need to find the minimum spanning tree of a graph (i.e. a set S of edges in said graph such that the edges in S together with the respective vertices form a tree; additionally, from all such sets, the sum of the cost of all edges in S has to be minimal). But there's a catch. You are given an initial set of fixed edges K such that K must be included in S.
In other words, find some MST of a graph with a starting set of fixed edges included.
My approach: standard Kruskal's algorithm but before anything else join all vertices as pointed by the set of fixed edges. That is, if K = {1,2}, {4,5} I apply Kruskal's algorithm but instead of having each node in its own individual set initially, instead nodes 1 and 2 are in the same set and nodes 4 and 5 are in the same set.
The question: does this work? Is there a proof that this always yields the correct result? If not, could anyone provide a counter-example?
P.S. the problem only inquires finding ONE MST. Not interested in all of them.
Yes, it will work as long as your initial set of edges doesn't form a cycle.
Keep in mind that the resulting tree might not be minimal in weight since the edges you fixed might not be part of any MST in the graph. But you will get the lightest spanning tree which satisfies the constraint that those fixed edges are part of the tree.
How to implement it:
To implement this, you can simply change the edge-weights of the edges you need to fix. Just pick the lowest appearing edge-weight in your graph, say min_w, subtract 1 from it and assign this new weight,i.e. (min_w-1) to the edges you need to fix. Then run Kruskal on this graph.
Why it works:
Clearly Kruskal will pick all the edges you need (since these are the lightest now) before picking any other edge in the graph. When Kruskal finishes the resulting set of edges is an MST in G' (the graph where you changed some weights). Note that since you only changed the values of your fixed set of edges, the algorithm would never have made a different choice on the other edges (the ones which aren't part of your fixed set). If you think of the edges Kruskal considers, as a sorted list of edges, then changing the values of the edges you need to fix moves these edges to the front of the list, but it doesn't change the order of the other edges in the list with respect to each other.
Note: As you may notice, giving the lightest weight to your edges is basically the same thing as you suggest. But I think it is a bit easier to reason about why it works. Go with whatever you prefer.
I wouldn't recommend Prim, since this algorithm expands the spanning tree gradually from the current connected component (in the beginning one usually starts with a single node). The case where you join larger components (because your fixed edges might not all be in a single component), would be needed to handled separately - it might not be hard, but you would have to take care of it. OTOH with Kruskal you don't have to adapt anything, but simply manipulate your graph a bit before running the regular algorithm.
If I understood the question properly, Prim's algorithm would be more suitable for this, as it is possible to initialize the connected components to be exactly the edges which are required to occur in the resulting spanning tree (plus the remaining isolated nodes). The desired edges are not permitted to contain a cycle, otherwise there is no spanning tree including them.
That being said, apparently Kruskal's algorithm can also be used, as it is explicitly stated that is can be used to find an edge that connects two forests in a cost-minimal way.
Roughly speaking, as the forests of a given graph form a Matroid, the greedy approach yields the desired result (namely a weight-minimal tree) regardless of the independent set you start with.

Minimum vertex cover

I am trying to get a vertex cover for an "almost" tree with 50,000 vertices. The graph is generated as a tree with random edges added in making it "almost" a tree.
I used the approximation method where you marry two vertices, add them to the cover and remove them from the graph, then move on to another set of vertices. After that I tried to reduce the number of vertices by removing the vertices that have all of their neighbors inside the vertex cover.
My question is how would I make the vertex cover even smaller? I'm trying to go as low as I can.
Here's an idea, but I have no idea if it is an improvement in practice:
From https://en.wikipedia.org/wiki/Biconnected_component "Any connected graph decomposes into a tree of biconnected components called the block-cut tree of the graph." Furthermore, you can compute such a decomposition in linear time.
I suggest that when you marry and remove two vertices you do this only for two vertices within the same biconnected component. When you have run out of vertices to merge you will have a set of trees not connected with each other. The vertex cover problem on trees is tractable via dynamic programming: for each node compute the cost of the best answer if that node is added to the cover and if that node is not added to the cover. You can compute the answers for a node given the best answers for its children.
Another way - for all I know better - would be to compute the minimum spanning tree of the graph and to use dynamic programming to compute the best vertex cover for that tree, neglecting the links outside the tree, remove the covered links from the graph, and then continue by marrying vertices as before.
I think I prefer the minimum spanning tree one. In producing the minimum spanning tree you are deleting a small number of links. A tree with N nodes had N-1 links, so even if you don't get back the original tree you get back one with as many links as it. A vertex cover for the complete graph is also a vertex cover for the minimum spanning tree so if the correct answer for the full graph has V vertices there is an answer for the minimum spanning tree with at most V vertices. If there were k random edges added to the tree there are k edges (not necessarily the same) that need to be added to turn the minimum spanning tree into the full graph. You can certainly make sure these new edges are covered with at most k vertices. So if the optimum answer has V vertices you will obtain an answer with at most V+k vertices.
Here's an attempt at an exact answer which is tractable when only a small number of links are added, or when they don't change the inter-node distances very much.
Find a minimum spanning tree, and divide edges into "tree edges" and "added edges", where the tree edges form a minimum spanning tree, and the added edges were not chosen for this. They may not be the edges actually added during construction but that doesn't matter. All trees on N nodes have N-1 edges so we have the same number of added edges as were used during creation, even if not the same edges.
Now pretend you can peek at the answer in the back of the book just enough to see, for one vertex from each added edge, whether that vertex was part of the best vertex cover. If it was, you can remove that vertex and its links from the problem. If not, the other vertex must be so you can remove it and its links from the problem.
You now have to find a minimum vertex cover for a tree or a number of disconnected trees, and we know how to do this - see my other answer for a bit more handwaving.
If you can't peek at the back of the book for an answer, and there are k added edges, try all 2^k possible answers that might have been in the back of the book and find the best. If you are lucky then added link A is in a different subtree from added link B. In that case you can confine the two calculations needed for the two possibilities for added link A (or B) to the dynamic programming calculations for the relevant subtree so you have only doubled the work instead of quadrupled it. In general, if your k added edges are in k different subtrees that don't interfere with each other, the cost is multiplied by 2 instead of 2^k.
Minimum vertex cover is an NP complete algorithm, which means that you can not solve it in a reasonable time even for something like 100 vertices (not to mention 50k).
For a tree there is a polynomial time greedy algorithm which is based on DFS, but the fact that you have "random edges added" screws everything up and makes this algorithm useless.
Wikipedia has an article about approximation algorithm, claims that it reaches factor 2 and claims that no better algorithm is know, which makes it quit unlikely that you will find one.

Completely disconnecting a bipartite graph

I have a disconnected bipartite undirected graph. I want to completely disconnect the graph. Only operation that I can perform is to remove a node. Removing a node will automatically delete its edges. Task is to minimize the number of nodes to be removed. Each node in the graph has atmost 4 edges.
By completely disconnecting a graph, I mean that no two nodes should be connected through a link. Basically an empty edge set.
I think, you cannot prove your algorithm is optimal because, in fact, it is not optimal.
To completely disconnect your graph minimizing the number of nodes to be removed, you have to remove all the nodes belonging to the minimal vertex cover of your graph. Searching the minimal vertex cover is usually NP-complete, but for bipartite graphs there is a polynomial-time solution.
Find maximum matching in the graph (probably with Hopcroft–Karp algorithm). Then use König's theorem to get the minimal vertex cover:
Consider a bipartite graph where the vertices are partitioned into left (L) and right (R) sets. Suppose there is a maximum matching which partitions the edges into those used in the matching (E_m) and those not (E_0). Let T consist of all unmatched vertices from L, as well as all vertices reachable from those by going left-to-right along edges from E_0 and right-to-left along edges from E_m. This essentially means that for each unmatched vertex in L, we add into T all vertices that occur in a path alternating between edges from E_0 and E_m.
Then (L \ T) OR (R AND T) is a minimum vertex cover.
Here's a counter-example to your suggested algorithm.
The best solution is to remove both nodes A and B, even though they are different colors.
Since all the edges are from one set to another, find these two sets using say BFS and coloring using 2 colours. Then remove the nodes in smaller set.
Since there are no edges among themselves the rest of the nodes are disconnected as well.
[As a pre-processing step you can leave out nodes with 0 edges first.]
I have thought of an algorithm for it but am not able to prove if its optimal.
My algorithm: On each disconnected subgraph, I run a BFS and color it accordingly. Then I identify the number of nodes colored with each color and take the minimum of the two and store. I repeat the procedure for each subgraph and add up to get the required minimum. Help me prove the algorithm if it's correct.
EDIT: The above algorithm is not optimal. The accepted answer has been verified to be correct.

Resources