动态规划算法实现多段图的最短路径问题算法设计与分析实验报告

合集下载

最短路径的实验报告

最短路径的实验报告

最短路径的实验报告最短路径的实验报告引言:最短路径问题是图论中一个经典的问题,涉及到在一个带有权重的图中找到两个顶点之间的最短路径。

本实验旨在通过实际操作和算法分析,深入探讨最短路径算法的性能和应用。

实验设计:本次实验使用了Dijkstra算法和Floyd-Warshall算法来解决最短路径问题。

首先,我们使用Python编程语言实现了这两个算法,并对它们进行了性能测试。

然后,我们选择了几个不同规模的图进行实验,以比较这两种算法的时间复杂度和空间复杂度。

最后,我们还在实际应用中使用了最短路径算法,以验证其实用性。

实验过程:1. 实现Dijkstra算法Dijkstra算法是一种贪心算法,用于求解单源最短路径问题。

我们首先实现了该算法,并对其进行了性能测试。

在测试中,我们使用了一个包含1000个顶点和5000条边的图,记录了算法的运行时间。

结果显示,Dijkstra算法的时间复杂度为O(V^2),其中V表示图中的顶点数。

2. 实现Floyd-Warshall算法Floyd-Warshall算法是一种动态规划算法,用于求解所有顶点对之间的最短路径。

我们在Python中实现了该算法,并对其进行了性能测试。

在测试中,我们使用了一个包含100个顶点和5000条边的图,记录了算法的运行时间。

结果显示,Floyd-Warshall算法的时间复杂度为O(V^3),其中V表示图中的顶点数。

3. 比较两种算法通过对Dijkstra算法和Floyd-Warshall算法的性能测试,我们可以看到,Dijkstra算法在处理较大规模的图时性能更好,而Floyd-Warshall算法在处理较小规模的图时性能更好。

因此,在实际应用中,我们可以根据图的规模选择合适的算法。

4. 应用实例为了验证最短路径算法的实际应用性,我们选择了一个城市交通网络图进行实验。

我们使用了Dijkstra算法来计算两个城市之间的最短路径,并将结果与实际的驾车时间进行比较。

算法设计与分析实验报告三篇

算法设计与分析实验报告三篇

算法设计与分析实验报告一实验名称统计数字问题评分实验日期2014 年11 月15 日指导教师姓名专业班级学号一.实验要求1、掌握算法的计算复杂性概念。

2、掌握算法渐近复杂性的数学表述。

3、掌握用C++语言描述算法的方法。

4.实现具体的编程与上机实验,验证算法的时间复杂性函数。

二.实验内容统计数字问题1、问题描述一本书的页码从自然数1 开始顺序编码直到自然数n。

书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。

例如,第6 页用数字6 表示,而不是06 或006 等。

数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2, (9)2、编程任务给定表示书的总页码的10 进制整数n (1≤n≤109) 。

编程计算书的全部页码中分别用到多少次数字0,1,2, (9)三.程序算法将页码数除以10,得到一个整数商和余数,商就代表页码数减余数外有多少个1—9作为个位数,余数代表有1—余数本身这么多个数作为剩余的个位数,此外,商还代表1—商本身这些数出现了10次,余数还代表剩余的没有计算的商的大小的数的个数。

把这些结果统计起来即可。

四.程序代码#include<iostream.h>int s[10]; //记录0~9出现的次数int a[10]; //a[i]记录n位数的规律void sum(int n,int l,int m){ if(m==1){int zero=1;for(int i=0;i<=l;i++) //去除前缀0{ s[0]-=zero;zero*=10;} }if(n<10){for(int i=0;i<=n;i++){ s[i]+=1; }return;}//位数为1位时,出现次数加1//位数大于1时的出现次数for(int t=1;t<=l;t++)//计算规律f(n)=n*10^(n-1){m=1;int i;for(i=1;i<t;i++)m=m*10;a[t]=t*m;}int zero=1;for(int i=0;i<l;i++){ zero*= 10;} //求出输入数为10的n次方int yushu=n%zero; //求出最高位以后的数int zuigao=n/zero; //求出最高位zuigaofor(i=0;i<zuigao;i++){ s[i]+=zero;} //求出0~zuigao-1位的数的出现次数for(i=0;i<10;i++){ s[i]+=zuigao*a[l];} //求出与余数位数相同的0~zuigao-1位中0~9出现的次数//如果余数是0,则程序可结束,不为0则补上所缺的0数,和最高位对应所缺的数if(yushu==0) //补上所缺的0数,并且最高位加1{ s[zuigao]++;s[0]+=l; }else{ i=0;while((zero/=10)>yushu){ i++; }s[0]+=i*(yushu+1);//补回因作模操作丢失的0s[zuigao]+=(yushu+1);//补回最高位丢失的数目sum(yushu,l-i-1,m+1);//处理余位数}}void main(){ int i,m,n,N,l;cout<<"输入数字要查询的数字:";cin>>N;cout<<'\n';n = N;for(i=0;n>=10;i++){ n/=10; } //求出N的位数n-1l=i;sum(N,l,1);for(i=0; i<10;i++){ cout<< "数字"<<i<<"出现了:"<<s[i]<<"次"<<'\n'; }}五.程序调试中的问题调试过程,页码出现报错。

多段图算法实验报告

多段图算法实验报告

算法分析与设计实验报告课题: 多段图******班级:计算机1101学号:**********目录一、实验目的二、实验内容三、实验要求四、概要设计五、详细设计六、实验心得一、实验目的加深理解动态规划策略,求出多段图中源点到各点的最短路径。

二、实验内容设G=(V,E)是一个赋权有向图,其顶点集V被划分成k>2个不相交的子集Vi: 1≤i≤k,其中,V1和Vk分别只有一个顶点s(称为源)和一个顶点t(称为汇),图中所有的边(u,v)的始点和终点都在相邻的两个子集Vi和Vi+1中:u∈Vi,v∈Vi+1。

找一条从s到t的最短路线。

三、实验要求在上机前写出全部源程序;能在机器上正确运行程序;四、概要设计图采用邻接矩阵表示设P(i,j)是一条从Vi中的结点j到汇点t的最小成本路径,COST(i,j)是这条路的成本。

则从Vi中节点j到t的最小代价为:cost((i,j)=min{cost(i+1,l)+c (j,l) }, l∈Vi+1 , j∈Vicost(i+1,l)是从Vi+1中节点l 到t的最小代价。

算法概要设计如下:多段图的向前处理算法procedure FGRAPH(G,k,n,P){//G有n个结点的k段图。

E是边集,c[i,j]是边<i,j>的成本。

P[1:k]是最小成本路径。

//COST[n], D[n一1],P[k],r,j,k,nCOST[n]← 0for j←n-1to 1 by -1 do //计算COST[j]//{设r是一个这样的结点,(j,r) E且使c[j,r]+COST[r]取最小值COST[j]←c[j,r]+COST[r]D[j]←r} //向前对j-1进行决策//P[1]←1P[k]←nfor j←2 to k-1 do //找路径上的第j个节点//P[j]←D [ P[j-1] ]五、详细设计:#include <stdio.h>#include <stdlib.h>#define N 12#define K 5#define MAX 23767int cost[N][N];int path[K];typedef struct node{int v;int w;struct node *next;}node;node L[N];void init(node *L[]){int i, j;node *p, *q;for (i = 0; i < N; i++)for (j = 0; j < N; j++)cost[i][j] = MAX;cost[0][1] = 9;cost[0][2] = 7;cost[0][3] = 3;cost[0][4] = 2;cost[1][5] = 4;cost[1][6] = 2;cost[1][7] = 1;cost[2][5] = 2;cost[2][6] = 7;cost[3][7] = 11;cost[4][6] = 11;cost[4][7] = 8;cost[5][8] = 6;cost[5][9] = 5;cost[6][8] = 4;cost[6][9] = 3;cost[7][9] = 5;cost[7][10] = 6;cost[8][11] = 4;cost[9][11] = 2;cost[10][11] = 5;/*生成邻接表*/for (i = 0; i < N; i++)L[i] = (node *)malloc(sizeof(node));for (i = 0; i < N; i++){q = L[i];for (j = 0; j < N; j++)if (cost[i][j] > 0 && cost[i][j] < MAX){p = (node *)malloc(sizeof(node));p->v = j;p->w = cost[i][j];q->next = p;q = p;}q->next = NULL;}}void Method1() /*使用邻接矩阵存储*/{int i, j, maxlen, temp, v[N], d[N];for (i = 0; i < N; i++)v[i] = 0;for (i = N - 2; i >= 0; i--){for (maxlen = MAX, j = i + 1; j <= N - 1; j++)if (cost[i][j] > 0 && cost[i][j] + v[j] < maxlen){maxlen = cost[i][j] + v[j];temp = j;}v[i] = maxlen;d[i] = temp;}path[0] = 0;path[K-1] = N - 1;for (i = 1; i <= K - 2; i++)path[i] = d[path[i-1]];}void Method2(node *L[]) /*使用邻接表存储*/ {int i, j, maxlen, temp, v[N], d[N];node *p;for (i = 0; i < N; i++)v[i] = 0;for (i = N - 2; i >= 0; i--){p = L[i]->next;maxlen = MAX;while (p){if (p->w + v[p->v] < maxlen){maxlen = p->w + v[p->v];temp = p->v;}p = p->next;}v[i] = maxlen;d[i] = temp;}path[0] = 0;path[K-1] = N - 1;for (i = 1; i <= K - 2; i++)path[i] = d[path[i-1]];}void print(){int i;for (i = 0; i < K; i++)printf("%d ", path[i] + 1);printf("\n");}int main(){init(&L);printf("最短路径:\n ");Method1();print();printf("最短路径:\n");Method2(&L);print();system("pause");return 0;}六.实验心得通过本次试验,掌握了动态规划的思想,即如果一个问题的最优解可以分解为找子问题的最优解,那么即可使用动态规划。

算法设计与分析-多段图最短路径问题

算法设计与分析-多段图最短路径问题

算法设计与分析-多段图最短路径问题关于多段图最短路径问题的探讨摘要:本⽂主要描述的是分别⽤动态规划法、贪⼼法和分⽀限界法来解决多段图最短路径问题时的情况,并在附录中附有实际问题的程序来辅助阐述观点。

⽂章⾸先阐述了各个⽅法的原理,主要的思路是通过输⼊⼀组数据,⽐较三者的输出结果的准确性以及运⾏时间,以之为基础来分析、讨论三者的性能区别。

另外,众所周知,多段图是有向图的⼀个简单的模型,它在有向图的基础上忽略了两点之间的线的双向性的问题,并且对点与点之间的线有很多的要求,从⽽把图简化为可分为⼏段的模式,⽂章最后讲述了若这⼏种⽅法运⾏到有向图中的情况,⼏种⽅法的对⽐和它们⽐较适应的使⽤情况的讨论,并给出了⾃⼰的建议。

关键字:多段图最短路径问题动态规划法分⽀限界法多段图与有向图的关系有向图最短路径算法引⾔:当前社会,关于最短路径的问题屡屡出现。

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

在早些时间的课程中,我们学习过数据结构这门课程,其中就包括最短路径这⽅⾯的讨论。

当时⽼师给我们介绍了分别⾯向单源(Dijkstra算法)与⾮单源(Floyd算法)两种问题的算法法---,这是我们最早的对最短路径⽅⾯的理解,也是我们接触的⽐较早的关于图的问题。

在这学期的算法课程中,我们学习了许多了⽅法,包括贪⼼法、动态规划法等算法,它们把以前学习的许多⽅法都命名并归纳分类起来,其中有许多算法都是可以⽤来解决这个最短路径的问题的,并且该问题作为⼀个图的问题,对该问题的继续探讨优化的需求很⼤,本⽂将就不同算法在解决该最短路径问题时的不同⽅法进⾏对⽐并给出该问题在不同基础上不同的最终解决⽅案。

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

动态规划实现最短路径问题

动态规划实现最短路径问题

动态规划实现最短路径问题⼀、设计最短路径的动态规划算法 <算法导论>中⼀般将设计动态规划算法归纳为下⾯⼏个步骤: 1)分析最优解的结构 2)递归定义最优解的值 3)⾃底向上计算最优解的值 4)从计算的最优解的值上⾯构建出最优解⼆、最短路径的结构 从最优解的结构开始分析(我们假设没有权值为负的路径),对于图G<V,E>的所有结点对最短路径的问题,我们能知道⼀条最短路径的⼦路径都是最短路径。

