Approximation algorithem for finding diameter of a graph - algorithm

Given Graph G=(V,E) ,undirected and weightless, we would want to find the value of diameter D of graph G. Show how to find a value X such that X<=D<=2*X in running time of O(|V|+|E|).
Now, to find the actual diameter of graph you simply need to run BFS twice.Once from and arbitrary node and then from the most distend node. But in this question I need to find an approximation to the diameter. My guess was to run BFS once and choosing the largest distance as the diameter. There are two edge cases that can occur.
The first one occur when the chosen node is located on the perimeter of graph G. The distend node will be located on the opposite side of the perimeter and thus X will be equal to D.
The second case will occur when the chosen node is in the center of G and X will be equal to half of D( X in this case will be the radios of G).
This was my answer to this question. And yet I was given 15/25 . Is there an edge case that I didn't handle or was it wrong from the start?
Thank you in advance.

60% seems a bit harsh to this former algorithms TA -- you gave the correct algorithm and identified the extremal cases for the two inequalities. Nevertheless, I agree with amit that you needed to give a formal proof. If your graders are particularly strict, you might have needed to say a word or two as well about why your algorithm is linear-time.
Here's the start of a formal proof. Let d(v, w) be the minimum length of a path between vertices v and w. The diameter is defined to be D = max_{v, w} d(v, w). Your algorithm chooses an arbitrary vertex s and outputs X = max_{w} d(s, w).
You need to do a little bit of algebra to show two facts: that X <= D and that D <= 2 X. You'll need the triangle inequality d(a, b) + d(b, c) >= d(a, c), which holds for all vertices a, b, c, as well as the symmetry d(a, b) = d(b, a).

Related

Minimum spanning tree for pairs of adjacent edges

For some graph, there is a cost associated with each pair of adjacent edges. I hope to find a subgraph such that every point is connected and the cost is minimised (a minimum spanning tree).
For the above example, the solution will include the edges AB, BC and CD, but not DA, avoiding the expensive CDA and DAB triplets, and getting a score of 28 (weight of ABC + BCD).
To motivate this question, let's imagine that we're designing a road network between places, and whenever a car turns around a sharp bend it slows down. Creating the ideal network, one with a small number of sharp bends, may benefit from us taking node triplets into account.
The graphs I intend to apply this algorithm to will have 5,000 to 20,000 nodes, and 15,000 to 80,000 edges. Presumably, the function will be of this type or similar:
(
nodes: [T],
edges: [(int, int)],
distance: (a: T, b: T, c: T) => float
) => [(int, int)]
Where b is connected to both a and c, but a and c are not necessarily connected.
What algorithm solves this problem?
Thank you for any help you may give.
The quadratic objective feels like enough leeway to construct gadgets for an NP-hardness reduction, though I have no proof at this time.
Since your graph is sparse, I’m hoping that the max degree is small, especially given your comment about road networks. I’d suggest the following integer programming formulation:
Variables: for each edge {v, w}, let there be a 0-1 variable x(v, w) that is 1 if {v, w} belongs to the spanning tree and 0 otherwise. Also, for each vertex v and each nonempty subset S of edges incident to e, let there be a 0-1 variable y(v, S) that is 1 if the subset of edges incident to e in the tree is S and 0 otherwise.
Objective: minimize ∑v,S ∑{u,w}⊆S distance(u, v, w) y(v, S).
Initial constraints: we require that ∑v,S y(v, S) = 1, that is, each vertex has to choose exactly one neighborhood in the tree. We also require for each edge {v, w} that ∑v,S∋w y(v, S) = x(v, w), that is, the neighborhood that v chooses has to be consistent with whether the edge exists.
Connectivity constraints: right now nothing forces the solver to choose any edges at all. It’s possible to formulate connectivity constraints statically, but instead I’d recommend the following approach. Run the solver with the constraints so far and compute its connected components. If there’s exactly one component, great, it’s the optimal solution. Otherwise, for each component C, require that ∑{v,w}∈E(C,V∖C) x(v, w) ≥ 1 – that is, the tree contains at least one edge with one endpoint in C and one endpoint not in C – and try again.
I usually use OR-Tools because it’s the preferred library where I work, but you have many options.

Algorithm for minimum vertex cover in Bipartite graph

