How to find ALL Eulerian paths in directed graph - algorithm

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.)

Related

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.

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

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.

what whould be suitable algorithm?

I am trying to do c++ program.I am trying to do problem in which i have numbers of points. Now i need to find the path that goes through all the points. This is not actually TSP because as per my knowledge in TSP it is possible to travel from all points to every other points. But in my case the path network between the points is fixed and i just need to find the suitable path that goes through all the points provided that all points may not have connection to every other point..so what algorithm am i supposed to follow.
It seems you are looking for a way to traverse a graph? If so have you tried Breadth first search http://en.wikipedia.org/wiki/Breadth-first_search or Depth first search http://en.wikipedia.org/wiki/Depth-first_search to traverse your graph.
You want to find a Hamiltonian path for a graph.
In the mathematical field of graph theory, a Hamiltonian path (or
traceable path) is a path in an undirected graph that visits each
vertex exactly once. A Hamiltonian cycle (or Hamiltonian circuit) is a
Hamiltonian path that is a cycle. Determining whether such paths and
cycles exist in graphs is the Hamiltonian path problem, which is
NP-complete.
Some techniques that exist :
There are n! different sequences of vertices that might be Hamiltonian
paths in a given n-vertex graph (and are, in a complete graph), so a
brute force search algorithm that tests all possible sequences would
be very slow. There are several faster approaches. A search procedure
by Frank Rubin divides the edges of the graph into three classes:
those that must be in the path, those that cannot be in the path, and
undecided. As the search proceeds, a set of decision rules classifies
the undecided edges, and determines whether to halt or continue the
search. The algorithm divides the graph into components that can be
solved separately. Also, a dynamic programming algorithm of Bellman,
Held, and Karp can be used to solve the problem in time O(n2 2n). In
this method, one determines, for each set S of vertices and each
vertex v in S, whether there is a path that covers exactly the
vertices in S and ends at v. For each choice of S and v, a path exists
for (S,v) if and only if v has a neighbor w such that a path exists
for (S − v,w), which can be looked up from already-computed
information in the dynamic program.
Andreas Björklund provided an alternative approach using the
inclusion–exclusion principle to reduce the problem of counting the
number of Hamiltonian cycles to a simpler counting problem, of
counting cycle covers, which can be solved by computing certain matrix
determinants. Using this method, he showed how to solve the
Hamiltonian cycle problem in arbitrary n-vertex graphs by a Monte
Carlo algorithm in time O(1.657n); for bipartite graphs this algorithm
can be further improved to time O(1.414n).
For graphs of maximum degree three, a careful backtracking search can
find a Hamiltonian cycle (if one exists) in time O(1.251n).

Find the shortest path in a graph which visits certain nodes

