我是靠谱客的博主 欢呼小土豆,最近开发中收集的这篇文章主要介绍A*算法示例代码和详解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

#include<iostream>
#include<queue>
#include<cmath>
using namespace std;

char maze[10][10] = {'.','.','.','.','.','.','.','.','.','.',
                     '.','.','*','*','*','.','.','.','.','.',
                     '.','.','.','.','*','.','.','.','.','.',
                     '.','.','.','.','*','.','.','.','.','.',
                     '.','S','.','.','*','.','.','.','.','.',
                     '.','.','.','.','.','.','.','.','.','.',
                     '.','.','.','.','*','.','.','.','.','.',
                     '.','.','.','.','*','.','.','.','E','.',
                     '.','.','*','*','*','*','*','*','*','.',
                     '.','.','.','.','.','.','.','.','.','.',};
class point
{
public:
	char val;
	int x, y;
	int f,g,h;
	int prex, prey;
	bool isopen;
	bool isclose;
};

struct pointcmp
{
	bool operator() (point x, point y)
	{
		if(x.f == y.f)
			return x.h > y.h;
		else
			return x.f > y.f;
	}
};

int xx[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
point ma[10][10];
priority_queue<point, vector<point>,pointcmp> open_list;
priority_queue<point> close_list;

void getpath()
{
	ma[4][1].h = 10;
	ma[4][1].f = 10;
	ma[4][1].isopen = true;
	open_list.push(ma[4][1]);
	point node1, node2;
	int px, py, g;
	while(!open_list.empty())
	{
		node1 = open_list.top();
		open_list.pop();
		ma[node1.x][node1.y].isclose = true;
		g = node1.g + 1;
		for(int i = 0; i < 4; i++)
		{
			px = node1.x + xx[i][0];
			py = node1.y + xx[i][1];
			if(px < 0 || py < 0 || px > 9 || py > 9) continue;
			if(ma[px][py].val == '.' && ma[px][py].isopen == false && ma[px][py].isclose == false)
			{
				ma[px][py].g = g;
				ma[px][py].h = abs(px - 7) + abs(py - 8);
				ma[px][py].f = g + ma[px][py].h;
				ma[px][py].isopen = true;
				ma[px][py].prex = node1.x;
				ma[px][py].prey = node1.y;
				open_list.push(ma[px][py]);
			}
			else if(ma[px][py].val == '.' && ma[px][py].isopen == true && ma[px][py].isclose == false)
			{
				if(g + abs(px - 7) + abs(py - 8) < ma[px][py].f)
				{
					ma[px][py].g = g;
					ma[px][py].h = abs(px - 7) + abs(py - 8);
					ma[px][py].f = g + ma[px][py].h;
					ma[px][py].prex = node1.x;
					ma[px][py].prey = node1.y;
				}
			}
			else if(ma[px][py].val == 'E')
			{
				ma[px][py].prex = node1.x;
				ma[px][py].prey = node1.y;
				node2 = ma[px][py];
				while(node2.val != 'S')
				{
					cout << "("<<node2.x<<", "<<node2.y<<")"<<endl;
					node2 = ma[node2.prex][node2.prey];
				}
				return;
			}
		}
	}
}

int main()
{
	for(int i = 0; i < 10; i++)
		for(int j = 0; j < 10; j++)
		{
			ma[i][j].val = maze[i][j];
			ma[i][j].f = 0;
			ma[i][j].g = 0;
			ma[i][j].h = 0;
			ma[i][j].isopen = false;
			ma[i][j].isclose = false;
			ma[i][j].x = i;
			ma[i][j].y = j;
		}
	getpath();
}



算法详解:讲解之前需要了解BFS,在此基础上,我们深入了解A*
我们定义g[i][j]是从起点到点(i,j)的花费,h[i][j]是点(i,j)到终点的预估花费。

(花费:比如起点(0,0)经过(0,1)到达点(1,1)那么,g[1][1]就是2. 预估花费:比如现在我走到点(3,3),终点是(4,5),那么,我从(3,3)到终点的预估花费就是1+2=3,即这两个点的坐标相减的绝对值,也称为曼哈顿距离)
我们对预估花费采用曼哈顿距离。当然,还有一些其他距离可以使用,如:对角线距离,欧几里得距离等。
定义f[i][j] = g[i][j] + h[i][j]为该点目前的总花费。

定义开启列表和结束列表,开启列表用优先队列(这里的开启列表类似于BFS使用的队列,唯一的不同就是它是优先队列,至于按照什么优先呢?按照f的值从小到大,越小越优先,如果相等,则可以按照h的值从小到大)
首先,我们将起点(或者到达某一位置后的点P)放入开启列表:接下来遍历该点上下左右的四个相邻节点,对于每一个相邻节点Q,执行如下步骤:

(1) 如果Q点可通过(本示例程序中以'.'表示),且该点不在开启列表也不在关闭列表中,则计算Q点g,h,f值,将P点记录为Q点的前驱节点。并加入开启列表

(2)如果Q点可通过,且该点在开启列表中,则计算从点P到点Q得到的f值是否比Q点当前的f值更小(已经在开启列表中的点一定是计算过f,g,h的),如果小,则更新Q点的f,g,h值,并将Q的前驱节点改为P。如果大,则什么都不做。
(3)如果Q点在关闭列表中,或者Q点不可通过,什么都不做,直接忽略。

(4)如果Q点是终点,则整个搜索就可以结束了,我们可以通过Q点的前驱节点,前驱节点通过它的前驱节点不断遍历直到起点,从而得到整个路径,程序over。

遍历完上下左右四个点之后,我们就把P点放入关闭列表中,接着继续从开启列表中拿第一个节点,重复上述4步。直到结束。

最后

以上就是欢呼小土豆为你收集整理的A*算法示例代码和详解的全部内容,希望文章能够帮你解决A*算法示例代码和详解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部