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.
Related
Let G = (V, E) be a flow network
with source s, sink t, and capacity function c(·). Assume that, for every
edge e ∈ E, c(e) is an integer. Define the size of an s-t cut (A, B) in G
to be the number of edges directed from A to B. Our goal is to identify,
from among all minimum cuts in G, a minimum cut whose size is as small
as possible.
Let us define a new capacity function c'(·) for G as follows. For each
edge e ∈ E, by c'(e) = m·c(e)+1. Suppose (A, B) is a minimum
cut in in G with respect to the capacity function c'(·).
(a) Show that (A, B) is a minimum cut with respect to the original capacity
function c(·).
(b) Show that, amongst all minimum cuts in G, (A, B) is a cut of smallest
size.
(c) Use the results of parts (a) and (b) to obtain a polynomial-time algorithm
to find a minimum cut of smallest size in a flow network.
How can I write a polynomial time algorithm for this? Any Idea?
I won't spoil the answer, but I will leave a hint to any student who finds this post in the future. Consider what happens if you take two min-cuts (A,B) and (C,D) in G, such that the number of edges in one is minimal and the number of edges in the other is not. Then map them to G' and consider the value of these two cuts.
Search up dijkstra's algorithm, it's usually used for shortest paths in a graph. I dont fully understand the algorithm you are trying to achieve but I feel it is very similar and the thinking behind dijstra's could be used
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.)
I'm quite surprised I couldn't find anything on this anywhere, it seems to be a problem that should be quite well known:
Consider the Euclidean shortest path problem, in two dimensions. Given a set of obstacle polygons P and two points a and b, we want to find the shortest path from a to b not intersecting the (interior of) any p in P.
To solve this, one can create the visibility graph for this problem, the graph whose nodes are the vertices of the elements of P, and where two nodes are connected if the straight line between them does not intersect any element of P. The edge weight for any such edge is simply the Euclidean distance between such two points. To solve this, one can then determine the shortest path from a to b in the graph, let's say with A*.
However, this is not a good approach. Creating the visibility graph in advance requires checking if any two vertices from any two polygons are connected, a check that has higher complexity than determining the distance between two nodes. So working with a modified version of A* that "does everything what it can before checking if two nodes are actually connected" actually speeds up the problem.
Still, A* and all other shortest path problems always start with an explicitly given graph for which adjacent vertices can be traversed cheaply. So my question is, is there a good (optimal?) algorithm for finding a shortest path between two nodes a and b in an "implicit graph" that minimizes checking if two nodes are connected?
Edit:
To clarify what I mean, this is an example of what I'm looking for:
Let V be a set, a, b elements of V. Suppose w: V x V -> D is a weighing function (to some linearly ordered set D) and c: V x V -> {true, false} returns true iff two elements of V are considered to be connected. Then the following algorithm finds the shortest path from a to b in V, i.e., returns a list [x_i | i < n] such that x_0 = a, x_{n-1} = b, and c(x_i, x_{i+1}) = true for all i < n - 1.
Let (V, E) be the complete graph with vertex set V.
do
Compute shortest path from a to b in (V, E) and put it in P = [p_0, ..., p_{n-1}]
if P = empty (there is no shortest path), return NoShortestPath
Let all_good = true
for i = 0 ... n - 2 do
if c(p_i, p_{i+1}) == false, remove edge (p_i, p_{i+1}) from E, set all_good = false and exit for loop
while all_good = false
For computing the shortest paths in the loop, one could use A* if an appropriate heuristic exists. Obviously this algorithm produces a shortest path from a to b.
Also, I suppose this algorithm is somehow optimal in calling c as rarely as possible. For its found shortest path, it must have ruled out all shorter paths that the function w would have allowed for.
But surely there is a better way?
Edit 2:
So I found a solution that works relatively well for what I'm trying to do: Using A*, when relaxing a node, instead of going through the neighbors and adding them to / updating them in the priority queue, I put all vertices into the priority queue, marked as hypothetical, together with hypothetical f and g values and the hypothetical parent. Then, when picking the next element from the priority queue, I check if the node's connection to its parent is actually given. If so, the node is progressed as normal, if not, it is discarded.
This greatly reduces the number of connectivity checks and improves performance for me a lot. But I'm sure there's still a more elegant way, in particular one where the "hypothetical new path" doesn't just extend by length one (parents are always actual, not hypothetical).
A* or Dijkstra's algorithm do not need an explicit graph to work, they actually only need:
source vertex (s)
A function next:V->2^V such that next(v)={u | there is an edge from v to u }
A function isGoal:V->{0,1} such that isGoal(v) = 1 iff v is a target node.
A weight function w:E->R such that w(u,v)= cost to move from u to v
And, of course, in addition A* is going to need a heuristic function h:V->R such that h(v) is the cost approximation.
With these functions, you can generate only the portion of the graph that is needed to find shortest path, on the fly.
In fact, A* algorithm is often used on infinite graphs (or huge graphs that do not fit in any existing storage) in artificial inteliigence problems using this approach.
The idea is, you only look on edges in A* from a given node (all (u,v) in E for some given u). You don't need the entire edges set E in order to do it, you can just use your next(u) function instead.
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).
I'm looking for a solution to the following problem, related to shortest path.
Given a directed Graph G = (V,E), source s, targets t1, t2, ..., tk and the costs for traveling edge {i,j} is cij. Now I want to know the shortest paths from s to t1, ..., tk. BUT, if a vertext vi (not source or targets) is used then we have an additional cost of C. Note that is two paths use the same vertext vi, the costs C is only paid once.
If you are looking for the shortest path, and each path is penaltised if using c then:
Create a modified weightning function:
w'(u,v) = w(u,v) + C if v == c
w'(u,v) = w(u,v) otherwise
It is easy to see that when running dijkstra's algorithm or Bellman Ford, with w' any path that uses c is penaltized by exactly C, since if c appears in the path - it appears exactly once, so C is added to the total weight [note that c cannot appear more then once in a shortest path], and of course there is no penalty if c is not used in this path.
EDIT: I am not sure I understood correctly, if what #SaeedAmiri is mentioning is correct, and if you want to give the penalty only once [and minimize the total sum of paths to t1,...,tk] Then you should use a different solution - with a similar idea:
create a weightning function w' such that:
w'(u,v) = w(u,v) + C + epsilon if v == c
w'(u,v) = w(u,v) otherwise
Note that it is important epsilon is a small size that can be achieved only on w', and is the smallest possible size.
Run dijkstra or BF on the graph with w, let's denote the weights as
W1
Run dijkstra or BF in the graph with w' let's denote the weights as W2
If W1[ti] == W2[ti] for each ti ∈ { t1, ..., tk } - then you don't need c in the shortest paths, and the total result is SUM(W1[ti])
Otherwise - the result is min { SUM(W1[ti]) + C , SUM(W2[ti])`
The idea behind step 4 is you got two possibilities:
You can get to all of t1, ... , tk without using c, and it will be cheaper then using a path with it, so you return the sum of W2.
Or, if ignoring c - will only be more expansive - thus you use it freely [and return the sum of W1], and add the penalty only once.
The standard O(n^3) dynamic programming solution...
http://en.wikipedia.org/wiki/Dijkstras_algorithm
...still works, with only a minor adjustment:
Just calculate the adjacency matrix of direct costs and then iterate through considering shortcuts, but when calculating the cost of a shortcut add on vi.
You haven't told us exactly what the problem is yet, but there's an unambiguous fragment that admits an objective-preserving reduction from set cover.
For an arbitrary instance of set cover, set up a graph with a source, vertices for each set, and vertices for each element. The terminals t1, ..., tk are the element-vertices. Each set-vertex has edges of weight zero to the source and to the vertices corresponding to its elements. On this graph, we have to buy a set cover in order to reach the terminals from the source, and every set cover suffices.
Unless there's something you can tell us about your instances, the approximation ratios for polynomial-time algorithms won't be any better than Theta(log n), so I suggest integer programming.