@@ -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,32 +83,38 @@ 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
101
115
if (cx == (int )x2 && cy==(int )y2) { // we reached (x2,y2)
102
116
// reconstruct path & return
117
+ as->num_nodes = 2 ;
103
118
uint32_t tmp = x2*ncol+y2;
104
119
while ((tmp=came_from[tmp]) != x1*ncol+y1) {
105
120
as->num_nodes ++;
@@ -109,15 +124,20 @@ namespace alg {
109
124
110
125
tmp = x2*ncol+y2;
111
126
int idx=0 ;
127
+ as->path [idx++] = x2;
128
+ as->path [idx++] = y2;
112
129
while ((tmp=came_from[tmp]) != x1*ncol+y1) {
113
130
as->path [idx++] = tmp/ncol;
114
131
as->path [idx++] = tmp%ncol;
115
132
}
133
+ as->path [idx++] = x1;
134
+ as->path [idx++] = y1;
116
135
return as;
117
136
}
118
137
119
- openset.delete_min ();
120
- m_closedset (cy, cx) = true ;
138
+ m_openset.delete_min ();
139
+ m_closedset (cx, cy) = true ;
140
+ m_openset_grid (cx, cy) = false ;
121
141
122
142
// for each neighbor
123
143
int nx, ny;
@@ -127,26 +147,27 @@ namespace alg {
127
147
if (ny<0 || ny>=(int )nrow) continue ;
128
148
129
149
// except the wall;
130
- if (m_grid (ny,nx ) == WALL) continue ;
150
+ if (m_grid (nx,ny ) == WALL) continue ;
131
151
// except the cur itself
132
152
if (nx == cx && ny==cy) continue ;
133
153
// if neighbour in the closed set
134
- if (m_closedset (ny,nx )) continue ;
154
+ if (m_closedset (nx,ny )) continue ;
135
155
136
- float tentative = g_score (cy,cx );
156
+ float tentative = g_score (cx,cy );
137
157
if (nx == cx || ny == cy) {
138
- tentative += 1 + m_grid (ny,nx );
158
+ tentative += 1 + m_grid (nx,ny );
139
159
} else {
140
- tentative += (1 + m_grid (ny,nx )) * SQRT2;
160
+ tentative += (1 + m_grid (nx,ny )) * SQRT2;
141
161
}
142
162
143
163
// if neighbour not in the openset or dist < g_score[neighbour]
144
- if (!openset. contains (nx*ncol+ ny) || tentative < g_score (ny,nx )) {
164
+ if (!m_openset_grid (nx, ny) || tentative < g_score (nx,ny )) {
145
165
came_from[nx*ncol+ny] = cx*ncol+cy; // record path
146
- g_score (ny,nx) = tentative;
147
- f_score (ny,nx) = tentative + estimate (nx,ny,x2,y2);
148
- if (!openset.contains (nx*ncol+ny)) {
149
- 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 ;
150
171
}
151
172
}
152
173
}
0 commit comments