I have a undirected graph with about 100 nodes and about 200 edges. One node is labelled 'start', one is 'end', and there's about a dozen labelled 'mustpass'.
I need to find the shortest path through this graph that starts at 'start', ends at 'end', and passes through all of the 'mustpass' nodes (in any order).
( http://3e.org/local/maize-graph.png / http://3e.org/local/maize-graph.dot.txt is the graph in question - it represents a corn maze in Lancaster, PA)
Everyone else comparing this to the Travelling Salesman Problem probably hasn't read your question carefully. In TSP, the objective is to find the shortest cycle that visits all the vertices (a Hamiltonian cycle) -- it corresponds to having every node labelled 'mustpass'.
In your case, given that you have only about a dozen labelled 'mustpass', and given that 12! is rather small (479001600), you can simply try all permutations of only the 'mustpass' nodes, and look at the shortest path from 'start' to 'end' that visits the 'mustpass' nodes in that order -- it will simply be the concatenation of the shortest paths between every two consecutive nodes in that list.
In other words, first find the shortest distance between each pair of vertices (you can use Dijkstra's algorithm or others, but with those small numbers (100 nodes), even the simplest-to-code Floyd-Warshall algorithm will run in time). Then, once you have this in a table, try all permutations of your 'mustpass' nodes, and the rest.
Something like this:
//Precomputation: Find all pairs shortest paths, e.g. using Floyd-Warshall
n = number of nodes
for i=1 to n: for j=1 to n: d[i][j]=INF
for k=1 to n:
for i=1 to n:
for j=1 to n:
d[i][j] = min(d[i][j], d[i][k] + d[k][j])
//That *really* gives the shortest distance between every pair of nodes! :-)
//Now try all permutations
shortest = INF
for each permutation a[1],a[2],...a[k] of the 'mustpass' nodes:
shortest = min(shortest, d['start'][a[1]]+d[a[1]][a[2]]+...+d[a[k]]['end'])
print shortest
(Of course that's not real code, and if you want the actual path you'll have to keep track of which permutation gives the shortest distance, and also what the all-pairs shortest paths are, but you get the idea.)
It will run in at most a few seconds on any reasonable language :)
[If you have n nodes and k 'mustpass' nodes, its running time is O(n3) for the Floyd-Warshall part, and O(k!n) for the all permutations part, and 100^3+(12!)(100) is practically peanuts unless you have some really restrictive constraints.]
run Djikstra's Algorithm to find the shortest paths between all of the critical nodes (start, end, and must-pass), then a depth-first traversal should tell you the shortest path through the resulting subgraph that touches all of the nodes start ... mustpasses ... end
This is two problems... Steven Lowe pointed this out, but didn't give enough respect to the second half of the problem.
You should first discover the shortest paths between all of your critical nodes (start, end, mustpass). Once these paths are discovered, you can construct a simplified graph, where each edge in the new graph is a path from one critical node to another in the original graph. There are many pathfinding algorithms that you can use to find the shortest path here.
Once you have this new graph, though, you have exactly the Traveling Salesperson problem (well, almost... No need to return to your starting point). Any of the posts concerning this, mentioned above, will apply.
Actually, the problem you posted is similar to the traveling salesman, but I think closer to a simple pathfinding problem. Rather than needing to visit each and every node, you simply need to visit a particular set of nodes in the shortest time (distance) possible.
The reason for this is that, unlike the traveling salesman problem, a corn maze will not allow you to travel directly from any one point to any other point on the map without needing to pass through other nodes to get there.
I would actually recommend A* pathfinding as a technique to consider. You set this up by deciding which nodes have access to which other nodes directly, and what the "cost" of each hop from a particular node is. In this case, it looks like each "hop" could be of equal cost, since your nodes seem relatively closely spaced. A* can use this information to find the lowest cost path between any two points. Since you need to get from point A to point B and visit about 12 inbetween, even a brute force approach using pathfinding wouldn't hurt at all.
Just an alternative to consider. It does look remarkably like the traveling salesman problem, and those are good papers to read up on, but look closer and you'll see that its only overcomplicating things. ^_^ This coming from the mind of a video game programmer who's dealt with these kinds of things before.
This is not a TSP problem and not NP-hard because the original question does not require that must-pass nodes are visited only once. This makes the answer much, much simpler to just brute-force after compiling a list of shortest paths between all must-pass nodes via Dijkstra's algorithm. There may be a better way to go but a simple one would be to simply work a binary tree backwards. Imagine a list of nodes [start,a,b,c,end]. Sum the simple distances [start->a->b->c->end] this is your new target distance to beat. Now try [start->a->c->b->end] and if that's better set that as the target (and remember that it came from that pattern of nodes). Work backwards over the permutations:
[start->a->b->c->end]
[start->a->c->b->end]
[start->b->a->c->end]
[start->b->c->a->end]
[start->c->a->b->end]
[start->c->b->a->end]
One of those will be shortest.
(where are the 'visited multiple times' nodes, if any? They're just hidden in the shortest-path initialization step. The shortest path between a and b may contain c or even the end point. You don't need to care)
Andrew Top has the right idea:
1) Djikstra's Algorithm
2) Some TSP heuristic.
I recommend the Lin-Kernighan heuristic: it's one of the best known for any NP Complete problem. The only other thing to remember is that after you expanded out the graph again after step 2, you may have loops in your expanded path, so you should go around short-circuiting those (look at the degree of vertices along your path).
I'm actually not sure how good this solution will be relative to the optimum. There are probably some pathological cases to do with short circuiting. After all, this problem looks a LOT like Steiner Tree: http://en.wikipedia.org/wiki/Steiner_tree and you definitely can't approximate Steiner Tree by just contracting your graph and running Kruskal's for example.
Considering the amount of nodes and edges is relatively finite, you can probably calculate every possible path and take the shortest one.
Generally this known as the travelling salesman problem, and has a non-deterministic polynomial runtime, no matter what the algorithm you use.
http://en.wikipedia.org/wiki/Traveling_salesman_problem
The question talks about must-pass in ANY order. I have been trying to search for a solution about the defined order of must-pass nodes. I found my answer but since no question on StackOverflow had a similar question I'm posting here to let maximum people benefit from it.
If the order or must-pass is defined then you could run dijkstra's algorithm multiple times. For instance let's assume you have to start from s pass through k1, k2 and k3 (in respective order) and stop at e. Then what you could do is run dijkstra's algorithm between each consecutive pair of nodes. The cost and path would be given by:
dijkstras(s, k1) + dijkstras(k1, k2) + dijkstras(k2, k3) + dijkstras(k3, 3)
How about using brute force on the dozen 'must visit' nodes. You can cover all the possible combinations of 12 nodes easily enough, and this leaves you with an optimal circuit you can follow to cover them.
Now your problem is simplified to one of finding optimal routes from the start node to the circuit, which you then follow around until you've covered them, and then find the route from that to the end.
Final path is composed of :
start -> path to circuit* -> circuit of must visit nodes -> path to end* -> end
You find the paths I marked with * like this
Do an A* search from the start node to every point on the circuit
for each of these do an A* search from the next and previous node on the circuit to the end (because you can follow the circuit round in either direction)
What you end up with is a lot of search paths, and you can choose the one with the lowest cost.
There's lots of room for optimization by caching the searches, but I think this will generate good solutions.
It doesn't go anywhere near looking for an optimal solution though, because that could involve leaving the must visit circuit within the search.
One thing that is not mentioned anywhere, is whether it is ok for the same vertex to be visited more than once in the path. Most of the answers here assume that it's ok to visit the same edge multiple times, but my take given the question (a path should not visit the same vertex more than once!) is that it is not ok to visit the same vertex twice.
So a brute force approach would still apply, but you'd have to remove vertices already used when you attempt to calculate each subset of the path.

