-
file: A_star.h
-
brief:A_star类用法的注意事项
-
author:AIplusX
-
version:beta_v0.0
-
date:2021_11_15
-
update:2021_11_15
-
warning:offset_x和offset_y数组的大小有2种形式,大小分别是4和8,分别对应宏定义的曼哈顿距离和欧几里得距离,因为曼哈顿距离只走4个格子,而欧几里得距离要走8个格子,所以在显示算法的时候env_nums要进行更改(曼哈顿距离是4,欧几里得距离是8)。在记录探索和轨迹路径的时候,作者是在堆里面申请的内存,所以vector里面存的都是指针,指向堆里的内存
-
todo:无
#pragma once
#include "Graph.h"
#include <vector>
//#define Manhattan_Distance 0
#define Euclidean_Distance 1
#define MIN(x,y) ((x) >= (y) ? (y) : (x))
class Graph;
class A_star
{
public:
A_star() {};
~A_star();
void Astar_algorithm();
bool judge_env_legal(const Point&);
int calcu_Hn(const Point&);
int calcu_Gn(const Point&);
int calcu_cost(const Point&, const Point&);
void set_start_end_obs_map(Graph&);
void add_openset(Point* p) { openset.push_back(p); };
void add_fatherset(Point* p) { fatherset.push_back(p); };
void delete_openset(const int& idx) {openset.erase(openset.begin() + idx);};
void search_env_block(Point*);
void calcu_type_selection(int&, const int&, const int&);
void show_para_below(Point*);
bool is_alread_set(std::vector<Point*>&, Point*);
void get_trajectory(const Point*);
UserPara get_astar_userpara();
Point* find_min_Fn(int& idx);
private:
int cross_cost = 14;
int plane_cost = 10;
std::vector<Point*> openset;
std::vector<Point*> fatherset;
//std::vector<Point*> trajectory;
std::vector<Point*> obstacleset;
Point start;
Point end;
UserPara user_trajectory;
const int env_nums = 8;
//int offset_x[4] = {0, 1, 0, -1};
//int offset_y[4] = {-1, 0, 1, 0};
int offset_x[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
int offset_y[8] = { -1, -1, -1, 0, 1, 1, 1, 0};
};
-
file:A_star.cpp
-
brief:以下函数顺序就是文件内函数的存储顺序。
-
author:AIplusX
-
param[in|out] 输入:vector和待查找元素 | 输出:布尔值(true或者false)
-
return 找到了返回true,没找到返回false
-
exception 无
-
note:
-
这是个基于模板实现的函数,功能是在vector里面找寻是否有相同的元素
-
remarks:可以进行改进,注意在查找的时候是比对vector元素和被查找元素的是否一样,如果改成指针向量的话,注意要对比指针所指内存的元素和被查找元素是否相同,不要进行指针的对比
#include "A_star.h"
#include <math.h>
#include <limits>
template <typename T>
const bool vector_contain(std::vector<T>& Vec, const T& Element)
{
if (std::find(Vec.begin(), Vec.end(), Element) != Vec.end())
return true;
return false;
}
-
file:A_star.cpp
-
brief:析构函数
-
author:AIplusX
-
param[in|out] 输入:无 | 输出:无
-
return:无
-
exception:无
-
note:
-
析构函数里面释放掉堆里的内存,这里释放了openset和fatherset向量里指针所指的内存,障碍物的内存在Graph类的析构函数里进行了回收
-
remarks:无
A_star::~A_star()
{
for (int i = 0; i < openset.size(); i++) {
delete openset[i];
openset.erase(openset.begin());
}
for (int i = 0; i < fatherset.size(); i++) {
delete fatherset[i];
fatherset.erase(fatherset.begin());
}
}
-
file:A_star.cpp
-
brief:从Graph类的对象获取起点,终点坐标,障碍物坐标点向量,用户参数的结构体
-
author:AIplusX
-
param[in|out]:输入:Graph类对象 | 输出:无
-
return:无
-
exception:无
-
note:
-
从Graph类的对象获取起点,终点坐标,障碍物坐标点向量,用户参数的结构体,然后修改用户参数结构体里的二维数组相应内容,修改成可走路径,障碍物,起点终点
-
remarks:注意要在这里面初始化起点的G和F
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;
}
}
-
file:A_star.cpp
-
brief:A*算法的主体
-
author:AIplusX
-
param[in|out]:输入:无 | 输出:无
-
return:无
-
exception:无
-
note:
-
利用openset和fatherset进行更新待搜索向量和父节点向量,算法运行可视化是通过Graph的静态函数实现的,算法运行的基本循环逻辑是:找到最小F节点->在该节点附近开始探索->找到局部最优点->存到父节点向量->从openset中删除->更改map内容
-
remarks:注意节点信息都是存在堆里的,栈里只存了指向堆的指针向量
void A_star::Astar_algorithm()
{
int min_Fn_idx(0);
Point* min_Fn_p = new Point(start.x, start.y);
memcpy(min_Fn_p, &start, sizeof(start));
add_openset(min_Fn_p);
while (!openset.empty()) {
Graph::show_map(user_trajectory);
min_Fn_p = find_min_Fn(min_Fn_idx);
show_para_below(min_Fn_p);
if (*min_Fn_p == end) { break; }
search_env_block(min_Fn_p);
add_fatherset(min_Fn_p);
delete_openset(min_Fn_idx);
user_trajectory.map[min_Fn_p->x][min_Fn_p->y] = PASS_SEARCH;
}
get_trajectory(min_Fn_p);
}
-
file:A_star.cpp
-
brief:获取最终轨迹(黄色方块)
-
author:AIplusX
-
param[in|out]:输入:终点内存的指针 | 输出:无
-
return:无
-
exception:无
-
note:
-
获取最终的路径
-
remarks:注意要返回堆中终点内存的地址,因为之前在set_start_end_obs_map也获取了起点和终点信息,但是那是存在栈里的,没有指向前一个方块的指针信息,所以不能用,一定是要返回堆中终点内存的地址
void A_star::get_trajectory(const Point* p)
{
p = p->pre_point;
while (p != nullptr) {
user_trajectory.map[p->x][p->y] = GENERATE;
p = p->pre_point;
}
user_trajectory.map[start.x][start.y] = START;
user_trajectory.map[end.x][end.y] = END;
Graph::show_map(user_trajectory);
}
-
file:A_star.cpp
-
brief:可视化界面下方显示坐标参数
-
author:AIplusX
-
param[in|out]:输入:堆中内存的地址 | 输出:无
-
return:无
-
exception:无
-
note:
-
可视化界面下方显示坐标参数
-
remarks:无
void A_star::show_para_below(Point* p)
{
wchar_t s1[5];
_stprintf_s(s1, _T("(%d,"), p->x);
outtextxy(0, 480, s1);
wchar_t s2[5];
_stprintf_s(s2, _T("%d)"), p->y);
outtextxy(50, 480, s2);
}
评论(0)
您还未登录,请登录后发表或查看评论