数据结构复习笔记 最短路径Shortest path
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

数据结构复习笔记 最短路径Shortest path

  • 1,509 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,509
On Slideshare
1,508
From Embeds
1
Number of Embeds
1

Actions

Shares
Downloads
6
Comments
0
Likes
0

Embeds 1

http://webcache.googleusercontent.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. 最短路径 ShortestPath_DIJ 1 最短路径算法 在日常生活中,我们如果需要常常往返 A 地区和 B 地区之间,我们最希望知道的可能是从 A 地区到 B 地区间的众多路径中,那一条路径的路途最短。最短路径问题是图论研究中的一个经典算法问题, 旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。 算法具体的形式包括: (1)确定起点的最短路径问题:即已知起始结点,求最短路径的问题。 (2)确定终点的最短路径问题:与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。 (3)确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径。 (4)全局最短路径问题:求图中所有的最短路径。 用于解决最短路径问题的算法被称做“最短路径算法”, 有时被简称作“路径算法”。 最常用的路径算法有:Dijkstra 算法、A*算法、Bellman-Ford 算法、Floyd-Warshall 算法、Johnson 算法。 本文主要研究 Dijkstra 算法的单源算法。 2 Dijkstra 算法 2.1 Dijkstra 算法 Dijkstra 算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra 算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。 Dijkstra 算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。 2.2 Dijkstra 算法思想 Dijkstra 算法思想为:设 G=(V,E)是一个带权有向图,把图中顶点集合 V 分成两组,第一组为已求出最短路径的顶点集合(用 S 表示,初始时 S 中只有一个源点,以后每求得一条最短路径 , 就将 加入到集合 S 中,直到全部顶点都加入到 S 中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用 U 表示),按最短路径长度的递增次序依次把第二组的顶点加入 S 中。在加入的过程中,总保持从源点 v 到 S 中各顶点的最短路径长度不大于从源点 v 到 U 中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S 中的顶点的距离就是从 v 到此顶点的最短路径长度, 中的顶点的距离, U 是从 v 到此顶点只包括S 中的顶点为中间顶点的当前最短路径长度。 2.3 Dijkstra 算法具体步骤 1
  • 2. (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 中。 算法:(a) 初始化:用起点 v 到该顶点 w 的直接边(弧)初始化最短路径,否则设为∞; (b) 从未求得最短路径的终点中选择路径长度最小的终点 u:即求得 v 到 u 的最短路径; (c) 修改最短路径:计算 u 的邻接点的最短路径,若(v,…,u)+(u,w)<(v,…,w),则以(v,…,u,w)代替。 (d) 重复(b)-(c),直到求得 v 到其余所有顶点的最短路径。 特点:总是按照从小到大的顺序求得最短路径。 2.4 Dijkstra 算法举例说明 如下图,设 A 为源点,求 A 到其他各顶点(B、C、D、E、F)的最短路径。线上所标注为相邻线段之间的距离,即权值。(注:此图为随意所画,其相邻顶点间的距离与图中的目视长度不能一一对等) 图一:Dijkstra 无向图 2
  • 3. 算法执行步骤如下表:以上部分参考:http://2728green-rock.blog.163.com/blog/static/43636790200901211848284/ 从 A 点到各终点的 D 值和最短路径的求解过程 终点 i=1 i=2 i=3 i=4 i=5 6 5 B (A,B) (A,C,B) 3 C (A,C) 6 6 D ∞ (A,C,D) (A,C,D) 7 7 7 E ∞ (A,C,E) (A,C,E) (A,C,E) 9 9 F ∞ ∞ ∞ (A,C,D,F) (A,C,D,F) 选择点 C B D E F S {A,C} {A,C,B] {A,C,B,D} {A,C,B,D,E} {A,C,B,D,E,F}例 2:用迪杰斯特拉算法求下图中 A 到其余顶点的最短路径。 3
  • 4. 说明:求得 v�u 的最短路径后,只要计算 u 到其余顶点是否(比原来)有更短路径即可,这样可以减少计算量。另外,注意合并路径。最短路径算法:void ShortesPath_DIJ(MGraph G, int v0,PathMatrix &P, ShortPathTable &D ){//若 w 是从 v0 到 v 最短路径上的顶点,则 p[v][w]为 TRUE//已经求得从 v0 到 v 的最短路径,final[v]为 TRUE{for(v=0; v<G.vexnum; ++v) {final[v] = FALSE; D[v] = G.arcs[v0][v]; for(w=0; w<G.vexnum; ++w) P[v][w] = FALSE; // 设空路径 if (D[v]<INFINITY) {p[v][v0]=TRUE; p[v][v] = TRUE; } }// forD[v0] = 0; final[v0] = TRUE; // 初始化,v0 顶点属于 S 集// 开始主循环,每次求得 v0 到某个 v 顶点的最短路径,并加 v 到 S 集for (i=1; i<G.vexnum; ++i) // 其余 G.vexnum-1 个顶点 {min = INFINITY; //当前所知离 v0 顶点的最近距离 for(w=0;w<G.vexnum; ++w) if (! final[w]) // w 顶点在 V -S 中 if(D[w]<min) {v = w; min = D[w]; } // w 顶点离 v0 顶点更近 final[v] = TRUE; // 离 v0 顶点最近的 v 加入 s 集 for(w=0; w<G.vexnum; ++w) //更新当前最短路径及距离 if(! final[w] &&(min+G.arcs[v][w]<D[w])) { D[w] = min + G.arcs[v][w]; //修改 D[w]和 P[w],w∈V-S P[w] = P[v]; P[w][w] = TRUE; // P[w] = P[v] + [w] }// if }// for}// ShortestPath_DIJ 4
  • 5. 弗洛伊德算法这个算法真的不会,只好贴别人的了。求每对顶点之间的最短路径。依次计算 A(0), (1), A(n)。 (0)为邻接矩阵, A …, A 计算 A(k)时, (k)(i,j)=min{A(k-1)(i,j), A(k-1)(i,k)+A(k-1)(k,j)}。 A技巧:计算 A(k)的技巧。第 k 行、第 k 列、对角线的元素保持不变,对其余元素,考查 A(i,j)与 A(i,k)+A(k,j) (“行+列”1) ,如果后者更小则替换 A(i,j),同时修改路径。例:用弗洛伊德算法计算图中各顶点之间的最短路径。技巧:当不变行或不变列(即第 k 行、第 k 列)某元素为∞时,其所在的列或行元素也不变。例如:计算 A(1)时,A(2,1) = A(3,1) = ∞,所以第 2、3 行都不变,而 A(1,4) = ∞,所以第 4 列也不变,这样,只剩下 A(4,2)和 A(4,3)需要计算了。1 第 k 列 i“行”元素加上第 k 行 j“列”元素。 5