假设⽤邻接矩阵W=w(ij)来表⽰输⼊带权图,考虑从结点i到结点j的⼀条最短路径p,如果p最多有m(m为有限值)条边。

若i=j,则p的权值为0⽽且不包含其他边。

若i ≠ j,可以将i到j的路径转换为i -> k、k->j。

三、⼀个给定的图 1)给定⼀个有向图 2)我们可以给出这个有向图的邻接矩阵四、C++实现1 #include <iostream>2 #include<fstream>3 #include<sstream>4 #include<vector>5 #include<string>6using namespace std;7const int Max_Num = 100;89 typedef struct Point {10int n; //点的个数11double p[Max_Num];12double q[Max_Num];13int root[Max_Num][Max_Num];14double w[Max_Num][Max_Num];15double e[Max_Num][Max_Num];16 }Point;1718 vector<Point> points;19 vector<string> res;20 vector<int> num;2122void file_read();23void createPoint();24void optimalBST();25void printRoot(Point P);26void printOptimalBST(int i, int j, int r, Point P, ofstream &fileWrite);27 template <class Type>28 Type stringToNum(const string& str) {29 istringstream iss(str);30 Type num;31 iss >> num;32 iss.str("");33return num;34 }3536void file_read() {37string str2, str1 = "", result;38 ifstream fileRead("in.dat");39if (fileRead.is_open()) {40while (getline(fileRead, str2, '\n')) {41if (str2.find("") != -1) {42 str1.append(str2 + "");43 }44else {45 num.push_back(stringToNum<int>(str2));46if (str1 != "") {47 res.push_back(str1);48 }49 str1 = "";50 }51 }52 res.push_back(str1);53 fileRead.close();54 }55 }5657void createPoint() {58string temp;59 Point P;60for (int i = 0; i < res.size(); i++) {61 vector<string> temp_str; //存放按照空格分开后的数字62int n = num[i];63 stringstream input(res[i]);64while (input >> temp) {65 temp_str.push_back(temp);66 }67 P.n = n;68for(int k = 0; k<=n; k++) P.p[k] = stringToNum<double>(temp_str[k]);69for(int k = n + 1; k<temp_str.size(); k++) P.q[k-(n+1)] = stringToNum<double>(temp_str[k]);70 points.push_back(P);71 }72 }7374//根据书上的伪代码:接收概率列表p1....pn和q0.....qn以及规模n作为输⼊计算出e和root75void optimalBST(){76 Point P;77for(int i = 0; i<res.size(); i++) {78 vector<string> temp_str; //存放按照空格分开后的数字79int n = num[i];80string temp;81 stringstream input(res[i]);82while (input >> temp) {83 temp_str.push_back(temp);84 }85 P.n = n;8687for(int k = 0; k<=n; k++) P.p[k] = stringToNum<double>(temp_str[k]);88for(int k = n + 1; k<temp_str.size(); k++) P.q[k-(n+1)] = stringToNum<double>(temp_str[k]); 8990//初始化只包括虚拟键的⼦树91for (int i = 1;i <= P.n + 1;++i){92 P.w[i][i-1] = P.q[i-1];93 P.e[i][i-1] = P.q[i-1];94 }95//由下到上,由左到右逐步计算96for (int len = 1;len <= P.n;++len){97for (int i = 1;i <= P.n - len + 1;++i){98int j = i + len - 1;99 P.e[i][j] = Max_Num;100 P.w[i][j] = P.w[i][j-1] + P.p[j] + P.q[j];101//求取最⼩代价的⼦树的根102for (int r = i;r <= j;++r)103 {104double temp = P.e[i][r-1] + P.e[r+1][j] + P.w[i][j];105if (temp < P.e[i][j])106 {107 P.e[i][j] = temp;108 P.root[i][j] = r;109 }110 }111 }112 }113 points.push_back(P);114 }115 }116117void printOptimalBST(int i, int j, int r, Point P, ofstream &fileWrite){118int root_node = P.root[i][j];//⼦树根节点119if (root_node == P.root[1][P.n]){120//输出整棵树的根121 fileWrite << "k" << root_node << "是根" << endl;122 printOptimalBST(i, root_node - 1, root_node, P, fileWrite);123 printOptimalBST(root_node +1 , j, root_node, P, fileWrite);124return;125 }126127if (j < i - 1){128return;129 }else if (j == i - 1){//遇到虚拟键130if (j < r)131 fileWrite << "d" << j << "是" << "k" << r << "的左孩⼦" << endl;132else133 fileWrite << "d" << j << "是" << "k" << r << "的右孩⼦" << endl;134return;135 }136else{//遇到内部结点137if (root_node < r)138 fileWrite << "k" << root_node << "是" << "k" << r << "的左孩⼦" << endl; 139else140 fileWrite << "k" << root_node << "是" << "k" << r << "的右孩⼦" << endl; 141 }142 printOptimalBST(i, root_node - 1, root_node, P, fileWrite);143 printOptimalBST(root_node + 1, j, root_node, P, fileWrite);144 }145146//输出最优⼆叉查找树所有⼦树的根147void printRoot(Point P){148 cout << "各⼦树的根:" << endl;149for (int i = 1;i <= P.n;++i){150for (int j = 1;j <= P.n;++j){151 cout << P.root[i][j] << "";152 }153 cout << endl;154 }155 cout << endl;156 }157158int main(){159 file_read();160 optimalBST();161 ofstream fileWrite("out.dat");162 Point P ;163for(int i = 0; i<points.size(); i++) {164 P = points[i];165 printRoot(P);166 printOptimalBST(1,P.n,-1, P, fileWrite);167 }168 fileWrite.clear();169return0;170 } 上述代码是将给定的邻接矩阵从⽂件中读取 然后根据输⼊的邻接矩阵求出最短路径。

算法分析与设计实验报告--动态规划

算法分析与设计实验报告--动态规划

算法分析与设计实验报告--动态规划《算法分析与设计》实验报告完成⽇期:20011.11.241、实验⽬的(1)掌握动态规划⽅法贪⼼算法思想(2)掌握最优⼦结构原理(3)了解动态规划⼀般问题2、实验内容(1)编写⼀个简单的程序,解决0-1背包问题。

设N=5,C=10,w={2,2,6,5,4},v={6,3,5,4,6}(2)合唱队形安排。

【问题描述】N位同学站成⼀排,⾳乐⽼师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。

合唱队形是指这样的⼀种队形:设K 位同学从左到右依次编号为1,2…,K,他们的⾝⾼分别为T1,T2,…,TK,则他们的⾝⾼满⾜T1<...Ti+1>…>TK(1<=i<=K)。

已知所有N位同学的⾝⾼,计算最少需要⼏位同学出列,可以使得剩下的同学排成合唱队形。

3、实验要求(1)写出源程序,并编译运⾏(2)详细记录程序调试及运⾏结果4、算法思想:利⽤动态规划的思想,解决诸如0—1背包问题,最⼤合唱队形问题等问题的最优解,能在最短的时间内,找到最好的解决⽅案的⼀种算法。

5、实验过程:1、0—1背包问题:源代码如下:#include#includeusing namespace std;#define N 5#define c 10int w[N+1]={0,2,2,6,5,4},v[N+1]={0,6,3,5,4,6};int m[N+1][c+1];int min(int x,int y){if(x<=y)return x;else return y;}int max(int x,int y){if(x>=y) return x;else return y;}void KnapSack(int v[],int w[]){int jMax=min(w[1],c);for (int j=1;j<=jMax;j++) //当0=m[1][j]=0;for (j=w[1];j<=c;j++) // 当j>=w[n]时, m(n,j)=v[n]m[1][j]=v[1];for (int i=2;i<=N;i++) //DP{ int jMax=min(w[i],c);for (j=1;jfor (j=jMax;j<=c;j++) //m(n,j)=v[n] 当j>=w[n] m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]); }}void main(){KnapSack(v,w);for(int i=1;i<=N;i++){for(int j=0;j<=c;j++)cout<cout<}}运⾏截图如下:合唱队形问题:代码如下:#include#includeusing namespace std;#define MAXN 200void main(){int n, a[MAXN], b[MAXN], c[MAXN], i, j, max,lab,pre[MAXN]; cout<<"输⼊数据个数:"; cin>>n;cout<<"\n输⼊"<for (i = 1; i <= n; i++) //O(n)cin>> a[i];memset(b, 0, sizeof(a));memset(c, 0, sizeof(c));b[1] = 1;pre[i]=0; //i=1->nfor (i = 2; i <= n; i++){max = 0;for (j = i - 1; j >= 1; j--) {if (a[j]max) {max = b[j];pre[i]=j;}}b[i] = max + 1;}//lab:max所对应a数组元素下标O(n)max = b[1];for (i = 2; i <= n; i++){ if (b[i] > max){max = b[i];lab=i;}}cout<<"Longest Increasing Subsequence is:"<i = lab;int num=max;j=max;while( num>0 ){c[j--]=a[i];i=pre[i];num--;}//输出数列O(n)for(i=1;i<=max;i++)cout<cout<}截图如下:6.实验过程分析本次实验做的是01背包和合唱队形,之前01背包也⽤贪⼼算法讨论过,但得不到最优解,这次实验⽤动态规划实现的,涉及到剪枝函数部分要考虑清楚,实验过程中通过画图,对理解有很⼤帮助;第⼆个实验其实是利⽤了两次LIS问题,再综合⼀下,总的来说,本次实验还是⽐较成功,对动态规划算法的思想理解得挺透彻的。

算法课设实验报告(3篇)

算法课设实验报告(3篇)

第1篇一、实验背景与目的随着计算机技术的飞速发展,算法在计算机科学中扮演着至关重要的角色。

为了加深对算法设计与分析的理解,提高实际应用能力,本实验课程设计旨在通过实际操作,让学生掌握算法设计与分析的基本方法,学会运用所学知识解决实际问题。

二、实验内容与步骤本次实验共分为三个部分,分别为排序算法、贪心算法和动态规划算法的设计与实现。

1. 排序算法(1)实验目的:熟悉常见的排序算法,理解其原理,比较其优缺点,并实现至少三种排序算法。

(2)实验内容:- 实现冒泡排序、快速排序和归并排序三种算法。

- 对每种算法进行时间复杂度和空间复杂度的分析。

- 编写测试程序,对算法进行性能测试,比较不同算法的优劣。

