对Dijkstra算法原理的一些理解

Dijkstra算法是经典的最小路径求解算法,本文主要谈谈我对Dijkstra算法原理的理解。重点是对算法迭代过程的合理性做简要阐述,并不是严格的证明。

关于算法的具体过程这里不再赘述。举个例子,假如研究对象是一个无向的加权图,由OABCDEFG八个节点和它们之间的加权边构成。Dijkstra算法的目的在于找到从O点开始到其他各点的最短路径。

Dijkstra算法中,首先需要构造一个数组用于保存O点到其余各点的路径长度:


用其余各点和O点间边的权值来初始化该数组,如果其余节点与O点之间没有相连的边,则路径长度为∞,如果是写代码,一般可以用一个较大的数代替。O点是第一个选定的节点,所谓选定的节点就是已经确定最短路径的节点(在图中用红色表示),其余的都是候选节点。然后进入迭代过程,每一次迭代会对所有候选节点对应的路径长度进行更新,然后选出路径最短的候选节点作为新的选定节点,其路径就是相应的最短路径。依次迭代,直到所有的候选节点都被选定。

以下图为例:

对Dijkstra算法原理的一些理解_第1张图片

注意,图中的节点间的连线不代表两节点间的实际连接,只是代表它们之间的连通关系(可能存在中间节点)。经过三次迭代之后,依次选定了ABC三个节点。然后进行第四次迭代,更新DODDOEDOFDOG。假设DOD是最小值,那么将节点D作为第四个选定的节点,O到D的最短路径为DOD。具体的更新过程如下:

DOD=min(DODDOC+dCD)=min(dODDOA+dADDOB+dBDDOC+dCD);

DOE=min(DOEDOC+dCE)=min(dOEDOA+dAEDOB+dBEDOC+dCE);

DOF=min(DOFDOC+dCF)=min(dOFDOA+dAFDOB+dBFDOC+dCF);

DOG=min(DOGDOC+dCG)=min(dOGDOA+dAGDOB+dBGDOC+dCG);

DOD<DOEDOFDOG

其中,D代表节点间的路径长度(存在中间节点),d代表节点间边的权值(不存在中间节点)。

下面我们来说明,为什么满足上面的条件后,D点肯定是下一个选定的节点,也就是为什么更新后的DOD就是O到D最短路径长度。

如果我们假设DOD不是O到D的最短路径长度,也就是说最短路径的前驱节点不在选定节点(O、A、B、C)当中。那么,列出O到D的最短路径的节点序列,肯定满足这样的情况:一串选定节点+一串候选节点+D节点(根据Dijkstra算法的详细过程自行脑补)。为方便说明,假设选定节点序列为OBA(说明DOBA=DOA),候选节点序列为EFG(说明DOBAE=DOE),那么O到D的最短路径的节点序列为:OBAEFGD,且DOBAEFGD<DOD。所以,DOE =DOBAE< DOBAEFGD<DOD,这显然与前面的条件矛盾。所以DOD肯定是O到D最短路径长度。

总结一下,我嘚啵嘚啵了那么久,就是要说明这样一个问题:如果第四次迭代后DOD最小,那么在O到D之间的最短路径中,D的前驱节点必然来自于已选定的节点(O、A、B、C)。为什么捏?因为如果你在D前面存在另一个候选节点E的话,可以证明,第四次迭代产生的DOE肯定要小于DODDOD就不会是最小的了。

你可能感兴趣的:(算法,数据结构)