I am trying to figure out an algorithm for finding minimum vertex cover of a bipartite graph.
I was thinking about a solution, that reduces the problem to maximum matching in bipartite graph. It's known that it can be found using max flow in networ created from the bip. graph.
Max matching M should determine min. vertex cover C, but I can't cope with choosing the vertices to set C.
Let's say bip. graph has parts X, Y and vertices that are endpoints of max matching edges are in set A, those who are not belong to B.
I would say I should choose one vertex for an edge in M to C.
Specifically the endpoint of edge e in M that is connected to vertex in set B, else if it is connected only to vertices in A it does not matter.
This idea unfortunately doesn't work generally as there can be counterexamples found to my algorithm, since vertices in A can be also connected by other edges than those who are included in M.
Any help would be appriciated.
Kőnig's theorem proof does exactly that - building a minimum vertex cover from a maximum matching in a bipartite graph.
Let's say you have G = (V, E) a bipartite graph, separated between X and Y.
As you said, first you have to find a maximum matching (which can be achieved with Dinic's algorithm for instance). Let's call M this maximum matching.
Then to construct your minimum vertex cover:
Find U the set (possibly empty) of unmatched vertices in X1, ie. not connected to any edge in M
Build Z the set or vertices either in U, or connected to U by alternating paths (paths that alternate between edges of M and edges not in M)
Then K = (X \ Z) U (Y ∩ Z) is your minimum vertex cover
The Wikipedia article has details about how you can prove K is indeed a minimum vertex cover.
1 Or Y, both are symmetrical

Need assistance in resolving this variation of shortest path algorithm

The below picture is the representation from the question which was asked to me during samsung interview. I had to write the program to find the minimum distance between I and M. There was an additional constraint that we can change one of the edges. For example, The edge FM can be moved to join edge L and M and the edge value will still be 4.
If you notice, the distance between I and M via I-> E -> F -> G -> M is 20. However, if we change one of the edges such that L to M edge value is 4 now. We have to move edge FM to join L and M now. By this method, the distance between I and M is 20.
An arbitrary edge u, v can be changed to u, t or t,v. It can not be changed to x,y. So one of the vertices in the edge has to be same.
Please find the picture below to illustrate the scenario -
So my problem is that I had to write the program for this. To find the minimum distance between two vertices, I thought of using Djikstra's algorithm. However , I as not sure how to take care of the additional constraint where I had the option of changing one of the vertices. If I could get some help to solve this, I would really appreciate it.
If we move an edge (A, B), the new end should be either the start S or the target T vertex (otherwise, the answer is not optimal).
Let's assume that we move the edge (A, B) and the new end is T (the case when it's S is handled similarly). We need to know the shortest path from S to A that doesn't use this edge (once we know it, we can update the answer with the S->A->T path).
Let's compute the shortest path from S to all other vertices using Dijkstra's algorithm.
Let's fix a vertex A and compute the two minimums of dist[B] + weight(A, B) for all B adjacent to A. Let's iterate over all edges adjacent to A. Let the current edge be (A, B). If dist[B] + weight(A, B) is equal to the first minimum, let d be the second minimum. Otherwise, let d be the first minimum. We need to update the answer with d + weight(A, B) (it means that (A, B) becomes (A, T) now).
This solution is linear in the size of the graph (not counting the Dijkstra's algorithm run time).
To avoid code duplication, we can handle the case when the edge is redirected to S by swapping S and T and running the same algorithm (the final answer is the minimum of the results of these two runs).
In the graph you've shown, the shortest path I see is I -> E -> F -> M with a length of 13.
Moving the edge F -> M so that it connects L -> M just makes things worse. The new shortest path is I -> E-> F -> L -> M with a length of 18.
The obvious answer is to move edge F -> M so that it connects I directly to M, giving a length of 4.
In other words, find the shortest edge that's connected to I or M and use it to connect I directly to M.
For future reference, it's highly unlikely that you'll be asked to implement Djikstra's algorithm from memory in an interview. So you need to look for something simpler.

Directed graph decomposition

I want to decompose a directed acyclic graph into minimum number of components such that in each component the following property holds true-
For all pair of vertices (u,v) in a components, there is a path from u to v or from v to u.
Is there any algorithm for this?
I know that when the or is replaced by and in the condition, it is same as finding the number of strongly connected components(which is possible using DFS).
*EDIT: * What happens if the Directed graph contains cycles (i.e. it is not acyclic)?
My idea is to order the graph topologically O(n) using DFS, and then think about for what vertices can this property be false. It can be false for those who are joining from 2 different branches, or who are spliting into 2 different branches.
I would go from any starting vertex(lowest in topological ordering) and follow it's path going into random branches, till you cannot go further and delete this path from graph(first component).This would be repeated till the graph is empty and you have all such components.
It seems like a greedy algorithm, but consider you find a very short path in the first run(by having a random bad luck) or you find a longest path(good luck). Then you would still have to find that small branch component in another step of algorithm.
Complexity would be O(n*number of components).
When there is and condition, you should be considering any oriented graph, as DAG cannot have strongly connected component.
The two existing answers both have problems that I've outlined in comments. But there's a more fundamental reason why no decomposition into components can work in general. First, let's concisely express the relation "u and v belong in the same component of the decomposition" as u # v.
It's not transitive
In order to represent a relation # as vertices in a component, that relation must be an equivalence relation, which means among other things that it must transitive: That is, if x # y and y # z, it must necessarily be true that x # z. Is our relation # transitive? Unfortunately the answer is "No", since it may be that there is a path from x to y (so that x # y), and a path from z to y (so that y # z), but no path from x to z or from z to x (so that x # z does not hold), as the following graph shows:
z
|
|
v
x----->y
The problem is that according to the above graph, x and y belong in the same component, and y and z belong in the same component, but x and z belong in different components, which is a contradiction. This means that, in general, it's impossible to represent the relationship # as a decomposition into components.
If an instance happens to be transitive
So there is no solution in general -- but there can still be input graphs for which the relation # happens to be transitive, and for which we can therefore compute a solution. Here is one way to do that (though probably not the most efficient way).
Compute shortest paths between all pairs of vertices (using e.g. the Floyd-Warshall algorithm, in O(n^3) time for n vertices). Now, for every vertex pair (u, v), either d(u, v) = inf, indicating that there is no way to reach v from u at all, or not, indicating that there is some path from u to v. To answer the question "Does u # v hold?" (i.e., "Do u and v belong in the same component of the decomposition?"), we can simply calculate d(u, v) != inf || d(v, u) != inf.
This gives us a relation that we can use to build an undirected graph G' in which there is a vertex u' for each original vertex u, and an edge between two vertices u' and v' if and only if d(u, v) != inf || d(v, u) != inf. Intuitively, every connected component in this new graph must be a clique. This property can be checked in O(n^2) time by first performing a series of DFS traversals from each vertex to assign a component label to each vertex, and then checking that each pair of vertices belongs to the same component if and only if they are connected by an edge. If the property holds then the resulting cliques correspond to the desired decomposition; otherwise, there is no valid decomposition.
Interestingly, there are graphs that are not chains of strongly connected components (as claimed by Zotta), but which nonetheless do have transitive # relations. For example, a tournament is a digraph in which there is an edge, in some direction, between every pair of vertices -- so clearly # holds for every pair of vertices in such a graph. But if we number the vertices 1 to n and include only edges from lower-numbered to higher-numbered vertices, there will be no cycles, and thus the graph is not strongly connected (and if n > 2, then clearly it's not a path).

Single edge addition to minimize number of bridges in a graph

You are given a graph G with N vertices and M edges with N<=10^4 and M<=10^5. Now, you have to add exactly one edge (u,v) to the graph so that the total number of bridges is minimized. G may have multiple edges, but no self loops. On the other hand, the newly generated graph, after adding the edge, G', may have both self loops and multiple edges. If many such (u,v) with u<=v is possible then output the lexicographically smallest one (the vertices are numbered from 1..n).
A trivial idea would be to try all edges in order and then use the bridges finding algorithm to find the number of bridges. This takes time O(V^2 * E), so it is clearly useless. How to do better in terms of runtime ?
EDIT: Following advice by j_random_hacker, I add the following details about the source of the above problem. This is a problem named Computer Network (specifically problem 3) from India's IOI Training Camp '14 Practice Test (Test 3). It was an onsite offline test, so I cannot prove that it is not from a present contest, by giving a link. But I have a PDF of the problem statement.
This is not a complete answer but some ideas to steer you towards it:
To avoid having to run the bridge-finding algorithm after trying each possible edge, it pays to ask: By how much can adding a single edge (u, v) change the number of bridges in a graph G?
If u and v are not already connected by any path in G, then certainly (u, v) will itself become a bridge. What about the "bridgeness" (bridgity? bridgulence?) of all other pairs of vertices? Does it change? (Most importantly: Can any edge go from being a bridge to being a non-bridge? If you can prove that this can never happen, then you can immediately discard all such vertex pairs (u, v) from consideration as they can only ever make the situation worse.)
If u and v are already connected in G, there are 2 possibilities:
Every path P that connects them shares some edge (x, y) (note that x and y are not necessarily distinct from u and v). Then (x, y) is a bridge in G, and adding (u, v) will cause (x, y) to stop being a bridge, because it will then become possible to get from x to y "the long way", by going from x back to u, via the new edge (u, v) to v, and then back up to y. (This assumes that x is closer to u on P than y is, but clearly the argument still works if y is closer: just swap u and v.) There could be multiple such bridges (x, y): in that case, all of them will become non-bridges after (u, v) is added.
There are at least 2 edge-disjoint paths P and Q already connecting u and v. Obviously no edge (x, y) on P or Q can be a bridge, since if (x, y) on P were deleted, it's still possible to get from x to y "the long way" via Q. The question is, again: What about the bridgeness of all other vertex pairs? You should be able to prove that this property doesn't change, meaning that adding the edge (u, v) leaves the total number of bridges unchanged, and can therefore be disregarded as a useless move (unless there are no bridges at all to start with).
We see that 2.1 above is the only case in which adding an edge (u, v) can be useful. Furthermore, it seems that the more bridges we can find in a single path in G, the more of them we can neutralise by choosing to connect the endpoints of that path.
So it seems like "Find the path in G that contains the most bridges" might be the right criterion. But first we need to ask ourselves: Does the number of bridges in a path P accurately count the number of bridges eliminated by adding an edge from the start of P to the end? (We know that adding such an edge must eliminate at least those bridges, but perhaps some others are also eliminated as a "side effect" -- and if so, then we need to count them somehow to make sure that we add the edge that eliminates the most bridges overall.)
Happily the answer is that no other bridges are eliminated. This time I'll do the proof myself.
Suppose that there is a path P from u to v, and suppose to the contrary that adding the edge (u, v) would eliminate a bridge (x, y) that is not on P. Then it must be that the single edge (x, y) is the only path from x to y, and that adding (u, v) would create a second path Q from x, via the edge (u, v) in either direction, to y that avoids the edge (x, y). But for any such Q, we could replace the edge (u, v) in Q with the path P, which from our initial assumption avoids (x, y), and still get a path Q' from x to y that avoids the edge (x, y) -- this means that (x, y) must have already been connected by two edge-disjoint paths (namely the single edge (x, y) and Q'), so it could not have been a bridge in the first place. Since this is a contradiction, it follows that no such "removed as a side effect" bridge (x, y) can exist.
So "Find the path in G that contains the most bridges, and add an edge between its endpoints" definitely gives the right answer -- but there is still a problem: this sounds a lot like the Longest Path problem, which is NP-hard for general graphs, and therefore slow to solve.
However, there is a way out. (There must be: you already have an O(V^2*E) algorithm, so it can't be that your problem is NP-hard :-) ) Think of the biconnected components in your input graph G as being vertices in another graph G'. What do the edges between these vertices (in G') correspond to in G? Do they have any particular structure? Final (big) hint: What is a critical path?
This answer is a spoiler. You should probably think along with j_random_hacker's answer instead.
If I understand your problem correctly:
Think of the graph as a tree of biconnected components. Find the longest path in this tree and link up its ends with the new edge.
There is a linear-time algorithm for finding biconnected components using depth first search. Finding the longest path in a tree takes linear time and can be done using depth-first search---make it do "find the farthest vertex and return both it and its distance" and use that. So this takes linear time overall.
(You can roll it all into a single depth-first search that returns the number of bridge edges in the bridgiest path and the farthest vertex in said bridgiest path.)

Resources