1

I've looked at the implementation of dijkstra's algorithm found here , but it seems to work fine for negative weights.

Specifically, the relax method updates the vertex's distance in the priority queue or inserts it back in if it wasn't originally in the queue.

And since there aren't any checks to make sure we don't reinsert an already known vertex, wouldn't this implementation be more like a bellman-ford algorithm where we keep inserting vertices to visit and relax until run out of edges that reduce distance?

For example:

When running it on the image below with A as the source, we first determine the following distances:

C = 0
B = 1
D = 99

Then after our queue removals, we are left with (D, 99), which makes us visit vertex D and relax it. When relaxing vertex D, we find that (D to B = -300), which makes the distance to B to be -201. Now using the "relax" method above, we reinsert (B, -201) back in the queue. Now we take the min of the queue which is the (B, -201) that we just inserted. From this, we relax B and we can get the distance to C to be -200.

enter image description here

I know that any negative cycle will make the program not terminate, but what if we are given a graph with no negative cycle? Hopefully I'm not missing anything trivial here. Thanks for any help!

libik
  • 22,239
  • 9
  • 44
  • 87
gurdingering
  • 207
  • 5
  • 12
  • 1
    Try a negative weight in any cycle. – greybeard Jan 12 '16 at 20:34
  • This question has quite a history on SO alone, but have a look at his [CS answer](http://cs.stackexchange.com/questions/19771/why-does-dijkstras-algorithm-fail-on-a-negative-weighted-graphs). – greybeard Jan 12 '16 at 21:21

2 Answers2

0

Because if you put in a negative weight it will throw new IllegalArgumentException("edge " + e + " has negative weight");

Riley Carney
  • 804
  • 5
  • 18
  • That's true....but what if I took the exception out? The reasoning seems to still work – gurdingering Jan 12 '16 at 20:57
  • Personally I haven't delved into this algorithm but I believe it would not create a shortest path, and solve the problem wrong. The developer obviously put in that `throw` for a reason, and even specifies that it is for "where the edge weights are nonnegative." If you allowed for negative weights, it would probably provide invalid output's which aren't correct, or have some sort of error which isn't apparent at first glance. However, it may be able to solve some correctly, but typically the authors of programs want 100% correct solutions, not a high percent correct. – Riley Carney Jan 12 '16 at 21:01
0

Dijkstra is based on fact, that once the node is visited and all of its edges "used", it is NEVER visited anymore and therefore the complexity is low (no need for "re-balancing the whole graph".)

Both of this is based on non-negative edges, because if there is negative one, you have to "re-balance" them and complexity can rise a lot. And as you mentioned, cycles with negative cycles do not end at all.


The reason the author throws exception is because he does not want handle "not valid" graph and especially endless cycles.


PS : Your particular graph actually SHOULD be solvable by Dijkstra, but imagine this graph with negative edge and no cycles:

A ->(1) B ->(1) -> C
|      (-300)
v       ^
(5)     |
D ->(1) E 

You actually solve

B=1
C=2

And after this you CLOSE the A, B and C and do not want to enter them again. But after this you find that A->D->E->B is -294 and then you have re-enter all other values.

To imagine why this is so bad, I give you another example

    A ->(1) B ->(1) -> C -> SUPERGRAPH
    |    (-999999)
    v       ^
  (99999)   |
    D ->(1) E 

So now A->D is extremely high value and C is pointing to some SUPERGRAPH which however do not go over 99999 in total "length" from A.

What happens? Even if this works and there is no other cycles, you solve the whole supergraph from A, but after that, you find that actually A->B is much shorter and you have to solve the whole SUPERGRAPH again. If you have more of situations like this, for each one, you have to run Dijkstra alghoritm once again.

libik
  • 22,239
  • 9
  • 44
  • 87