A* C++代码实现【AI自动编程】

本文详细介绍了如何使用C++编程实现A*搜索算法,适用于路径规划、游戏AI等领域,通过实例展示了算法的步骤和代码实现过程。
摘要由CSDN通过智能技术生成

A* C++代码实现【AI自动编程】

#include "pch.h"
#include "A_Start.h"
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>

// 定义节点类型
struct Node {
	int x; // 节点的 x 坐标
	int y; // 节点的 y 坐标
	double g; // 从起点到该节点的路径代价
	double h; // 从该节点到目标节点的启发式估计代价
	double f; // 该节点的估价函数值
	Node* parent; // 指向该节点的父节点的指针
	Node(int x_, int y_, double g_, double h_, Node* parent_ = nullptr)
		: x(x_), y(y_), g(g_), h(h_), f(g_ + h_), parent(parent_) {}
};

// 定义比较函数,用于在 priority_queue 中比较节点的估价函数值
struct CompareNodes {
	bool operator()(Node* n1, Node* n2) const {
		return n1->f > n2->f;
	}
};

// 定义 A* 算法函数
std::vector<Node*> astar(int start_x, int start_y, int goal_x, int goal_y, std::vector<std::vector<int>>& grid) {
	// 定义起点和终点节点
	Node* start = new Node(start_x, start_y, 0, 0);
	Node* goal = new Node(goal_x, goal_y, 0, 0);
	// 定义 open 和 closed 列表
	std::priority_queue<Node*, std::vector<Node*>, CompareNodes> open;
	std::vector<Node*> closed;
	// 将起点加入 open 列表
	open.push(start);
	// 当 open 列表非空时循环
	while (!open.empty()) {
		// 取出 open 列表中估价函数值最小的节点
		Node* current = open.top();
		open.pop();
		// 如果该节点是目标节点,返回路径
		if (current->x == goal->x && current->y == goal->y) {
			std::vector<Node*> path;
			while (current) {
				path.push_back(current);
				current = current->parent;
			}
			return path;
		}
		// 将该节点加入 closed 列表
		closed.push_back(current);
		// 遍历当前节点的邻居
		for (int i = -1; i <= 1; i++) {
			for (int j = -1; j <= 1; j++) {
				// 跳过当前节点
				if (i == 0 && j == 0) continue;
				// 计算邻居节点的坐标
				int x = current->x + i;
				int y = current->y + j;
				// 如果邻居节点越界或为障碍物或已在 closed 列表中,跳过
				if (x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] == 1) continue;
				bool in_closed = false;
				for (Node* n : closed) {

					if (n->x == x && n->y == y) {
						in_closed = true;
						break;
					}
				}
				if (in_closed) continue;
				// 计算从起点到该邻居节点的路径代价
				double g = current->g + std::sqrt(i * i + j * j);
				// 如果邻居节点不在 open 列表中,或者新的路径代价更小
				bool in_open = false;
				Node* neighbor = nullptr;
				for (Node* n : open._Get_container()) {
					if (n->x == x && n->y == y) {
						in_open = true;
						neighbor = n;
						break;
					}
				}
				if (!in_open || g < neighbor->g) {
					// 更新或插入邻居节点
					double h = std::sqrt((x - goal->x) * (x - goal->x) + (y - goal->y) * (y - goal->y));
					if (in_open) {
						open._Get_container().erase(std::find(open._Get_container().begin(), open._Get_container().end(), neighbor));
					}
					Node* new_node = new Node(x, y, g, h, current);
					open.push(new_node);
				}
			}
		}
	}
	// 如果找不到路径,返回空向量
	return std::vector<Node*>();
}
// 测试 A* 算法函数
int main() {
	std::vector<std::vector<int>> grid = {
	{0, 0, 1, 0, 0},
	{0, 0, 1, 0, 0},
	{0, 0, 0, 0, 0},
	{0, 0, 1, 0, 0},
	{0, 0, 0, 0, 0},
	};
	int start_x = 0;
	int start_y = 0;
	int goal_x = 4;
	int goal_y = 4;
	std::vector<Node*> path = astar(start_x, start_y, goal_x, goal_y, grid);
	if (path.empty()) {
		std::cout << "No path found!" << std::endl;
	}
	else {
		for (auto it = path.rbegin(); it != path.rend(); ++it) {
			std::cout << "(" << (*it)->x << ", " << (*it)->y << ") ";
		}
		std::cout << std::endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值