From aaab95a8c7bd71b5ee0262a91ad215906ad3ced1 Mon Sep 17 00:00:00 2001 From: Lendemor Date: Sun, 27 Mar 2016 18:09:15 +0200 Subject: [PATCH] added minmax a_star --- src/main.cpp | 2 ++ src/tools/pathfinder.cpp | 67 +++++++++++++++++++++++++++++++++++++--- src/tools/pathfinder.h | 5 +++ 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bd55e57..4ea0a4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -50,4 +50,6 @@ int main(){ Loader::setTexDirectory("../data/"); std::vector meshes = Loader::loadMesh("sword.obj"); + RenderingWidget; + } diff --git a/src/tools/pathfinder.cpp b/src/tools/pathfinder.cpp index d5f6c91..29277f7 100644 --- a/src/tools/pathfinder.cpp +++ b/src/tools/pathfinder.cpp @@ -62,22 +62,79 @@ std::vector PathFinder::a_star(GraphNode* start, GraphNode* goal, bo } } + if(debug) std::cout << "path cost :" << cost[goal] << std::endl; + return backtrack_path(start,goal,pred); +} + +std::vector PathFinder::a_star_min_max(GraphNode* start,GraphNode* goal,bool debug = false) +{ + 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 = std::max(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; + } + } + } + + if(debug) std::cout << "path cost :" << cost[goal] << std::endl; + return backtrack_path(start,goal,pred); +} + +std::vector PathFinder::backtrack_path(GraphNode* start,GraphNode* goal, std::map pred){ // reconstruct path by backtracking from goal to start std::vector path = std::vector(); + GraphNode* current = goal; 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(); + return a->getPriority() > b->getPriority(); } - - diff --git a/src/tools/pathfinder.h b/src/tools/pathfinder.h index faeaf94..6dd674b 100644 --- a/src/tools/pathfinder.h +++ b/src/tools/pathfinder.h @@ -6,9 +6,14 @@ class PathFinder { +private: + static std::vector backtrack_path(GraphNode* start,GraphNode* goal, std::map pred); + public: PathFinder(); static std::vector a_star(GraphNode* start,GraphNode* goal,bool debug = false); + static std::vector a_star_min_max(GraphNode* start,GraphNode* goal,bool debug = false); + }; class ComparePriority{