网络原理实验报告(DIJKSTRA)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//设置自己到自己的距离为0 for(int i=0;i<route.length-1;i++){ System.out.print("【随机】路由"+route[i]+"到其他路由的距离 依次为: "); for(int j=i+1;j<route.length;j++){ int ran=new Random().nextInt(150); if(ran>100){ //设定随机值
我们编程最容易遇到的问题莫过于此: 一个算法用数学语言 或者人类自然语言比较容易描述和理解,但是代码(机器语言) 却很难把简单的一段话实现, 但是如果按照前面讲过的几个要点 依次来编写就是很容易的,这里就谈谈关键的几个步骤吧: 1. “图”的绘制——想必大家都是手工输入节点和任意 两条边间的距离吧?不说太夸张的, 如果我有 15 个节点, 有 50 条边,估计手指按键盘都得按疼(100 个节点,300 条边更不说了) 这里,我听取了学长的建议,无论是节点的名称、 节点的个数、源节点的选取还是边的权值都用系统随机 数设置(这里比如还可以设随到-1 的话表示无穷大)— —这就是全自动化的好处,再也不用担心手疼了!因此,
System.out.print("【统计】本架构中总共有: "); //统计有限权值边的条数 System.out.print(count); System.out.print(" 条边! } } ");
(二) Dijkstra 类
import java.util.Random; public class Dijkstra { public static int min(int[] a){ int min=a[0]; int minsign=0; for(int i=0;i<a.length;i++){ if(a[i]!=0){ if(a[i]<min){ min=a[i]; minsign=i; } } } return minsign; } //min表示最小值,minsign表示对应的元素下标 //返回数组中的最小值的下标
百度文库
//逆推至源节点表示最短路径完全确定了 for(int t=0;t<num;t++){ if(vname[t].equals(p1)) p1=p[t]; } path[i]+=p1+" "; } }
} String[][] path01=new String[num][]; //以下部分均是路径显示格式的调整与转换 String[] truepath=new String[num]; for(int i=0;i<num;i++) truepath[i]=""; for(int i=0;i<num;i++) path01[i]=path[i].split(" "); for(int i=0;i<num;i++) path01[i][path01[i].length-1]=route[sorce]; for(int i=0;i<num;i++){ for(int j=path01[i].length-1;j>=0;j--){ if(path01[i][j]!=null) truepath[i]+=path01[i][j]+" "; } } for(int i=0;i<num;i++){ truepath[i]=truepath[i].replaceAll(" ", "→"); truepath[i]=truepath[i].substring(0,truepath[i].length()-1); } return truepath; } public static void dijkstra(Grap g,String star){
姓名: 班级: 学号: 教师:
1. 实验目的
运用各种编程语言实现基于 Dijkstra 算法的路由软件。 PS:这里使用的是 JAVA 语言
2. 实验意义
通过本实验,使学生能够对路由原理和路由算法有进一步的 理解和掌握。
3. 实验背景
设:c(i,j): 结点 i 至结点 j 之间链路的代价,若 i,j 不直接相连, 则为无穷大。 D(v): 当前从源结点至目的结点 V 之间路由的代价。 p(v): 从源结点至目的结点 V 之间路由中 V 之前的结点 N: 已经知道最优路径的结点集合 1 Initialization: 2 N = {A} 3 for all nodes v 4 if v adjacent to A 5 then D(v) = c(A,v) 6 else D(v) = infty 7 Loop 8 find w not in N such that D(w) is a minimum 9 add w to N
//设置一定的概率出现“无穷大”
distance[i][j]=10000; System.out.print(" ∞");
distance[j][i]=distance[i][j]; } else{ distance[i][j]=ran; System.out.print(" ");
System.out.print(ran); //依次显示每个顶点到其他顶点的距离 distance[j][i]=ran; count++; } } System.out.println(); }
和对应的最短路径 D. Public static void main(String[] args)——主函数, 用于程序的初始化(比如随机顶点集的初始化) 和程序算法的执行(调用各功能函数)
8. 代码展示与描述
(一) Grap 类
import java.util.Random; public class Grap { String[] route; int[][] distance; int count=0; public Grap(String[]v){ route=v; //获取顶点集
distance=new int[route.length][route.length]; //用二维数组保存任意两条边的距离 System.out.print("【随机】设置了"+v.length+"个路由器 "); //统计路由器总数 System.out.print("路由名分别为: "); for(int i=0;i<v.length;i++) {System.out.print(v[i]);System.out.print(" ");//依次显示路径名称 System.out.println(); for(int i=0;i<route.length;i++) distance[i][i]=0;
我选择使用 JAVA 里的随机类 Random,一方面是方便省 心省力另一方面“All Random”(全随机)更能帮你检查 算法正确性以及更加符合实际 2. 选 D()最小值: 自己写一个求数组最小值的 min()函数 就可以了, 每次求 D()最小值是要排除已经选过的节点的, 怎么实现呢?——可以把选过的节点的 D()值用另一个数 组的元素暂存起来,然后自己被赋成∞,这样 min{D(Vi)} 就不会出现重复了 3. D()值更新——其实也就是算法最精华的部分, 采用 判断语句就可以了: 数学表达:D(B) = min{ D(B), distance(C,B)+D(C) } 代码表达:D[i]=D[i]<dis[k][i]+D[k]?D[i]:dis[k][i]+D[k] 或者 if+else 语句也行 4. 最佳路径的查找——也就是迭代 我们可以使用 while 语句进行, 终止条件就是迭代得 到的节点是源节点就可以了,例如目标节点是 D,源节点 是 A 那么由 p(D)得到了 C,再由 p(C)得到 B,再有 p(B)得 到 A,迭代终止——我们可以以此得到 DCBA,颠倒顺序 就可以得到最短路径 ABCD 了!
7. 类概览与描述
(1) Grap 类: 自定义的 “图” 类, 用于模拟各个路由器 (节 点)和各条链路(边) ,主要功能函数如下:
Public
Grap(String[]v)——自定义的构造函数,主要
功能有: A. 接收随机定义好的(名字和数量都是由系统随 机指定的)顶点集 B. 对顶点集经行初始化并且初始化任意两个定点 间的距离值(如果不可直达则为无穷大) ,这里 的距离值(即权值)是由系统随机数指定的 C. 依次显示路由器数量、名称、各路由器到其他 路由器的距离值 D. 统计非无穷大边(有限权值边)的数量并显示 (2) Dijkstra 类:主函数类,实现核心功能,主要功能函 数有: A. Public static int min(int[] a)——最小值函数, 获取 一个指定的整型数组中最小值对应的数组下标 B. Public static String[] closestpath(String[] route,String[] p,int star)——路径计算函数,该函 数是建立在已经计算得到最小距离之上的,用 字符串数组依次保存源节点到各目标节点的最 短路径上的路由器名称 C. Public static void dijkstra(Grap g,String star)—— Dijkstra 算法中求找最小距离的功能函数,运行 结果依次显示源节点到各目标节点的最小距离
public static String[] closestpath(String[] route,String[] p,int star){ //计算各条最短路径并且保存于字符串数组中 int num=route.length; int sorce=star; String[] vname=route; String[] path=new String[num]; for(int i=0;i<num;i++) path[i]=vname[i]+" "; String p1="AB"; for(int i=0;i<num;i++){ if(i!=sorce){ p1=p[i]; path[i]+=p1+" "; while( p1!=null&&(!p1.equals(vname[sorce])) ){ //采用逆推思维,从后向前依次表示 //获取节点数 //获取源节点 //获取顶点集 //路径
10 update D(v) for all v adjacent to w and not in N: 11 D(v) = min( D(v), D(w) + c(w,v) ) 12 /* new cost to v is either old cost to v or known 13 shortest path cost to w plus cost from w to v */ 14 until all nodes in N
假设源节点为 A,目标节点为 B,上一行(循环)选中 的节点为 C,那么 D(B) = min{ D(B), distance(C,B)+D(C) } 4. 重复 2、3 步骤(循环)——循环何时终止呢?大家看表 4-3 就会明白循环次数就是节点的个数 5. 得到了最短距离后如何得到最短路径呢?这个时候 p() 就派上用场了,方法也很简单,逆推即可: 设源节点是 A,目标节点是 B,路径就该是 B ← p(B) ← p(p(B)) ← …… ← A
也许如果只是要我们写一个算法,求最短路径和最小距 离,那么我们可能不同的人有不同的“自然而然”的思路, 而且肯定很多并不与 Dijkstra 算法雷同, 但令我们头疼的是: 这里是别人写好了一个算法,我们得去理解,而不是让我
们自己去操刀。 在我看来,与其看那些枯燥无味的算法文字叙述还不如 看图看表—— 我就是看了(中文版) P240 的表 4-3 (它对应着 P238 的图 4-27)才明白是“怎么算的” ,这里我就说下自己的理 解,也不过就是几句话而已: 1. 一开始,将源节点到各点的直达距离作为最短距离; PS: 这里还是要理解表中 D()和 p()的含义——D()就是刚 才说的到目标节点的 “目前认为” 的最短距离, 而 p()是 “当 前认为”的最短路径上到目标节点的前一节点(至少我是 这么认为的:如果只求最短距离,p()是不需要的,p()的作 用是最后用来“逆推”出最短路径! ) 2. 取最小的 D()值那个节点,我们“假装”认为它是最短的 距离。 PS:这里书上说添到一个新的集合中,其实我觉得为 了达到算法目的, 不要这个集合也行, 只要做到以下两点: (1 ) 虑在内 (2) 每一行 D()的更新只需要做到对剩下每一个 D() 检查一次更新即可 3. 到新的一行(也就是每次循环)就对剩下(还没有选过 的节点)的 D()做一个检查更新,方法也很简单: 下一行选最小 D()值时不把之前选过的节点考
4. 实验步骤
(1) 选择合适的编程语言编程实现基于 Dijkstra 算法的路 由软件。 (2) 输入不同的网络拓扑和链路代价测试和验证自己的 路由软件。
5. 实验环境
(1) (2) (3) 实验语言:JAVA 实验平台:Eclipse 引用库函数:随机(Random)库
6. 算法思想理解与描述
在编写代码时, 我曾遇到过两个问题也是最容易碰到的难题, 这里我介绍一下自己的解决方法: