最短路径问题:
对于一个指定的网络(由节点和路径组成的),找出一条路径,使得两结点间的距离最短。
迪杰斯特拉算法(Dijkstra)算法:
可以解决带权值的有向无向图(但是这里的权值不能为负)里的单源点最短路径问题(即从指定出发源点,到达途中任意一点的最短路径问题)。
其特点:起始点为中心向外,层层扩张,直到扩张覆盖所有顶点。
其主要思想:
我认为它是用到了贪心策略,贪心算法是一种通过分级处理某些最优解问题的方法。贪心算法,在求解过程的每一步中都采取当前状态下看来是最好或
最优的选择,从而希望最终的结果是最好或最优的。如果一个复杂的问题能够分解成几个子问题来解决,并且子问题的最优解能最终递推到最终问题的
最优解,简言之,如果局部最优解能最终推导出全局最优解,那么贪心算法在解决这类问题时非常有效。
转:http://blog.sina.com.cn/s/blog_72fa47290101g4dp.html
迪杰斯特拉算法执行步骤:
设 n 为图 G=(V,E) 中的顶点数,dist[n] 存放从源点到每个终点当前最短路径的长度,path[n] 存放相应路径,S为已求得最短路径的终点的集合,U为V-S,初始为不含有源点的所有顶点。
(1)初始化已求的最短路径的集合S为只含有元素源点a,S={a}。
(2)从U中选取一个距离源点v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。
(3)以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u(u U)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值为顶点k的距离加上顶点k到u边上的权。
(4)重复步骤(2)和(3)直到所有顶点都包含在S中。
迪杰斯特拉算法举例说明
(1)有向图如下,以a为源点,求源点a到其他各顶点的最短路径。
算法详细步骤如下表:
步骤 |
S集合中 |
U集合中 |
初始化 |
选入a,此时s={a} 此时最短路径有a->a=0 以a为中间点,从a开始找 |
U={b,c,d,e,f} a->b=1 a->c=2 a->e=15 a->其他U中顶点为无穷 |
1 |
从U={b,c,d,e,f}中发现路径a->b=1最短 选入b,S={a,b} 此时最短路径有a->a=0,a->b=1 以b为中间点,从a->b=1这条最短路径开始找 |
U={c,d,e,f} (a->b->d=7)<初始的无穷 改写a->b->d=无穷为当前的a->b->d=7 a-> b->其他U中顶点为无穷 |
2 |
从U={c,d,e,f}中发现路径a->c=2最短 选入c,S={a,b,c} 此时最短路径有 a->a=0,a->b=1,a->c=2 以b为中间点,从a->c=2这条最短路径开始找 |
U={d,e,f} (a->c->d=5)<已有的7 改写为a->c->d=5 |
3 |
从U={d,e,f}中发现路径a->c->d=5最短 选入d,S={a,b,c,d} 此时最短路径有 a->a=0,a->b=1,a->c=2,a->c->d=5 以d为中间点,从a->c->d=5这条最短路径开始找 |
U={e,f} (a->c->d->e=9)<步骤1中的15 改写为a->c->d->e=9 (a->c->d->f=6)<初始的无穷 改写为a->c->d->f=6 |
4 |
从U={e,f}中发现路径a->c->d->f=6最短 选入f,S={a,b,c,d,f} 此时最短路径有 a->a=0,a->b=1,a->c=2,a->c->d=5 a->c->d->f=6 以f为中间点,从a->c->d->f=6这条最短路径开始找 |
U={e} (a->c->d->f->e=7)<步骤3中改写成的9 改写为a->c->d->f->e=7 |
5 |
从U={f}中发现路径a->c->d->f->e=7最短 选入f,S={a,b,c,d,f,e} 此时最短路径有 a->a=0,a->b=1,a->c=2,a->c->d=5 a->c->d->f=6,a->c->d->f->e=7 |
U集合已空,查找完毕。 |
Floyd(弗洛伊德)算法:
又称为插点法,是一种用于寻找给定的加权图中多源点之间的最短路径算法。使用对象:多源、无负权边的最短路。
Floyd-Warshall算法:
Floyd-Warshall算法是解决任意两点间的最短路径算法。使用对象:通常可以在任何图中使用,包括有向图、带负权边的图。