Dijkstra's Algorithm Does not generate Shortest Path? - algorithm

I am working through a shortest path problem using Dijkstra's Algorithm. I am having trouble because the algorithm is supposed to provide the shortest path, but after running the algorithm I get a shorted path by hand. Is this just a by-product of this algorithm?
The path I am trying to generate is from a -> z
Here is the path that I get from applying the algorithm, taking the shortest distance jump at each vertex I visit:
2 4 2 2 1 2 1 1 8 = 23
a -> d -> g -> k -> r -> n -> q -> p -> t -> z
This is confusing to me because if I take this path:
4 2 2 2 2 2 2 = 16
a -> c -> f -> i -> m -> p -> s -> z
I get a distance that is 5 less than the distance generated from the algorithm.
Did I misstep somewhere?

Looks like you misunderstand how Dijkstra's algorithm works. Instead of taking the edge with the smallest weight at each node, you always need to consider the total distance from the beginning (node $a$). You maintain a heap of all possible paths under consideration, which starts off as just the starting node with no edges and expands by adding all the paths with each outgoing edge of a node added to the path you're currently considering at each step.
That's a jumble of words trying to summarise where you went wrong. I suggest re-reading how Dijkstra's algorithm works: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

Related

Shortest cycle in undirected weighted graph which contains every node

Problem: Find the 'shortest cycle in undirected weighted graph which contains every node'. All weights are positive. A node may be visited more than once, the is distinguishes the problem from a Hamiltonian cycle (TSP).
A naïve attempt might be to use the minimum spanning tree (MST) and backtrack to get to the starting node. This results in a length of 2*MST but is not the minimum cycle.
Example: Consider a complete graph with vertices 1,2,3,4 and edge costs c12=c13=c14=1 and c23=c24=c34=100. TSP distance = 202 (1 -> 2 -> 3 -> 4 -> 1). Shortest cycle distance = 6 (1 -> 2 -> 1 -> 3 -> 1 -> 4 -> 1)
Edit: I am looking for an algorithm to find the shortest cycle.
In the Wikipedia page on TSP, it mentions a special case called "metric TSP", in which distances satisfy the triangle inequality.
In metric TSP, it does not matter whether or not you can visit the same city twice, because doing so is never necessary. You can always easily remove all the repeated visits without making your path any longer.
Every instance of "metric TSP" is, therefore, an instance of your problem. Metric TSP is still NP-hard, so your problem is too.

Shortest path with another constraint

