#include "pathfinder.h" #include #include #include #include //#include "fiboheap.h" PathFinder::PathFinder(){ } std::vector PathFinder::a_star(GraphNode* start, GraphNode* goal, bool debug) { // Check if priorityqueue sort value in right order. std::priority_queue,ComparePriority> frontier = std::priority_queue,ComparePriority>(); std::map cost = std::map(); //cost of visited node std::map pred = std::map(); //pred of visited node std::set visited = std::set(); // init frontier, cost, and pred with value for start frontier.push(start); cost.insert(std::pair(start,0)); pred.insert(std::pair(start,NULL)); GraphNode* current; while(!frontier.empty()){ //pick best element from frontier (with priority queue the best is in front) current = frontier.top(); //current = pn->node.first; frontier.pop(); if (visited.count(current) == 0) visited.insert(current); else continue; if(debug) std::cout << "Exploring node " << current->getValue() << std::endl; // goal reached, end of a-star if (current == goal){ break; } // for all neighbours of current node for (GraphNode* next : current->getNeighbours()){ float new_cost = cost[current] + current->cost(next); if(debug) std::cout << "\tExploring neighbours node " << next->getValue() << " with cost " << new_cost << std::endl; if ((cost.count(next) == 0) || (new_cost < cost[next])){ // affect processed cost to next node in cost_map cost[next] = new_cost; // calcul priority of node with heuristic,and add it to frontier float priority = new_cost + next->heuristic(goal); if(debug) std::cout << "\t\t Priority: " << priority << std::endl; next->setPriority(priority); visited.erase(next); frontier.push(next); // memorize predecessor for next pred[next] = current; } } } // reconstruct path by backtracking from goal to start std::vector path = std::vector(); while(current != start){ path.push_back(current); current = pred[current]; } path.push_back(start); std::reverse(path.begin(),path.end()); if(debug) std::cout << "path cost :" << cost[goal] << std::endl; return path; } bool ComparePriority::operator ()(GraphNode* a, GraphNode* b) { return a->getPriority() > b->getPriority(); }