码迷,mamicode.com
首页 > 编程语言 > 详细

A星寻路算法以及C++实现

时间:2014-05-26 19:16:57      阅读:413      评论:0      收藏:0      [点我收藏+]

标签: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++实现如下:

  

bubuko.com,布布扣
  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
bubuko.com,布布扣
bubuko.com,布布扣
  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 }
bubuko.com,布布扣

 

测试代码:

bubuko.com,布布扣
 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 }
bubuko.com,布布扣

 

A星寻路算法以及C++实现,布布扣,bubuko.com

A星寻路算法以及C++实现

标签:style   c   class   blog   code   java   

原文地址:http://www.cnblogs.com/wolfred7464/p/3751940.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!