2 DFS算法
DFS(深度优先搜索)算法,搜索过程是类似于不撞南墙不回头的意思,DFS一般使用堆栈(先入后出)这种数据结构实现,由此一来,以初始起点为中心进行搜索,首先是周围点加入到堆栈中,起始点搜索完毕后,需要从周围点选择一个点进行访问,然而由于先入后出的特点,导致周围点中最后一个进入堆栈的节点被访问。然而,新的节点也有周围点,这些周围点也会被推入堆栈,由此一来,起始点周围的点还未访问完毕,新的周围点又加入到其中,循环往复,使得搜索不断的朝着一个方向进行。我使用链表完成先入后出的操作
我所编写的代码的流程:
- 创建
OPEN
与CLOSED
列表,代表已访问的点以未访问的点 - 添加初始节点到
OPEN
中 - 判断
OPEN
列表是否为空,为空则结束搜索,未找到路径,(循环1)- 取出
OPEN
中最后面的点,记为cueent_node
,将其从OPEN
中删除,并添加到CLOSED
中 - 获取
current_node
周围点(子节点),并遍历(循环2)- 判断周围点是否在
CLOSED
中,在其中则continue
。 - 判断周围单是否在
OPEN
中,在其中则continue
。 - 到此步则说明该子节点是新节点,因此构建子节点与父节点之间关系,并直接将其添加到
OPEN
中 - 判断该子节点是否为终点,为终点则直接返回。
- 判断周围点是否在
- 取出
- 返回带有父节点信息的终点。
- 从终点遍历到起点,保存每个点,最终形成路径集合。
2.1 核心代码
地图类:
#ifndef MYMAP_H_
#define MYMAP_H_
#include <vector>
using std::vector;
namespace mymap {
class MyMap {
public:
// 构造函数
MyMap(){
};
MyMap(const int map_xlength, const int map_ylength);
// 设置平行与X轴的一排障碍物,[x_begin, x_end]
void SetObsLineX(const int x_begin, const int x_end, const int y);
// 设置平行与Y轴的一排障碍物,[y_begin, y_end]
void SetObsLineY(const int y_begin, const int y_end, const int x);
// 获取(x, y)处的地图状态,1为有障碍物,0为无障碍物
bool GetMapPointState(const int x, const int y) const;
// 获取成员变量接口
vector<vector<int>> map() const {
return map_; };
int map_xlength() const {
return map_xlength_; };
int map_ylength() const {
return map_ylength_; };
private:
vector<vector<int>> map_; // 地图矩阵
int map_xlength_; // 地图列数,长
int map_ylength_; // 地图行数,宽
int unfree = 1; // 地图点状态
int free = 0;
};
} // namespace mymap
#endif // MYMAP_H
#include "mymap.h"
namespace mymap {
// 构造函数,构建指定长宽的地图大小
MyMap::MyMap(const int map_xlength, const int map_ylength)
: map_xlength_(map_xlength), map_ylength_(map_ylength) {
map_.resize(map_ylength_);
for (auto &e : map_) {
e.resize(map_xlength_);
}
int x_scale = map_xlength_ / 5;
int y_scale = map_ylength_ /5;
SetObsLineX(0, map_xlength_ - 1, 0);
SetObsLineX(0, map_xlength_ - 1, map_ylength_ - 1);
SetObsLineY(0, map_ylength_ - 1, 0);
SetObsLineY(0, map_ylength_ - 1, map_xlength_ - 1);
SetObsLineX(x_scale, x_scale * 2, y_scale * 3);
SetObsLineX(x_scale * 3, x_scale * 4, y_scale * 2);
SetObsLineX(0, x_scale, y_scale * 2);
SetObsLineX(x_scale * 4, x_scale * 5, y_scale * 3);
SetObsLineY(0, y_scale * 3, x_scale * 2);