(3)实验步骤:- 分析冒泡排序、快速排序和归并排序的原理。

- 编写三种排序算法的代码。

- 分析代码的时间复杂度和空间复杂度。

- 编写测试程序,生成随机测试数据,测试三种算法的性能。

- 比较三种算法的运行时间和内存占用。

2. 贪心算法(1)实验目的:理解贪心算法的基本思想,掌握贪心算法的解题步骤,并实现一个贪心算法问题。

(2)实验内容:- 实现一个贪心算法问题,如活动选择问题。

- 分析贪心算法的正确性,并证明其最优性。

(3)实验步骤:- 分析活动选择问题的贪心策略。

- 编写贪心算法的代码。

- 分析贪心算法的正确性,并证明其最优性。

- 编写测试程序,验证贪心算法的正确性。

3. 动态规划算法(1)实验目的:理解动态规划算法的基本思想,掌握动态规划算法的解题步骤,并实现一个动态规划算法问题。

(2)实验内容:- 实现一个动态规划算法问题,如背包问题。

- 分析动态规划算法的正确性,并证明其最优性。

(3)实验步骤:- 分析背包问题的动态规划策略。

- 编写动态规划算法的代码。

- 分析动态规划算法的正确性,并证明其最优性。

- 编写测试程序,验证动态规划算法的正确性。

三、实验结果与分析1. 排序算法实验结果:- 冒泡排序:时间复杂度O(n^2),空间复杂度O(1)。

最短路径实验报告

最短路径实验报告

最短路径实验报告最短路径实验报告引言:最短路径算法是计算机科学中的一个经典问题,它在许多领域中都有广泛的应用,如交通规划、电路设计、网络通信等。

本实验旨在通过实践探索最短路径算法的实际应用,并对其性能进行评估。

一、问题描述:我们将研究一个城市的交通网络,其中包含多个节点和连接这些节点的道路。

每条道路都有一个权重,表示通过该道路所需的时间或距离。

我们的目标是找到两个节点之间的最短路径,即使得路径上各个道路权重之和最小的路径。

二、算法选择:为了解决这个问题,我们选择了Dijkstra算法和Floyd-Warshall算法作为比较对象。

Dijkstra算法是一种单源最短路径算法,它通过不断选择当前最短路径的节点来逐步扩展最短路径树。

Floyd-Warshall算法则是一种多源最短路径算法,它通过动态规划的方式计算任意两个节点之间的最短路径。

三、实验设计:我们首先构建了一个包含10个节点和15条道路的交通网络,每条道路的权重随机生成。

然后,我们分别使用Dijkstra算法和Floyd-Warshall算法计算两个节点之间的最短路径,并记录计算时间。

四、实验结果:经过实验,我们发现Dijkstra算法在计算单源最短路径时表现出色,但是在计算多源最短路径时效率较低。

而Floyd-Warshall算法在计算多源最短路径时表现出色,但是对于大型网络的单源最短路径计算则需要较长的时间。

五、性能评估:为了评估算法的性能,我们对不同规模的交通网络进行了测试,并记录了算法的计算时间。

实验结果显示,随着交通网络规模的增大,Dijkstra算法的计算时间呈指数级增长,而Floyd-Warshall算法的计算时间则呈多项式级增长。

因此,在处理大型网络时,Floyd-Warshall算法具有一定的优势。

六、实际应用:最短路径算法在实际应用中有着广泛的用途。

例如,在交通规划中,最短路径算法可以帮助我们找到最优的行车路线,减少交通拥堵。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

动态规划算法实现多段图的最短路径问题算法设计与分析实验报告
算法设计与分析实验报告
实验名称 动态规划算法实现多段图的最短路径问题 评分 实验日期 年 月 日 指导教师 姓名 专业班级 学号
一.实验要求
1. 理解最优子结构的问题。

