Dijkstra算法的思想和数学归纳法

ospf协议很多人都知道,很多人也会配置而且很熟练,但是很少有人懂得其背后的思想是什么,Dijkstra算法是求解单源最短路径的绝妙算法之一,我打心眼里头喜欢这个算法,真想把之一去掉。Dijkstra算法是一种贪心算法,贪心算法的本质就是最值的和还是最值,也就是说人们相信我只要在点滴当中尽自己最大的努力,那么最后的结果就是最好的,可能你会说不一定,但是你敢说如果有一个环节你没有尽最大的努力,最后的结果会更好吗?你不能,我也不能,因为现实总是很残酷,事后诸葛亮只能出现在理想状态,事情已经发生,那么你就不能说更好的结果需要什么条件,正所谓“证明一件事是错的很容易,但是证明一件事正确根本不可能!”,因此贪心算法的证明非常复杂,可是Dijkstra算法确实是正确的,为什么?不是因为它不是纯粹的贪心算法,正是因为它的条件里面存在的信息很少,我们可以利用另一把利器来证明之,这把利器就是“数学归纳法”。

数学归纳法是一种艺术,玩过多米诺骨牌的都知道,要使得任意数量的所有牌全部翻掉需要两个条件而且只需要两个条件,一个就是任意两张牌间隔足够近,另一个条件就是你必须推到第一张牌,就是这么简单。于是如果你往这个游戏靠拢你会发现,牌的倒掉和牌的数量以及牌上的内容没有任何关系,那么任何可以归结到这个游戏的数学模型都可以用这个原理进行求解,多米诺骨牌游戏的数学模型就是数学归纳法,数学归纳法进行的证明需要两点,第一就是初始条件(推到第一张牌),第二就是假设n成立证明n+1成立(两张牌间隔足够近),贪心算法是一个步骤问题,如果我们可以证明贪心算法的第一部很显然正确并且在归纳假设的情况下证明归纳假设的系一个步骤也正确的话,那么贪心算法的局部最优解结合成的全局解一定是全局最优解,这是一定的。

Dijkstra算法是一个贪心算法,那么我们可以通过数学归纳法证明其正确性,关键就是如何建立数学模型。Dijkstra算法的步骤是显然的,是简单的,我们只需要证明这个算法产生的路径就是最短的就可以了,于是模型就有了,很多书上都用open-set作为“外面”的点,将close-set作为加入到“里面”的点,那么我们就证明每通过Dijkstra算法加入到close-set的点到原点的距离就是到原点距离的最短距离,这样我们就证明了算法本身的正确性,因此开始用数学归纳法证明吧,当close-set中除了原点只有一个点的时候,这个点p离原点s的距离一定是最短的,因为如果s先到x再到p的距离比s直接到p还短,那么s到x会更短,算法就不会选中p而会选中x,与假设矛盾,这里已经证明了初始条件,下面开始归纳假设,设close-set中有k个点时,所有close-set中的k个点根据算法算出的距离都是最短的距离,那么我们考虑加入第k+1个点加入时的情形,只要能证明k+1个点按照算法加入进close-set从而算出的距离也是最短距离的话,那么问题得证,这个问题也是很好证明的,同样用反证法,假设不是靠算法加入的,那么路径中一定除了终点p之外还有一个点在open-set中,如果这样的话,根本就不可选中终点p而会选中那个经过的点,也是矛盾的,由此问题得证。在上面额证明中,所有在close-set中和p相连的点都会参与最后的最短距离竞争,因此就在它们当中选一条路径最为结果就是问题的答案,而这正是算法的行为。

这里可以看到有时候贪心算法可以用数学归纳法来证明,但是有的时候不能,不能的原因就在于约束条件太多,要么就是因为初始条件无法被证明但是归纳假设却正确,其实千万不要过度怀疑贪心算法,我们人做事的时候不是也都是在用贪心算法吗?如果有谁在做事之前来个全局证明或者必须证明其严密性的话,那么这个人最终会因为理智过度要么被社会淘汰,要么成为划时代的思想家。贪心算法来自于一个事实,那就是爆炸,爆炸波的包络面总是呈球面向外扩撒,球面刚接触到一个点的时候,这个点到爆炸源的距离肯定最短,这不是废话吗?这个点到爆炸源的连线不是一条线段吗?很多的时候是一条线段,但是考虑到爆炸不是在一个密度相同的没有障碍物的地方,而是在一个建筑物里面,该建筑物内部有复杂的小隔间,而且各个隔间相通,隔间之间是坚固的钢板隔开,爆炸无法摧毁这些隔板,那么爆炸波的包络面虽然是球面,但是实际路线却不是线段,而是沿着各个隔间之间的通道走的,这个时候首先被波及的点沿着爆炸波的路线回到爆炸点,路线肯定是最短的,这是事实啊,好事怎么也波及不到我们,坏事总是用最快的是速度到来。

有时候觉得人做事很多时候挺像计算机的,用了很多的算法,按经验步骤进行,不求甚解,而我们从小学开始学的那些数学,比如解方程,函数求导之类的却是纯思维的东西,这些一般来用发掘新的算法,人的算法还来自于经验,但是到底哪个更重要呢?

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

原文地址:https://www.cnblogs.com/ksiwnhiwhs/p/10389109.html

时间: 2024-10-06 03:23:00

Dijkstra算法的思想和数学归纳法的相关文章

最短路-Floyd算法和Dijkstra算法

两者在负权问题上不是很好,最好只处理正值 Dijkstra算法的话,为了方便,我认为从i到i点不可达:百部百科解释挺好,那个堆优化挺好的 Floyd算法百部百科也不错,都是老算法了,哪都有资料 博客园这位筒子的写得很好 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html Mathematica下的代码[我也觉得mathematica写很诡异...] (*Dijkstra算法,其思想和Prim有点像,输出的是每个点的

dijkstra算法模板_HDU3790

问题描述:  有n个点,m个边,每条边上有一个权值,求从s节点到e节点的最短路径,即途径路上的权值和为最小. 是求单起点,多终点最短路的问题. dijkstra算法基本思想 1:设置一个distanse数组,存储从起始点s到各个节点的距离(权值和),distanse[i]即从s到i的最短路 2:初始状态,distanse[i]=mp[s][i],found[s]=1 3:每次从所有 1未访问的节点中  挑出 2distanse最小的点k  choose() 进行松弛操作: 4:松弛操作.如果经过

单源点最短路径的Dijkstra算法

在带权图(网)里,点A到点B所有路径中边的权值之和为最短的那一条路径,称为A,B两点之间的最短路径;并称路径上的第一个顶点为源点(Source),最后一个顶点为终点(Destination).在无权图中,最短路径则是两点之间经历的边数最少的路径.实际上,只要把无权图上的每条边都看成是权值为1的边,那么无权图和带权图的最短路径是一致的. 给定一个带权有向图G=(V,E),指定图G中的某一个顶点的V为源点,求出从V到其他各顶点之间的最短路径,这个问题称为单源点最短路径问题. 迪杰斯特拉(Dijkst

(转)图算法单源最短路径Dijkstra算法(邻接表/邻接矩阵+优先队列STL)

一.前言 最短路径算法,顾名思义就是求解某点到某点的最短的距离.消耗.费用等等,有各种各样的描述,在地图上看,可以说是图上一个地点到达另外一个地点的最短的距离.比方说,我们把地图上的每一个城市想象成一个点,从一个城市到另一个城市的花费是不一样的.现在我们要从上海去往北京,需要考虑的是找到一条路线,使得从上海到北京的花费最小.有人可能首先会想到,飞机直达啊,这当然是时间消耗最小的方法,但是考虑到费用的高昂,这条线路甚至还不如上海到北京的高铁可取.更有甚者,假设国家开通了从上海到西藏,再从西藏到兰州

dijkstra算法:寻找到全图各点的最短路径

dijkstra算法介绍:即迪杰斯特拉算法,是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止,是一种广度优先的搜索方法. dijkstra算法原理:最优子路径存在.假设从S→E存在一条最短路径SE,且该路径经过点A,那么可以确定SA子路径一定是S→A的最短路径.证明:反证法.如果子路径SA不是最短的,那么就必然存在一条更短的'SA,从而SE路径也就不是最短,与原假设矛盾. dijkstra算法缺点:与此前

数学建模法-Dijkstra算法

一.引言 哈喽大家好,今天要讲的是图论中的一个经典的算法.是一种叫Dijkstra算法的东东.这个算法是干什么用的呢.首先大家先看下面这幅图: 这个东西是什么呢.我们可以这样理解,假如A到F表示6个地点.那些连接线就是道路.连接线上的数字就是两个地点间的距离.这样讲是不是很直观呢.好了,假如博主家在A点,博主的女神家在F点,有一天博主想去女神家,就有很多条路线可以走.可是博主很懒诶,肯定就想走最短的路线.那么,怎么才能很快的就求解出最短的路线呢.Dijkstra算法就是用来解决这样的问题的. 二

算法导论——最短路径Dijkstra算法

package org.loda.graph; import org.loda.structure.IndexMinQ; import org.loda.structure.Stack; import org.loda.util.In; /** * * @ClassName: Dijkstra * @Description: Dijkstra最短路径算法--贪心算法 * @author minjun * @date 2015年5月27日 下午4:49:27 * */ public class D

Dijkstra算法求单源最短路径

1.最短路径 在一个连通图中,从一个顶点到另一个顶点间可能存在多条路径,而每条路径的边数并不一定相同.如果是一个带权图,那么路径长度为路径上各边的权值的总和.两个顶点间路径长度最短的那条路径称为两个顶点间的最短路径,其路径长度称为最短路径长度. 最短路径在实际中有重要的应用价值.如用顶点表示城市,边表示两城市之间的道路,边上的权值表示两城市之间的距离.那么城市A到城市B连通的情况下,哪条路径距离最短呢,这样的问题可以归结为最短路径问题. 求最短路径常见的算法有Dijkstra算法和Floyd算法

658 - It's not a Bug, it's a Feature! (Dijkstra算法)

今天第一次系统的学习了一下最短路算法,开始刷第十一章,第一次写Dijkstra算法,出现了很多喜闻乐见的错误..而且uva上样例很水,瓢虫也很水 ,坑了我好久. 首先是对于结点的处理,我们必须要维护一个二元组,一个表示结点一个表示当前结点最短路.   因为Dijkstra算法利用了优先队列来加速算法,所以需要定义小于运算符,一开始我直接将状态装进了优先队列,显然是不对的,因为优先队列的作用就是取出当前距离最短的结点. 其次,说说最短路算法蕴含的巧妙思想: 每次从当前所有还未标记的结点中选择一个距