标签:style c class blog code java
A星寻路算法真是我一生接触的第一个人工智能算法了。。。
A星寻路算法显然是用来寻路的,应用也很普遍,比如梦幻西游。。。算法的思路很简单,就是在bfs的基础上加了估值函数。
它的核心是 F(x) = G(x) + H(x) 和open、close列表:
G(x)表示从起点到X点的消耗(或者叫移动量什么的),H(X)表示X点到终点的消耗的估值,F(x)就是两者的和值。open列表记录了可能要走的区域,close列表记录了不会再考虑的区域。我们每次都选F值最小的区域搜索,就能搜到一条到终点的最短路径,其中估值H越接近准确值,需要搜索的节点就越少。
A星算法的步骤:
{
将起点区域添加到open列表中,该区域有最小的和值。
重复以下:
将open列表中最小F值的区域X移除,然后添加到close列表中。
对于与X相邻的每一块可通行且不在close列表中的区域T:
如果T不在open列表中:添加到open列表,把X设为T的前驱
如果T已经在open列表中:检查 F 是否更小。如果是,更新 F 和前驱
直到:
终点添加到了close列表。(已找到路径)
终点未添加到close列表且open列表已空。(未找到路径)
}
C++实现如下:
1 /*************************** 2 * A星寻路算法 3 * 4 * Anti-Magic 5 * 2014/5/26 6 ****************************/ 7 8 #ifndef __ASTAR_H__ 9 #define __ASTAR_H__ 10 11 #include <map> 12 #include <set> 13 #include <vector> 14 #include <list> 15 16 //属性宏 17 #define SYNTHESIZE(varType, varName, funName) 18 protected: 19 varType varName; 20 public: 21 virtual varType get##funName(void) const { 22 return varName; 23 } 24 virtual void set##funName(varType var) { 25 varName = var; 26 } 27 28 /*************************** 29 * Point类 30 * 表示一个二维坐标 31 ****************************/ 32 class Point 33 { 34 SYNTHESIZE(int, _x, X); 35 SYNTHESIZE(int, _y, Y); 36 public: 37 Point(); 38 Point(int x, int y); 39 //获得曼哈顿距离 40 int getManhattanDistance(const Point& t) const; 41 //获得欧几里得距离 42 double getEuclidDistance(const Point& t) const; 43 bool operator== (const Point& t) const; 44 bool operator< (const Point& t) const; 45 }; 46 47 /*************************** 48 * Local类 49 * 在A星寻路算法中的单位区域 50 ****************************/ 51 class Local : public Point 52 { 53 SYNTHESIZE(int, _g, G); 54 SYNTHESIZE(int, _h, H); 55 public: 56 Local(); 57 Local(int x, int y, int g, int h); 58 Local(const Point& t, int g, int h); 59 Local(const Local& t); 60 int getF() const; 61 bool operator< (const Local& t) const; 62 }; 63 64 /*************************** 65 * SuperCloseList类 抽象类 66 * Close列表的基类 67 * 因为实现Close列表在不同场合有不同的实现 68 * 需要继承此类 69 ****************************/ 70 class SuperCloseList 71 { 72 public: 73 //插入close列表 74 virtual void insert(const Local& p) = 0; 75 //查询close列表中是否已存在此区域 76 virtual bool find(const Local& p) const = 0; 77 }; 78 79 /*************************** 80 * CloseList类 81 * Close列表的哈希实现 82 ****************************/ 83 class CloseList : public SuperCloseList 84 { 85 public: 86 CloseList(); 87 CloseList(int x, int y); 88 ~CloseList(); 89 void insert(const Local& p) override; 90 bool find(const Local& p) const override; 91 private: 92 bool** _close; 93 int size_x, size_y; 94 //申请数组内存 95 void newClose(int x, int y); 96 }; 97 98 /*************************** 99 * A星算法类 100 * 实现A星算法的逻辑 101 ****************************/ 102 class AStar 103 { 104 public: 105 AStar(std::vector<std::vector<bool> >& legal, Point& start, Point& end); 106 //获得距离 107 int getDistance() const; 108 //获得路径 109 std::list<Point> getPath() const; 110 private: 111 std::vector<std::vector<bool> > _legal; 112 std::multiset<Local> open; 113 CloseList close; 114 Point _start; 115 Point _end; 116 std::map<Point, Point> _path_pre; 117 std::list<Point> _path_list; 118 int _distance; 119 //路径规划,算法的核心 120 void pathPlanning(); 121 //检查区域 122 void checkLocal(Local& local_tar, Local& local_cur); 123 //生成路径 124 void initPath(); 125 }; 126 127 #endif
1 #include "AStar.h" 2 3 Point::Point() 4 { 5 _x = _y = 0; 6 } 7 Point::Point(int x, int y) 8 { 9 _x = x; 10 _y = y; 11 } 12 int Point::getManhattanDistance(const Point& t) const 13 { 14 return std::abs(_x - t._x) + std::abs(_y - t._y); 15 } 16 double Point::getEuclidDistance(const Point& t) const 17 { 18 return std::sqrt((_x - t._x) * (_x - t._x) + (_y - t._y) * (_y - t._y)); 19 } 20 bool Point::operator== (const Point& t) const 21 { 22 return _x == t._x && _y == t._y; 23 } 24 bool Point::operator< (const Point& t) const 25 { 26 if (_x == t._x) 27 { 28 return _y < t._y; 29 } 30 return _x < t._x; 31 } 32 33 Local::Local() : Point() 34 { 35 _g = _h = 0; 36 } 37 Local::Local(int x, int y, int g, int h) : Point(x, y) 38 { 39 _g = g; 40 _h = h; 41 } 42 Local::Local(const Point& t, int g, int h) : Point(t) 43 { 44 _g = g; 45 _h = h; 46 } 47 Local::Local(const Local& t) 48 { 49 _x = t._x; 50 _y = t._y; 51 _g = t._g; 52 _h = t._h; 53 } 54 int Local::getF() const 55 { 56 return _g + _h; 57 } 58 bool Local::operator< (const Local& t) const 59 { 60 return getF() > t.getF(); 61 } 62 63 CloseList::CloseList() 64 { 65 newClose(100, 100); 66 } 67 CloseList::CloseList(int x, int y) 68 { 69 newClose(x, y); 70 } 71 CloseList::~CloseList() 72 { 73 for (int i = 0; i < size_y; i++) 74 { 75 delete[] _close[i]; 76 } 77 delete[] _close; 78 } 79 void CloseList::insert(const Local& p) 80 { 81 _close[p.getX()][p.getY()] = true; 82 } 83 bool CloseList::find(const Local& p) const 84 { 85 return _close[p.getX()][p.getY()] == true; 86 } 87 void CloseList::newClose(int x, int y) 88 { 89 size_x = x; 90 size_y = y; 91 _close = new bool*[x]; 92 for (int i = 0; i < x; i++) 93 { 94 _close[i] = new bool[y]; 95 memset(_close[i], false, sizeof(_close[i])); 96 } 97 } 98 99 AStar::AStar(std::vector<std::vector<bool> >& legal, Point& start, Point& end) 100 { 101 _legal = legal; 102 _start = start; 103 _end = end; 104 pathPlanning(); 105 } 106 int AStar::getDistance() const 107 { 108 return _distance; 109 } 110 std::list<Point> AStar::getPath() const 111 { 112 return _path_list; 113 } 114 void AStar::pathPlanning() 115 { 116 open.insert(Local(_start, 0, 0)); 117 int dir[][2] = { 118 { 0, 1 }, { 0, -1 }, 119 { 1, 0 }, { -1, 0 } 120 }; 121 while (!open.empty()) 122 { 123 Local cur = *open.begin(); 124 open.erase(open.begin()); 125 close.insert(cur); 126 if (cur == _end) 127 { 128 initPath(); 129 _distance = cur.getG(); 130 return; 131 } 132 for (int i = 0; i < 4; i++) 133 { 134 int x = cur.getX() + dir[i][0]; 135 int y = cur.getY() + dir[i][1]; 136 int g = cur.getG() + 1; 137 int h = _end.getManhattanDistance(Point(x, y)); 138 Local point_choose(x, y, g, h); 139 checkLocal(point_choose, cur); 140 } 141 } 142 _distance = -1; 143 } 144 void AStar::checkLocal(Local& local_tar, Local& local_cur) 145 { 146 int x = local_tar.getX(); 147 int y = local_tar.getY(); 148 int g = local_tar.getG(); 149 int h = local_tar.getH(); 150 if (x < _legal.size() && x >= 0 && y < _legal[0].size() && y >= 0 && 151 _legal[x][y] && !close.find(local_tar)) 152 { 153 bool inopen = false; 154 for (std::multiset<Local>::iterator it = open.begin(); it != open.end(); it++) 155 { 156 if (it->getX() == x && it->getY() == y) 157 { 158 inopen = true; 159 if (it->getG() > g) 160 { 161 open.erase(it); 162 open.insert(local_tar); 163 _path_pre[local_tar] = local_cur; 164 break; 165 } 166 } 167 } 168 if (!inopen) 169 { 170 open.insert(local_tar); 171 _path_pre[local_tar] = local_cur; 172 } 173 } 174 } 175 void AStar::initPath() 176 { 177 Point path_res = _end; 178 while (!(path_res == _start)) 179 { 180 _path_list.push_front(path_res); 181 path_res = _path_pre[path_res]; 182 } 183 _path_list.push_front(_start); 184 }
测试代码:
1 #define _CRT_SECURE_NO_DEPRECATE 2 3 #include "AStar.h" 4 #include <stdio.h> 5 6 int main() 7 { 8 std::vector<std::vector<bool> > legal { 9 std::vector<bool> {0, 0, 0, 1, 1, 1, 1}, 10 std::vector<bool> {1, 1, 1, 1, 0, 1, 0}, 11 std::vector<bool> {1, 1, 1, 1, 1, 0, 0}, 12 std::vector<bool> {1, 0, 0, 0, 0, 0, 0}, 13 std::vector<bool> {1, 1, 1, 1, 1, 1, 1}, 14 }; 15 Point start(1, 5); 16 Point end(4, 5); 17 AStar* astar = new AStar(legal, start, end); 18 printf("%d\n", astar->getDistance()); 19 std::list<Point> path = astar->getPath(); 20 for (auto path_cur : path) 21 { 22 printf(".....%d %d\n", path_cur.getX(), path_cur.getY()); 23 } 24 delete astar; 25 system("pause"); 26 return 0; 27 }
标签:style c class blog code java
原文地址:http://www.cnblogs.com/wolfred7464/p/3751940.html