22 #ifndef CRNPathFinding_HEADER
23 #define CRNPathFinding_HEADER
62 typename StepCostFunc,
63 typename DistanceEstimationFunc,
64 typename NeighborFunc,
65 typename std::enable_if<!traits::HasLT<Node>::value,
int>::type = 0
67 std::vector<Node>
AStar(
const Node &first,
const Node &last,
const StepCostFunc &stepcost,
const DistanceEstimationFunc &heuristic,
const NeighborFunc &get_neighbors)
69 using NodePtr = std::shared_ptr<AStarNode<Node>>;
70 std::vector<NodePtr> openset;
71 std::vector<NodePtr> closeset;
75 n->distToEnd = heuristic(n->node, last);
76 n->totalCost = n->distToEnd;
77 openset.push_back(std::move(n));
78 while (!openset.empty())
81 auto minit = std::min_element(openset.begin(), openset.end(), [](
const NodePtr &n1,
const NodePtr &n2){
return n1->cumulCost < n2->cumulCost; });
82 NodePtr currentnode = *minit;
84 std::swap(*minit, openset.back()); openset.pop_back();
85 closeset.push_back(currentnode);
86 if (currentnode->node == last)
88 std::vector<Node> path;
92 path.push_back(currentnode->node);
93 currentnode = currentnode->parent.lock();
95 return std::vector<Node>(path.rbegin(), path.rend());
100 const std::vector<Node> neighbors(get_neighbors(currentnode->node));
101 for (
const Node &neigh : neighbors)
105 const double newcost = currentnode->cumulCost + stepcost(currentnode->node, neigh);
107 auto openit = std::find_if(openset.begin(), openset.end(), [&neigh](
const NodePtr &n){
return n->node == neigh; });
108 if (openit != openset.end())
110 if ((*openit)->cumulCost <= newcost)
116 std::swap(*openit, openset.back()); openset.pop_back();
122 auto closeit = std::find_if(closeset.begin(), closeset.end(), [&neigh](
const NodePtr &n){
return n->node == neigh; });
123 if (closeit != closeset.end())
125 if ((*closeit)->cumulCost <= newcost)
130 closeset.erase(closeit);
135 nn->cumulCost = newcost;
136 nn->distToEnd = heuristic(nn->node, last);
137 nn->totalCost = newcost + nn->distToEnd;
138 nn->parent = currentnode;
139 openset.push_back(std::move(nn));
158 bool operator()(
const std::shared_ptr<AStarNodeC> &n1,
const std::shared_ptr<AStarNodeC> &n2)
const {
return n1->node < n2->node; }
180 typename StepCostFunc,
181 typename DistanceEstimationFunc,
182 typename NeighborFunc,
183 typename std::enable_if<traits::HasLT<Node>::value,
int>::type = 0
185 std::vector<Node>
AStar(
const Node &first,
const Node &last,
const StepCostFunc &stepcost,
const DistanceEstimationFunc &heuristic,
const NeighborFunc &get_neighbors)
187 using NodePtr = std::shared_ptr<AStarNodeC<Node>>;
188 const auto comparer =
typename AStarNodeC<Node>::CMP{};
189 auto openset = std::set<NodePtr, typename AStarNodeC<Node>::CMP>(comparer);
190 auto closeset = std::set<NodePtr, typename AStarNodeC<Node>::CMP>(comparer);
192 auto n = std::make_shared<AStarNodeC<Node>>();
194 n->distToEnd = heuristic(n->node, last);
195 n->totalCost = n->distToEnd;
196 openset.insert(std::move(n));
197 while (!openset.empty())
200 auto minit = std::min_element(openset.begin(), openset.end(), [](
const NodePtr &n1,
const NodePtr &n2){
return n1->cumulCost < n2->cumulCost; });
201 auto currentnode = *minit;
202 openset.erase(minit);
203 closeset.insert(currentnode);
204 if (currentnode->node == last)
206 auto path = std::vector<Node>{};
210 path.push_back(currentnode->node);
211 currentnode = currentnode->parent.lock();
213 return std::vector<Node>(path.rbegin(), path.rend());
218 auto neighbors = get_neighbors(currentnode->node);
219 for (
auto &&neigh : neighbors)
221 auto nn = std::make_shared<AStarNodeC<Node>>();
222 nn->node = std::move(neigh);
223 const double newcost = currentnode->cumulCost + stepcost(currentnode->node, nn->node);
225 auto openit = openset.find(nn);
226 if (openit != openset.end())
228 if ((*openit)->cumulCost <= newcost)
233 openset.erase(openit);
239 auto closeit = closeset.find(nn);
240 if (closeit != closeset.end())
242 if ((*closeit)->cumulCost <= newcost)
247 closeset.erase(closeit);
252 nn->cumulCost = newcost;
253 nn->distToEnd = heuristic(nn->node, last);
254 nn->totalCost = newcost + nn->distToEnd;
255 nn->parent = currentnode;
256 openset.insert(std::move(nn));
260 throw ExceptionNotFound{
"AStar(): No path found."};
std::vector< Node > AStar(const Node &first, const Node &last, const StepCostFunc &stepcost, const DistanceEstimationFunc &heuristic, const NeighborFunc &get_neighbors)
A* path finding.
std::weak_ptr< AStarNode > parent
bool operator()(const std::shared_ptr< AStarNodeC > &n1, const std::shared_ptr< AStarNodeC > &n2) const
std::weak_ptr< AStarNodeC< Node > > parent
An item was not found in a container.