'CSP Finding Path
I am able to implement the default uniform cost search (python) to find the shortest path between two nodes (path cost). I followed this pseudocode:
Solution 1:[1]
This is called the 'Constrained Shortest Path Problem' and has a pseudo-polynomial time solution using Dijkstra's algorithm. Instead of just having nodes, our new graph has (node, spent_fuel)
pairs, which increases the number of edges and vertices by a factor of the maximum fuel budget B
.
If your original algorithm for Dijkstra's ran in time O(|E| + |V| log |V|)
, where E
is your edge set (or actions, in this case) and V
is your vertex set, the new algorithm will run in time O(B|E| + B|V| log (B|V|))
. If your budget isn't much larger than the size of your graph, this is not so bad; otherwise you'll need more advanced methods of solving, since Constrained Shortest Paths is NP-Hard when the budget is unbounded.
Here, we still process the (node, fuel_cost)
pairs in monotonically-increasing order by distance, so the first time we explore the target, we have the minimum distance to reach it under budget.
Here's the pseudocode. There are some optimizations possible: you can filter out (node, fuel_cost, path_cost)
if we know of a path to this node with fuel <= fuel_cost
and a distance less than or equal to path_cost
. You can do this, for example, by building a binary-search-tree for each node, and only consider (node, fuel_cost)
if its path-cost is smaller than that of any (node, fuel_cost + c), c >= 0
.
function Constrained-Uniform-Cost-Search(problem)
start <- node with State = problem.initial-state, Path-Cost 0
// Elements of frontier are (node, fuel_cost) pairs, ordered by distance.
frontier <- priority queue, contains (start, 0)
explored <- empty set
while frontier is not empty:
(node, fuel_cost) <- pop(frontier)
if node == target: return Solution(node, fuel_cost)
add (node, fuel_cost) to explored
for action in problem.Actions(node):
(neighbor, neighbor_fuel) <- Child-Node(node, fuel_cost, action)
if neighbor_fuel > problem.Budget: continue
if (neighbor, neighbor_fuel) not in explored or frontier:
frontier <- insert((neighbor, neighbor_fuel), frontier)
else if (neighbor, neighbor_fuel) in frontier with higher Path-Cost:
replace that frontier node with (neighbor, neighbor_fuel)
return Failure
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |