Bellman-Ford algorithm's intermediate optimality property, is it correct? - algorithm

Bellman-Ford algorithm is famously known to solve the single source shortest path problem (SSSPP) for any arbitrary connected graph G(V,E) with additive edge weights, whenever one exists.
The basic implementation version of the algorithm for e.g.: Bellman-Ford-Wiki-page and its proof of correctness, when used parallel relaxation of all edges, as per my understanding, implies an interesting by-product, which I call as "intermediate optimality property", (which might be very helpful for some applications like this question) is stated as below:
After k iterations, we have every node identified with its shortest path from the same source, under the constraint of #edges in the path is <= k
This, under the assumption of simple shortest-path existence, will ensure producing the shortest path solution to SSSPP, for every destination node, after at most |V|-1 iterations.
Is the above property correct?
According to some people (for e.g. comments just below this question), it is not correct and I fail to understand why!!
(UPDATED: I am using a parallel update on all the vertices.)

Suppose we have a simple graph A->B->C->D with all weights equal to 1.
If we visit the vertices in the order A,B,C,D then during the first iteration we will relax all of the following:
A->B, finds shortest path to B is 1
B->C, finds shortest path to C is 2
C->D, finds shortest path to D is 3.
So in the first iteration we have found the shortest path to D despite this path needing 3 edges.
However, if the vertices were visited in the order D,C,B,A it would take more iterations to find the shortest path to D.
In other words, after k iterations we will have certainly found any shortest paths with #edges <= k, however we may also have found a better route that uses more edges.

Related

Find a positive simple s-t Path on a Graph is NP-Complete?

I'm trying to find something on the literature to help me to solve this problem:
Given a graph with non negative edge weights, find a simple s-t positive path of any size, i.e., a path that goes from s to t with length greater than 0. I was trying to use dijkstra algorithm to find a positive shortest path by avoiding relax the edges that have cost zero, but this is wrong. I don't want to believe that this problem is NP-Complete =/. Sometimes it seems to be NP-Complete, because there may be a case where the only positive path is the longest path. But this is such a specific case. I think that on this kind of instance the longest path problem is polynomially solvable.
Can someone help me identifying this problem or showing that it is NP-Complete ?
Observations: The only requirement is to be some positive path (not necessarily the lowest or longest). In case of multiple positive paths it can be anyone. In case of non existence of such path, the algorithm should flag that the graph has no positive path.
Dijkstra's algorithm produces an answer in polynomial time (so in P rather than NP) and provides a shortest path between any 2 points on the graph.
Please refer to Dijkstra's Algorithm Wiki for further details.
You don't really need any more proof.
I'm not quite sure how "relax the edges that have cost 0" has any impact on this question at all.
The problem is NP-complete even with only one single edge having value 1, and all the others having value 0. Reduce from Two Directed Paths:
Two Directed Paths
Input: A directed graph G and two pairs of vertices (s1, t1) and (s2, t2)
Output: Two vertex-disjoint paths, one from s1 to t1 and from from s2 to t2.
Create a new instance with all edges having weight 0, and create an edge from t1 to s2 with weight 1.

Shortest path on graph with changing weights

I was trying to solve a local programming contest question. The problem is basically about finding the shortest path in a weighted graph. I am pretty new to these types of problems and I thought I could use Dijkstra's algorithm. However, there is a small complication - certain values are different, depending on the situation of this current path.
Problem
There are two types of weights: normal weights and weights with condition (let's call them K). The condition is this: once you move through edge with weight K, all other weights of type K have value of 0. This brings a few more problems, because the apparent shortest path can be beaten by a combination of edges with weights of type K.
Example
Below is this type of problem. If no weights would change their value, we could find the shortest path easily with Dijkstra. However, when weights K change their value, we can find a shorter path, because the weight of the edge C-D is 0 after moving through the edge A-C.
Question
How can I find the shortest path?
Can I use Dijkstra's algorithm here or is it better to use another algorithm like A* or BFS?
How many K's are there?
I it's only one, Dijkstra is good.
I will add to say that BFS does not handle weighs well.
Reminder: Dijkstra finds the shortest path from a vertex to all vertexes.
Run Dijkstra twice and define a different wight function for each run. First the wight function for K values is infinite. Second wight function for K values is 0.
Than compare the result from run1 to run2+K.
This is true because if the shortest path is without K first run will find it. otherwise it's with K and the second run will find it. Either way the algorithm will find it.

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.

How to find ALL Eulerian paths in directed graph

I have a directed graph and I want to find all existing eulerian paths (in my graph I actually know that those will be circuits).
I have done some research so I can use for example Hierholzer's algorithm as in here: http://stones333.blogspot.co.uk/2013/11/find-eulerian-path-in-directed-graph.html to find a path from given node but this algorithm returns only one path I believe.
My idea to solve this is to have an algorithm that will return ALL existing Eulerian paths / circuits starting from given node. Then I will run this algorithms for all nodes and get the results. This will have n^2 or n^3 complexity which is great.
So my question is if there is an algorithm that will find all Eulerian paths / circuits in directed graph from given node? Or maybe someone knows another solution to my problem.
EDIT:
after Gassa comment I think that the solution with Euler paths might be an overkill for my problem. Problem is as follows: for given n we create a pairs of integers which sum is <= n. For those pairs find all paths that connects all of the pairs such that second value of previous pair equals to the first value from next pair (like domino).
Example: n = 2, then available pairs = {(0,0), (0,1),(1,0),(1,1),(2,0),(0,2)}. One of the valid chains = (0,0)=>(0,1)=>(1,1)=> (1,0)=>(0,2)=>(2,0). I preferred algorithm using graphs because for example (0,0) might not be valid sometimes, but let's say it is valid for the sake of this question. Brute force solution to this problem is to of course create all permutations of available pairs and then see if they are valid but this is obviously O(n!) complex. I am pretty sure this could be done in some "smart" way.
In the general case, the number of distinct Eulerian paths is exponential in the number of vertices n. Just counting the number of Eulerian circuits in an undirected graph is proven to be #P-complete (see Note on Counting Eulerian Circuits by Graham R. Brightwell and Peter Winkler). Quoting Wikipedia:
A polynomial-time algorithm for solving a #P-complete problem, if it
existed, would imply P = NP, and thus P = PH. No such algorithm is
currently known.
So perhaps you will need another approach.
If however your graph has certain properties which make the exponential number of Eulerian circuits impossible, do tell us these properties.
If you want to enumerate all Eulerian paths (and, like Gassa, I have my doubts), then the following simple output-sensitive algorithm has polynomial overhead, which, since n will be very small, should suffice. There's a recursive procedure for enumerating all paths from v that goes like this in Python.
def paths(v, neighbors, path): # call initially with path=[]
yield path[:] # return a copy of the mutable list
for w in list(neighbors[v]):
neighbors[v].remove(w) # remove the edge from the graph
path.append((v, w)) # add the edge to the path
yield from paths(w, neighbors, path) # recursively enumerate
# all path extensions from w
# in the residual graph
path.pop() # remove the edge from the path
neighbors[v].add(w) # add the edge to the graph
To return Eulerian paths only, we make two modifications. First, we prune the recursion if there is no Eulerian path extending the current path. Second, we do the first yield only when neighbors[v] is empty, i.e., the only extension is the trivial one, so path is Eulerian. Since the degree balance condition is satisfied, we prune by just checking strong connectivity of the non-isolated vertices at each recursive call, given that we add an arc from the starting vertex to v. This can be accomplished with two traversals, one to verify that every non-isolated vertex can reach the starting vertex and one to verify that every non-isolated vertex is reachable from v. (Alternatively, you could add the arc temporarily and do one traversal, but then you'd have to handle multigraphs, which you may not want to.)

How do I find the number of Hamiltonian cycles that do not use "forbidden" edges?

This question actually rephrases that one. The code jam problem is the following:
You are given a complete undirected graph with N nodes and K "forbidden" edges. N <= 300, K <= 15. Find the number of Hamiltonian cycles in the graph that do not use any of the K "forbidden" edges.
The straightforward DP approach of O(2^N*N^2) does not work for such N. It looks like that the winning solutions are O(2^K). Does anybody know how to solve this problem ?
Let's find out for each subset S of forbidden edges, how many Hamiltonian cycles there exist, that use all edges of S. If we solve this subtask then we'll solve the problem by inclusion-exclusion formula.
Now how do we solve the subtask? Let's draw all edges of S. If there exist a vertex of degree more than 2, then obviously we cannot complete the cycle and the answer is 0. Otherwise the graph is divided into connected components. Each component is a sole vertex, a cycle or a simple path.
If there exists a cycle, then it must pass through all vertices, otherwise we won't be able to complete the Hamiltonian cycle. If this is the case, the answer is 2. (The cycle can be traversed in 2 directions.) Otherwise the answer is 0.
The remaining case is when there are c paths and k sole vertices. To complete the Hamiltonian cycle we must choose the direction of each path (2^c ways) and then choose the order of components. We've got c+k components, so they can be rearranged in (c+k)! ways. But we are interested in cycles, so we don't distinguish the orderings which turn into one another by cyclic shifts. (So (1,2,3), (2,3,1) and (3,1,2) are the same.) It means that we must divide the answer by the number of shifts, c+k. So the answer (to the subtask) is 2^c (c+k-1)!.
This idea is implemented in bmerry's solution (very clean code, btw).
Hamiltonian cycle problem is a special case of travelling salesman problem (obtained by setting the distance between two cities to a finite constant if they are adjacent and infinity otherwise.)
These are NP Complete problems which in simple words means no fast solution to them is known.
A trivial heuristic algorithm for locating Hamiltonian paths is to construct a path abc... and extend it until no longer possible; when the path abc... xyz cannot be extended any longer because all neighbours of z already lie in the path, one goes back one step, removing the edge yz and extending the path with a different neighbour of y; if no choice produces a Hamiltonian path, then one takes a further step back, removing the edge xy and extending the path with a different neighbour of x, and so on. This algorithm will certainly find an Hamiltonian path (if any) but it runs in exponential time.
For more check NP Complete problem chapter of "Introduction to Algos" by Cormen

Resources