Longest Simple Path

So, I understand the problem of finding the longest simple path in a graph is NP-hard, since you could then easily solve the Hamiltonian circuit problem by setting edge weights to 1 and seeing if the length of the longest simple path equals the number of edges.
My question is: What kind of path would you get if you took a graph, found the maximum edge weight, m, replaced each edge weight w with m - w, and ran a standard shortest path algorithm on that? It's clearly not the longest simple path, since if it were, then NP = P, and I think the proof for something like that would be a bit more complicated =P.
If you could solve shortest path problems with negative weights you would find a longest path, the two are equivalent, this could be done by putting a weight of -w instead of w
The standard algorithm for negative weights is the Bellman-Ford algorithm. However the algorithm will not work if there is a cycle in the graph such that the sum of edges is negative. In the graph that you create, all such cycles have negative sum weights and so the algorithm won't work. Unless of course you have no cycles, in which case you have a tree (or a forest) and the problem is solvable via dynamic programming.
If we replace a weight of w by m-w, which guarantees that all weights will be positive, then the shortest path can be found via standard algorithms. If the shortest path P in this graph has k edges then the length is k*m-w(P) where w(P) is the length of the path with the original weights. This path is not necessarily the longest one, however, of all paths with k edges, P is the longest one.
alt text http://dl.getdropbox.com/u/317805/path2.jpg
The graph above is transformed to below using your algorithm.
The Longest path is the red line in the above graph.And depending on how ties are broken and algorithm you use, the shortest path in the transformed graph could be the blue line or the red line. So transforming graph edge weights using the constant that you mentioned yields no significant results. This is why you cannot find the longest path using the shortest path algorithms no matter how clever you are. A simpler transformation could be to negate all the edge weights and run the algorithm. I dont know if I have answered your question but as far as the path property goes the transformed graph doesnt have any useful information regarding the distance.
However this particular transformation is useful in other areas. For example you could force the algorithm to select a particular edge weight in bipatrite matching if you have more than one constraint by adding a huge constant.
Edit: I have been told to add this statement: The above graph is not just about the physical distance. They need not hold the triangle inequality. Thanks.

Resources