当前位置:文档之家› 基于SDN的最短路径算法(迪杰斯特拉)dijkstra

基于SDN的最短路径算法(迪杰斯特拉)dijkstra

基于SDN的最短路径算法(迪杰斯特拉)dijkstra
基于SDN的最短路径算法(迪杰斯特拉)dijkstra

基于SDN的最短路径算法(迪杰斯特拉)

一.实验要求

下面为示例拓扑图,我们要用算法计算出id为1设备到id为7的设备和设备id 为2到ide为8设备的最优路线。

图示:组网拓扑

说明:此处拓扑图仅作为一个举例,路由算法程序应该能够处理各种拓扑情况,只要输入数据符合格式要求。程序应能够处理不同的Input.txt数据,并且可以处理带宽资源约束(input第一段最后属性)和路径需求(input第二段最后属性)。

二.实验环境及思路

算法用java语言实现,采用非常典型的dijkstra最短路径算法,根据带宽约束及带宽需求寻找最优路径,当两条路径上的带宽约束最小值相等时,则取经过交换机的跳数小的那条路径为最优路径。

首先读取input.txt中的数据(带宽约束、源节点、目的节点和带宽需求bdw),调用Dijkstra()方法计算各目的节点到源节点的最短路径,计算更新dist[]、mprev[]、hop[]、c[][]中的数据(dist[]数组用来存放整条路径上的最低带宽,mprev[]数组用来存放当前节点到源节点的下一跳节点,hop[]存放当前节点到源节点的跳数,c[][]存放两节点间的带宽),最后调用searchPath()方法查找目的节点到源节点的整条路径,并输出到output.txt文件中。

程序中的Dijkstra()方法是dijkstra最短路径算法的实现,我们先计算各条路径的最低带宽约束(指两条直连节点之间的带宽)并选择最低带宽约束大的那条路径作为最短路径;只有当两条路径的最低带宽相等时,我们才比较两条路径经过节点的跳数,并取跳数小的那条路径为最优路径。

程序流程图如下图所示:

图1:主程序流程图图2:searchpath方法流程图

图3:dijkstra算法流程图

三.实验步骤

采用java语言编写zhlsdn.java文件实现上面的流程图,将zhlsdn.java 文件转换为zhlsdn.exe文件(zhlsdn.exe运行需要jdk支持),在命令行输入如下命令:

zhlsdn.exe input.txt output.txt

如下图所示,

其中input.txt的内容如下:

leftnodeID,rightnodeID,bandwidth

1,3,100

1,4,100

2,3,100

2,4,100

3,4,100

3,5,100

3,6,100

4,5,100

4,6,100

5,6,100

5,7,100

5,8,100

6,7,100

6,8,100

;

srcNodeID,dstNodeID,bandwidth

1,7,90

3,8,90

zhlsdn.exe执行完成后,输出的output.txt文件内容如下:

1,3,5,7

3,5,8

更改input.txt中的数据如下:

leftnodeID,rightnodeID,bandwidth

1,3,80

1,4,100

2,3,60

2,4,100

3,4,100

3,5,95

3,6,100

4,5,80

4,6,110

5,6,90

5,7,120

5,8,100

6,7,95

6,8,100

;

srcNodeID,dstNodeID,bandwidth

1,7,90

3,8,90

输出的output.txt的内容如下:

1,4,6,8,5,7

3,6,8

四.实验结论:zhlsdn.java实现了采用dijkstra最短路径算法并结合带宽需求计算最优路径及输出的功能,达到了实验的要求。

附录:zhlsdn.java

import java.io.*;

import java.util.Vector;

public class zhlsdn {

final static int maxnum = 100;

final static int minint = 0;

final static int maxint = 999999;

static int dist[] = new int[maxnum]; //当前路径中的最小带宽

static int mprev[] = new int[maxnum]; //当前节点的前一跳节点

static int c[][] = new int[maxnum][maxnum]; //两个节点之间的带宽

static int hop[] = new int[maxnum]; //当前节点到源节点的跳数

public static void Dijkstra(int n,int v,int b,int dist[],int mprev[],int

c[][]){

boolean s[] = new boolean[maxnum];

for(int i=1;i<=n;i++){

dist[i] = c[v][i];

s[i] = false;

if(dist[i] == minint)

mprev[i] = 0;

else {

mprev[i] = v;

hop[i] = 1;

}

}

dist[v] = maxint;

s[v] = true;

for(int i=2;i<=n;i++){

int tmp = b;

int u = v;

for(int j=1;j<=n;j++){

if((!s[j]) && dist[j]>=tmp){

u = j;

tmp = dist[j];

}

}

s[u]= true;

for(int j=1;j<=n;j++){

int least = dist[u];

if(c[u][j]

least = c[u][j]; //最得最小的带宽值

if((!s[j]) &&(least > dist[j])){ //如果当前节点到源点的路径中的最小带宽过小,更新当前节点最小带宽及路径

hop[j] = hop[u]+1;

mprev[j] = u;

dist[j] = least;

}

else if((!s[j]) &&(least == dist[j])){ //如果相等,则比较跳数,跳数小者成为当前节点的路径

if(hop[j]>hop[u]+1){

hop[j] = hop[u]+1;

mprev[j] = u;

dist[j] = least;

}

}

}

}

}

public static void searchPath(int mprev[],int v,int u,String output) throws FileNotFoundException{

OutputStream out = new FileOutputStream(output,true);

int que[] = new int[maxnum];

int tot = 1;

que[tot] = u;

tot++;

int tmp = mprev[u];

while(tmp != v){

que[tot] = tmp;

tot++;

tmp = mprev[tmp];

}

que[tot] = v;

for(int i = tot;i>=1;i--){

if(i != 1){

int num = que[i];

try {

out.write(String.valueOf(num).getBytes());

out.write(",".getBytes());

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

else{

try {

out.write(String.valueOf(que[i]).getBytes());

out.write("\r\n".getBytes());

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

try {

out.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public static void main(String[] args) throws IOException { String input = args[0];

String output = args[1];

BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(new File(input))));

String str = new String();

int NodeNum = 0;

int LineNum = 0;

Vector vstr = new Vector();

Vector dstr = new Vector();

str = in.readLine();

while(true){

str = in.readLine();

if(str.isEmpty()){

break;

}

vstr.add(str);

LineNum++;

}

in.readLine();

in.readLine();

while(true){

str = in.readLine();

if(str == null)

break;

else if(str.isEmpty())

break;

dstr.add(str);

}

String LastLine = (String) https://www.doczj.com/doc/f214652397.html,stElement();

String[] strdata = LastLine.split("\\,");

int firststr = Integer.parseInt(strdata[0]);

int secondstr = Integer.parseInt(strdata[1]);

if(firststr

NodeNum = secondstr;

else

NodeNum = firststr;

for(int i=1;i<=NodeNum;i++){

for(int j=1;j<=NodeNum;j++){

c[i][j] = minint;

}

}

for(int i=1;i<=LineNum;i++){

String Readvstr = (String) vstr.get(i-1);

String[] vstrdata = Readvstr.split("\\,");

int firstvstr = Integer.parseInt(vstrdata[0]);

int secondvstr = Integer.parseInt(vstrdata[1]);

int thirdvstr = Integer.parseInt(vstrdata[2]);

if(thirdvstr > c[firstvstr][secondvstr]){

c[firstvstr][secondvstr] = thirdvstr;

c[secondvstr][firstvstr] = thirdvstr;

}

}

for(int i=1;i<=NodeNum;i++){

dist[i] = minint;

hop[i] = minint;

}

int src,dst,bdw;

OutputStream out = new FileOutputStream(output,false);

out.write("".getBytes());

out.close();

for(int i=1;i<=dstr.size();i++){

String Readvstr = (String) dstr.get(i-1);

String sdstr[] = Readvstr.split(",");

src = Integer.parseInt(sdstr[0]);

dst = Integer.parseInt(sdstr[1]);

bdw = Integer.parseInt(sdstr[2]);

Dijkstra(NodeNum,src,bdw,dist,mprev,c);

searchPath(mprev,src,dst,output);

}

}

}

最短路径的Dijkstra算法及Matlab程序

两个指定顶点之间的最短路径 问题如下:给出了一个连接若干个城镇的铁路网络,在这个网络的两个指定城镇间,找一条最短铁路线。 以各城镇为图G 的顶点,两城镇间的直通铁路为图G 相应两顶点间的边,得图G 。对G 的每一边e ,赋以一个实数)(e w —直通铁路的长度,称为e 的权,得到赋权图G 。G 的子图的权是指子图的各边的权和。问题就是求赋权图G 中指定的两个顶点00,v u 间的具最小权的轨。这条轨叫做00,v u 间的最短路,它的权叫做00,v u 间的距离,亦记作),(00v u d 。 求最短路已有成熟的算法:迪克斯特拉(Dijkstra )算法,其基本思想是按距0u 从近到远为顺序,依次求得0u 到G 的各顶点的最短路和距离,直至0v (或直至G 的所有顶点),算法结束。为避免重复并保留每一步的计算信息,采用了标号算法。下面是该算法。 (i) 令0)(0=u l ,对0u v ≠,令∞=)(v l ,}{00u S =,0=i 。 (ii) 对每个i S v ∈(i i S V S \=),用 )}()(),({min uv w u l v l i S u +∈ 代替)(v l 。计算)}({min v l i S v ∈,把达到这个最小值的一个顶点记为1+i u ,令}{11++=i i i u S S 。 (iii). 若1||-=V i ,停止;若1||-

Dijkstra算法

5.3.4 附录E 最短路径算法——Dijkstra 算法 在路由选择算法中都要用到求最短路径算法。最出名的求最短路径算法有两个,即Bellman-Ford 算法和Dijkstra 算法。这两种算法的思路不同,但得出的结果是相同的。我们在下面只介绍Dijkstra 算法,它的已知条件是整个网络拓扑和各链路的长度。 应注意到,若将已知的各链路长度改为链路时延或费用,这就相当于求任意两结点之间具有最小时延或最小费用的路径。因此,求最短路径的算法具有普遍的应用价值。 令v 部分: 不直接相连与结点若结点 1 v ? ?∞在用计算机进行求解时,可以用一个比任何路径长度大得多的数值代替∞。对于上述例子, 可以使D (v ) = 99。 (2) 寻找一个不在N 中的结点w ,其D (w )值为最小。把w 加入到N 中。然后对所有不在N 中的结点v ,用[D (v ), D (w ) + l (w , v )]中的较小的值去更新原有的D (v )值,即: D (v )←Min[D (v ), D (w ) + l (w , v )] (E-1) (3) 重复步骤(2),直到所有的网络结点都在N 中为止。 表E-1是对图E-1的网络进行求解的详细步骤。可以看出,上述的步骤(2)共执行了5次。表中带圆圈的数字是在每一次执行步骤(2)时所寻找的具有最小值的D (w ) 值。当第5次执行步骤(2)并得出了结果后,所有网络结点都已包含在N 之中,整个算法即告结束。 表E-1 计算图E-1的网络的最短路径

现在我们对以上的最短路径树的找出过程进行一些解释。 因为选择了结点1为源结点,因此一开始在集合N中只有结点1。结点1只和结点2, 3和4直接相连,因此在初始化时,在D(2),D(3)和D(4)下面就填入结点1到这些结点相应的距离,而在D(5)和D(6)下面填入∞。 下面执行步骤1。在结点1以外的结点中,找出一个距结点1最近的结点w,这应当是w = 4,因为在D(2),D(3)和D(4)中,D(4) = 1,它的之值最小。于是将结点4加入到结点集合N中。这时,我们在步骤1这一行和D(4)这一列下面写入①,数字1表示结点4到结点1的距离,数字1的圆圈表示结点4在这个步骤加入到结点集合N中了。 接着就要对所有不在集合N中的结点(即结点2, 3, 5和6)逐个执行(E-1)式。 对于结点2,原来的D(2) = 2。现在D(w) + l(w, v) = D(4) + l(4, 2) = 1 + 2 = 3 > D(2)。因此结点2到结点1距离不变,仍为2。 对于结点3,原来的D(3) = 5。现在D(w) + l(w, v) = D(4) + l(4, 3) = 1 + 3 = 4 < D(3)。因此结点3到结点1的距离要更新,从5减小到4。 对于结点5,原来的D(5) = ∞。现在D(w) + l(w, v) = D(4) + l(4, 5) = 1 + 1 = 2 < D(5)。因此结点5到结点1的距离要更新,从∞减小到2。 对于结点6,现在到结点1的距离仍为∞。 步骤1的计算到此就结束了。 下面执行步骤2。在结点1和4以外的结点中,找出一个距结点1最近的结点w。现在有两个结点(结点2和5)到结点1的距离一样,都是2。我们选择结点5(当然也可以选择结点2,最后得出的结果还是一样的)。以后的详细步骤这里就省略了,读者可以自行完 1的路由表。此路由表指出对于发往某个目的结点的分组,从结点1发出后的下一跳结点(在算法中常称为“后继结点”)和距离。当然,像这样的路由表,在所有其他各结点中都有一个。但这就需要分别以这些结点为源结点,重新执行算法,然后才能找出以这个结点为根的最短路径树和相应的路由表。

计算最短路径的Dijkstra算法的编程实现

计算最短路径的Dijkstra算法的编程实现 实验环境: C++ 为了进行网络最短路径路径分析,需将网络转换成有向图。如果要计算最短路径,则权重设置为两个节点的实际距离,Dijkstra算法可以用于计算从有向图中任意一个节点到其他节点的最短路径。 算法描述: 1)用带权的邻接矩阵来表示带权的n个节点的有向图,road[i][j]表示弧< vertex i, vertex j>的权值,如果从vertex i到vertex j不连通,则road road[i][j]=无穷大=9999。引进一个辅助向量Distance,每个Distance[i]表示从起始点到终点vertex i的最短路径长度。设起始点为first,则Distance[i]= road[first][i]。令S为已经找到的从起点出发的最短路径的终点的集合。 2)选择vertex j使得Distance[j]=Min{ Distance[i]| vertexi∈V-S},vertex j就是当前求得的一条从起始点出的的最短路径的终点的,令S=S∪{ vertex j} 3)修改从起始点到集合V-S中任意一个顶点vertex k的最短路径长度。如果Distance[j]+ road[j][k]< Distance[k],则修改Distance[k]为:Distance[k]= Distance[j]+ road[j][k]。 4)重复2,3步骤操作共n-1次,由此求得从起始点出发到图上各个顶点的最短路径长度递增的序列。 算法复杂度为O(n2)。 程序代码如下: #include #include "Dijkstra.h" int main() { int Graph_list_search[max][max]={{0,3,2,5,9999,9999}, {9999,0,9999,2,9999,9999}, {9999,9999,0,1,9999,9999}, {9999,9999,9999,0,9999,5}, {9999,9999,5,3,0,1}, {9999,9999,9999,9999,9999,0}}; printf_edge(Graph_list_search); Dijkstra(Graph_list_search,0,5); return 0; }

数据结构课程设计报告Dijkstra算法求最短路径

中南大学 《数据结构》课程设计 题目第9题 Dijkstra算法求最短路径 学生姓名 XXXX 指导教师 XXXX 学院信息科学与工程学院 专业班级 XXXXXXX 完成时间 XXXXXXX

目录 第一章问题分析与任务定义---------------------------------------------------------------------3 1.1 课程设计题目-----------------------------------------------------------------------------3 1.2 原始数据的输入格式--------------------------------------------------------------------3 1.3 实现功能-----------------------------------------------------------------------------------3 1.4 测试用例-----------------------------------------------------------------------------------3 1.5 问题分析-----------------------------------------------------------------------------------3 第二章数据结构的选择和概要设计------------------------------------------------------------4 2.1 数据结构的选择--------------------------------------------------------------------------4 2.2 概要设计-----------------------------------------------------------------------------------4 第三章详细设计与编码-----------------------------------------------------------------------------6 3.1 框架的建立---------------------------------------------------------------------------------6 3.2 点结构体的定义---------------------------------------------------------------------------7 3.3 创立带权值有向图------------------------------------------------------------------------8 3.4 邻接矩阵的显示---------------------------------------------------------------------------9 3.5 递归函数的应用---------------------------------------------------------------------------10 3.6 Dijkstra算法实现最短路径--------------------------------------------------------------10 第四章上机调试------------------------------------------------------------------------------------11 4.1 记录调试过程中错误和问题的处理---------------------------------------------------11 4.2 算法的时间课空间性能分析------------------------------------------------------------11 4.3 算法的设计、调试经验和体会---------------------------------------------------------11 第五章测试结果-----------------------------------------------------------------------------------12 第六章学习心得体会-----------------------------------------------------------------------------12 第七章参考文献-----------------------------------------------------------------------------------12 附录------------------------------------------------------------------------------------------------------12

gis计算最短路径的Dijkstra算法详细讲解

最短路径之Dijkstra算法详细讲解 1最短路径算法 在日常生活中,我们如果需要常常往返A地区和B 地区之间,我们最希望知道的可能是从A地区到B地区间的众多路径中,那一条路径的路途最短。最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。算法具体的形式包括: (1)确定起点的最短路径问题:即已知起始结点,求最短路径的问题。 (2)确定终点的最短路径问题:与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。 (3)确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径。 (4)全局最短路径问题:求图中所有的最短路径。 用于解决最短路径问题的算法被称做“最短路径算法”,有时被简称作“路径算法”。最常用的路径算法

有:Dijkstra算法、A*算法、Bellman-Ford算法、Floyd-Warshall算法、Johnson算法。 本文主要研究Dijkstra算法的单源算法。 2Dijkstra算法 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)初始时,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中。 2.4 Dijkstra算法举例说明 如下图,设A为源点,求A到其他各顶点(B、C、D、E、F)的最短路径。线上所标注为相邻线段之间的距离,即权值。(注:此图为随意所画,其相邻顶点间的距离与图中的目视长度不能一一对等)

Dijkstra最短路径算法

5.3.4 附录E 最短路径算法——Dijkstra算法 在路由选择算法中都要用到求最短路径算法。最出名的求最短路径算法有两个,即Bellman-Ford算法和Dijkstra算法。这两种算法的思路不同,但得出的结果是相同的。我们在下面只介绍Dijkstra算法,它的已知条件是整个网络拓扑和各链路的长度。 应注意到,若将已知的各链路长度改为链路时延或费用,这就相当于求任意两结点之间具有最小时延或最小费用的路径。因此,求最短路径的算法具有普遍的应用价值。 下面以图E-1的网络为例来讨论这种算法,即寻找从源结点到网络中其他各结点的最短路径。为方便起见,设源结点为结点1。然后一步一步地寻找,每次找一个结点到源结点的最短路径,直到把所有 点1, j)为结点i (1) 初始化 令N表示网络结点的集合。先令N = {1}。对所有不在N中的结点v,写出

不直接相连与结点若结点直接相连 与结点若结点 1 1 ),1()(v v v l v D ? ? ?∞= 在用计算机进行求解时,可以用一个比任何路径长度大得多的数值代替∞。对于上述例子,可以使D (v ) = 99。 (2) 寻找一个不在N 中的结点w ,其D (w )值为最小。把w 加入到N 中。然后对所有不在N 中的结点v ,用[D (v ), D (w ) + l (w , v )]中的较小的值去更新原有的D (v )值,即: D (v )←Min[D (v ), D (w ) + l (w , v )] (E-1) (3) 重复步骤(2),直到所有的网络结点都在N 中为止。 表E-1是对图E-1的网络进行求解的详细步骤。可以看出,上述的步骤(2)共执行了5次。表中带圆圈的数字是在每一次执行步骤(2)时所寻找的具有最小值的D (w ) 值。当第5次执行步骤(2)并得出了结果后,所有网络结点都已包含在N 之中,整个算法即告结束。 表E-1 计算图E-1的网络的最短路径

迪杰斯特拉算法求解最短路径

#include #define MAX_VERTEX_NUM 50 #define INFINITY 300 typedef char VertexType[3]; typedef struct vertex { int adjvex;//顶¥点?编括?号? VertexType data;//顶¥点?信?息¢ }Vertex_Type;//顶¥点?类え?型í typedef struct graph { int Vertex_Num;//顶¥点?数簓 int Edge_Num;//边?数簓 Vertex_Type vexs[MAX_VERTEX_NUM];//顶¥点?数簓组哩? int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];// 边?的?二t维?数簓组哩? }AdjMatix;//图?的?邻ⅷ?接?矩?阵?类え?型í int Create_Adjmatix(AdjMatix &g) { int i,j,k,b,t,w; printf("请?输?入?图?的?顶¥点?数簓和í边?数簓:阰\n"); scanf("%4d%4d",&g.Vertex_Num,&g.Edge_Num); for (i=0;i0) g.edges[b][t]=w; else {printf("输?入?错洙?误?!?");return 0;} } return 1;

Dijkstra算法求最短路径

Dijkstra算法求最短路径(C#版)行如下图的路径,(V0是中心): 经过该算法后转化为下图 using System; using System.Collections; using System.Text; namespace Greedy {

class Marx { private int[] distance; private int row; private ArrayList ways = new ArrayList(); public Marx(int n,params int[] d) { this.row = n; distance = new int[row * row]; for (int i = 0; i < row * row; i++) { this.distance[i] = d[i]; } for (int i = 0; i < this.row; i++) //有row个点,则从中心到各点的路有row-1条 { ArrayList w = new ArrayList(); int j = 0; w.Add(j); ways.Add(w); } } //------------------------------ public void Find_way() { ArrayList S = new ArrayList(1); ArrayList Sr = new ArrayList(1); int []Indexof_distance=new int[this.row]; for(int i=0; i < row; i++) { Indexof_distance[i]=i; } S.Add( Indexof_distance[0] ); for (int i = 0; i < this.row; i++) { Sr.Add( Indexof_distance[i] ); } Sr.RemoveAt(0); int[] D = new int[this.row]; //存放中心点到每个点的距离 //---------------以上已经初始化了,S和Sr(里边放的都是点的编

迪杰斯特拉算法计算最短路径

利用Dijkstra算法计算最短路径 摘要 福格环游地球问题是一个十分典型的最短路径求解问题,题设给出了当时世界上主要交通网络图及交通通畅的城市之间来往所需时长,并限定了福格的出行方向(福格选择的是往东走),给出起止地点后要求找出福格环游世界天数最短的最佳路径。 我们认为,这个问题的实质在于最短路径的求解和优化。我们对比图论中的多种最短路径算法,决定利用Dijkstra算法解决这个问题。 由于Dijkstra算法要求输入图G的关联矩阵,且图G为二维赋权图,而题中给出的地图可看成是三维环状地图,因此,我们对题设地图做相关处理,将其从起点处“切断”并展开为二维图,然后根据此图建立关联矩阵。同时,我们考虑到最短路径可能会与切断线有交点,在切断线以西找出若干地点一分为二,修改关联矩阵。 对于题目中缺失的两处数据,本文将以当时的交通数据为基础,经过合理的数据处理,结合Google Earth测距软件与题目数据的合理类比,补充缺失数据,完成关联矩阵。 得到关联矩阵后,我们分别以伦敦、纽约和上海作为起点,调整关联矩阵起点和终点,用matlab编程进行求解得到最短环游时间和最短路径,进而判断出所选择的路径是否能让他赢得赌注。根据我们的求解结果,在这三个城市,福格均能在80天内环游地球,赢得赌注。 本文进一步对此种算法的优缺点、灵敏度与推广性进行了分析,同时初步提出了两种优化方法。 关键词:最短路径算法 dijkstra算法算法优化

一、问题重述 儒勒?凡尔纳的著名小说《环游世界80天》中,英国绅士福格在伦敦与人打赌能够在80天内环游世界,这在当时的1872年是一个了不起的壮举。当时最快的旅行方式是火车和轮船,然而世界上大部分地区还是靠马车、大象、驴子或者步行来旅行。下面是一个从伦敦环游世界不同路线的交通网络图,福格选择的是往东走,每段路线所需要的天数显示在图上(见附录一),旅行的时间基于1872年能采用的旅行方式以及距离。 我们将解决以下问题: 1.我们将设计一个算法为福格选择一条最佳路径,即环游世界天数最短,并判断所选择的路径是否能让他赢得赌注。 2.若他在别的地方与人打赌,如纽约或者上海,我们将分别设计最佳路径并判断所选择的路径是否能让他赢得赌注。 二、问题分析 福格环游地球问题是一个十分典型的最短路径求解问题,题设给出了当时世界上主要交通网络图及交通通畅的城市之间来往所需时长,并限定了福格的出行方向(福格选择的是往东走),给出起止地点后要求找出福格环游世界天数最短的最佳路径。 本题实质在于最短路径的求解和优化,如何求解最短路径呢,我们联系到图论中求解最短路径的Dijkstra算法,然而,要满足Dijkstra算法的条件,首要任务是弄清如何处理题设所给的世界交通网络图。我们可以把题中给出的地图看成是三维环状地图,而Dijkstra算法要求输入图G的关联矩阵,且图G为二维赋权图,因此,我们应该对题设地图做相关处理,将其从起点处“切断”并展开为二维图,然后根据此图建立关联矩阵。但是,考虑到最短路径可能会与切断线有交点,我们必须在切断线以西找出若干地点一分为二,修改关联矩阵。 在创建关联矩阵的时候,必须考虑到如何估计两处缺失的数据,当时的地区交通状况文献已经无法查询,因此,我们只能根据当地周围相似地形地势处的已知交通状况进行估值。如何估值呢,我们用Google Earth对两地距离进行测量,并进行若干假设,与附近相似地形已知数据处进行同比例估值,得到近似结果。对于题目提出的问题,分别以伦敦、纽约和上海作为起点,我们只需调整关联矩阵起点和终点用matlab编程进行求解即可得到最短环游时间和最短路径,从而判断出所选择的路径是否能让他赢得赌注。 三、基本假设 1、题目中给出的数据均准确。 2、题目中给出的数据均采用当时能达到的最高效的交通方式。 3、在环游地球的路程中,福格不会在任何地点因任何原因停留。

单源最短路径的Dijkstra算法

单源最短路径的Dijkstra算法: 问题描述: 给定一个带权有向图G=(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在要计算从源到所有其他各顶点的最短路长度。这里路的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。算法描述: Dijkstra算法是解单源最短路径的一个贪心算法。基本思想是:设置顶点集合S并不断地做贪心选择来扩充这个集合。一个顶点属于S当且仅当从源到该顶点的最短路径长度已知。初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist做必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其他顶点之间的最短路径长度。 源代码: #include #define MAX 1000 #define LEN 100 int k=0, b[LEN]; using namespace std;

//-------------------------------------数据声明------------------------------------------------//c[i][j]表示边(i,j)的权 //dist[i]表示当前从源到顶点i的最短特殊路径长度 //prev[i]记录从源到顶点i的最短路径上的i的前一个顶点 //--------------------------------------------------------------------------------------------- void Dijkstra(int n, int v, int dist[], int prev[], int c[][LEN]) { bool s[LEN]; // 判断是否已存入该点到S集合中 for (int i = 1; i <= n; i++) { dist[i] = c[v][i]; s[i] = false; //初始都未用过该点 if (dist[i] == MAX) prev[i] = 0; //表示v到i前一顶点不存在 else prev[i] = v; } dist[v] = 0; s[v] = true; for (int i = 1; i < n; i++)

最短路径_Dijkstra算法__实验报告

实验六:编程实现Dijkstra 算法求最短路问题. 1.需求分析: 首先让用户输入一个带权的有向图,输入时可通过一对一对输入存在弧的两个弧头与弧尾顶点以及弧上的权值从而输入整个有向图。用户输入一对对弧后,我们可以采用数组的形式来进行存储每个顶点之间的权值,最后由用户输入该有向图的源点(即每个最短路径的起点),要求源点必须为刚才输入的各顶点中的某一个,如果用户输入错误,程序要给出错误信息提示并退出程序。然后,我们可以设计一个Graph这样的类,将对关系的各种操作放入其中,然后我们在主函数中调运这个类就可以实现最短路问题的求解了。 2.概要设计: ①.构造一个新的类Graph: class Graph { private: int arcs[MAX][MAX],Path[MAX][MAX],D[MAX]; int arcnum,vexnum,weight,v0; Type a,b,vexs[MAX]; public: void Creat_Graph(); void Show_ShortestPath(); void ShortestPath_DIJ(); }; ②.结构化调用类中方法的主函数: int main() { Graph G; G.Creat_Graph(); G.ShortestPath_DIJ(); G.Show_ShortestPath(); return 0; } 3.代码实现: #include #define MAX 100 #define INFINITY INT_MAX enum BOOL{FALSE,TRUE}; using namespace std; template class Graph {

dijkstra最短路径算法

数据通信与计算机网络大作业 Dijkstra 最 短 路 径 算 法

【摘要】 摘要:最短路径分析在地理信息系统、计算机网络路由等方面发挥了重要的作用, 对其进行优化很有必要。本文分析了传统 的最短路径算法(即Dijkstra 算法)的优化途径及现有的优化算法, 然后在Dijkstra 算法的基础上, 采用配对堆结构来实现路 径计算过程中优先级队列的一系列操作, 经理论分析与实验测试结果对比, 可以大大提高该算法的效率和性能。 【关键词】 最短路径; Dijkstra 算法; 【正文】 随着计算机网络技术和地理信息科学的发展, 最短路径问题无论是在交通运输, 还是在城市规划、物流管理、网络通讯等方面, 它都发挥了重要的作用。因此, 对它的研究不但具有重要的理论价值, 而且具有重要的应用价值。研究最短路径问题通常将它们抽象为图论意义下的网络问题, 问题的核心就变成了网络图中的最短路径问题。此时的最短路径不单指“纯距离”意义上的最短路径, 它可以是“经济距离”意义上的最短路径, “时间”意义上的最短路径, “网络”意义上的最短路径。关于最短路径问题, 目前所公认的最好的求解方法, 是由F.W.Dijkstra 提出的标号法, 即Dijkstra 算法。 1 Dijkstra 算法 Dijkstra 算法是求最短路径的最基本和使用最广泛的算法。在求从网络中的某一节点(源点)到其余各节点的最短路径时, 经典Dijkstra 算法将网络中的节点分成三部分: 未标记节点、临时标记节点和最短路径节点(永久标记节点)。算法开始时源点初始化为最短路径节点, 其余为未标记节点, 算法执行过程中, 每次从最短路径节点往相邻节点扩展, 非最短路径节点的相邻节点修改为临时标记节点, 判断权值是否更新后, 在所有临时标记节点中提取权值最小的节点, 修改为最短路径节点后作为下一次的扩展源, 再重复前面的步骤, 当所有节点都做过扩展源后算法结束。具体算法描述如下: 设在一非负权简单连通无向图G=(V:顶点集, E:边集, W:边权值)中, d 为图G 的邻接矩阵, 求源点P 0到其余所有节点Pi的最短路径长度。 ⑴将V 分为未标记节点子集N、临时最短路径节点子集T和最短路径节点子集S, 每个节点上的路径权值为D(i)。初始化:S={P0}, T=¢, N=V- S, D(0)=0, D(i)=∞; ⑵更新:将新加入S 集合的节点Ps 作为扩展源, 计算从扩展源到相邻节点的路径值。若该值比节点上的原值小, 则用该值替换原值, 否则保持原值不变, 即D(i)=min{D(s)+d[s][i],D(i)},并将这些相邻节点之中的未标记节点归为临时标记节点, 即T= T∪Pi, N=N- Pi; ⑶选择:在T 中选择具有最小路径值D(s)的节点Ps, 归入集合S 中, 即S=S ∪Ps, T=T- Ps;

迪杰斯特拉算法总结

总结:最短路径算法关键先把已知最短路径顶点集(只有一个源点)和未知的顶点分开,然后依次把未知集合的顶点按照最短路径(这里特别强调一下是源点到该顶点的路径权重和,不仅仅是指它和父结点之间的权重,一开始就是在没有这个问题弄清楚)加入到已知结点集中。在加入时可以记录每个顶点的最短路径,也可以在加入完毕后回溯找到每个顶点的最短路径和权重。 迪杰斯特拉算法用于求解一个有向图(也可以是无向图,无向图是有向图的一种特例)的一个点(称之为原点)到其余各点(称之为周边点)的最短路径问题。算法构思很是巧妙(我这么认为),简直达到了“无心插柳柳成荫”的境界。算法本身并不是按照我们的思维习惯——求解从原点到第一个点的最短路径,再到第二个点的最短路径,直至最后求解完成到第n个点的最短路径,而是求解从原点出发的各有向路径的从小到大的排列(如果这个有向图中有环1-2-3-1算法岂不是永无终结之日了??!!),但是算法最终确实得到了从原点到图中其余各点的最短路径,可以说这是个副产品,对于算法的终结条件也应该以求得了原点到图中其余各点的最短路径为宜。清楚了算法的这种巧妙构思

后,理解算法本身就不是难题了。 算法把一个图(G)中的点划分成了若干部分: 1):原点(v); 2):所有周边点(C); 另外有一个辅助集合S,从v到S中的点的最短路径已经求得。S的最初状态是空集。 这样就可以进一步划分图(G): 1):原点(v); 2):已求出v至其最短路径的周边点(S); 3):尚未求出v至其最短路径的周边点(Other=C-S); 算法的主体思想: A、找到v——Other所有路径中的的最短路径vd=v——d(Other的一个元素); B、找到v——S——Other所有路径中的的最短路径vi=v——i(Other 的一个元素); C、比较vd和vi如果vd<=vi则将d加入S且从Other中删除,否则将i加入S且从Other中删除。 重复以上步骤直至Other为空集。 我们求得的最短路径是升序排列的,那为什么下一条最短路径就存在于v——

最短路径算法―Dijkstra(迪杰斯特拉)算法分析与实现(

Dijkstra(迪杰斯特拉算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。 Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。 其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。 初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S 中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。 例如,对下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径的过程列在下表中。 Dijkstra算法的迭代过程: 主题好好理解上图! 以下是具体的实现(C/C++: 1. /*************************************** 2. * About: 有向图的Dijkstra算法实现

3. * Author: Tanky Woo 4. * Blog: https://www.doczj.com/doc/f214652397.html, 5. ***************************************/ 6. 7. #include 8. using namespace std; 9. 10. const int maxnum = 100; 11. const int maxint = 999999; 12. 13. 14. void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum] 15. { 16. bool s[maxnum]; // 判断是否已存入该点到S集合中 17. for(int i=1; i<=n; ++i 18. { 19. dist[i] = c[v][i]; 20. s[i] = 0; // 初始都未用过该点 21. if(dist[i] == maxint 22. prev[i] = 0; 23. else 24. prev[i] = v; 25. } 26. dist[v] = 0; 27. s[v] = 1; 28. 29. // 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中

暴强Dijkstra算法求任意两点间最短路径

效果展示: 开头输入的是点的序列号(表示第几个点),显示的是最短路径的走法(同样以点的序列号显示,表示途径的第几个点)。 %编写m文件 function [distance,path]=dijkstra(A,s,e) % [DISTANCE,PATH]=DIJKSTRA(A,S,E) % returns the distance and path between the start node and the end node. % % A: adjcent matrix % s: start node % e: end node % initialize n=size(A,1); % node number D=A(s,:); % distance vector path=[]; % path vector visit=ones(1,n); % node visibility visit(s)=0; % source node is unvisible parent=zeros(1,n); % parent node % the shortest distance for i=1:n-1 % BlueSet has n-1 nodes temp=zeros(1,n); count=0; for j=1:n if visit(j) temp=[temp(1:count) D(j)]; else temp=[temp(1:count) inf]; end count=count+1; end [value,index]=min(temp); j=index; visit(j)=0; for k=1:n if D(k)>D(j)+A(j,k) D(k)=D(j)+A(j,k); parent(k)=j; end

Dijkstra算法求最短路径(C#版)

Dijkstra算法求最短路径(C#版) 行如下图的路径,(V0是中心): 经过该算法后转化为下图 using System; using System.Collections; using System.Text; namespace Greedy { class Marx

{ private int[] distance; private int row; private ArrayList ways = new ArrayList(); public Marx(int n,params int[] d) { this.row = n; distance = new int[row * row]; for (int i = 0; i < row * row; i++) { this.distance[i] = d[i]; } for (int i = 0; i < this.row; i++) //有row个点,则从中心到各点的路有row-1条 { ArrayList w = new ArrayList(); int j = 0; w.Add(j); ways.Add(w); } } //------------------------------ public void Find_way() { ArrayList S = new ArrayList(1); ArrayList Sr = new ArrayList(1); int []Indexof_distance=new int[this.row]; for(int i=0; i < row; i++) { Indexof_distance[i]=i; } S.Add( Indexof_distance[0] ); for (int i = 0; i < this.row; i++) { Sr.Add( Indexof_distance[i] ); } Sr.RemoveAt(0); int[] D = new int[this.row]; //存放中心点到每个点的距离 //---------------以上已经初始化了,S和Sr(里边放的都是点的编号)------------------ int Count = this.row - 1;

相关主题
文本预览
相关文档 最新文档