Given a weighted undirected graph, I need to find the shortest path between two nodes, a classical shortest path problem actually. But there is one more constraint : Each node contains a "reduction" value that can be used to reduce the cost of the following edges for one traversal(not only adjacent, and reduction are not cumulative). So you can reduce the cost of an edge using the "Reduction" that was in one of the node you went throught before (the final cost for each edge can't be less than 0).
Note that once we went throught a node with a reduction, we can use it again for all the following edges (not just adjacent, and it is available an unlimited amount of time). Reduction doesn't accumulate.
Let's consider this graph :
in this graph the shortest path from node 1 to 5 is :
1 -> 4 for a cost of 13 (15-2)
4 -> 3 for a cost of 0 (12-12)
3 -> 5 for a cost of 0 (10-12) In this case, we reuse the reduction of node 4 because it is bigger than the reduction of node 3 (We went throught the node n°4 then we have an unlimited amount of reduction of cost 12). It is 0 and not -2 because the weight of an edge can't be negative.
Then the total cost from node 1 to node 5 is 13 + 0 + 0 = 13
To solve this problem, I've tried to use the classical Dijkstra/Bellman-Ford but it didn't work, can you help me with this ?
It seems to be this can be solved with a variation of Bellman-Ford.
Every path up to a given node can be summarised as a pair (C, D) where C is the cost of that path (after discounts) and D is the best discount factor available on that path. Since a discount can be reused an unlimited number of times once that node has been visited, it makes sense to always use the biggest discount seen so far on that path. For example, the path (1 -> 4 -> 3) has cost C = 13 and discount D = 12.
The complication over the undiscounted problem is that we cannot tell from the cost what the "best" path is to nodes in between the source and destination. In your example the path (1 -> 2 -> 3) has lower cost than (1 -> 4 -> 3), but the latter has a better discount which is why the best path from 1 to 5 is (1 -> 4 -> 3 -> 5).
Rather than recording the lowest cost path to each node (in Bellman-Ford algorithm), we need to record all "feasible" paths from the source to that node found so far. A path can be said to be feasible if there is no other known path that has both a lower cost and a better discount. After the algorithm terminates we can take from all feasible paths from source to destination the one with the smallest cost, ignoring the discount.
(Edit: I originally suggested Djikstra could be used but I think that not be so straightforward. I'm not sure we can choose "the closest" unvisited node in any meaningful way such that we are guaranteed to find the minimal path. Someone else might see how to make it work though...)
I think you can use a Dijkstra-type algorithm. Dijkstra's algorithm can be thought of computing the minimum spanning tree that contains the shortest paths from a source vertex to all other vertices. Let's call this the "Dijkstra tree" that contains all the shortest paths from a given source vertex.
Dijkstra keeps adding new vertices to the current tree. For the next vertex he chooses the one that is closest to the current tree. See this animation from wikipedia:
So when Dijkstra adds a new vertex v to an already inserted vertex u (of the current tree), the edge weight of {u, v} has to be considered. In your case, the costs are not just the edge weight of {u, v}, but the weight reduced by the sum of vertex-reductions along the shortest path to u in the current tree. So you have to remember the sum of the vertex reductions along the paths of this "Dijkstra" tree in the vertices.

Distance vector algorithm - maximum paths with 4 points

while programing bellman-ford algorithm I encountered one problem, it's question more theoretical than technical but here it is:
I have 4 points A,B,C,D, cost from A to B equals 3 etc. here is the graph:
B--3--C
| |
3 9
| |
A--1--D
Let's say I want to know what cost is from A to C via D, will it be: 10 ? or it will go from A to D (which cost is 1) then back from D to A (total cost is 1+1=2) then from A to B (1+1+3=5) and from B to C (1+1+3+3=8) so it will be 8 not 10 ?
I searched everywhere but I couldn't find any rational answer to my question.
EDIT:
let's say that for A->D and D->C paths count will be 2 and for A->D then D->A then A->B then B->C there will be total paths count equals 4 so will it choose the way with shortest paths count (paths count = 2) or the longer one (paths count = 4)?
For the via problem, I wouldn't use single go of the algorithm; I would call it twice. First, for A -> D, then for D -> C, as that is practically the problem; then, final path is sum of those two.
Note: I'm not familiar with Bellman-Ford algorithm; this answer is just a general remark regarding pathfinding.
If there are no negative-weight cycles, then every shortest path visits each vertex at most once.

Calculating the number of paths through graph

I am looking the number of unique x length paths through a graph starting at a particular node.
However I have a restriction that no node is visited more than once on any path.
For example take the following graph:
If I am after the number of 3 length paths starting at 5.
The answer would be 9.
5 -> 2 -> 1 -> 3
5 -> 2 -> 4 -> 3
5 -> 2 -> 4 -> 7
5 -> 4 -> 2 -> 1
5 -> 4 -> 3 -> 1
5 -> 4 -> 7 -> 6
5 -> 6 -> 7 -> 4
5 -> 7 -> 4 -> 2
5 -> 7 -> 4 -> 3
Note I am only concerted with the answer (9) not the specific paths.
I have tried using an adjacency matrix to the power of x to give the number of paths, but I cannot work out how to account for unique node restriction.
I have also tried using a depth-first search but the amount of nodes and size of x makes this infeasible.
EDIT: Confused DFS with BFS (Thank you Nylon Smile & Nikita Rybak).
This is NP-Hard.
Reduction from Hamiltonian Path.
Given a graph whose Hamiltonian Path existence we need to check...
Run your algorithm for each vertex, with a path length n-1. Any non-zero return corresponds to Hamiltonian path and vice versa.
So basically, if you find a polynomial time algorithm to solve your problem, then you have a polynomial time algorithm to solve the Hamiltonian Path problem, effectively proving P=NP!
Note: This assumes x is an input.
If you x was fixed (i.e. independent of the number of vertices in the graph), then you have O(n^x) time algorithms, which is in P, but still pretty impractical for medium sized x.
This problem is a counting problem in #P (number of solutions) instead of a decision problem in NP (yes or no).
Moron's reduction still works to prove the problem is #P-Complete because Hamilton Paths is also #P-complete.

Weighted Graph Algorithm

I have a weighted, directed graph with multiples edges starting from the ending at the same nodes.
Ex.
Multiple edges going from node A to node B.
What would be the best search algorithm to get all of the paths to a certain node and the associated costs of these paths?
Since you want all the paths, I'd use a simple breadth-first search. However, I also suggest that you collapse all the parallel edges into a single edge that has a list of weights.
Once you get all the different paths (that is, all the paths in which the nodes visited are different), for each path you can calculate all the possible alternative parallel routes.
So if you've got the following edges:
A -> C (5)
A -> C (3)
A -> B (7)
B -> C (1)
B -> C (4)
The first step transforms it into:
A -> C (5,3)
A -> B (7)
B -> C (1,4)
The breadth-first search on this graph will yield the following paths between A and B:
A -> B (7)
A -> C -> B (5,3) + (1,4)
So for the second path, you'll get the following costs:
5 + 1
5 + 4
3 + 1
3 + 4
This isn't going to be any faster in itself than just doing a BFS on the original graph, but a simpler graph is easier to handle.
If you have to output the cost of each path, there is nothing better than a plain DFS (or BFS). Since the problem is output sensitive and you might just have O(E + V) paths, you cannot accomplish anything better in terms of big-O notation.
As already stated, you can do bruteforce/backtracking using Depth First Search, etc.
Don't expect to find any shortcuts for this - if your graph is dense enough there can be lots of paths and even just finding how many of them there are is #P-complete (ie.: untractable).
(If your problem is different - maybe repeated nodes are allowed or you only want to find the shortest path or something like that then there could be tractable solution)
do you allow the cycling, that is you have directed link/path from a->b b-x-x-->a? for which case you will end up with unlimited paths.

Resources