@@ -52,6 +52,10 @@ namespace alg {
52
52
53
53
private:
54
54
const Array2D<unsigned char > & m_grid;
55
+ // the openset
56
+ Heap<uint32_t > m_openset;
57
+ // The set of nodes open -- for fast testing of a point in openset. heap contains test is quite slow -- O(n)
58
+ Array2D<bool > m_openset_grid;
55
59
// The set of nodes already evaluated.
56
60
Array2D<bool > m_closedset;
57
61
// Cost from start along best known path.
@@ -61,9 +65,14 @@ namespace alg {
61
65
public:
62
66
AStar (const Array2D<unsigned char > & grid) :
63
67
m_grid (grid),
68
+ m_openset (grid.row()*grid.col()),
69
+ m_openset_grid (grid.row(),grid.col()),
64
70
m_closedset (grid.row(),grid.col()),
65
71
g_score (grid.row(),grid.col()),
66
- f_score (grid.row(),grid.col()) { }
72
+ f_score (grid.row(),grid.col()) {
73
+ m_openset_grid.clear (false );
74
+ m_closedset.clear (false );
75
+ }
67
76
68
77
/* *
69
78
* the A* algorithm
@@ -74,27 +83,32 @@ namespace alg {
74
83
static float SQRT2 = 1.414213562373095 ;
75
84
uint32_t nrow = m_grid.row ();
76
85
uint32_t ncol = m_grid.col ();
77
- m_closedset.clear (false );
86
+
87
+ // test wheather the (x1, y1) is the wall, we don't do stupid searching.
88
+ // if (m_grid(x1, y1) == WALL) {
89
+ // return NULL;
90
+ // }
78
91
79
92
// the set of tentavie nodes to be evaluated,
80
93
// initialy containing the start node
81
94
// encoding [x,y] to [x*ncol + y]
82
95
// using binary heap ...
83
- Heap<uint32_t > openset (nrow*ncol);
84
- openset.insert (0 , x1*ncol+y1);
96
+ m_openset.insert (0 , x1*ncol+y1);
97
+ // record the starting point in openset_grid
98
+ m_openset_grid (x1,y1) = true ;
85
99
86
100
// The map of navigated nodes.
87
101
HashTable<uint32_t , uint32_t > came_from (nrow*ncol);
88
102
89
- g_score (y1,x1 ) = 0 .0f ;
90
- f_score (y1,x1 ) = g_score (y1,x1 ) + estimate (x1,y1,x2,y2);
103
+ g_score (x1,y1 ) = 0 .0f ;
104
+ f_score (x1,y1 ) = g_score (x1,y1 ) + estimate (x1,y1,x2,y2);
91
105
92
106
AStarResult * as = new AStarResult;
93
107
as->path = NULL ;
94
108
as->num_nodes = 0 ;
95
109
96
- while (!openset .is_empty ()) {
97
- uint32_t value = openset .min_value ();
110
+ while (!m_openset .is_empty ()) {
111
+ uint32_t value = m_openset .min_value ();
98
112
int cx = value/ncol;
99
113
int cy = value%ncol;
100
114
@@ -121,8 +135,9 @@ namespace alg {
121
135
return as;
122
136
}
123
137
124
- openset.delete_min ();
125
- m_closedset (cy, cx) = true ;
138
+ m_openset.delete_min ();
139
+ m_closedset (cx, cy) = true ;
140
+ m_openset_grid (cx, cy) = false ;
126
141
127
142
// for each neighbor
128
143
int nx, ny;
@@ -132,26 +147,27 @@ namespace alg {
132
147
if (ny<0 || ny>=(int )nrow) continue ;
133
148
134
149
// except the wall;
135
- if (m_grid (ny,nx ) == WALL) continue ;
150
+ if (m_grid (nx,ny ) == WALL) continue ;
136
151
// except the cur itself
137
152
if (nx == cx && ny==cy) continue ;
138
153
// if neighbour in the closed set
139
- if (m_closedset (ny,nx )) continue ;
154
+ if (m_closedset (nx,ny )) continue ;
140
155
141
- float tentative = g_score (cy,cx );
156
+ float tentative = g_score (cx,cy );
142
157
if (nx == cx || ny == cy) {
143
- tentative += 1 + m_grid (ny,nx );
158
+ tentative += 1 + m_grid (nx,ny );
144
159
} else {
145
- tentative += (1 + m_grid (ny,nx )) * SQRT2;
160
+ tentative += (1 + m_grid (nx,ny )) * SQRT2;
146
161
}
147
162
148
163
// if neighbour not in the openset or dist < g_score[neighbour]
149
- if (!openset. contains (nx*ncol+ ny) || tentative < g_score (ny,nx )) {
164
+ if (!m_openset_grid (nx, ny) || tentative < g_score (nx,ny )) {
150
165
came_from[nx*ncol+ny] = cx*ncol+cy; // record path
151
- g_score (ny,nx) = tentative;
152
- f_score (ny,nx) = tentative + estimate (nx,ny,x2,y2);
153
- if (!openset.contains (nx*ncol+ny)) {
154
- openset.insert (f_score (ny,nx), nx*ncol+ny);
166
+ g_score (nx,ny) = tentative;
167
+ f_score (nx,ny) = tentative + estimate (nx,ny,x2,y2);
168
+ if (!m_openset_grid (nx,ny)) {
169
+ m_openset.insert (f_score (nx,ny), nx*ncol+ny);
170
+ m_openset_grid (nx,ny) = true ;
155
171
}
156
172
}
157
173
}
0 commit comments