fixed some error in A*, deleted struct PriorityNode

This commit is contained in:
Lendemor 2016-03-06 11:48:54 +01:00
parent 69df304725
commit f593f7018c
5 changed files with 42 additions and 24 deletions

View File

@ -31,10 +31,11 @@ int main(){
GraphNode n4 = GraphNode(); GraphNode n4 = GraphNode();
n4.setValue(4); n4.setValue(4);
n1.addNeighbours(&n2,2); n1.addNeighbours(&n2,7);
n1.addNeighbours(&n3,3); n1.addNeighbours(&n3,3);
n2.addNeighbours(&n3,5); n2.addNeighbours(&n4,2);
n3.addNeighbours(&n4,2); n3.addNeighbours(&n4,20);
n3.addNeighbours(&n2,2);
std::vector<GraphNode*> path = PathFinder::a_star(&n1,&n4); std::vector<GraphNode*> path = PathFinder::a_star(&n1,&n4);
std::cout << "Path Size: " << path.size() << std::endl; std::cout << "Path Size: " << path.size() << std::endl;

View File

@ -48,6 +48,15 @@ int GraphNode::getValue(){
return m_testvalue; return m_testvalue;
} }
void GraphNode::setPriority(float a){
m_priority = a;
}
float GraphNode::getPriority(){
return m_priority;
}
GraphEdge::GraphEdge(GraphNode* gn,float v):m_target(gn),m_weight(v) GraphEdge::GraphEdge(GraphNode* gn,float v):m_target(gn),m_weight(v)

View File

@ -10,6 +10,8 @@ class GraphNode
{ {
std::vector<GraphEdge> m_neighbours; std::vector<GraphEdge> m_neighbours;
int m_testvalue; //temp variable int m_testvalue; //temp variable
float m_priority;
public: public:
GraphNode(); GraphNode();
GraphNode(std::vector<GraphEdge>); GraphNode(std::vector<GraphEdge>);
@ -18,10 +20,15 @@ public:
void addNeighbours(GraphNode*,float); void addNeighbours(GraphNode*,float);
void addNeighbours(GraphEdge); void addNeighbours(GraphEdge);
int getNbNeighbours(); int getNbNeighbours();
virtual float heuristic(GraphNode*){return 1;}; virtual float heuristic(GraphNode*){
std::cout << "WARNING : You're using the default heuristic. For better result, redefine the heuristic function in GraphNode." << std::endl;
return 1;
};
void setValue(int); void setValue(int);
int getValue(); int getValue();
void setPriority(float);
float getPriority();
void print(std::string prefix); void print(std::string prefix);
}; };

View File

@ -8,27 +8,26 @@
PathFinder::PathFinder(){ PathFinder::PathFinder(){
} }
std::vector<GraphNode*> PathFinder::a_star(GraphNode* start,GraphNode* goal) std::vector<GraphNode*> PathFinder::a_star(GraphNode* start,GraphNode* goal,bool debug)
{ {
// Check if priorityqueue sort value in right order. // Check if priorityqueue sort value in right order.
std::priority_queue<PriorityNode*> frontier = std::priority_queue<PriorityNode*>(); std::priority_queue<GraphNode*,std::vector<GraphNode*>,ComparePriority> frontier = std::priority_queue<GraphNode*,std::vector<GraphNode*>,ComparePriority>();
std::map<GraphNode*, float> cost = std::map<GraphNode*, float>(); //cost of visited node std::map<GraphNode*, float> cost = std::map<GraphNode*, float>(); //cost of visited node
std::map<GraphNode*, GraphNode*> pred = std::map<GraphNode*, GraphNode*>(); //pred of visited node std::map<GraphNode*, GraphNode*> pred = std::map<GraphNode*, GraphNode*>(); //pred of visited node
// init frontier, cost, and pred with value for start // init frontier, cost, and pred with value for start
PriorityNode* pn = new PriorityNode(); frontier.push(start);
pn->node = std::pair<GraphNode*,float>(start,0);
frontier.push(pn);
cost.insert(std::pair<GraphNode*,float>(start,0)); cost.insert(std::pair<GraphNode*,float>(start,0));
pred.insert(std::pair<GraphNode*,GraphNode*>(start,NULL)); pred.insert(std::pair<GraphNode*,GraphNode*>(start,NULL));
GraphNode* current; GraphNode* current;
while(!frontier.empty()){ while(!frontier.empty()){
//pick best element from frontier (with priority queue the best is in front) //pick best element from frontier (with priority queue the best is in front)
pn = frontier.top(); current = frontier.top();
current = pn->node.first; //current = pn->node.first;
frontier.pop(); frontier.pop();
if(debug) std::cout << "Exploring node " << current->getValue() << std::endl;
// goal reached, end of a-star // goal reached, end of a-star
if (current == goal){ if (current == goal){
break; break;
@ -37,16 +36,19 @@ std::vector<GraphNode*> PathFinder::a_star(GraphNode* start,GraphNode* goal)
// for all neighbours of current node // for all neighbours of current node
for (GraphEdge next : current->getNeighbours()){ for (GraphEdge next : current->getNeighbours()){
float new_cost = cost[current] + next.getWeight(); float new_cost = cost[current] + next.getWeight();
if(debug) std::cout << "\tExploring neighbours node " << next.getTarget()->getValue() << " with cost " << new_cost << std::endl;
if ((cost.count(next.getTarget()) == 0) || (new_cost < cost[next.getTarget()])){ bool never_visited = cost.count(next.getTarget()) == 0;
if ((never_visited) || (new_cost < cost[next.getTarget()])){
// affect processed cost to next node in cost_map // affect processed cost to next node in cost_map
cost[next.getTarget()] = new_cost; cost[next.getTarget()] = new_cost;
// calcul priority of node with heuristic,and add it to frontier // calcul priority of node with heuristic,and add it to frontier
float priority = new_cost; //+ heuristic(next.getTarget(), goal); float priority = new_cost + next.getTarget()->heuristic(goal);
PriorityNode* pn = new PriorityNode(); if(debug) std::cout << "\t\t Priority: " << priority << std::endl;
pn->node = std::pair<GraphNode*,float>(next.getTarget(),priority); next.getTarget()->setPriority(priority);
frontier.push(pn); if(never_visited)
frontier.push(next.getTarget());
// memorize predecessor for next // memorize predecessor for next
pred[next.getTarget()] = current; pred[next.getTarget()] = current;
@ -62,6 +64,7 @@ std::vector<GraphNode*> PathFinder::a_star(GraphNode* start,GraphNode* goal)
} }
path.push_back(start); path.push_back(start);
std::reverse(path.begin(),path.end()); std::reverse(path.begin(),path.end());
if(debug) std::cout << "path cost :" << cost[goal] << std::endl;
return path; return path;
} }

View File

@ -8,16 +8,14 @@ class PathFinder
{ {
public: public:
PathFinder(); PathFinder();
static std::vector<GraphNode*> a_star(GraphNode* start,GraphNode* goal); static std::vector<GraphNode*> a_star(GraphNode* start,GraphNode* goal,bool debug = false);
}; };
struct PriorityNode class ComparePriority{
public:
bool operator() (GraphNode* a,GraphNode* b)
{ {
std::pair<GraphNode*, float> node; return a->getPriority() > b->getPriority();
bool operator<(PriorityNode other) const
{
return node.second < other.node.second;
} }
}; };
#endif // PATHFINDER_H #endif // PATHFINDER_H