简体   繁体   中英

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM