多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx

上传人:b****6 文档编号:5920024 上传时间:2023-01-02 格式:DOCX 页数:11 大小:79.76KB
下载 相关 举报
多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx_第1页
第1页 / 共11页
多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx_第2页
第2页 / 共11页
多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx_第3页
第3页 / 共11页
多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx_第4页
第4页 / 共11页
多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx

《多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx》由会员分享,可在线阅读,更多相关《多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx(11页珍藏版)》请在冰豆网上搜索。

多种方法求多段图地最短路径问题 算法设计与分析报告课程设计.docx

多种方法求多段图地最短路径问题算法设计与分析报告课程设计

学号:

《算法设计与分析B》

大作业

 

题目

多种方法解决多段图的最短路径问题

学院

计算机科学与技术学院

专业

软件工程

班级

姓名

指导教师

2014

12

26

多种方法解决多段图的最短路径问题

摘要

多段图的最短路径问题是求从源点到终点的最小代价路径。

本文主要描述的是分别用动态规划法、贪心法和分支限界法来解决多段图最短路径问题时的情况。

文章首先阐述了各个方法的原理,主要的思路是通过输入一组数据,比拟三者的输出结果的准确性以与运行时间,以之为根底来分析、讨论三者的性能区别。

文章最后讲述了假如这几种方法运行到有向图中的情况,几种方法的比照和它们比拟适应的使用情况的讨论,并给出了自己的建议。

关键字:

多段图最短路径问题;动态规划法;分支限界法;贪心法

3贪心法求解2

1引言

当前社会,关于最短路径的问题屡屡出现。

例如在开车自驾游的一个过程中,排除其它影响因素,从一个地点到另一点,这个时候必然是希望有一条距离最短的路程来尽量减少消耗的时间以与花费的〔它们在模型中被称为代价〕,市场上对该问题的解决有很大的需求,因此,这里我将讨论多段图的最短路径的问题。

大二开设的《数据结构》课程中就包括最短路径这方面问题的讨论。

当时教师介绍了分别面向单源〔Dijkstra算法〕与非单源〔Floyd算法〕两种问题的算法——这是我们最早的对最短路径方面的理解,也是我们接触的比拟早的关于图的问题。

在这学期的《算法设计与分析》课程中,我们学习了很多根本的算法设计技术,蛮力法、分治法、减治法、动态规划法、贪心法、回溯法、分支限界法等,它们把以前学习的诸多方法都命名并归纳分类起来,其中有多种算法都可以用来解决最短路径问题,并且该问题作为一个图的问题,对该问题的继续探讨优化的需求很大、本文将就不同算法在解决该最短路径问题时的不同方法进展比照并给出该问题在不同根底上不同的最终解决方案。

由于时间的限制,本文将重点分析动态规划法下的情况,并会对图的情况加以简化、限制,最后会对其它的图做一些拓展。

2问题描述

设图G=(V,E)是一个带权有向连通图,如果把顶点集合V划分成k个互不相交的子集Vi〔2≤k≤n,1≤i≤k〕,使得E中的任何一条边(u,v),必有u∈Vi,v∈Vi+m〔1≤i<k,1<i+m≤k〕,如此称图G为多段图,称s∈V1为源点,t∈Vk为终点。

多段图的最短路径问题是求从源点到终点的最小代价路径。

多段图的最短路径问题是求从源点到终点的最小代价路径。

由于多段图将顶点划分为k个互不相交的子集,所以,可以将多段图划分为k段,每一段包含顶点的一个子集。

不失一般性,将多段图的顶点按照段的顺序进展编号,同一段内顶点的相互顺序无关紧要。

假设图中的顶点个数为n,如此源点s的编号为0,终点t的编号为n-1,并且,对图中的任何一条边(u,v),顶点u的编号小于顶点v的编号。

这里我们讨论的多段图是可以分段的,各段之间的关系最好是单向的,即对该有向图来说,图中是没有环的存在的。

3贪心法求解

3.1贪心法介绍

贪心法是一种简单有效的方法。

它在解决问题的策略上只根据当前已有的信息就做出选择,而且一旦做出了选择,不管将来有什么结果,这个选择都不会改变。

贪心法并不是从整体最优考虑,它所做出的选择只是在某种意义上的局部最优。

这种局部最优选择并不总能获得整体最优解,但通常能获得近似最优解。

本例中利用的贪心算法,是每当要选择下一个结点时,总是选择与当前结点间代价最小的点,这就叫做总是优先局部最优解,以此得到最终的解序列。

这里举一个贪心法的拓展例子Dijkstra算法。

Dijkstra算法是一种最短路径算法,用于计算一个节点到其它所有节点的最短路径,动态路由协议OSPF中就用到了Dijkstra算法来为路由计算最短路径。

算法本身并不是按照我们的正常思维习惯,我们一般会从原点遍历所有与之相连的节点,找到最短路径,再从最短路径上的那个点遍历与之相连的所有其它点〔原点除外〕,然后依次类推。

这样做虽然可以算出一个树形,但是在大多数情况下,这种算法会产生很屡次优路径,也就是说非最短路径。

Dijkstra算法的大概过程:

假设有两个集合或者说两个表,表A和表B,表A表示生成路径,表B表示最后确定的路径

(1)从原点出发,遍历检查所有与之相连的节点,将原点和这些节点存放到表A中,并记录下两节点之间的代价;

(2)将代价最小的代价值和这两节点移动到表B中〔其中一个是原点〕;

(3)把这个节点所连接的子节点找出,放入到表A中,算出子节点到原点的代价;

(4)重复第二步和第三步直到表A为空。

然后根据表B中的数据算出最优树。

维基百科中还有另一种说法,Dijkstra算法的输入包含了一个有权重的有向图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到任何其它顶点的最短路径。

3.2问题分析

以起始点为中心向外层层扩展,直到扩展到终点为止。

Dijstra算法〔边的拓展〕{

While〔!

(每一个d[v]==最短路径)〕

If〔存在一条从u到v的边〕

If(d[u]+w(u,v)

d[v]=d[u]+w(u,v);}

4动态规划法求解

4.1动态规划法介绍

动态规划主要用于求解以时间划分阶段的动态过程的优化问题,但是一些与时间无关的静态规划〔如线性规划、非线性规划〕,可以人为地引进时间因素,把它视为多阶段决策过程,也可以用动态规划方法方便地求解。

动态规划是考察问题的一种途径,或是求解某类问题的一种方法。

动态规划问世以来,在经济管理、生产调度、工程技术和最优控制等方面得到了广泛的应用。

例如最短路线、库存管理、资源分配、设备更新、排序、装载等问题,用动态规划方法比其它方法求解更为方便。

动态规划法设计算法一般分成三个阶段:

(1)划分子问题:

将原问题分解为假如干个子问题,每个子问题对应一个决策阶段,并且子问题之间具有重叠关系;

(2)确定动态规划函数:

根据子问题之间的重叠关系找到子问题满足的递推关系式(即动态规划函数),这是动态规划法的关键;

(3)填写表格:

设计表格,以自底向上的方式计算各个子问题的解并填表,实现动态

原问题的解

原问题

……

填表

 

子问题1

子问题2

子问题n

规划过程。

 

4.2问题分析

设数组cost[n]存储最短路径长度,cost[j]表示从源点s到顶点j的最短路径长度,数组path[n]记录状态转移,path[j]表示从源点到顶点j的路径上顶点的前一个顶点,动态规划法求解多段图的最短路径问题的算法如下:

输入:

多段图的代价矩阵

输出:

最短路径长度与路径

1.循环变量j从1~n-1重复下述操作,执行填表工作:

1.1考察顶点j的所有入边,对于边(i,j)∈E:

1.1.1cost[j]=min{cost[i]+cij};

1.1.2path[j]=使cost[i]+cij最小的i;

1.2j++;

2.输出最短路径长度cost[n-1];

3.循环变量i=path[n-1],循环直到path[i]=0:

3.1输出path[i];

3.2i=path[i];

第一局部是依次计算各个顶点到终点的最短路径,由两层嵌套的循环组成,外层循环执行n-1次,内层循环对所有入边进展计算,并且在所有循环中,每条入边只计算一次。

假定图的边数为m,如此这局部的时间性能是O(m);第二局部是输出最短路径经过的顶点,设多段图划分为k段,其时间性能是O(k)。

所以,该算法的时间复杂性为O(n+k)。

5分支限界法求解

5.1分支限界法介绍

分支限界法按广度优先策略搜索问题的解空间树,在搜索过程中,对待处理的结点根据限界函数估算目标函数的可能取值,从中选取使目标函数取得极值〔极大或极小〕的结点优先进展广度优先搜索,从而不断调整搜索方向,尽快找到问题的解。

5.2问题分析

讨论当用分支限界法用来解决多段图路径问题的过程:

首先对该多段图应用贪心法求得近似解,并算出其代价路径。

将其作为多段图最短路径问题的上界。

而把每一段最小的代价相加,可以得到一个非常简单的下界。

于是,就可以得到了目标函数的一个大致的X围。

由于多段图将顶点划分为k个互不相交的子集,所以,多段图划分为k段,一旦某条路径的一些段被确定后,就可以并入这些信息并计算局部解的目标函数值的下界。

一般情况下,对于一个正在生成的路径,假设已经确定了i段〔1≤i≤k〕,其路径为(r1,r2,…,ri,ri+1),此时,该局部解的目标函数值的计算方法即限界函数如下:

应用分支限界法同样求解多段图的最短路径问题,具体的搜索过程是这样进展的,首先考虑根节点,根据限界函数算出目标函数的值,这里每种情况下的目标函数值下界都要算出来并且加以比拟,下界的计算方法为除了加上选定点与初始点之间的距离外,以后的第一个点选择一选定点为初始点到下段最小代价的路径,以后的段与段之间的代价都按它们之间最小的代价来计算。

这样再加上根节点与初始阶段之间的最小代价,就得到这种情况下的解了。

在得到的代价中,找出最小的代价,并以之为初始结点循环往下做,直到到达目标结点。

算法如下:

1.根据限界函数计算目标函数的下界down;采用贪心法得到上界up;

2.将待处理结点表PT初始化为空;

3.for(i=1;i<=k;i++)x[i]=0;

4.i=1;u=0;//求解第i段

5.while(i>=1)

5.1对顶点u的所有邻接点v

5.1.1计算目标函数值lb;

5.1.2假如lb<=up,如此将i,,lb存储在表PT中;

5.2如果i==k-1且叶子结点的lb值在表PT中最小,

如此输出该叶子结点对应的最优解;

5.3否如此,如果i==k-1且表PT中的叶子结点的lb值不是最小,如此

5.3.1up=表PT中的叶子结点最小的lb值;

5.3.2将表PT中目标函数值超出up的结点删除;

5.4u=表PT中lb最小的结点的v值;

5.5i=表PT中lb最小的结点的i值;i++;

6程序清单

6.1源代码

#include

constintN=20;

constintMAX=1000;

intarc[N][N];

intBackpath(intn);

intcreatGraph();

intcreatGraph()

{

inti,j,k;

intweight;

intvnum,arum;

cout<<"输入顶点的个数和边的个数:

"<

cin>>vnum>>arum;

for(i=0;i

for(j=0;j

arc[i][j]=MAX;

for(k=0;k

{

cout<<"输入边的两个顶点和权值:

";

cin>>i>>j>>weight;

arc[i][j]=weight;

}

returnvnum;

}

intBackpath(intn)

{

inti,j,temp;

intcost[N];

intpath[N];

for(i=0;i

{

cost[i]=MAX;

path[i]=-1;

}

cost[0]=0;

for(j=1;j

{

for(i=j-1;i>=0;i--)

{

if(arc[i][j]+cost[i]

{

cost[j]=arc[i][j]+cost[i];

path[j]=i;

}

}

}

cout<

i=n-1;

while(path[i]>=0)

{

cout<<"<-"<

i=path[i];

}

cout<

returncost[n-1];

}

intmain()

{

intn=creatGraph();

intpathLen=Backpath(n);

cout<<"最短路径的长度是:

"<

return0;

}

6.2结果截图

7结果分析

(1)贪心法、动态规划法和分支限界法都可以用来解决多段最短路径问题,然而在这种情况相比之下,贪心法的运算效率比拟高,因为它不像另外两种方法一样,需要涉与到许多的点。

可以看到,动态规划法由于需要填表,并有一个相关的迭代问题,它几乎涉与了所有的点;而分支限界法,它通过贪心法设置的上下限,并以它们为依据进展剪枝,减少了许多的运算量。

而贪心法,访问了最少的点。

(2)就结果准确性来看,就此题例子来看,贪心法结果为02479,路径的代价为20;动态分配法采取的路径为:

03589,路径的代价为16;而分支限界法,结果为03589,路径的代价为16。

可以看出,在这个方面,动态分配法和分支限界法都达到了预期的结果,相比直线,贪心法的误差就比拟大了。

由以上的讨论,我们可以看出分支限界法的综合性能比拟好,它和动态规划法在解决多段最短路径问题时都可以得到正确解,而贪心法虽然可以省时间与空间,但结果不准确是它的缺点。

各方法都是有利有弊的。

因此在选择方法时,还应当根据实际情况。

当只需要大概的一个解时,当然是要用省时省力的贪心法;如果对结果又比拟高的要求的话,就要采取动态规划法或分支限界法。

dijkstra算法的明显优点就是它的多用性,它可以求任意一点到其它某一点的距离,但是它访问的数据量很大,几乎要访问所有的边〔相对于贪心法而言〕,因此这里来说,在单纯的解决多段最短路径问题时,它们的功能都差不多,而在解决其它较复杂的图时,Dijkstra算法有明显的优越性,但当然,作为贪心法的一种,它的结果的准确性不是那么的高。

Dijkstra算法在本质上为贪心算法,每一步的选择为当前步的最优,复杂度为O(n*n)。

动态规划法是可以看作是对分支限界法的改良。

其实,它们各有各的优缺点,可以尝试将它们混合起来用,扬长避短,设置X围,并且过程中对肯定不会是最后结果的数据“剪枝〞。

这样就可以提高运行速率了。

8课程体会

算法分析与设计是一门非常重要的课程。

很多问题的解决,程序的编写都要依赖它,在软件还是面向过程的阶段,就有“程序=算法+数据结构〞这个公式。

算法的学习对于培养一个人的逻辑思维能力是有极大帮助的,它可以培养我们养成思考分析问题,解决问题的能力。

作为IT行业学生,学习算法无疑会增强自己的竞争力,修炼自己的“内功〞。

 

谢谢教师的指导,学习《算法分析与设计》使我对软件根底知识中算法的地位有了充分的了解,虽然课程完毕了,但我依然还会继续学习算法分析与设计,以后我将充分利用所学到我实际的开发项目中。

9参考文献

[1]

[2]严蔚敏,吴伟民.数据结构(C语言版).:

清华大学.2010

[3]余祥宣,催国华,邹海明.计算机算法根底〔第三版〕[M].某某:

华中科技大学.2006

  

 

班级

学号

某某

大作业题目

多种方法解决多段图的最短路径问题

评阅点

评分标准〔细如此〕

分值

实得分

算法设计与实现

〔40分〕

正确实现本程序所需全部功能,算法设计正确合理且有一定创新,结果正确

40分

实现所需功能,算法正确,结果正确

30分

根本实现所需功能,结果正确

15分

有明显重大错误

5分

无法实现程序功能

0分

算法分析

〔20分〕

算法分析全面、详细、正确

20分

算法分析比拟全面、正确

15分

算法分析根本正确

10分

算法分析有明显错误

5分

程序可读、可维护性

〔10分〕

程序可读性好、逻辑清晰,程序完整,可维护性好

10分

程序可读、可维护

8分

根本可读可维护

5分

逻辑混乱、不可读

0分

报告质量

〔20分〕

报告规X,符合技术用语要求,行文流畅,层次清晰

20分

报告书写根本规X,符合技术用语要求,文理较通畅

15分

结构较合理,层次较清楚,根本符合要求

10分

结构混乱,文不对题目,或者有明显抄袭现象

5分

设计验收

好10分;通过8分;根本合格6分

10分

总分

大作业成绩评定表

教师签名:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学

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

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