K negative edges - single source shortest path - algorithm

I've managed to solve the problem finding all single source shortest paths when there's exactly one negative edge using dijkstra.
Now i'm trying to face a new problem, how to find all shortest paths from a given source when there are exactly K negative edges using dijkstra only (Not bellman ford). (k is known).
Can't really think of a good way to do it.
any suggestions?

If it is a nondirectional graph, there is no single shortest path because even with a single negative edge, you could just go back and forth on that negative edge and have an infinite number of paths of negative infinity.
However, assuming a directional graph with no negative cycles, you could use Breadth First Search and keep track of both the negative edges you've already hit and the shortest path to each node you've discovered so far. If you see a node you've already visited, you only go there again if it would be better than the previous path you took to get there.
Since there are no negative cycles the algorithm must terminate. After the algorithm terminates the target node should have the best path that was used to get there.

Related

Preprocess shortest paths under contention

It is easy to prove that if P is a shortest path between u and v, then every subpath is also a shortest path.
Given a connected Graph, I want to preprocess a the shortest path between every pair of nodes in a Matrix, such that:
Path[u,v] = Path[v,u]
If x,y in Path[u,v] then Path[x,y] is a subpath of Path[u,v].
I can not figure out an algorithm or a prove and actually I do not know if this is posible.
Any idea is welcome.Thank you.
You can only get (1) if you are working with undirected graphs OR if it is guaranteed that the weight of the arc (a, b) is equal to the weight of the arc (b, a) for all arcs in your graph.
The problem you describe sounds like the all-pairs shortest path problem: for each pair of nodes in a connected graph, find the shortest paths between nodes in the pair. The Floyd-Warshall algorithm can be used to find the lengths of paths and it is straightforward to reconstruct the shortest paths from there.
This algorithm further requires that there are no negative cycles (otherwise a shorter path could always be obtained by running through that cycle again) but that requirement seems reasonable.
To guarantee property (2), you need to make sure when reconstructing paths you are reconstructing "canonical" paths whenever more than one shortest path may be possible. To do this, impose an ordering on the vertices and always test candidate nodes in ascending order, always preferring the lowest-ordered node which maintains the shortest-path property.
Wikipedia has a fairly good write-up.

Dijkstra with Parallel edges and self-loop

If I have a weighted undirected Graph with no negative weights, but can contain multiple edges between vertex and self-loops, Can I run Dijkstra algorithm without problem to find the minimum path between a source and a destination or exists a counterexample?
My guess is that there is not problem, but I want to be sure.
If you're going to run Dijkstra's algorithm without making any changes to he graph, there's a chance that you'll not get the shortest path between source and destination.
For example, consider S and O. Now, finding the shortest path really depends on which edge is being being traversed when you want to push O to the queue. If your code picks edge with weight 1, you're fine. But if your code picks the edge with weight 8, then your algorithm is going to give you the wrong answer.
This means that the algorithm's correctness is now dependent on the order of edges entered in the adjacency list of the source node.
You can trivially transform your graph to one without single-edge loops and parallel edges.
With single-edge loops you need to check whether their weight is negative or non-negative. If the weight is negative, there obviously is no shortest path, as you can keep spinning in place and reduce your path length beyond any limit. If however the weight is positive, you can throw that edge away, as no shortest path can go through that edge.
A zero-weight edge would create a similar problem than any zero-weight loop: there will be not one but an infinite number of shortest paths, going through the same loop over and over again. In these cases the sensible thing is again to remove the edge from the graph.
Out of the parallel edges you can throw away all but the one with the lowest weight. The reasoning for this is equally simple: if there was a shortest path going through an edge A that has a parallel edge B with lower weight, you could construct an even shorter path by simply replacing A with B. Therefore no shortest path can go through A.
It just needs a minor variation. If there are multiple edges directed from u to v and each edge has a different weight, you can either:
Pick the weight with least edge for relaxation; or
Run relaxation for each edge.
Both of the above will have the same complexity although the constant factors in #2 will have higher values.
In any case you'll need to make sure that you evaluate all edges between u and v before moving to the next adjacent node of u.
I don't think it will create any kind of problem.As the dijkstra algorithm will use priority queue ,so offcourse minimum value will get update first.

need to detect a ending path in the graph with minimilistic weight

Would like to find the shortest weighted path from the node a to any node. The destination node is not given. One can visit any vertex many time.
if the path weight's should be less than Integer.MAX
what is the algorithm to proceed ..?? cant detect the algorithm itself.
i did try for travelling salesman problem but it doesn't match ; neither it match for Dijkstra ...
how to keep in memory all the paths is the major challenge here ..
Edit: Graph is not directed one and there are no negative wieghts.
references: http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare
http://en.wikipedia.org/wiki/Travelling_salesman_problem
For an undirected graph with no negative weights, it's possible to use Floyd-Warshall algorithm to find all-pairs shortest path with time complexity of O(V^3), where V is a number of vertices. The algorithm also allows an easy way to reconstruct the all computed shortest paths. It uses O(V^2) memory to store distances and additional information for reconstructing the path.
There are also some other algorithms for solving this problem with better time complexity, but Floyd-Warshall is really easy to code and start with.
Would like to find the shortest weighted path from the node a to any
node.
I immediately think Dijkstra's algorithm, because that's exactly what it does.
how to keep in memory all the paths is the major challenge here ..
For each node in the graph, keep track of it's previous node that would result in the shortest path. Take a look at the pseudocode, line 20.
To build the path, simply go backwards from the destination node until you reach the source node.

Can I use Dijkstra's shortest path algorithm in my graph?

I have a directed graph that has all non-negative edges except the edge(s) that leave the source (S). There are no edges from any other vertices to the source. To find the shortest distance from source (S) to a vertex (T) in the graph, can I use Dijkstra's shortest path algorithm even though the edges leaving the source is negative?
Assuming only source-adjecent edges can have negative weights and there is no path back to the source from any of the source-adjecent nodes (as mentioned in the comment), you can just add a constant C onto all edges leaving the source to make them all non-negative. Then subtract C from the final result.
On a more general note, Dijkstra can be used to solve shortest-path in any graph with negative edge weights (but no negative cycles) after applying Johnson's reweighting algorithm (which is essentially Bellman-Ford, but needs to be performed only once).
Yes, you can use Dijkstra on that type of directed graph.
If you use already finished alghoritm for Dijsktra and it cannot use negative values, it can be good practise to find the lowest negative edge and add that number to all starting edges, therefore there is no-negative number at all. You substract that number after finishing.
If you code it yourself (which is acutally pretty easy and I recommend it to you), you almost does not change anything, just start with lowest value (as usual for Dijkstra) and allow it, that lowest value can be negative. It will work in your case.
The reason you generally can't use Dijkstra's algorithm for (directed) graphs with negative links is that Dijkstra's algorithm is greedy. It assumes that once you pick a vertex with minimum distance, there is no way it can later be reached by a smaller paths.
In your particular graph, after the very first step, you traverse all possible negative edges and Dijkstra's assumption actually holds from now on. Regardless of the fact that those vertices directly connected to start now have negative values, once you identify which has the minimum distance, it can never be reached again with a smaller distance (since all edges you would traverse from this point on would have a positive distance).
If you think about the conditions that dijkstra's algorithm puts upon the edges for the algorithm to work it is only that they are never decreasing after initialisation.
Thus, it actually doesn't matter if the first step is negative as from those several points onwards the function is constantly increasing and thus the correct output will be found (provided there is no way to get back to the start square.).

What modifications could you make to a graph to allow Dijkstra's algorithm to work on it?

So I've been thinking, without resorting to another algorithm, what modifications could you make to a graph to allow Dijkstra's algorithm to work on it, and still get the correct answer at the end of the day? If it's even possible at all?
I first thought of adding a constant equal to the most negative weight to all weights, but I found that that will mess up everthing and change the original single source path.
Then, I thought of traversing through the graph, putting all weights that are less than zero into an array or somwthing of the sort and then multiplying it by -1. I think his would work (disregarding running time constraints) but maybe I'm looking at the wrong way.
EDIT:
Another idea. How about permanently setting all negative weights to infinity. that way ensuring that they are ignored?
So I just want to hear some opinions on this; what do you guys think?
Seems you looking for something similar to Johnson's algorithm:
First, a new node q is added to the graph, connected by zero-weight edges to each of the other nodes.
Second, the Bellman–Ford algorithm is used, starting from the new vertex q, to find for each vertex v the minimum weight h(v) of a path
from q to v. If this step detects a negative cycle, the algorithm is
terminated.
Next the edges of the original graph are reweighted using the values computed by the Bellman–Ford algorithm: an edge from u to v,
having length w(u,v), is given the new length w(u,v) + h(u) − h(v).
Finally, q is removed, and Dijkstra's algorithm is used to find the shortest paths from each node s to every other vertex in the
reweighted graph.
By any algorithm, you should check for negative cycles, and if there isn't negative cycle, find the shortest path.
In your case you need to run Dijkstra's algorithm one time. Also note that in Johnson's algorithm semi Bellman–Ford algorithm runs just for new added node. (not all vertices).

Resources