A*/AStar规划算法(C++版本)

AStart.h头文件

#pragma once
#include<vector>
#include<list>
#include<iostream>
using namespace std;
const int kCost1 = 10; //直移一格消耗
const int kCost2 = 14; //斜移一格消耗
typedef struct Point {
	Point* parent;
	int x;
	int y;
	int f;
	int g;
	int h;
	Point(int _x,int _y) :x(_x), y(_y), f(0), g(0), h(0), parent(NULL) {};
}* PPoint;
class AStart
{
private:
	vector<vector<int>> map;
	list<PPoint> openList;
	list<PPoint> closeList;
public:
	void initMap(vector<vector<int>> &_map);
	PPoint findPath(PPoint start, PPoint end);
	PPoint inInList(PPoint point, list<PPoint> &list);
	list<PPoint> findAroundPoint(PPoint curPoint);
	PPoint findLeastFPoint();
	int calG(PPoint& point, PPoint& parentPoint);
	void calF(PPoint& point, PPoint& endPoint);
	int calStep(PPoint& p1, PPoint& p2);
	int calDistance(PPoint& p1, PPoint& p2);
};

AStart.cpp文件

#include "AStart.h"

void AStart::initMap(vector<vector<int>> &_map) {
	map = _map;
	//map[0][0] = 99;
	//cout << map[0][0] << ' '<<map[0][1]<< endl;
}
int AStart::calDistance(PPoint& p1, PPoint& p2) {
	return (abs(p1->x - p1->x) + abs(p1->y + p2->y)) * kCost1;
}
int AStart::calStep(PPoint& p1, PPoint& p2) {
	int dt = abs(p1->x - p2->x) + abs(p1->y - p2->y);
	if (dt == 1) {
		return kCost1;
	}
	else if (dt == 0) {
		return 0;
	}
	else {
		return kCost2;
	}
}
int AStart::calG(PPoint& point, PPoint &parentPoint) {
	return parentPoint->g + calStep(point, parentPoint);
}
void AStart::calF(PPoint& point,PPoint &endPoint) {
	if (point->parent) {
		point->g = calG(point,point->parent);
		point->h = calDistance(point, endPoint);
		point->f = point->g + point->h;
	}
}
PPoint AStart::findPath(PPoint start, PPoint end) {
	calF(start,end);
	openList.push_back(start);
	while (openList.size()>0)
	{
		// 取得F最小的点
		PPoint curPoint= findLeastFPoint();
		// 将点从open列表中移除
		openList.remove(curPoint);
		// 将点添加到close列表中
		closeList.push_back(curPoint);
		//查找当前点的周边节点
		list<PPoint> aroundList =  findAroundPoint(curPoint);
		for (auto arountPoint : aroundList) {
			if (arountPoint->x == end->x && arountPoint->y == end->y) {
				//已经找到目标点
				arountPoint->parent = curPoint;
				calF(arountPoint,end);
				return arountPoint;
			}
			// 在close表
			else if (inInList(arountPoint, closeList)) {
				//不用处理
			}
			else if (inInList(arountPoint, openList)) {
				int tmpG = calG(arountPoint, curPoint);
				if (tmpG < arountPoint->g) {
				//更新节点
					arountPoint->g = tmpG;
					arountPoint->f = arountPoint->g + arountPoint->h;
					arountPoint->parent = curPoint;
				}
			}
			else {
				//添加到open表中
				arountPoint->parent = curPoint;
				calF(arountPoint, end);
				openList.push_back(arountPoint);
			}
		}
	}
	return NULL;
}
PPoint AStart::findLeastFPoint() {
	PPoint tmpPoint = NULL;
	for (auto point : openList) {
		if (!tmpPoint || tmpPoint->f>point->f) {
			tmpPoint = point;
		}
	}
	return tmpPoint;
}
PPoint AStart::inInList(PPoint point, list<PPoint> &list) {
	for (auto item : list) {
		if (item->x == point->x && item->y == point->y) {
			return item;
		}
	}
	return NULL;
}

