forked from JenJenChung/RAGS
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Queue.h
143 lines (128 loc) · 3.72 KB
/
Queue.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#ifndef QUEUE_H_
#define QUEUE_H_
#include <vector> // std::vector
#include <queue> // std::priority_queue
#include <boost/math/special_functions/erf.hpp> // erf_inv
#include "Node.h"
#include "Search.h"
using namespace boost::math ; // erf_inv
using std::vector ;
using std::priority_queue ;
typedef unsigned long int ULONG ;
#ifndef PTHRESH
#define PTHRESH 0.50
#endif
double pthresh = 0.5 ;
heuristic COMPARE = RAGSCOMPARE ;
class CompareNode{
double eConst ;
public:
CompareNode(){eConst = erf_inv(1.0-2.0*pthresh) ;}
~CompareNode(){}
bool operator() (const Node * n1, const Node * n2) const{
if (COMPARE == RAGSCOMPARE){
double n1Cost = n1->GetMeanCost() ;
double n2Cost = n2->GetMeanCost() ;
double thresh = n1Cost + sqrt(2.0)*sqrt(pow(n1->GetSigCost(),2) + pow(n2->GetSigCost(),2))*eConst ;
return (n2Cost < thresh) ;
}
else{
double n1Cost = n1->GetMeanCost()+n1->GetHeuristic() ;
double n2Cost = n2->GetMeanCost()+n2->GetHeuristic() ;
return (n2Cost < n1Cost) ;
}
}
} ;
// Custom queue type to perform priority queue updates
class Queue
{
public:
typedef priority_queue<Node *, vector<Node *>, CompareNode> QUEUE ;
Queue(Node * source, pathOut pType){
if (pType == ALL)
pthresh = PTHRESH ;
else
COMPARE = HEURISTIC ;
itsPQ = new QUEUE ;
eConst = erf_inv(1.0-2.0*pthresh) ;
itsPQ->push(source) ;
}
~Queue(){
while (!itsPQ->empty()){
Node * temp = itsPQ->top() ;
delete temp ;
temp = 0 ;
itsPQ->pop() ;
}
delete itsPQ ;
itsPQ = 0 ;
for (ULONG i = 0; i < closed.size(); i ++){
delete closed[i] ;
closed[i] = 0 ;
}
}
vector<Node *> GetClosed() const {return closed ;}
bool EmptyQueue() const {return itsPQ->empty() ;}
ULONG SizeQueue() const {return (ULONG)itsPQ->size() ;}
void UpdateQueue(Node * newNode) ;
Node * PopQueue() ;
private:
QUEUE * itsPQ ;
vector<Node *> closed ;
double eConst ;
bool CompareNodes(const Node * n1, const Node * n2) const ;
} ;
void Queue::UpdateQueue(Node * newNode)
{
// Compare newNode to nodes in closed set
// if closed contains node with same vertex, compare their costs
// choose whether or not to create a new node
bool dom = false ;
for (ULONG i = 0; i < closed.size(); i++){
if (closed[i]->GetVertex() == newNode->GetVertex()){
dom = CompareNodes(newNode, closed[i]) ;
if (dom){
delete newNode ;
newNode = 0 ;
return ;
}
}
}
itsPQ->push(newNode) ;
}
Node * Queue::PopQueue()
{
// Check if next node is already dominated by existing node in closed set
Node * newNode = itsPQ->top() ;
bool dom = false ;
for (ULONG i = 0; i < closed.size(); i++){
if (closed[i]->GetVertex() == newNode->GetVertex()){
dom = CompareNodes(newNode, closed[i]) ;
if (dom){
delete newNode ;
newNode = 0 ;
itsPQ->pop() ;
return 0 ;
}
}
}
closed.push_back(itsPQ->top()) ;
itsPQ->pop() ;
return closed[(ULONG)closed.size()-1] ;
}
bool Queue::CompareNodes(const Node * n1, const Node * n2) const
{
// out: Is n1 worse than or equal to n2? Does n2 dominate n1?
double n1Cost = n1->GetMeanCost() ;
double n2Cost = n2->GetMeanCost() ;
// return (n1Cost >= n2Cost && n1->GetSigCost() >= n2->GetSigCost()) ; // old domination metric
/* if (n1Cost > n2Cost && n1->GetSigCost() > n2->GetSigCost())
return true ;
else if (n2Cost > n1Cost && n2->GetSigCost() > n1->GetSigCost())
return false ;
else
return (n1Cost > n2Cost) ;*/
double thresh = n1Cost + sqrt(2.0)*sqrt(pow(n1->GetSigCost(),2) + pow(n2->GetSigCost(),2))*eConst ;
return (n2Cost < thresh) ; // does n2 dominate n1?
}
#endif //QUEUE_H_