Support edge visit callbacks in util::pathfinder
This commit is contained in:
parent
012591da85
commit
dc232b8fba
1 changed files with 21 additions and 3 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/util/functional.hpp>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
@ -8,7 +10,7 @@
|
||||||
namespace psemek::util
|
namespace psemek::util
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename Cost, typename Node, typename NeighboursFn, typename HeuristicFn>
|
template <typename Cost, typename Node, typename NeighboursFn, typename HeuristicFn, typename EdgeCallback>
|
||||||
struct pathfinder
|
struct pathfinder
|
||||||
{
|
{
|
||||||
struct node_compare
|
struct node_compare
|
||||||
|
|
@ -30,15 +32,17 @@ namespace psemek::util
|
||||||
|
|
||||||
NeighboursFn node_neighbours;
|
NeighboursFn node_neighbours;
|
||||||
HeuristicFn heuristic;
|
HeuristicFn heuristic;
|
||||||
|
EdgeCallback edge_callback;
|
||||||
|
|
||||||
std::unordered_map<Node, Cost> cost;
|
std::unordered_map<Node, Cost> cost;
|
||||||
std::unordered_map<Node, Cost> priority;
|
std::unordered_map<Node, Cost> priority;
|
||||||
std::unordered_map<Node, Node> previous;
|
std::unordered_map<Node, Node> previous;
|
||||||
std::set<Node, node_compare> queue;
|
std::set<Node, node_compare> queue;
|
||||||
|
|
||||||
pathfinder(NeighboursFn && node_neighbours, HeuristicFn && heuristic)
|
pathfinder(NeighboursFn && node_neighbours, HeuristicFn && heuristic, EdgeCallback && edge_callback)
|
||||||
: node_neighbours(std::forward<NeighboursFn>(node_neighbours))
|
: node_neighbours(std::forward<NeighboursFn>(node_neighbours))
|
||||||
, heuristic(std::forward<HeuristicFn>(heuristic))
|
, heuristic(std::forward<HeuristicFn>(heuristic))
|
||||||
|
, edge_callback(std::forward<EdgeCallback>(edge_callback))
|
||||||
, queue(node_compare{priority})
|
, queue(node_compare{priority})
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -72,6 +76,8 @@ namespace psemek::util
|
||||||
node_neighbours(node, [&](Node const & neighbour, Cost const & edge_cost){
|
node_neighbours(node, [&](Node const & neighbour, Cost const & edge_cost){
|
||||||
Cost const new_cost = node_cost + edge_cost;
|
Cost const new_cost = node_cost + edge_cost;
|
||||||
|
|
||||||
|
edge_callback(node, node_cost, neighbour, edge_cost);
|
||||||
|
|
||||||
auto it = cost.find(neighbour);
|
auto it = cost.find(neighbour);
|
||||||
|
|
||||||
if (it == cost.end() || new_cost < it->second)
|
if (it == cost.end() || new_cost < it->second)
|
||||||
|
|
@ -117,10 +123,22 @@ namespace psemek::util
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Cost, typename Node, typename NeighboursFn, typename HeuristicFn, typename EdgeCallback>
|
||||||
|
auto make_pathfinder(NeighboursFn && node_neighbours, HeuristicFn && heuristic, EdgeCallback && edge_callback)
|
||||||
|
{
|
||||||
|
return pathfinder<Cost, Node, NeighboursFn, HeuristicFn, EdgeCallback>(std::forward<NeighboursFn>(node_neighbours), std::forward<HeuristicFn>(heuristic), std::forward<EdgeCallback>(edge_callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Cost, typename Node, typename NeighboursFn, typename HeuristicFn>
|
||||||
|
auto make_pathfinder(NeighboursFn && node_neighbours, HeuristicFn && heuristic)
|
||||||
|
{
|
||||||
|
return pathfinder<Cost, Node, NeighboursFn, HeuristicFn, decltype(util::nop)>(std::forward<NeighboursFn>(node_neighbours), std::forward<HeuristicFn>(heuristic), util::nop);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Cost, typename Node, typename NeighboursFn, typename HeuristicFn>
|
template <typename Cost, typename Node, typename NeighboursFn, typename HeuristicFn>
|
||||||
std::optional<std::deque<Node>> find_path(Node const & start, Node const & end, NeighboursFn && node_neighbours, HeuristicFn && heuristic)
|
std::optional<std::deque<Node>> find_path(Node const & start, Node const & end, NeighboursFn && node_neighbours, HeuristicFn && heuristic)
|
||||||
{
|
{
|
||||||
pathfinder<Cost, Node, NeighboursFn, HeuristicFn> helper(std::forward<NeighboursFn>(node_neighbours), std::forward<HeuristicFn>(heuristic));
|
auto helper = make_pathfinder<Cost, Node>(std::forward<NeighboursFn>(node_neighbours), std::forward<HeuristicFn>(heuristic));
|
||||||
|
|
||||||
helper.init(start);
|
helper.init(start);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue