confusion about dijkstra algorithm? - algorithm

According to the Algorithms book Corman, Dijkstra is applicable for only those graphs whose all edges have non negative weights.
Does that mean, if there is any edge with negative weight it will not work for whole of the graph?
or
Will it not count that negative weight edge?
Please indicate which one is right?

Dijkstra algorithm can work on a graph of some negative edges sometimes,like:
A-->B-->C
while w(A, B) = -1 and w(B, C) = -2.
But when there is at least one negative edge, it can't prove to be always right. like:
A-->B-->C-->D
\ /
\ _____ /
where w(A, B) = 1, w(B, C) = 3, w(C, D) = -5 ,w(A, D) = 2.
If you choose A as sourcepoint, you will get the length of shortest path from A to D is 2 by Dijkstra algorithm, not -1 in fact.
It is because that Dijkstra algorithm is a greedy algorithm, and its proof procedure of correctness uses that all its edges is non-negative to obtain a contradiction.
About its proof procedure, you can look it up at Theorem 24.6 (Correctness of Dijkstra’s algorithm) ,Introduction to Algorithm.

The major problem with negative edges are negative cycles. If a graph contains a negative cycle between vertex S and vertex T, then there is no shortest path between S and T. Dijkstra finds a shortest path, which is incorrect.
Thus, negative edges are not only ignored but contribute to entirely false solutions.
An alternative is Bellman-Ford algorithm which finds those negative cycles in it's |V|-th iteration.

Related

Given a weighted graph and natural number k how to find the cheapest path from node s to t that can be divided by k?

Given a weighted graph G=(V,E) which doesnt include negative cycles, a natural number k, and two verticles: s,t.
How can I find the cheapest route from s to t which its length can be divied by k?
Prepare a new graph G' with vertices V × {0, 1, …, n−1} and for each arc v → w of length ℓ in G, arcs (v, x) → (w, (x + ℓ) mod k). Then use Dijkstra's algorithm to find a shortest path from (s, 0) to (t, 0).
Use BFS with a priority queue, so as to always examine states (= paths from s) that are shortest. Unlike normal Dijkstra, your states are full paths, and you can revisit already-visited vertices as often as they are encountered.
I cannot prove that such an algorithm would be optimal, but at least it should be correct, always returning a valid shortest-path answer if it exists. Runtime for certain graphs and values of K would be very high, and the algorithm may not finish at all if there are no k-divisible paths from s to t but there are loops with a path-length divisible by k. You could find and filter those out first by using a preliminary DFS.

Completeness of A* Search

I have been reading about the completeness of A* and I understand that it must be complete if it has a finite branching factor , but why it must be also complete when each edge weight is greater than 0 ?
It's not true that if the graph has finite branching factor and each edge weight is greater than zero then A* terminates.
For example, consider the graph with vertices 0, 1, 2, 3, ... and a single vertex *. Let the weight of the edge between i and i+1 be 1/2^i, and let the weight of the edge between 0 and * be 2. Let the heuristic be 0, so A* degenerates into Dijkstra's algorithm.
Then A* will not find (in finite time) the path from 0 to * -- it will explore the path along the natural numbers since the distance from 0 to n is always less than 2. So despite the fact that this graph has finite branching factor and positive edge weights, A* does not find the solution.
The correct statement of the theorem is: "If a graph has a finite branching factor and all weights are greater than some ε>0 then A* is complete." The proof is straightforward: if the path from the start to the end is of weight d, then in the worst case all vertices distance <= d are visited before the end node. But there can be at most finitely many of them because the path from the start node to each can consist of at most d/ε vertices.

LocalBridge of degree k in Graph

What would be the best algorithm to find localbridge(k) in Graph? A local bridge of degree k is an edge whose removal would enlarge the shortest distance between its two end-points to at least k.
Wikipedia: http://en.wikipedia.org/wiki/Bridge_(interpersonal)#Local_bridge
Run an all-shortest-path-costs algorithm, like the Floyd-Warshall algorithm, but where you use tuples (d1,d2) for distances, instead of the typical real numbers d:
d1 is the length of the shortest path
d2 is the length of the second shortest path
This modification to the Floyd-Warshall algorithm should be straightforward.
When you are done running the all-shortest-path-costs algorithm, the localbridge(k) edges are those edges e = {u, v} such that the distance (1,d2) between u and v satisfies d2 >= k.

graph - Shortest path with Vertex Weight

Here is an excise:
In certain graph problems, vertices have can have weights instead of
or in addi- tion to the weights of edges. Let Cv be the cost of vertex
v, and C(x,y) the cost of the edge (x, y). This problem is concerned
with finding the cheapest path between vertices a and b in a graph G.
The cost of a path is the sum of the costs of the edges and vertices
encountered on the path.
(a) Suppose that each edge in the graph has a weight of zero (while
non-edges have a cost of ∞).Assume that Cv =1 for all vertices 1≤v≤n
(i.e.,all vertices have the same cost). Give an efficient algorithm to
find the cheapest path from a to b and its time complexity.
(b) Now suppose that the vertex costs are not constant (but are all
positive) and the edge costs remain as above. Give an efficient
algorithm to find the cheapest path from a to b and its time
complexity.
(c) Now suppose that both the edge and vertex costs are not constant
(but are all positive). Give an efficient algorithm to find the
cheapest path from a to b and its time complexity.
Here is my answer:
(a) use normal BFS;
(b) Use dijkstra’s algorithm, but replace weight with vertex weight;
(c)
Also use dijkstra’s algorithm
If only considering about edge weight, then for the key part of dijkstra's algorithm, we have:
if (distance[y] > distance[v]+weight) {
distance[y] = distance[v]+weight; // weight is between v and y
}
Now, by considering about vertex weight, we have:
if (distance[y] > distance[v] + weight + vertexWeight[y]) {
distance[y] = distance[v] + weight + vertexWeight[y]; // weight is between v and y
}
Am I right?
I guess my answer to (c) is too simple, is it?
You are on the right track, and the solution is very simple.
In both B,C, Reduce the problem to normal dijkstra, which assumes no weights on the vertices.
For this, you will need to define w':E->R, a new weight function for edges.
w'(u,v) = w(u,v) + vertex_weight(v)
in (b) w(u,v) = 0 (or const), and the solution is robust to fit (c) as well!
The idea behind it is using an edge cost you the weight of the edge, and the cost of reaching the target vertice. The cost of the source was already paid, so you disregard it1.
Reducing a problem, instead of changing an algorithm is usually much simpler to use, prove and analyze!.
(1) In this solution you "miss" the weight of the source, so the shortest path from s to t will be: dijkstra(s,t,w') + vertex_weight(s)_ [where dijkstra(s,t,w') is the distance from s to t using out w'
The vertex weight can be removed by slicing every vertex a in two vertices a1 and a2 with an edge from a1 to a2 with the weight of a.
I think you are right for the adaptation of dijkstra’s algorithm.

Use Dijkstra's to find a Minimum Spanning Tree?

Dijkstra's is typically used to find the shortest distance between two nodes in a graph. Can it be used to find a minimum spanning tree? If so, how?
Edit: This isn't homework, but I am trying to understand a question on an old practice exam.
The answer is no. To see why, let's first articulate the question like so:
Q: For a connected, undirected, weighted graph G = (V, E, w) with only nonnegative edge weights, does the predecessor subgraph produced by Dijkstra's Algorithm form a minimum spanning tree of G?
(Note that undirected graphs are a special class of directed graphs, so it is perfectly ok to use Dijkstra's Algorithm on undirected graphs. Furthermore, MST's are defined only for connected, undirected graphs, and are trivial if the graph is not weighted, so we must restrict our inquiry to these graphs.)
A: Dijkstra's Algorithm at every step greedily selects the next edge that is closest to some source vertex s. It does this until s is connected to every other vertex in the graph. Clearly, the predecessor subgraph that is produced is a spanning tree of G, but is the sum of edge weights minimized?
Prim's Algorithm, which is known to produce a minimum spanning tree, is highly similar to Dijkstra's Algorithm, but at each stage it greedily selects the next edge that is closest to any vertex currently in the working MST at that stage. Let's use this observation to produce a counterexample.
Counterexample: Consider the undirected graph G = (V, E, w) where
V = { a, b, c, d }
E = { (a,b), (a,c), (a,d), (b,d), (c,d) }
w = {
( (a,b) , 5 )
( (a,c) , 5 )
( (a,d) , 5 )
( (b,d) , 1 )
( (c,d) , 1 )
}
Take a as the source vertex.
Dijkstra's Algorithm takes edges { (a,b), (a,c), (a,d) }.
Thus, the total weight of this spanning tree is 5 + 5 + 5 = 15.
Prim's Algorithm takes edges { (a,d), (b,d), (c,d) }.
Thus, the total weight of this spanning tree is 5 + 1 + 1 = 7.
Strictly, the answer is no. Dijkstra's algorithm finds the shortest path between 2 vertices on a graph. However, a very small change to the algorithm produces another algorithm which does efficiently produce an MST.
The Algorithm Design Manual is the best book I've found to answer questions like this one.
Prim's algorithm uses the same underlying principle as Dijkstra's algorithm.
I'd keep to a greedy algorithm such as Prim's or Kruskal's. I fear Djikstra's won't do, simply because it minimizes the cost between pairs of nodes, not for the whole tree.
Of course, It's possible to use Dijkstra for minimum spanning tree:
dijsktra(s):
dist[s] = 0;
while (some vertices are unmarked) {
v = unmarked vertex with
smallest dist;
Mark v; // v leaves “table”
for (each w adj to v) {
dist[w] = min[ dist[w], dist[v] + c(v,w) ];
}
}
Here is an example of using Dijkstra for spanning tree:
You can find further explanation in Foundations of Algorithms book, chapter 4, section 2.
Hope this help

Resources