17

In this earlier question the OP asked how to find a shortest path in a graph that goes from u to v and also passes through some node w. The accepted answer, which is quite good, was to run Dijkstra's algorithm twice - once to get from u to w and once to get from w to v. This has time complexity equal to two calls to Dijkstra's algorithm, which is O(m + n log n).

Now consider a related question - you are given a sequence of nodes u1, u2, ..., uk and want to find the shortest path from u1 to uk such that the path passes through u1, u2, ..., uk in order. Clearly this could be done by running k-1 instances of Dijkstra's algorithm, one for each pair of adjacent vertices, then concatenating the shortest paths together. This takes time O(km + k n log n). Alternatively, you could use an all-pairs shortest paths algorithm like Johnson's algorithm to compute all shortest paths, then concatenate the appropriate shortest paths together in O(mn + n2 log n) time, which is good for k much larger than n.

My question is whether there is an algorithm for solving this problem that is faster than the above approaches when k is small. Does such an algorithm exist? Or is iterated Dijkstra's as good as it gets?

Community
  • 1
  • 1
templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • This sounds like an instance of the Travelling Salesman Problem http://en.wikipedia.org/wiki/Travelling_salesman_problem – AndyG Sep 06 '11 at 03:55
  • 3
    @SauceMaster- This isn't quite TSP because we are allowed to revisit nodes and because the order of the nodes is specified. But thanks! – templatetypedef Sep 06 '11 at 03:58
  • @templatetypdef: Agreed. Similar but not the same. – AndyG Sep 06 '11 at 04:08
  • I am skeptical that such an algorithm exists. Perhaps try cstheory.stackexchange? – Rob Neuhaus Sep 06 '11 at 04:23
  • 2
    `k` can not be much larger than `n` – Saeed Amiri Sep 06 '11 at 05:21
  • k can be much larger. if k == n^2, then you have all pairs shortest paths. – Rob Neuhaus Sep 06 '11 at 05:49
  • @Saeed Amiri: you are biaised because most problems of this kind preclude passing twice by the same node. However in this case several of the U nodes could in fact be the very same one, in which case you simply have several loops. – Matthieu M. Sep 06 '11 at 06:15
  • @ Matthieu M,Yes May be I have problem with problem statement or usage. @rrenaud, if k can be greater than `n` there isn't any limit for it, it can be infinite. – Saeed Amiri Sep 06 '11 at 06:31
  • @templatetypedef, If I wanna go from `a` to `b` and `v` is internal node should be passed, Is it acceptable to go from `a` to `b` then from `b` to `v` then from `v` to `b`? I mean b is within shortest path from `a` to `v`. (And vice verse). – Saeed Amiri Sep 06 '11 at 06:35
  • I don't know, but, I found something interesting IMO (it is also useless, but whatever). If the shortest path from `ux` to `uy` contains any sub-path that begins on `uk` and ends at `uk+1` then you can save at least 1 call to dijkstra's. – harold Sep 06 '11 at 07:11
  • Such an algorithm will make a nice article, if exists/found... – amit Sep 06 '11 at 07:56
  • @Saeed Amiri- Hmmm... I hadn't thought of that. Let's assume that the graph has no negative cycles, so you can take any path you'd like even if it isn't a simple path. – templatetypedef Sep 06 '11 at 08:45
  • @templatetypedef, Also if there isn't negative cycle we can have such situation (assume undirected symmetric graph): `w(a,b) = 10, w(a,v) = 200, w(b,v) = 10`, so from `a` to `b` using `v` as internal node in sequence, best way is `a->b->v->b`, if this way is not acceptable your problem seems to be NP-Hard. – Saeed Amiri Sep 06 '11 at 09:29
  • @Saeed Amiri- I suspect that you're right. What reduction would you use to prove that this version of the problem is NP-hard? And it's fine for this problem to consider routes that backtrack and use nodes multiple times. – templatetypedef Sep 06 '11 at 09:31
  • @templatetypedef, I don't know exactly but may be steiner tree or shortest super string problem can be converted to this, should think about it, now i'm in work, when i'm free I'll think about it. Also I mean using first and last node in rout is possible or not (not intermediate nodes), if is so I think there isn't good usage for this problem. – Saeed Amiri Sep 06 '11 at 11:11
  • @templatetypedef did you even find an answer for you question. as i am trying the same. getting path between 2 nodes while passing through 2 other nodes? – Mo Adel Aug 22 '14 at 10:48

3 Answers3

4

Rather than running isolated instances of Dijkstra's algorithm to find the paths u(k) -> u(k+1) one path at a time, can a single instance of a modified Dijkstra-like search be started at each node in the sequence simultaneously, with the paths formed when search regions meet "in-the-middle".

This would potentially cut down on the total number of edges visited and reduce re-traversal of edges compared to making a series of isolated calls to Dijkstra's algorithm.

An easy example would be finding the path between two nodes. It would be better to expand the search regions about both nodes than just expanding about one. In the case of a uniform graph, the second option would give a search region with radius equal to the distance between the nodes, the first option would give two regions of half the radius - less overall search area.

Just a thought.

EDIT: I guess I'm talking about a multi-directional variant of a bi-directional search, with as many directions as there are nodes in the sequence {u(1), u(2), ..., u(m)}.

Darren Engwirda
  • 6,915
  • 4
  • 26
  • 42
  • 3
    bi directional search fails when it comes to weighted edges. consider the following: (1)-(2)-(3)-(4)-(5) every edge's weight is 1, and an extra edge (1)-(5), weighted 3. the shortest path from 1 to 5 is using (1)-(5), but bi-directional search will give you 4, since it will first find 1->2->3 and 3->4->5. – amit Sep 06 '11 at 07:05
1

I don't see how we can do too much better, here's all I can think of. Assuming the graph is undirected, the shortest path from any node u to node v would be the same as that from v to u (in reverse of course).

Now, for your case of a shortest path in the order u1 u2 u3.. un, we could run Djikstra's algorithm on u2 (and find the shortest paths u1-u2, u2-u3 in one run), then on u4 (for u3-u4 and u4-u5), then u6.. and so on. This reduces the number of times you apply Djikstra's by roughly a half. Note that complexity wise, this is identical to the original solution.

kyun
  • 640
  • 4
  • 10
  • Nice approach. any idea/thought how to apply it for directed graphs? – amit Sep 06 '11 at 17:13
  • @kyun, amit:I think you can generalise this approach. For undirected graphs you could keep a count of the number of times each node occurs in the set of (currently) un-traversed paths, and start Dijkstra's from the node with the highest count to find adjacent paths. This should account for cases where nodes appear in more than 2 paths. For directed graphs you could keep a count of the numbers of times each node appears as the *origin* of a path in the un-traversed set, and follow the same approach. – Darren Engwirda Sep 07 '11 at 01:27
0

You get the shortest path from one vertex to all the other in the graph by one call to Dijkstra's algorithm. Thus you only need to do a search for each unique starting vertex so repeated vertices does not make the problem any harder.

Daniel Andrén
  • 2,143
  • 2
  • 14
  • 10