Reputation: 925
Consider a directed graph with n
nodes and m
edges. Each edge is weighted. There is a start node s
and an end node e
. We want to find the path from s
to e
that has the maximum number of nodes such that:
- the total distance is less than some constant
d
- starting from s, each node in the path is closer than the previous one to the node
e
. (as in, when you traverse the path you are getting closer to your destinatione
. in terms of the edge weight of the remaining path.)
We can assume there are no cycles in the graph. There are no negative weights. Does an efficient algorithm already exist for this problem? Is there a name for this problem?
Upvotes: 4
Views: 967
Reputation: 3909
Whatever you end up doing, do a BFS/DFS starting from s
first to see if e
can even be reached; this only takes you O(n+m) so it won't add to the complexity of the problem (since you need to look at all vertices and edges anyway). Also, delete all edges with weight 0
before you do anything else since those never fulfill your second criterion.
EDIT: I figured out an algorithm; it's polynomial, depending on the size of your graphs it may still not be sufficiently efficient though. See the edit further down.
Now for some complexity. The first thing to think about here is an upper bound on how many paths we can actually have, so depending on the choice of d
and the weights of the edges, we also have an upper bound on the complexity of any potential algorithm.
How many edges can there be in a DAG? The answer is n(n-1)/2
, which is a tight bound: take n
vertices, order them from 1 to n
; for two vertices i
and j
, add an edge i->j
to the graph iff i<j
. This sums to a total of n(n-1)/2
, since this way, for every pair of vertices, there is exactly one directed edge between them, meaning we have as many edges in the graph as we would have in a complete undirected graph over n
vertices.
How many paths can there be from one vertex to another in the graph described above? The answer is 2n-2. Proof by induction:
Take the graph over 2 vertices as described above; there is 1 = 20 = 22-2 path from vertex 1 to vertex 2: (1->2).
Induction step: assuming there are 2n-2 paths from the vertex with number 1
of an n
vertex graph as described above to the vertex with number n
, increment the number of each vertex and add a new vertex 1
along with the required n
edges. It has its own edge to the vertex now labeled n+1
. Additionally, it has 2i-2 paths to that vertex for every i
in [2;n] (it has all the paths the other vertices have to the vertex n+1
collectively, each "prefixed" with the edge 1->i
). This gives us 1 + Σnk=2 (2k-2) = 1 + Σn-2k=0 (2k-2) = 1 + (2n-1 - 1) = 2n-1 = 2(n+1)-2.
So we see that there are DAGs that have 2n-2 distinct paths between some pairs of their vertices; this is a bit of a bleak outlook, since depending on weights and your choice of d
, you may have to consider them all. This in itself doesn't mean we can't choose some form of optimum (which is what you're looking for) efficiently though.
EDIT: Ok so here goes what I would do:
Now that gives you a space complexity of O(n^3) and a time complexity of O(n²m) - the arrays have O(n²) entries, we have to iterate over O(m) arrays, one array for each edge - but I think it's very obvious where the wasteful use of data structures here can be optimized using hashing structures and other things than arrays. Or you could just use a one-dimensional array and only store the current minimum instead of recomputing it every time (you'll have to encapsulate the sum of edge weights of the path together with the predecessor vertex though since you need to know the predecessor to reconstruct the path), which would change the size of the arrays from n² to n since you now only need one entry per number-of-nodes-on-path-to-vertex, bringing down the space complexity of the algorithm to O(n²) and the time complexity to O(nm). You can also try and do some form of topological sort that gets rid of the vertices from which you can't reach e
, because those can be safely ignored as well.
Upvotes: 3