Skip to content

Commit 1b92df7

Browse files
committed
fix bugs in astar algorithm
1 parent f91fcfe commit 1b92df7

File tree

2 files changed

+37
-21
lines changed

2 files changed

+37
-21
lines changed

include/astar.h

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ namespace alg {
5252

5353
private:
5454
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;
5559
// The set of nodes already evaluated.
5660
Array2D<bool> m_closedset;
5761
// Cost from start along best known path.
@@ -61,9 +65,14 @@ namespace alg {
6165
public:
6266
AStar(const Array2D<unsigned char> & grid) :
6367
m_grid(grid),
68+
m_openset(grid.row()*grid.col()),
69+
m_openset_grid(grid.row(),grid.col()),
6470
m_closedset(grid.row(),grid.col()),
6571
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+
}
6776

6877
/**
6978
* the A* algorithm
@@ -74,27 +83,32 @@ namespace alg {
7483
static float SQRT2 = 1.414213562373095;
7584
uint32_t nrow = m_grid.row();
7685
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+
//}
7891

7992
// the set of tentavie nodes to be evaluated,
8093
// initialy containing the start node
8194
// encoding [x,y] to [x*ncol + y]
8295
// 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;
8599

86100
// The map of navigated nodes.
87101
HashTable<uint32_t, uint32_t> came_from(nrow*ncol);
88102

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);
91105

92106
AStarResult * as = new AStarResult;
93107
as->path = NULL;
94108
as->num_nodes = 0;
95109

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();
98112
int cx = value/ncol;
99113
int cy = value%ncol;
100114

@@ -121,8 +135,9 @@ namespace alg {
121135
return as;
122136
}
123137

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;
126141

127142
// for each neighbor
128143
int nx, ny;
@@ -132,26 +147,27 @@ namespace alg {
132147
if (ny<0 || ny>=(int)nrow) continue;
133148

134149
// except the wall;
135-
if(m_grid(ny,nx) == WALL) continue;
150+
if(m_grid(nx,ny) == WALL) continue;
136151
// except the cur itself
137152
if(nx == cx && ny==cy) continue;
138153
// if neighbour in the closed set
139-
if(m_closedset(ny,nx)) continue;
154+
if(m_closedset(nx,ny)) continue;
140155

141-
float tentative = g_score(cy,cx);
156+
float tentative = g_score(cx,cy);
142157
if (nx == cx || ny == cy) {
143-
tentative += 1 + m_grid(ny,nx);
158+
tentative += 1 + m_grid(nx,ny);
144159
} else {
145-
tentative += (1 + m_grid(ny,nx)) * SQRT2;
160+
tentative += (1 + m_grid(nx,ny)) * SQRT2;
146161
}
147162

148163
// 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)) {
150165
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;
155171
}
156172
}
157173
}

src/astar_demo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <time.h>
44
#include "astar.h"
55

6-
#define N 40
6+
#define N 128
77

88
#define MARK 0xEE
99

0 commit comments

Comments
 (0)