一. 图的基础
(1) 图的结构:
(2) 图的要素:
图 = 顶点(vertex) + 边(edge) + 权重(weight) + 度 (degree)
G(V, E, W, D)
- 度:与这个顶点相连接的边的数目。
- 入度:有向图中,指向该顶点的边。
- 出度:有向图中,从该顶点出发,指向其他顶点的边。
(3) 图的分类:
有向无向
有权无权
(4) 图的表示:
4.1 图的表示方法一:邻接表
引申:
应用:?
4.2 图的表示方法二:邻接矩阵
4.3 图的稠密稀疏判定
表示方法 | 空间、时间复杂度 | 是否能表示方向 | 能否直接表示权重 | 选取原则 | 一般性原则 | 稀疏稠密判定 |
---|---|---|---|---|---|---|
邻接表 | O(V+E) | 是 | 不能直接表示,改动后可以 | 适合表示稀疏图 | 同一个节点的边的个数小于10.均使用邻接表处理。 | ! ( V << E ) |
邻接矩阵 | O(V^2) | 是 | 能 | 适合表示稠密图 | V << E 接近完全图 |
【例1】图的表示方法实例:
Graph | testG.txt |
---|---|
|
|
邻接表 | 邻接矩阵 |
|
|
二. 图搜索基础:
2.1 深度优先搜索(DFS)
(1)DFS过程
0 | 1 | 2 |
---|---|---|
|
|
|
3 | 4 | 5 |
|
|
|
6 | 7 | 8 |
|
|
|
9 | 10 | |
|
|
(2) DFS代码:
|
【例2】DFS应用实例
2.2 广度优先搜索(BFS)----无权图单源最短路径问题
(1)BFS过程:
0 | 1 | 2 |
---|---|---|
3 | 4 | 5 |
6 | 7 | 8 |
9 | 10 | |
BFS输出了无权图的从起点到任意点的最短路径。 |
(2)BFS代码:
|
【例3】BFS应用实例----无权图最短路径算法
局限性:不能处理带权图
2.3 图搜索算法基本框架
/***********************************************************************************************************
1 维持一个容器,该容器中存放需要访问的顶点;
2. 首先用起始顶点Xs来初始化该容器;
3. LOOP:
3.1 依据预先设定好的Score Function,从容器中弹出一个顶点; (Remove)
3.2 根据该顶点,去拓展它的邻居; (Expansion)
3.3 将该顶点的邻居装进容器中; (Push)
4. END LOOP;
*************************************************************************/
【总结与反思】
DFS : 维护一个stack,优先弹出最先进入的顶点;
BFS : 维护一个queue,优先弹出层级最浅的顶点,但是只能用于求无权图的最短路径算法;
三.图搜索算法进阶:
与无权图相比,带权图的最短路径与顶点个数无关,与权值之和相关:
2.1 Dijkstra:----带权图单源最短路径问题----路径规划问题
(1)算法过程:
0 | 1 | 2 |
---|---|---|
3 | 4 | 5 |
6 | 7 | 8 |
(2)算法伪代码
/***********************************************************************************************************
1 维持一个优先级队列用来存放将要扩展的顶点;
2. 首先用起始顶点Xs来初始化该容器;
3.假设 g(Xs) = 0 and g(n) = 无穷大
4. LOOP:
4.1 if priority queue is empty
return false
break
4.2 remove mode "n" with the lowest g(n) from the priority queue ( Remove )
4.3 if the node "n" is the goal
return true
break
4.4 for all unexpanded nerghbors "m" of "n" ( Expansion )
if g(m) = 无穷大;
g(m) = g(n) + Cnm;
push m into the queue; ( Push )
if g(m) > g(n) + Cnm;
g(m)=g(n) + Cnm;
4.5 end
5. END LOOP;
*************************************************************************/
【例4】Dijkstra应用实例
【总结与反思】
Dijkstra 算法可以求解带权图的最短路径,但是该算法没有方向性,从起点开始,一层一层,向外盲目穷举,直到到达终点为止或者遍历结束为止。
如何引入方向性?---- 启发式搜索方式
2.2 贪心搜索算法:
heuristic:指的是人为定义的一种启发式策略,在下图中,我们可以定义当前节点距离与终点的欧氏距离或者曼哈顿距离为启发函数,每次弹出距离终点最短的节点,以该策略作为拓展节点的规则,如下所示:
在无障碍的环境下的效果演示:
在有障碍物的地图下的效果演示:
【总结与反思】
算法 | 优点 | 缺点 |
---|---|---|
BFS | 无权图最短路径 全局最优 | 无方向性,层序扩展 |
Dijkstra | 有权图最短路径 全局最优 | 无方向性,层序扩展 |
geedy best search | 有方向性 | 容易陷入局部最优 |
能否将二者进行结合?
2.3 A star算法:
(1) 算法思路:
A star = Dijkstra + Heuristic
- 维护一个从起点到当前节点的cost的累计情况:g(n)
- 通过启发函数,维护一个从当前节点到终点的估计值:h(n)
- 计算 f(n) = g(n) + h(n), 以f(n)的大小作为优先级队列的排序依据
- 从容器中弹出节点时,每次弹出f(n)最小的节点
(2)算法伪代码:
/***********************************************************************************************************
1 维持一个优先级队列用来存放将要扩展的顶点;
2. 启发式函数,h(n)的计算方式是预先设定好的
3. 首先用起始顶点Xs来初始化该容器;
4.假设 g(Xs) = 0 and g(n) = 无穷大
5. LOOP:
5.1 if priority queue is empty
return false
break
5.2 remove mode "n" with the lowest f(n) = g(n) + h(n) from the priority queue ( Remove )
5.3 if the node "n" is the goal
return true
break
5.4 for all unexpanded nerghbors "m" of "n" ( Expansion )
if g(m) = 无穷大;
g(m) = g(n) + Cnm;
push m into the queue; ( Push )
if g(m) > g(n) + Cnm;
g(m)=g(n) + Cnm;
5.5 end
6. END LOOP;
*************************************************************************/
(3)算法的最优性保证
反例:
如图:
f(G) = 5+0 = 5
f(A) = 1+6 = 7
虽然实际花费 S→ A → G < S → G 但是由于启发函数设计不合理 ,算法仍然选择了下面这条路。
最优性保证: 启发函数估计的 h(n) 必须小于实际花费 h*(n)
h(n) < h*(n)
上图的 情形,下面的几种 h(n) 是否满足最优性:
1 欧式距离
2 曼哈顿距离
3 无穷范数
4 0
【总结与反思】
(1)
最优? 最快?
如果算法稍微丧失最优性,但是速度却可以获得几十倍的提升的话,我们需要在最优与最快之间做权衡:
WeightedA* f(n) = g(n) + alpha * h(n) (最优性换取速度)
alpha = 0 Dijkstra
alpha = 1 A*
alpha = 无穷 贪心算法
特点:
1) 最优性换取速度
2) 花费大于最优情况下的花费
3) 速度比A×快
公式 | f (n) = a*g(n) + b*h(n) | ||||
---|---|---|---|---|---|
效果 |
| ||||
a | 0 | 1 | 1 | 1 | |
b | 1 | 1 | >1 | 0 | |
算法 | Greedy | A* | WeightA* | Dijkstra |
下面的链接中可以设置参数观看各种算法的情况
http://qiao.github.io/PathFinding.js/visual/
(2)最优启发式函数的选取
闭式解直接求最优h*(n)的条件:
结构化地图+固定移动方式
上图 h*(n) 可以直接求得。
2.4 拓展
- WeightA*
-
JPS算法
- D*
参考文献
【1】https://www.cnblogs.com/xuuold/p/10366834.html
【2】https://www.zhihu.com/search?type=content&q=Astar%E7%AE%97%E6%B3%95
【4】深蓝学院《移动机器人路径规划》
【5】liuyunbobobo老师《算法与数据结构》
【6】http://qiao.github.io/PathFinding.js/visual/