有一类问题的活动过程可以分成若干个阶段,而且在任一阶段后的行为依赖于该阶段的状态,与该阶段之前的过程如何达到这种状态的方式无关。

这类问题的解决是多阶段的决策过程。

在50年代,贝尔曼(Richard Bellman )等人提出了解决这类问题的“最优化原理”,从而创建了最优化问题的一种新的算法设计方法-动态规划。

对于一个多阶段过程问题,是否可以分段实现最优决策,依赖于该问题是否有最优子结构性质,能否采用动态规划的方法,还要看该问题的子问题是否具有重叠性质。

最优子结构性质:原问题的最优解包含了其子问题的最优解。

子问题重叠性质:每次产生的子问题并不总是新问题,有些子问题被反复计算多次。

问题的最优子结构性质和子问题重叠性质是采用动态规划算法的两个基本要素。

2.理解分段决策Bellman 方程。

每一点最优都是上一点最优加上这段长度。

即当前最优只与上一步有关。

U s 初始值,u j 第j 段的最优值。


⎩⎪⎨⎧+==≠}.{min ,
0ij
i
j
i j
s w u u u
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)是边<i,j>的成本。

P(1:k)是最小成本路径。

//
real COST(n),integer(n-1),P(k),r,j,k,n COST(n)<-0
for 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(j)<-r;Repeat //向前对j-1进行决策//
P(1)<-1; P(k)<-n;
for j<-2 to k-1 do // 找路径上的第j个节点//
P(j)<-D(P(j-1));repeat;
end FGRAPH
四.程序代码
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <iostream.h>
#define MAX 100
#define n 12 /*顶点数*/
#define k 5 /*段数*/
int c[n][n];
void init(int cost[]) //初始化图
{
int i,j;
for(i=0;i<13;i++)
{
for(j=0;j<13;j++)
{
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 cost[],int path[],int d[]) //使用向前递推算法求多段图的最短路径
{
int r,j,temp,min;
for(j=0;j<=n;j++)
cost[j]=0;
for(j=n-1;j>=1;j--)
{
temp=0;
min=c[j][temp]+cost[temp]; //初始化最小值
for(r=0;r<=n;r++)
{
if(c[j][r]!=MAX)
{
if((c[j][r]+cost[r])<min) //找到最小的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(j=2;j<k;j++)
path[j]=d[path[j-1]];
}
void bgraph(int bcost[],int path1[],int
d[])//使用向后递推算法求多段图的最短路径
{
int r,j,temp,min;
for(j=0;j<=n;j++)
bcost[j]=0;
for(j=2;j<=n;j++)
{
temp=12;
min=c[temp][j]+bcost[temp]; //初始化最小值
for(r=0;r<=n;r++)
{
if(c[r][j]!=MAX)
{
if((c[r][j]+bcost[r])<min) //找到最小的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(int i=4;i>=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动态规划解多段图问题"<<endl;
cout<<"\n\n";
init(cost);
fgraph(cost,path,d);
cout<<"输出使用向前递推算法后的最短路径:\n\n";
for(int i=1;i<=5;i++)
{
cout<<path[i]<<" ";
}
cout<<"\n";
cout<<endl<<"最短路径为长度:"<<cost[1]<<endl;
cout<<"\n";
cout<<"\n输出使用向后递推算法后的最短路径:\n\n";
bgraph(bcost,path1,d);
for(i=1;i<=5;i++)
{
cout<<path1[i]<<" ";
}
cout<<"\n";
cout<<endl<<"最短路径为长
度:"<<bcost[12]<<endl; cout<<"\n"; }
五.程序调试中的问题
在这次实验中,确实遇到了一些问题,例如最短路径的选择问题。

六.实验结果
1、数据的五段图
2、实验结果如下:
1
2
3
4
5
6
7
8
11
10
9
12
9
7 3 2
8
1 6
5 3 5 5
2 4
6 4 4 2 1 1 2 图为标准
7。

相关文档
最新文档