最短路径——迪杰斯特拉算法 学习笔记

迪杰斯特拉算法学习笔记
 
迪杰斯特拉算法用于求解最短路径问题,具体地说是求解一个有向图(或无向图,无向图是有向图的一个特例)中一个点到其余各点的最短路径,既然是求解最短路径问题,自然这里所描述的图的边都是具有权值的。比如我们可以用这个算法计算复杂的网络中一个节点到另外一个节点的最短路径,网络不单指因特网,也可以是交通网络或者其他什么的,同理路径未必就是以km或m什么的为单位进行衡量,也可以是时间、金钱或者其他什么概念。
 
算法叙述:
一个图G表示为点和边的集合,假设图G的点集为I,边集为E,那么G={I,E},要求解I中一个点o到I中除了o点之外所有点的最短路径,首先把I进行划分,把I中除了o以外的所有节点划为一个周边点集合P,并称o为原点,我们制作一个点的集合S,它用来存放节点x,x是这样的一些节点,o到x(o—……—x)的最短距离已经为算法求得,自然在算法开始之前S是个空集合。
还有一个值得注意的概念,E中有多少条边呢,我们通常可能会觉得E中的边数是可变的,但实际上我们可以求得E中的变数,我们假设Num(I)是I中点的个数,那么E中边的个数Num(E)就是Num(I)的平方,因为在实现算法的时候我们认为那些彼此之间没有边相连接的点它们变得权值为无穷大。根据上面的描述可知原点o可以“直接到达”P中的每一个点x,只不过距离某些x太过“遥远”,这个距离在概念上是无穷大。
 
下面对算法描述:
算法目的:求解原点o到任一周边点x的最短路径。
算法步骤:
1)  找到o到P中各点的最小值,经过查找o—x最小;
2)  找S中第一个点s0到集合P中所有点的最短距离,经过查找s0—px0最小,那么我们找S中第二个点s1集合P中所有点的最短距离,经过查找s1—px1最小,如此下去,直至我们找到了集合S中最后一个元素sn到P中所有点最短距离sn—pxm,这时我们需要找到o—s0—px0, o—s1—px1……o—sn—pxm中最短的一个o—si—pxj;
3)  比较o—x,o—si—pxj两条路径,如果前者更小则将x从P中剔除掉并纳入S中,如果后者更小则将pxj从P中剔除掉并纳入到S中,假设纳入到S中这个点位y,记录o—y的最小值,共以后计算使用;
4)  这一步我们要判断P是否为空集,如果P为空集算法结束,如果P中还有元素,重复上边三步。
 
算法会执行到P为空集时退出,P为空集表示S=I-{o};在上面的描述过程中得知,o到S中的元素的最短距离已被算法求得,到这时S中具有了除o以外点集I中的所有元素,所以o到图中任一一点的距离均已求得。
 
那么为什么最短距离是o—x或者o—si—pxj,而不会是o—pxi—pxj这样的形式呢,因为如果有这么一条路径的话,那么o—pxi一定小于o—pxi—pxj,就是说o—pxi才是真正的最短路径,而不会是o—pxi—pxj,而o—pxi所表示的意思不正是和o—x相同的吗?
 
这是毕业后在遇到OSPF(一个路由算法)时突然想起当初学习迪杰斯特拉时,颇有感悟,所以写了这个学习笔记,本是借此弥补大学没有努力学习的遗憾,后来无意中发现有人转载了此文,不胜羞愧,遂整理一番。

      

你可能感兴趣的:(@语言)