算法-从动态规划到贪心算法,Bellman-Ford和Dijkstra算法求解最短路

对于Dijkstra这个神奇的算法,作者从本科学数据结构开始就觉得很奇妙。每次看都感觉这算法很精巧,但是看完就忘了。直到现在系统学习算法之后才明白总是遗忘它的真正原因,那就是没有从本质上去理解它。这篇文章就最短路问题,系统总结一下从Bellman-Ford到Dijkstra算法的思路。也就这个问题阐述一下动态规划和贪心算法的关系,泛化此类问题。

本文按照模型、理论、算法的思路展开。

问题描述

现有一有向带权图G(V,E),试求解从起点s到终点x的最短路径。实例如图:
算法-从动态规划到贪心算法,Bellman-Ford和Dijkstra算法求解最短路_第1张图片

此为模型。

动态规划

从直观角度看,这是一个最优子结构之间相互依赖,需要进行枚举得到最优解的问题。换言之,动态规划问题。对于指定的终点,我们知道,最优解必定要经过指向它的弧。因此,最优解可以用下式表达:(此处u为起点,v为终点,总共有k条边。最长可能路径是k条边都经过。)
这里写图片描述
此为理论。

Bellman-Ford算法可以写成如下形式:
算法-从动态规划到贪心算法,Bellman-Ford和Dijkstra算法求解最短路_第2张图片
这种方法实质上遍历了所有的可能解,在每一个子节点处都进行了最优化计算,复杂度为O(mn)。

贪心算法

贪心算法不同于动态规划,或说优于动态规划的一点即在于,找到了某种贪心规则,使得每一步的决策可以被确定下来,不需要递归到最深处才得到结论。若用sub-problem graph的形式描述,见下图:
算法-从动态规划到贪心算法,Bellman-Ford和Dijkstra算法求解最短路_第3张图片
动态规划需要在画出整棵完整的树后,才能得到目标值并得出最优解。也即对于每一个结点,它的子问题都需要求解,均不可被舍弃。在图中的含义就是每一个孩子结点往下的树都要保留,从而带来了庞大的计算代价。而贪心是在观察问题后得出某种可以被证明的规则,使得每一层树向下生长时,只有一个结点被保留。换言之,多步决策中的每一步都是确定的。这样一来,树许多枝叶被剪去,计算复杂度大大降低。

回到最短路问题。要想使多步决策每一步可以确定,我们需要在实例中得到一个逐渐增长的确定性集合。在最短路问题中,即得到最短路确定的顶点集。

算法-从动态规划到贪心算法,Bellman-Ford和Dijkstra算法求解最短路_第4张图片

以上图实例说明。我们从最简单的情形出发。可以确定,从s点出发,若终点为s点时,路径即为s->s,距离为0。由此,确定性集合中有一个元素,即S={s}。

接下来我们思考一下,什么样的点它到达s的最短路已经可以确定了呢?对于一个逐步生长的确定性集合,我们目前能够考虑的范围仅有S中的点的出度。如图中所示,从s出发到达的点有u,x,v三者,权值分别为1,4,2。到这里我们可以首先猜测,从s出发到达u的最短路是可以被确定的,即s->u,权值为1。原因很简单,要从其它路径到达u的话,首先需要经过4或2的距离,到达x或v点,然后再寻求路径到达u点。无论之后的路径怎么样,因为绕开u已经花了4或2的代价,所以再走其它路势必花费更多的距离(这里用到了边权值均为非负数的前提)。明白这一点后,u点便可以加到确定性集合中,即S={s,u}。

总结一下上述贪心规则。对于一个确定性的集合,我们要并入一个新的顶点,即要观测在当前确定性集合可以到达的范围内,离起点最近的一个顶点。接下来便要证明这个贪心规则:(使用贪心规则最常用的证明方式,exchange argument,交换法)
算法-从动态规划到贪心算法,Bellman-Ford和Dijkstra算法求解最短路_第5张图片

得到贪心规则后,贪心的理论部分完成。

Dijkstra算法按照上述思路便可设计如下。其核心就是维护三个数据机构,分别是确定的顶点集S,到达各顶点的距离数组d(或队列等),和确定顶点集所经过的上一个点数组l(算法中未提及,但输出最短路时需要用到,感兴趣请翻阅严老师的数据结构书)。算法每次循环要做三件事,找出距离起点最小点并入确定集,更新其它点到达起点距离(每次循环只需算本次循环新并入的确定点出发到达的点即可),修正距离更新点的上一跳点。理解算法之后,3个数据结构,3个操作,循环至全部点确定,其实非常好记。
算法-从动态规划到贪心算法,Bellman-Ford和Dijkstra算法求解最短路_第6张图片

贪心算法相较DP,是好好观察了实例之后拟定一套完备的规则,从而减少了不必要的计算。从价值层面,这是一种灵感,也是算法设计者高明的体现。

不过,实际应用中,碍于算法设计者水平等原因,贪心规则往往是比较难总结出来的。关于这一点,老师在课堂上提及,可以用神经网络做贪心规则的有监督学习。他一度非常讨厌神经网络,认为可解释性太差,研究者必须审慎使用,甚至不用。然而后来转变了观念,因为对于计算机领域的某些问题,例如视觉方向的问题,也包括类似贪心规则这样涉及灵感的问题,人类往往没有足够的智慧去提取良好的特征或总结较好的规则。那么,“我们就用dirty的手段来对待dirty的问题”。上升到哲学层面的论断,余音绕梁。

参考文献

中国科学院大学 计算机算法设计与分析 卜东波老师 课件
http://bioinfo.ict.ac.cn/~dbu/AlgorithmCourses/CSB63009H/CSB63009H_2017.html

P.S. 若读者有国科大的计算机研究生,请一定选修卜老师的课,会受益良多。听过的人就会明白,他真的是一位 好、老、师。

你可能感兴趣的:(算法-从动态规划到贪心算法,Bellman-Ford和Dijkstra算法求解最短路)