算法设计与分析实验报告实验名称动态规划算法实现多段图的最短路径问题 评分实验日期 年月 日 指导教师 ## 专业班级 学号 一.实验要求1. 理解最优子结构的问题.有一类问题的活动过程可以分成若干个阶段,而且在任一阶段后的行为依赖于该阶段的状态,与该阶段之前的过程如何达到这种状态的方式无关.这类问题的解决是多阶段的决策过程.在50年代,贝尔曼〔Richard Bellman〕等人提出了解决这类问题的"最优化原理",从而创建了最优化问题的一种新的算法设计方法-动态规划.对于一个多阶段过程问题,是否可以分段实现最优决策,依赖于该问题是否有最优子结构性质,能否采用动态规划的方法,还要看该问题的子问题是否具有重叠性质.最优子结构性质:原问题的最优解包含了其子问题的最优解.子问题重叠性质:每次产生的子问题并不总是新问题,有些子问题被反复计算多次.问题的最优子结构性质和子问题重叠性质是采用动态规划算法的两个基本要素.2.理解分段决策Bellman方程.每一点最优都是上一点最优加上这段长度.即当前最优只与上一步有关.Us 初始值,uj第j段的最优值.3.一般方法1) 找出最优解的性质,并刻画其结构特征;2) 递归地定义最优值〔写出动态规划方程〕;3) 以自底向上的方式计算出最优值;4) 根据计算最优值时得到的信息,构造一个最优解.步骤1-3是动态规划算法的基本步骤.在只需要求出最优值的情形,步骤4可以省略,步骤3中记录的信息也较少;若需要求出问题的一个最优解,则必须执行步骤4,步骤3中记录的信息必须足够多以便构造最优解.二.实验内容1.编程实现多段图的最短路径问题的动态规划算法.2.图的数据结构采用邻接表.3.要求用文件装入5个多段图数据,编写从文件到邻接表的函数.4.验证算法的时间复杂性.三.程序算法多段图算法:Procedure FGRAPH〔E,k,n,P〕//输入是按段的顺序给结点编号的,有n个结点的k段图.E是边集,c〔i,j〕是边的成本.P〔1:k〕是最小成本路径.//real COST,integer,P,r,j,k,nCOST<-0for j<-n-1 to 1 by -1 do //计算COST〔j〕//设r是一个这样的结点,〔j,r〕E且使c〔j,r〕+COST〔r〕取最小值COST〔j〕<- c〔j,r〕+COST〔r〕;D<-r;Repeat //向前对j-1进行决策//P〔1〕<-1; P〔k〕<-n;for j<-2 to k-1 do // 找路径上的第j个节点// P〔j〕<-D>;repeat;end FGRAPH四. 程序代码#include #include #include #include #define MAX 100 #define n 12 /*顶点数*/#define k 5 /*段数*/int c[n][n];void init //初始化图{ int i,j; for { for { c[i][j]=MAX; } } c[1][2]=9; c[1][3]=7; c[1][4]=3; c[1][5]=2; c[2][6]=4; c[2][7]=2; c[2][8]=1; c[3][6]=2; c[3][7]=7; c[4][8]=11; c[5][7]=11; c[5][8]=8; c[6][9]=6; c[6][10]=5; c[7][9]=4; c[7][10]=3; c[8][10]=5; c[8][11]=6; c[9][12]=4; c[10][12]=2;c[11][12]=5;}void fgraph //使用向前递推算法求多段图的最短路径{ int r,j,temp,min; for cost[j]=0; for=1;j--> { temp=0; min=c[j][temp]+cost[temp]; //初始化最小值 for { if { if< //找到最小的r { min=c[j][r]+cost[r]; temp=r; } } } cost[j]=c[j][temp]+cost[temp]; d[j]=temp; } path[1]=1; path[k]=n; for path[j]=d[path[j-1]];}void bgraph//使用向后递推算法求多段图的最短路径{ int r,j,temp,min; for bcost[j]=0; for { temp=12; min=c[temp][j]+bcost[temp]; //初始化最小值 for { if { if< //找到最小的r { min=c[r][j]+bcost[r]; temp=r; } } } bcost[j]=c[temp][j]+bcost[temp]; d[j]=temp; } path1[1]=1; path1[k]=n; for=2;i--> { path1[i]=d[path1[i+1]]; }}void main<>{ int cur=-1; int cost[13],d[12],bcost[13]; int path[k]; int path1[k]; cout<<"\t\t\t动态规划解多段图问题"<; fgraph; cout<<"输出使用向前递推算法后的最短路径:\n\n"; for { cout<; for { cout<