您的位置:首页 > 编程语言 > C语言/C++

A STAR的实现和应用(c++版) 上

2006-10-27 18:33 337 查看
这是我第一次blog,写的不好不对的地方请大家一定批评指正.

最近看到论坛上在讨论a*算法,恰好忙完一个项目有空,就花了几天时间研修了一下A*算法.就把一些感想和代码贴上来跟大家分想交流.

一, 一些数据结构.

1,迷宫 二维数组 typedef vector<vector<element> > MAZE;

2,OpenList 用heap实现. my::Heap<element> hp; 另一个版本用list实现 typedef list<element> LE; 具体用宏USE_LIST 控制.

3,CloseList 用vector实现 VE close_list;(因为只涉及到插入(只在末端操作)和查找,所以从各方面考虑vector是最佳选择);

4,元素element看上去有点复杂,其实只是为了对元素进行比较,查找的操作而重载了几个运算符.具体见element.h


#ifndef ELEMENT_H__


#define ELEMENT_H__




#define START 'S'


#define END 'E'


#define WAY '#'


#define BLANK ' '


#define WALL '1'




struct location




...{


int x;


int y;




location(int xx=0,int yy=0):x(xx),y(yy)...{}


location& operator= (const location& other)




...{


if(this == &other)


return *this;


else




...{


this->x = other.x;


this->y = other.y;


}


return *this;


}


};




class element...{


public:


char terrain;


int dir;//no use now


int g;// have pass;


int h;// futher;


location pos;


element* father;


public:


element(char t=BLANK,int d=0,int gg=0,int hh=0,element* ff=NULL,location ll=location()):terrain(t),dir(d),g(gg),h(hh),father(ff)




...{pos.x = ll.x;pos.y=ll.y;}




bool operator==(const element& rth)...{return ((*this).pos.x==rth.pos.x && (*this).pos.y==rth.pos.y);}


element& operator= (const element& other)




...{


if(this == &other)




...{


return *this;


}


terrain = other.terrain;


dir = other.dir;


g = other.g;


h = other.h;


pos = other.pos;


father = other.father;


return *this;


}


bool operator<(const element& rhs)




...{


return (this->g+this->h) < (rhs.g+rhs.h);


}


bool operator>(const element& rhs)




...{


return (this->g+this->h) > (rhs.g+rhs.h);


}


friend ostream& operator<<(ostream& os,const element& ele)




...{




return os<< (ele.g + ele.h);


}


};


template <class T>


struct COMPARE




...{


bool operator()( T ta,T tb)




...{


return (ta.g + ta.h) < (tb.g + tb.h);


}


};




#endif

二.a*算法.

有了上面的数据结构,我们可以比较方便的来描述a*了.a*算法是一种启发式算法.他总会选择到达目标最短的路径. 一般的回溯很忙目.element.g 表示当前节点已走过的路径.element.h表示到达目标还需要走的路径.所以h是未知的,只是一种估计,好的设计应该在h的计算上下功夫.每次所选的下个节点都是g+h是最小的,即成本最小.本算法采用对角线权14,领边10.h的估算中忽律了地图上不可达的因素.简单 h = ads(end.pos - cur.pos);具体的 a*算法描述:

1) Add the starting square (or node) to the open list.
2) Repeat the following:
a) Look for the lowest F cost square on the open list. We refer to this as the current square.
b) Switch it to the closed list.
c) For each of the 8 squares adjacent to this current square …

If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following.

If it isn’t on the open list, add it to the open list. Make the current square the parent of this square. Record the F, G, and H costs of the square.

If it is on the open list already, check to see if this path to that square is better, using G cost as the measure. A lower G cost means that this is a better path. If so, change the parent of the square to the current square, and recalculate the G and F scores of the square. If you are keeping your open list sorted by F score, you may need to resort the list to account for the change.

d) Stop when you:

Add the target square to the closed list, in which case the path has been found (see note below), or

Fail to find the target square, and the open list is empty. In this case, there is no path.

3) Save the path. Working backwards from the target square, go from each square to its parent square until you reach the starting square. That is your path.
就这么简单.按部就班就好了,具体代码见A-Star.cpp 的bool search_path(MAZE& maze)函数.

三 OpenList的实现:

本来我是用list来维护open list 的,但是为了维护list的有序性算法开销是巨大的,特别当数据是海量的时候.这时bianry heap是很好的选择,因为他只是基本有序,且能完全满足我们的要求.stl的heap或 prority_queue是很好的选择.但是这些东东功能有限,不能满足

If it is on the open list already, check to see if this path to that square is better, using G cost as the measure. A lower G cost means that this is a better path. If so, change the parent of the square to the current square, and recalculate the G and F scores of the square. If you are keeping your open list sorted by F score, you may need to resort the list to account for the change. 这一条. 所以只好自己动手写一个heap了.heap的实现具体见heap.h.如果你对heap不了解,赶紧去温故一下严为名的<<数据结构>>和老猴的<<stl源码剖析>>.

4,maze的实现.
本算法是比较稳定成熟的maze生成代码.你可以动态生成maze,也可以手动编辑MazeData.txt文件.由于本文重点 要介绍的 A Star 算法,就不再喧宾夺主地详细介绍了,具体代码可参见maze.cpp和maze.h

好了,马上就要下班了,下次我会接着写完并把代码贴上来(晕,怎么直接上传文件啊.).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: