有一天晚上,有四个人需要通过架在山谷间的危桥,任意时刻最多只能有两个人在桥上,过桥需要一盏闪光灯,这些人只有一盏闪光灯。如果单独过桥他们分别需要10、5、2、1分钟,如果两人同时过桥则所需时间是较慢者所需的时间。18分钟后,沿山谷滚滚而下的山洪将把这座桥冲毁。这四个人能及时过桥吗?不用图论知识,证明你的结论;并说明如何用图论知识获得答案。

证明:只有一只手电筒,并且过桥时必须要用到手电筒,唯一的办法就是让2个人一起过桥,然后让其中的一个在返回来送手电筒,从桥上走一来回的结果是可以让1个人通过.当2个人一起过桥时,总是最慢的1个人决定过桥的速度。把这几个人按照花费时间的由多到少编号为D,C,B,A.。D的10分钟肯定要花费,其他三人只能用7分钟,为了让时间最少,D和C肯定得一起过,并且回来的时候不能用C或D,所以

1. 一开始应该让A和B先过  2分钟;

2. 然后A回来,让C和D过去  1+10分钟;

3. B回来,A和B一起过去 2+2分钟。

总用时为:2+1+10+2+2=17分钟,即这四个人在18分钟内及时能过桥。

用图论知识,可以以4个人在桥两端的状态来作为节点来构造一个有向图,以已经过桥了的人的状态作为图的节点,初始时没有人过桥,所以以空表示,第一轮有两个人过桥,有6种可能的组合,(1,2)(1,5)(1,10)(2,5)(2,10)(5,10),从空的状态转换到这些状态的需要的时间分别为2,5,10,5,10,10分钟,时间就作为有向边的权值。当有两个人过桥后,需要一个人拿手电筒回去接其他人,这时有四种可能的情况,分别是1,2,5,10中的一人留在了河的对岸,(1,2)这种状态只能转换到(1)(2)两种状态,对应的边的权值分别为2,1分钟,(1,2)转换到(1)时也就是2返回了,返回需要耗时2分钟,以此类推可以建立图论模型。

要求出最少需要多长时间4人全部通过小桥实际上就是在图中求出(空)节点到(1,2,5,10)节点间的最短路径。最后可用Dijkstra算法求出最短路径。

Dijkstra算法是典型的最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等。

Dijkstra算法思想为:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径,就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

(1)初始时,S只包含源点,即S=,v的距离为0。U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边)或(若u不是v的出边邻接点)。

(2)从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。

(3)以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u(u U)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。

(4)重复步骤(2)和(3),直到所有顶点都包含在S中。

Dijkstra算法是由荷兰计算机科学家艾兹格·迪科斯彻发现的。算法解决的是有向图中最短路径问题。

举例来说,如果图中的顶点表示城市,而边上的权重表示著城市间开车行经的距离。 Dijkstra算法可以用来找到两个城市之间的最短路径。

Dijkstra算法的输入包含了一个有权重的有向图G,以及G中的一个来源顶点S。 我们以V表示G中所有顶点的集合。图中的每一个边,都是两个顶点所形成的有序元素对。(u,v)表示从顶点uv有路径相连。 假设E为所有边的集合,而边的权重则由权重函数wE → [0, ∞]定义。 因此,w(u,v)就是从顶点u到顶点v的非负花费值(cost)。 边的花费可以想像成两个顶点之间的距离。任两点间路径的花费值,就是该路径上所有边的花费值总和。 已知有V中有顶点st,Dijkstra算法可以找到st的最低花费路径(i.e. 最短路径)。 这个算法也可以在一个图中,找到从一个顶点s到任何其他顶点的最短路径。

算法描述

这个算法是通过为每个顶点v保留目前为止所找到的从s到v的最短路径来工作的。初始时,源点s的路径长度值被赋为0(d[s]=0), 同时把所有其他顶点的路径长度设为无穷大,即表示我们不知道任何通向这些顶点的路径(对于V中所有顶点vsd[v]= ∞)。当算法结束时,d[v]中储存的便是从sv的最短路径,或者是无穷大(如果路径不存在的话)。

Dijstra算法的基础操作是边的拓展:如果存在一条从uv的边,那么从s到v的最短路径可以通过将边(u,v)添加到s到u的尾部来拓展。这条路径的长度是d[u]+w(u,v)。如果这个值比目前已知的d[v]的值要小,我们可以用新值来替代当前d[v]中的值。拓展边的操作一直执行到所有的d[v]都代表从s到v最短路径的花费。这个算法经过适当的组织因而当d[u]达到它最终的值的时候,每条边(u,v)都只被拓展一次。

算法维护两个顶点集S和Q。集合S保留了我们已知的所有d[v]的值已经是最短路径的值顶点,而集合Q则保留其他所有顶点。集合S初始状态为空,而 后每一步都有一个顶点从Q移动到S。这个被选择的顶点是Q中拥有最小的d[u]值的顶点。当一个顶点u从Q中转移到了S中,算法对每条外接边(u,v)进 行拓展。

算法思想

设S为最短距离已确定的顶点集(看作红点集),V-S是最短距离尚未确定的顶点集(看作蓝点集)。
①初始化
     初始化时,只有源点s的最短距离是已知的(SD(s)=0),故红点集S={s},蓝点集为空。
②重复以下工作,按路径长度递增次序产生各顶点最短路径
     在当前蓝点集中选择一个最短距离最小的蓝点来扩充红点集,以保证按路径权重递增的次序来产生各顶点的最短路径。
     当蓝点集中仅剩下最短距离为∞的蓝点,或者所有蓝点已扩充到红点集时,s到所有顶点的最短路径就求出来了。
   注意:
     ①若从源点到蓝点的路径不存在,则可假设该蓝点的最短路径是一条长度为无穷大的虚拟路径。
     ②从源点s到终点v的最短路径简称为v的最短路径;s到v的最短路径长度简称为v的最短距离,并记为SD(v)。
(3)在蓝点集中选择一个最短距离最小的蓝点k来扩充红点集
     根据按长度递增序产生最短路径的思想,当前最短距离最小的蓝点k的最短路径是:
     源点,红点1,红点2,…,红点n,蓝点k
 距离为:源点到红点n最短距离+<红点n,蓝点k>边长
     为求解方便,设置一个向量D[0..n-1],对于每个蓝点v∈ V-S,用D[v]记录从源点s到达v且除v外中间不经过任何蓝点(若有中间点,则必为红点)的"最短"路径长度(简称估计距离)。
     若k是蓝点集中估计距离最小的顶点,则k的估计距离就是最短距离,即若D[k]=min{D[i] i∈V-S},则D[k]=SD(k)。
     初始时,每个蓝点v的D[c]值应为权w<s,v>,且从s到v的路径上没有中间点,因为该路径仅含一条边<s,v>。
   注意:
     在蓝点集中选择一个最短距离最小的蓝点k来扩充红点集是Dijkstra算法的关键

(4)k扩充红点集s后,蓝点集估计距离的修改
     将k扩充到红点后,剩余蓝点集的估计距离可能由于增加了新红点k而减小,此时必须调整相应蓝点的估计距离。
    对于任意的蓝点j,若k由蓝变红后使D[j]变小,则必定是由于存在一条从s到j且包含新红点k的更短路径:P=<s,…,k,j>。且D [j]减小的新路径P只可能是由于路径<s,…,k>和边<k,j>组成。
     所以,当length(P)=D[k]+w<k,j>小于D[j]时,应该用P的长度来修改D[j]的值。

(5)Dijkstra算法

 Dijkstra(G,D,s){//用Dijkstra算法求有向网G的源点s到各顶点的最短路径长度//以下是初始化操作S={s};D[s]=0; //设置初始的红点集及最短距离for( all i∈ V-S )do //对蓝点集中每个顶点iD[i]=G[s][i]; //设置i初始的估计距离为w<s,i>//以下是扩充红点集for(i=0;i<n-1;i++)do{//最多扩充n-1个蓝点到红点集D[k]=min{D[i]:all i V-S}; //在当前蓝点集中选估计距离最小的顶点kif(D[k]等于∞)return; //蓝点集中所有蓝点的估计距离均为∞时,//表示这些顶点的最短路径不存在。S=S∪{k}; //将蓝点k涂红后扩充到红点集for( all j∈V-S )do //调整剩余蓝点的估计距离if(D[j]>D[k]+G[k][j])//新红点k使原D[j]值变小时,用新路径的长度修改D[j],//使j离s更近。D[j]=D[k]+G[k][j];}}

Dijkstra算法 ——四人过桥相关推荐

  1. 【逻辑】四人过桥问题

    一.问题 在漆黑的夜里,四位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话,大家是无论如何也不敢过桥去的.不幸的是,四个人一共只带了一只手电筒,而桥窄得只够让两个人同时过.如果各自单独过 ...

  2. 四人过桥、三盏灯 三个开关 的答案

    题目都还是比较老了,再来温习下吧: 1. 有两个房间,其中一间房里有三盏灯,另一间房里有控制这三盏灯的开关.这两间房是相对独立.相对封闭的,没有空 上的直接联系:三盏灯与三个开关也没有顺序上的必然联系 ...

  3. 智力题:四人过桥问题

    有A.B.C.D四个人,要在夜里过一座桥.他们通过这座桥分别需要耗时1.2.5.10分钟,只有一只手电,并且同时最多只能两个人一起过桥.请你安排过桥方案,能够使这四个人都过桥,且总共花的时间最短(17 ...

  4. 四人过桥问题c语言编程,SQL趣题:四人过桥的问题

    传说中的微软面试题: 有一群人A,B,C,D (人数>=2)要在夜里走过独木桥过河,他们只有一把手电筒.四个人的速度不同, 过河分别需要1,2,5,10分钟,桥上最多走两个人,两个人一起走时按速 ...

  5. C语言解决四人/多人过桥问题

    参加笔试的时候遇到一道经典的算法题,四人过桥问题.当时没写出来

  6. (单源最短路径)一文搞懂dijkstra算法

    前言 大家好,我是bigsai,今天给大家讲讲Dijkstra算法,下次拿着这个算法找女神少绕路,有女朋友的可以试试行不行的通. 对于Dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较 ...

  7. 图论(四)------非负权有向图的单源最短路径问题,Dijkstra算法

    Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负. Dijkstra算法是贪婪算法的一个很好的例子.设置一顶点集合S,从源点s到集合中的顶点的最终最短路径 ...

  8. 知识点二十四:最短路径——Dijkstra 算法

    前言 像 Google 地图.百度地图.高德地图这样的地图软件,你只需要输入起始.结束地址,地图就会给你规划一条最优出行路线.这里说的最优路线,有很多种定义,比如最短路线.最少用时路线.最少红绿灯路线 ...

  9. 【路径规划】Dijkstra算法——超详细原理图解

    Dijkstra算法详解 1. Dijkstra算法原理  1.1. 有向图的Dijkstra算法  1.2. 无向图和栅格网络的拓展   1.2.1. 无向图   1.2.2. 栅格网络 2. Di ...

最新文章

  1. curl取跳转地址 php_用PHP如何实现解析抖音无水印视频
  2. 【Android】ADT中使用NDK编译已有的C++实现的库文件
  3. php单例模式的实例,PHP的单例模式的一个实例_php
  4. 应用jBPM4解决中国特色的流程需求 (看过之后,强烈推荐)
  5. 机器学习中有监督学习——回归
  6. android手机定位
  7. Hibernate关联关系映射-----单向一对一映射配置
  8. 学科前沿技术专题第六章
  9. java将csv导入hdfs_把HDFS里的json数据转换成csv格式
  10. Oracle数据库基础入门视频合集
  11. 配电室智能监控系统设计及实现分析
  12. C题:无线充电电动小车(本科)--2018年TI杯大学生电子设计竞赛
  13. 几何分布(一种离散分布)
  14. 拉链表取某一天的历史快照
  15. 用html怎样实现抽奖效果,html5+css3实现抽奖活动的效果
  16. 100-days: thirty-two
  17. .NET开发十大常用工具软件分享
  18. buuoj Pwn writeup 106-110
  19. html使用阿里图标库(iconfont)制作字体图标
  20. 基于 Bootstrap 5 的教育和课程主题 HTML 网站模板

热门文章

  1. 网易严选ServiceMesh实践
  2. Unable to add window android.view.ColorViewRootImplHooks$ColorW@cc14612 -- permission denied for win
  3. OAuth2.0系列之使用JWT令牌实践教程(八)
  4. Photoshop 给图片换背景
  5. WORD图片批量居中对齐
  6. iOS性能优化 - 启动优化
  7. 你最拿手的5种程序设计语言是什么
  8. 使input文本框中文字居中
  9. java 项目中常用的工具类总结
  10. Java好还是网优好_大神告诉你|Java好还是Python好?