[Astar_algorithm03]随机障碍点生成以及坐标点传递方法

Posted AIplusX

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Astar_algorithm03]随机障碍点生成以及坐标点传递方法相关的知识,希望对你有一定的参考价值。

写在前面

障碍物在算法环境中是不可缺少的,可以看成是算法的约束条件。那么如何生成不重复的随机障碍点呢?接下来我就主要介绍这个办法,以及如何利用C++将坐标点数据在不同功能函数之间高效率传递。

结果展示

绿色:已搜索(待遍历)节点;
浅灰色:搜索过程中的最小F数值点;
红色:起点;
绿色:终点;
黄色:最终的生成路径;
黑色:障碍物(不可走坐标);

随机障碍物

我的思路是将地图上所有的坐标点都塞进一个vector里面,然后将这个vector乱序化,最终取vector前面的坐标点做为障碍物,这样可以保证取出的障碍点是无序且不重复的,C++实现如下图所示:


void Graph::set_obstacles_start_end()
{

	for (int i = 0; i <= graph_user_para.map_x; i++) {
		for (int j = 0; j <= graph_user_para.map_y; j++) {
			Point* obstacle = new Point(i, j);
			if (*obstacle != start && *obstacle != end) {
				obstacle_vector.push_back(obstacle);
			}
			else { delete obstacle; }
		}
	}

	std::random_device rd;
	std::mt19937 g(rd());
	std::shuffle(obstacle_vector.begin(), obstacle_vector.end(), rd);

	for (int i = 0; i < graph_user_para.obstacle_num; i++) {
		obstacle.push_back(obstacle_vector[0]);
		obstacle_vector.erase(obstacle_vector.begin());
	}

}

可以看到在第一个二重循环里面是在堆里面申请Point的内存,然后返回指向内存的指针,并且将指针塞进obstacle_vector里面,将所有坐标点(起点,终点除外)都申请了内存之后就得到了指向内存的指针的完整的obstacle_vector了。如果遇到了起点(start)或者终点(end),我们需要回收堆里面申请的内存,这点不能忘记了。

之后将obstacle_vector进行打乱顺序,写法如上所示,简单3句语句即可。打乱之后的操作就是按照顺序取出obstacle_vector中特定数量的内存指针放到obstacle里面去,将其做为最终的障碍点坐标集合。

std::vector<Point*> Graph::get_obstacle()
{
	return obstacle;
}

既然在算法开始之前申请了堆内的内存,那么在类的析构函数就需要回收申请的内存,避免内存溢出,养成良好习惯,从当下开始。

Graph::~Graph()
{
	for (int i = 0; i < obstacle_vector.size(); i++) {
		delete obstacle_vector[i];
		obstacle_vector.erase(obstacle_vector.begin());
	}


	for (int i = 0; i < obstacle.size(); i++) {
		obstacle.erase(obstacle.begin());
	}
}

坐标点传递

我在Graph里面生成障碍点的坐标,然后在A_star类里面进行算法的实现,所以就需要将Graph里面的障碍点坐标传到A_star类的函数里面去,那么这个是如何实现的呢?

我是将Graph类的obstacle直接传到了A_star类里面,因为obstacle里面存放的是指针,所以传递起来比较方便的,又因为是指针,所以要用的时候直接索引obstacle的里的指针就可以得到堆内的内存,也就是点的坐标。

void A_star::set_start_end_obs_map(Graph& user_graph)
{
	start = user_graph.get_start();
	end = user_graph.get_end();
	obstacleset = user_graph.get_obstacle();
	user_trajectory = user_graph.get_userPara();

	for (int i = 0; i <= user_trajectory.map_x; i++) {
		for (int j = 0; j <= user_trajectory.map_y; j++) {
			user_trajectory.map[i][j] = PATH;
		}
	}

	user_trajectory.map[start.x][start.y] = START;
	user_trajectory.map[end.x][end.y] = END;

	start.Gn = 0;
	start.Fn = start.Gn + calcu_Hn(start);

	for (int i = 0; i < obstacleset.size(); i++) {
		user_trajectory.map[obstacleset[i]->x][obstacleset[i]->y] = OBSTACLE;
	}

}

以上是关于[Astar_algorithm03]随机障碍点生成以及坐标点传递方法的主要内容,如果未能解决你的问题,请参考以下文章

[Astar_algorithm07]技术文档_Graph

[Astar_algorithm02]启发函数的比较

[Astar_algorithm05]技术文档_A_star

[Astar_algorithm01]A*算法伪代码以及思路

[Astar_algorithm06]技术文档_A_star

我想在给定区域的随机位置生成敌人。我不想让我的敌人随机出现在障碍物顶部等任何地方