A Start A星算法

4 篇文章 0 订阅

启发式算法

俗称Astart A*算法

 

 

//启发式算法
#include <iostream>  
#include <vector>  
#include <stdio.h>  
#include <algorithm>  
#include <memory>
#include <random>

//int nnn = 0;
using namespace std;
class Node {
public:
	int x;//行
	int y;//列
	int f;//g+h  
	int g;//起点到当前点的消耗   
	int h;//重点到当前点的理论消耗   
	std::shared_ptr <Node>parent;
	Node(int x, int y) {
		this->x = x;
		this->y = y;
		this->f = 0;
		this->g = 0;
		this->h = 0;
		this->parent = NULL;
	}
	Node(int x, int y, std::shared_ptr<Node> parent) {
		this->x = x;
		this->y = y;
		this->f = 0;
		this->g = 0;
		this->h = 0;
		this->parent = parent;
	}
};

//0表示可通过1表示障碍物   
int map[101][101] = {
	{ 0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0 },
	{ 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0 },
	{ 0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0 },
	{ 0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0 },
	{ 0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0 },
	{ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0 },
	{ 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0 },
	{ 0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0 },
	{ 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0 },
	{ 0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0 },
	{ 0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0 },
	{ 0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0 },
	{ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0 },
	{ 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0 },
	{ 0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0 },
	{ 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0 },
	{ 0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0 },
	{ 0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0 },
	{ 0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0 },
	{ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0 },
	{ 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0 }
};
int map1[101][101] = {
	{ 0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0 },
	{ 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0 },
	{ 0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0 },
	{ 0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0 },
	{ 0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0 },
	{ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0 },
	{ 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0 },
	{ 0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0 },
	{ 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0 },
	{ 0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0 },
	{ 0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0 },
	{ 0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0 },
	{ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0 },
	{ 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0 },
	{ 0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0 },
	{ 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0 },
	{ 0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0 },
	{ 0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0 },
	{ 0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0 },
	{ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0 },
	{ 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0 }
};

vector<std::shared_ptr<Node>> openList;
vector<std::shared_ptr<Node>> closeList;
int row;//地图总行数   
int col;//地图总列数   
std::shared_ptr<Node> startPos;//开始点   
std::shared_ptr<Node> endPos;//结束点   
int weightW;//平移权重   
int weightWH;//斜移权重   

int countH(std::shared_ptr<Node> sNode, std::shared_ptr<Node> eNode) {
	int w = abs(sNode->x - eNode->x);
	int h = abs(sNode->y - eNode->y);
	int cost = min(w, h)*weightWH + abs(w - h)*weightW;
	return cost;
}
void countFGH(std::shared_ptr<Node> sNode, std::shared_ptr<Node> eNode, int cost) {
	int h = countH(sNode, eNode);
	int g = sNode->parent->g + cost;
	int f = h + g;
	sNode->f = f;
	sNode->h = h;
	sNode->g = g;
}
//检测列表是否包含指定节点  
int isContains(vector<std::shared_ptr<Node>>* v, int x, int y) {
	for (int i = 0; i < v->size(); i++) {
		if (((*v)[i])->x == x
			&& ((*v)[i])->y == y) {
			return i;
		}
	}
	return -1;
}
void initMap() {
	row = 21;
	col = 25;
	memcpy(map, map1, sizeof(int) * 101 * 101);
	weightW = 15;
	weightWH = 20;

	std::random_device rd;
	std::mt19937 gen(rd());
	std::uniform_int_distribution<> dis(0, row);
	std::uniform_int_distribution<> dis1(0, col);

	startPos = std::shared_ptr<Node>(new Node(dis(gen), dis1(gen)));
	endPos = std::shared_ptr<Node>(new Node(dis(gen), dis1(gen)));
	startPos = std::shared_ptr<Node>(new Node(0, 0));
	endPos = std::shared_ptr<Node>(new Node(20, 24));
	//nnn += 2;
	printf("start(%d,%d),end(%d,%d)\n", startPos->x, startPos->y, endPos->x, endPos->y);
}

void printMap() {
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			printf("%d ", map[i][j]);
		}
		printf("\n");
	}
}
bool compare(std::shared_ptr<Node> n1, std::shared_ptr<Node> n2) {
	return n1->f < n2->f;
}
void checkMove(int x, int y, std::shared_ptr<Node> & parent, std::shared_ptr<Node> & end, int cost) {
	if (map[x][y] == 1) {
		return;
	}
	if (isContains(&closeList, x, y) != -1) {
		return;
	}
	int index = -1;
	if ((index = isContains(&openList, x, y)) != -1) {
		//是否存在更小的G值  
		std::shared_ptr<Node> sNode = openList[index];
		if (parent->g + cost < sNode->g) {
			sNode->parent = parent;
			sNode->g = parent->g + cost;
			sNode->f = sNode->g + sNode->h;
			//openList.push_back(sNode);
		}
	}
	else {
		std::shared_ptr<Node> n = std::shared_ptr<Node>(new Node(x, y, parent));
		countFGH(n, end, cost);
		openList.push_back(n);
	}
}
void printPath(std::shared_ptr<Node> node) {
	if (node->parent != NULL) {
		printPath(node->parent);
	}
	//将走过的点标记为2   
	map[node->x][node->y] = 2;  
	printf("->%d,%d", node->x, node->y);
}
// void releaseNode(std::shared_ptr<Node> n) {
// 	if (n->parent != NULL) {
// 		releaseNode(n->parent);
// 	}
// 	//delete n;
// 	nnn--;
// }
//-1错误0没找到1找到   
int startSearch(std::shared_ptr<Node> start, std::shared_ptr<Node> end) {
	if (start->x < 0 || start->y < 0 || start->x >= row || start->y >= col
		|| end->x < 0 || end->y < 0 || end->x >= row || end->y >= col) {
		return -1;
	}
	if (map[start->x][start->y] == 1 || map[end->x][end->y] == 1) {
		return -1;
	}

	start->h = countH(start, end);
	start->f = start->h + start->g;
	//查找算法  
	openList.push_back(start);
	std::shared_ptr<Node> root = NULL;
	int find = 0;
	while (openList.size() > 0) {
		root = openList[0];
		if (root->x == end->x&&root->y == end->y) {
			find = 1;
			break;
		}
		//上下左右   
		if (root->x > 0) {
			checkMove(root->x - 1, root->y, root, end, weightW);
		}
		if (root->y > 0) {
			checkMove(root->x, root->y - 1, root, end, weightW);
		}
		if (root->x < row - 1) {
			checkMove(root->x + 1, root->y, root, end, weightW);
		}
		if (root->y < col - 1) {
			checkMove(root->x, root->y + 1, root, end, weightW);
		}
		if (root->x < row - 1 && root->y>0) {
			checkMove(root->x + 1, root->y - 1, root, end, weightWH);
		}
		if (root->y < col - 1 && root->x>0) {
			checkMove(root->x - 1, root->y + 1, root, end, weightWH);
		}
		if (root->x > 0 && root->y > 0) {
			checkMove(root->x - 1, root->y - 1, root, end, weightWH);
		}
		if (root->y < col - 1 && root->x < row - 1) {
			checkMove(root->x + 1, root->y + 1, root, end, weightWH);
		}
		closeList.push_back(root);
		openList.erase(openList.begin());
		std::sort(openList.begin(), openList.end(), compare);
	}
	if (find) {
		printPath(root);
		printf("\n");
		//printMap();  
	}
	//releaseNode(root);
	printMap();
	openList.clear();
	closeList.clear();
	return find;
}

#include<windows.h>
int main(int argc, char *argv[]) {
	while (true)
	{
		initMap();
		printMap();
		int t = startSearch(startPos, endPos);
		if (t == 1) {
			printf("find!\n");
		}
		else if (t == 0) {
			printf("no find.\n");
		}
		else {
			printf("error!\n");
		}
		Sleep(10);
	}

	return 0;
}

 

获取更多帮主请关注小程序

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A算法是一种常用于寻路问题的启发式搜索算法,可以用Python进行实现。以下是一个用Python实现A算法的简单示例: ```python import heapq # 定义节点类 class Node: def __init__(self, position=None, parent=None): self.position = position # 当前节点位置 self.parent = parent # 父节点 self.g = 0 # 从起点到当前节点的实际代价 self.h = 0 # 从当前节点到目标节点的估计代价 self.f = 0 # f = g + h # 实现A算法 def a_star(start, goal): open_list = [] closed_list = [] # 添加起点到open list heapq.heappush(open_list, (0, start)) while open_list: # 选择f值最小的节点作为当前节点 current = heapq.heappop(open_list)[1] # 如果当前节点是目标节点,则搜索结束 if current == goal: path = [] while current: path.append(current.position) current = current.parent return path[::-1] # 反转路径,得到从起点到目标的最短路径 # 将当前节点添加到closed list中 closed_list.append(current) # 遍历当前节点的相邻节点 for neighbor in find_neighbors(current): # 如果相邻节点已经在closed list中,则跳过 if neighbor in closed_list: continue # 计算从起点经过当前节点到相邻节点的实际代价 temp_g = current.g + 1 # 如果相邻节点不在open list中,则添加到open list if neighbor not in [n[1] for n in open_list]: heapq.heappush(open_list, (neighbor.h, neighbor)) # 如果相邻节点已经在open list中,并且新计算的实际代价更小,则更新其实际代价和父节点 elif temp_g < neighbor.g: open_list.remove((neighbor.h, neighbor)) heapq.heappush(open_list, (neighbor.h, neighbor)) # 更新相邻节点的实际代价、估计代价和f值 neighbor.g = temp_g neighbor.h = heuristic(neighbor, goal) neighbor.f = neighbor.g + neighbor.h return [] # 搜索失败,返回空路径 # 定义估计函数,可以根据实际情况进行修改 def heuristic(node, goal): return abs(node.position[0] - goal.position[0]) + abs(node.position[1] - goal.position[1]) # 定义寻找相邻节点的函数 def find_neighbors(node): neighbors = [] # 编写具体的寻找相邻节点的逻辑 return neighbors # 调用A算法寻路 start_node = Node((0, 0)) goal_node = Node((3, 3)) path = a_star(start_node, goal_node) if path: print("最短路径为:", path) else: print("无法找到路径") ``` 以上是一个简单的用Python实现A算法的示例。通过定义节点类、实现A算法函数和相关辅助函数,可以使用A算法解决寻路问题。具体实现需要根据具体情况进行调整和完善。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值