list<PPoint> AStart::findAroundPoint(PPoint curPoint) {
	list<PPoint> around;
	int mapXSize = map.size();
	int mapYSize = map[0].size();
	for (int x = curPoint->x - 1; x <= curPoint->x + 1; x++) {
		if (x<0 || x>=mapXSize) {
			continue;
		}
		for (int y = curPoint->y - 1; y <= curPoint->y + 1; y++) {
			if (y < 0 || y >= mapYSize) {
				continue;
			}
			if (map[x][y] == 1) {
				continue; // 不可达
			}
			else {
				PPoint newPoint = new Point(x, y);
				around.push_back(newPoint);
			}
		}
	}
	return around;
}

主函数Main

#include <iostream>
#include <vector>
#include "AStart.h"
using namespace std;
void printMap(vector<vector<int>> map) {
    for (auto& row : map) {
        for (auto& cell : row) {
            cout << cell << ' ';
        }
        cout << endl;
    }
}
void pirntPath(PPoint path, vector<vector<int>> &map) {
    PPoint p = path;
    while (p->parent) {
        cout << p->x << ',' << p->y << endl;
        map[p->x][p->y] = 7;
        p = p->parent;
    }
    map[p->x][p->y] = 5;
}
int main(){
	vector<vector<int>> map= { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                       {1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1},
                                       {1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1},
                                       {1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1},
                                       {1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1},
                                       {1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},
                                       {1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1},
                                       {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} };

    AStart astar;
    PPoint start=new Point(1, 1);
    PPoint end=new Point(6, 10); 
    astar.initMap(map);
    PPoint path=astar.findPath(start, end);
    printMap(map);
    cout << "行驶轨迹" << endl;
    pirntPath(path, map);
    printMap(map);
    return 1;
	}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: a*算法是一种启发式搜索算法,常用于解决路径规划问题。matlab是一种科学计算软件,可以进行矩阵运算、图形处理和数学分析等,因此可以很好地用来实现a*算法。473x436表示地图的大小,其中473和436分别代表地图的宽和高。在a*算法中,地图被抽象成一个网格图,每个网格表示一个节点,图中的边代表相邻节点之间的关系。a*算法在搜索时,会构建一棵搜索树,根节点表示起始位置,叶子节点表示终点位置,树中的节点代表当前位置,通过启发式函数估计路径的质量,选择最优解最终到达终点。在实现过程中,matlab提供了方便的矩阵操作和可视化工具,可以对a*算法进行快速测试和分析。通过调整启发式函数、加速搜索等手段,可以提高算法的效率和准确性。最终,a*算法与matlab的结合,可以有效地解决路径规划问题,成为现代科学研究和实际应用中不可或缺的一部分。 ### 回答2: a*算法是一种启发式搜索算法,常用于寻找最短路径或最佳路径。在MATLAB中,可以使用a*算法来解决一个473x436的问题。 首先,我们需要定义问题的起点和终点。起点是指出发点,终点是指我们希望到达的位置。在这个问题中,起点可能是(0,0),终点可能是(473,436)。 然后,我们需要确定问题的状态空间和移动规则。状态空间是指所有可能的位置,移动规则是指从一个位置移动到另一个位置的方式和代价。在这个问题中,状态空间包括所有具有合法坐标的位置。移动规则可能是向上、向下、向左、向右移动,每个移动的代价可能是不同的。 接下来,我们需要实现a*算法算法的基本思想是维护一个开放列表和一个关闭列表。开放列表用于存储待探索的节点,关闭列表用于存储已经探索过的节点。算法开始时,将起点加入到开放列表中。然后,重复以下步骤直到找到终点或者开放列表为空: 1. 从开放列表中选择一个节点,并将其移入关闭列表。 2. 遍历该节点的邻居节点,计算邻居节点的代价。 3. 如果邻居节点不在开放列表中,将其加入到开放列表中,并计算邻居节点的启发式代价。 4. 如果邻居节点已经在开放列表中,比较当前路径代价与之前的路径代价,更新为更小的值。 最后,当找到终点或者开放列表为空时,算法结束。如果找到了终点,可以通过回溯路径来获取最短路径或最佳路径。 总之,使用MATLAB中的a*算法可以解决一个473x436的问题。我们需要定义起点和终点,确定问题的状态空间和移动规则,实现a*算法并找到最短路径或最佳路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值