ImageVerifierCode 换一换
格式:DOCX , 页数:8 ,大小:39.68KB ,
资源ID:4695704      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4695704.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(算法分析与设计 求带权最短路径 课程设计.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

算法分析与设计 求带权最短路径 课程设计.docx

1、算法分析与设计 求带权最短路径 课程设计算法设计与分析课程设计报告题 目: 求带权最短路径 专 业: * 学 号: * 姓 名: * 指导教师: * 成 绩: 年 月 日一、问题描述 给定n个 顶点的带权有向图G=(V,E),W=()为G的带权邻接矩阵。定义如下:=对于每一对顶点u,vV,试用动态规划方法,求从u到v的带权最短路径长度,其中路径权值为这条路径所有边上的权值之和。二、设计说明1、基本要求:利用Dijkstra算法,寻找有向图中最短路径 。2、算法说明:Dijkstra算法是由荷兰计算机科学家艾兹格迪科斯彻发现的。算法解决的是有向图中最短路径问题。 Dijkstra算法的输入包含了

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

3、为止所找到的从s到v的最短路径来工作的。初始时,源点s的路径长度值被赋为0(ds=0), 同时把所有其他顶点的路径长度设为无穷大,即表示我们不知道任何通向这些顶点的路径(对于V中所有顶点v除s外dv= )。当算法结束时,dv中储存的便是从s到v的最短路径,或者是无穷大(如果路径不存在的话)。 Dijstra算法的基础操作是边的拓展:如果存在一条从u到v的边,那么从s到v的最短路径可以通过将边(u,v)添加到s到u的尾部来拓展。这条路径的长度是du+w(u,v)。如果这个值比目前已知的dv的值要小,我们可以用新值来替代当前dv中的值。拓展边的操作一直执行到所有的dv都代表从s到v最短路径的花费。

4、这个算法经过适当的组织因而当du达到它最终的值的时候,每条边(u,v)都只被拓展一次。 算法维护两个顶点集S和Q。集合S保留了我们已知的所有dv的值已经是最短路径的值顶点,而集合Q则保留其他所有顶点。集合S初始状态为空,而后每一步都有一个顶点从Q移动到S。这个被选择的顶点是Q中拥有最小的du值的顶点。当一个顶点u从Q中转移到了S中,算法对每条外接边(u,v)进行拓展。3、算法思想: (1)设S为最短距离已确定的顶点集(看作红点集),V-S是最短距离尚未确定的顶点集(看作蓝点集)。 初始化:初始化时,只有源点s的最短距离是已知的(SD(s)=0),故红点集S=s,蓝点集为空。 重复以下工作,按路

5、径长度递增次序产生各顶点最短路径。在当前蓝点集中选择一个最短距离最小的蓝点来扩充红点集,以保证按路径权重递增的次序来产生各顶点的最短路径。当蓝点集中仅剩下最短距离为的蓝点,或者所有蓝点已扩充到红点集时,s到所有顶点的最短路径就求出来了。 注意:若从源点到蓝点的路径不存在,则可假设该蓝点的最短路径是一条长度为无穷大的虚拟路径。 从源点s到终点v的最短路径简称为v的最短路径;s到v的最短路径长度简称为v的最短距离,并记为SD(v)。 (2)在蓝点集中选择一个最短距离最小的蓝点k来扩充红点集 根据按长度递增序产生最短路径的思想,当前最短距离最小的蓝点k的最短路径是: 源点,红点1,红点2,红点n,蓝

6、点k 。距离为:源点到红点n最短距离+边长 为求解方便,设置一个向量D0n-1,对于每个蓝点v V-S,用Dv记录从源点s到达v且除v外中间不经过任何蓝点(若有中间点,则必为红点)的最短路径长度(简称估计距离)。 若k是蓝点集中估计距离最小的顶点,则k的估计距离就是最短距离,即若Dk=minDi iV-S,则Dk=SD(k)。 初始时,每个蓝点v的Dc值应为权w,且从s到v的路径上没有中间点,因为该路径仅含一条边。 注意: 在蓝点集中选择一个最短距离最小的蓝点k来扩充红点集是Dijkstra算法的关键 。(3)k扩充红点集s后,蓝点集估计距离的修改 将k扩充到红点后,剩余蓝点集的估计距离可能由

7、于增加了新红点k而减小,此时必须调整相应蓝点的估计距离。对于任意的蓝点j,若k由蓝变红后使Dj变小,则必定是由于存在一条从s到j且包含新红点k的更短路径:P=。且D j减小的新路径P只可能是由于路径和边组成。所以,当length(P)=Dk+w小于Dj时,应该用P的长度来修改Dj的值。例:如下在有向网G8中,假定以顶点0为源点,则它则其余各顶点的最短路径按路径递增序排列如下表所示 :三、源程序代码package sinboy.datastructure; import java.util.ArrayList; public class Dijkstra . static ArrayList m

8、ap = null; static ArrayList redAgg = null; static ArrayList blueAgg = null; static Side parents = null; public static void main(String args) . / 初始化顶点集 int nodes = . 0, 1, 3, 2, 4, 5,6 ; / 初始化有向权重图 map = new ArrayList(); map.add(new Side(0, 1, 10); map.add(new Side(0, 3, 30); map.add(new Side(0, 4,

9、100); map.add(new Side(1, 2, 50); map.add(new Side(2, 4, 10); map.add(new Side(3, 2, 20); map.add(new Side(3, 4, 60); map.add(new Side(4, 5, 50); map.add(new Side(3, 5, 60); map.add(new Side(5, 6, 10); map.add(new Side(3, 6, 80); / 初始化已知最短路径的顶点集,即红点集,只加入顶点0 redAgg = new ArrayList(); redAgg.add(nodes

10、0); / 初始化未知最短路径的顶点集,即蓝点集 blueAgg = new ArrayList(); for (int i = 1; i nodes.length; i+) blueAgg.add(nodesi); / 初始化每个顶点在最短路径中的父结点,及它们之间的权重,权重-1表示无连通 parents = new Sidenodes.length; parents0 = new Side(-1, nodes0, 0); for (int i = 0; i 0) . MinShortPath msp = getMinSideNode(); if(msp.getWeight()=-1) m

11、sp.outputPath(nodes0); else msp.outputPath(); int node = msp.getLastNode(); redAgg.add(node); / 如果因为加入了新的顶点,而导致蓝点集中的顶点的最短路径减小,则要重要设置 setWeight(node); 得到一个节点的父节点 param parents param node return public static int getParent(Side parents, int node) . if (parents != null) . for (Side nd : parents) . if (

12、nd.getNode() = node) . return nd.getPreNode(); return -1; 重新设置蓝点集中剩余节点的最短路径长度 param preNode param map param blueAgg public static void setWeight(int preNode) . if (map != null & parents != null & blueAgg != null) . for (int node : blueAgg) . MinShortPath msp=getMinPath(node); int w1 = msp.getWeight(

13、); if (w1 = -1) continue; for (Side n : parents) . if (n.getNode() = node) . if (n.getWeight() = -1 | n.getWeight() w1) . n.setWeight(w1); n.setPreNode(preNode);/重新设置顶点的父顶点 break; 得到两点节点之间的权重 param map param preNode param node return public static int getWeight(int preNode, int node) . if (map != nu

14、ll) . for (Side s : map) . if (s.getPreNode() = preNode & s.getNode() = node) return s.getWeight(); return -1; 从蓝点集合中找出路径最小的那个节点 param map param blueAgg return public static MinShortPath getMinSideNode() . MinShortPath minMsp = null; if (blueAgg.size() 0) . int index = 0; for (int j = 0; j blueAgg.s

15、ize(); j+) . MinShortPath msp = getMinPath(blueAgg.get(j); if (minMsp = null | msp.getWeight()!=-1 & msp.getWeight() minMsp.getWeight() . minMsp = msp; index = j; blueAgg.remove(index); return minMsp; 得到某一节点的最短路径(实际上可能有多条,现在只考虑一条)param node return public static MinShortPath getMinPath(int node) . Mi

16、nShortPath msp = new MinShortPath(node); if (parents != null & redAgg != null) . for (int i = 0; i -1) . int weight = getWeight(parent, curNode); if (weight -1) . tempMsp.addNode(parent); tempMsp.addWeight(weight); curNode = parent; parent = getParent(parents, parent); else break; if (msp.getWeight(

17、) = -1 | tempMsp.getWeight()!=-1 & msp.getWeight() tempMsp.getWeight() msp = tempMsp; return msp; 图中的有向边,包括节点名及他的一个前向节点名,和它们之间的权重 class Side . private int preNode; / 前向节点 private int node;/ 后向节点 private int weight;/ 权重 public Side(int preNode, int node, int weight) . this.preNode = preNode; this.nod

18、e = node; this.weight = weight; public int getPreNode() . return preNode; public void setPreNode(int preNode) . this.preNode = preNode; public int getNode() . return node; public void setNode(int node) . this.node = node; public int getWeight() . return weight; public void setWeight(int weight) . th

19、is.weight = weight; class MinShortPath . private ArrayList nodeList;/ 最短路径集 private int weight;/ 最短路径 public MinShortPath(int node) . nodeList = new ArrayList(); nodeList.add(node); weight = -1; public ArrayList getNodeList() . return nodeList; public void setNodeList(ArrayList nodeList) . this.node

20、List = nodeList; public void addNode(int node) . if (nodeList = null) nodeList = new ArrayList(); nodeList.add(0, node); public int getLastNode() . int size = nodeList.size(); return nodeList.get(size - 1); public int getWeight() . return weight; public void setWeight(int weight) . this.weight = wei

21、ght; public void outputPath() . outputPath(-1); public void outputPath(int srcNode) . String result = ; if (srcNode != -1) nodeList.add(srcNode); for (int i = 0; i nodeList.size(); i+) . result += + nodeList.get(i); if (i nodeList.size() - 1) result += ,; result += : + weight; System.out.println(res

22、ult); public void addWeight(int w) . if (weight = -1) weight = w; else weight += w; 运行结果如下: 0,1:10 0,3:30 0,3,2:50 0,3,2,4:60 0,3,5:90 0,3,5,6:100 四、其他最短路径问题 最短路径问题的提法很多,其它的最短路径问题均可用单源最短路径算法予以解决: 单目标最短路径问题(Single-Destination Shortest-Paths Problem):找出图中每一顶点v到某指定顶点u的最短路径。只需将图中每条边反向,就可将这一问题变为单源最短路径问题,

23、单目标u变为单源点u。 单顶点对间最短路径问题(Single-Pair Shortest-Path Problem):对于某对顶点u和v,找出从u到v的一条最短路径。显然,若解决了以u为源点的单源最短路径问题,则上述问题亦迎刃而解。而且从数量级来说,两问题的时间复杂度相同。 所有顶点对间最短路径问题(All-Pairs Shortest-Paths Problem):对图中每对顶点u和v,找出u到v的最短路径问题。这一问题可用每个顶点作为源点调用一次单源最短路径问题算法予以解决。五、总结 最短路径算法关键是先把已知最短路径顶点集(只有一个源点)和未知的顶点分开,然后依次把未知集合的顶点按照最短路径(这里特别强调一下是源点到该顶点的路径权重和,不仅仅是指它和父结点之间的权重,一开始就是没有在这个问题上弄清楚)加入到已知结点集中。在加入时可以记录每个顶点的最短路径,也可以在加入完毕后回溯找到每个顶点的最短路径和权重。参考文献:1数据结构 严蔚敏,吴伟民 清华大学出版社出版2算法设计与分析 霍红卫 清华大学出版社出版 3算法设计与分析 郑宗汉,郑晓明 清华大学出版社

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1