




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、.算法分析与设计实验报告第 X 次实验姓名刘悦学号201308080112班级物联1301班时间12.26上午地点工训楼C栋309 实验名称回溯法求旅行售货员问题实验目的通过上机实验,掌握回溯算法的思想,利用回溯法求旅行售货员问题并实现。实验原理旅行售货员问题的解空间树是一棵排列树。当i=n时,当前扩展结点是排列树的叶结点的父结点。此时算法检测图G是否存在一条从顶点xn-1到顶点xn的边和一条从顶点xn到顶点1的边。如果这两条边都存在,则找到一条旅行售货员回路。此时,算法还需要判断这条回路的费用是否优于已找到的当前最优回路的费用bestc。如果是,则必须更新当前最优值bestc和当前最优解be
2、stx。 当in时,当前扩展结点位于排列树的第i-1层。图G中存在从顶点xi-1到顶点xi的边时,x1:i构成图G的一条路径,且当x1:i的费用小于当前最优值时算法进入排列树的第i层,否则将减去相应的子树。算法中用变量cc记录当前路径x1:i的费用。 实验步骤 从起点开始,找其子结点,即存在一条边相连。 如果费用小于当前最优值则以此结点继续向下探索,否则就剪去相应的子树。 当扩展到叶结点的父结点时,检测此结点与叶结点,叶结点与起点是否有边相连。 若均有边相连,则检测此回路的费用是否小于最优费用。 若小于最优费用,则更新最优费用,同时记录最优解。关键代码/定义图的顶点数 const int N
3、= 4; /*=定义Traveling类来存储的信息。=*/ template class Traveling template friend T TSP(T *a, int n); private: void Backtrack(int i); int n, / 图G的顶点数 *x, / 当前解 *bestx; / 当前最优解 Type *a, / 图G的领接矩阵 cc, / 当前费用 bestc; / 当前最优值 int NoEdge; / 无边标记 ; /*=Backtrack函数为递归算法。 当i=n时,当前扩展结点是排列树的叶结点的父结点。此时算法检测图G是否存在一条从顶点xn-1到
4、顶点xn的边和一条从顶点xn到顶点1的边。如果这两条边都存在,则找到一条旅行售货员回路。此时,算法还需要判断这条回路的费用是否优于已找到的当前最优回路的费用bestc。如果是,则必须更新当前最优值bestc和当前最优解bestx。 当in时,当前扩展结点位于排列树的第i-1层。图G中存在从顶点xi-1到顶点xi的边时,x1:i构成图G的一条路径,且当x1:i的费用小于当前最优值时算法进入排列树的第i层,否则将减去相应的子树。算法中用变量cc记录当前路径x1:i的费用。 =*/ template void Traveling:Backtrack(int i) /前扩展结点是排列树的叶结点的父结点
5、 if (i = n) /检测是否存在一条从顶点xn-1到顶点xn的边和一条从顶点xn到顶点1的边 /存在且这条回路的费用小于已找到的最优费用 if (axn-1xn != 0 & axn1 != 0 & (cc + axn-1xn + axn1 bestc | bestc = 0) /记录最优解 for (int j = 1; j = n; j+) bestxj = xj;/更新最优费用 bestc = cc + axn-1xn + axn1; /前扩展结点位于排列树的第i-1层 else for (int j = i; j = n; j+) / 判断是否可进入xj子树 if (axi-1x
6、j != 0 & (cc + axi-1xi bestc | bestc = 0) / 搜索子树 /交换 int temp=xi;xi=xj;xj=temp; /当前费用累加 cc += axi-1xi; /排列向右扩展,排列树向下一层扩展 Backtrack(i+1); /当前费用减少 cc -= axi-1xi;/交换 temp=xi;xi=xj;xj=temp; /*=TSP函数进行初始化,并返回最短路径的长度。主要为使用Backtrack函数进行搜索。 =*/ template Type TSP(Type *a, int n) /定义traveling类型的变量Y Traveling
7、Y; /初始化Y Y.n=n; Y.x=new intn+1; Y.bestx=new intn+1; /置x为单位排列 for(int i=1;i=n;i+) Y.xi=i; Y.a=a; Y.cc=0; Y.bestc=0; Y.NoEdge=0; /搜索x2:n的全排列 Y.Backtrack(2); /输出最短回路 cout最短回路为:endl; for(int i=1;i=n;i+) coutY.bestxi ; coutY.bestx1endl; /删除动态内存分配 delete Y.x; Y.x=0; delete Y.bestx; Y.bestx=0; return Y.bes
8、tc; /*= Swap函数实现两个数值交换。 需要注意的是形参那里一定要使用&符号,不然的话修改之后的结果不会在其他函数中看到。 =*/ template inline void Swap(Type &a, Type &b) Type temp=a; a=b; b=temp; 测试结果1. 使用的图如下所示:2. 相应的排列树如下所示:3. 至个叶结点的路径叶结点路径长度路径顺序L591 -2 -3 -4-1M661 -2 -4 -3-1N251 -3 -2 -4-1O661 -3 -4-2-1P251 -4 -2 -3-1Q591 -4 -3 -2-14. 由上表可以知道最短的为至叶结点Q
9、的路径1 -3 -2 -4-1,长度为25。这里可能会有疑问,至结点P的距离也为25,为什么不选择路径1 -4 -2 -3-1。这是因为只有当求得的路径比当前最优值小的时候才会记录,这里一样大,所以不会记录,也就不会输出这条路径。5. 算法输出结果如下:输出时间。输出源结点到目的结点的最短路径的长度。输出源结点到目的结点的最短路径。输入起点与终点,即源结点与目的结点。6. 可以看到输出的结果与分析的结果一样,所以算法实现正确。并且可以看到分支限界法在实现我们给的这个图的时候,时间性能很好。实验心得因为我自己觉得解空间为排列树的问题的算法不是很好理解,所以就多编写了旅行售货员问题的代码,这里使用
10、的是回溯法实现。就整体上来说,我认为回溯法的思想还是很好理解的,就是扩展一个结点的子结点,继续扩展子结点的子结点,当不能扩展的时候,就返回到上一个扩展结点,找其他的子结点进行扩展,当往回找到根结点,根结点没有子结点继续扩展的时候,就结束算法。但是这里是排列树的回溯法,就难理解一点。主要是使用了交换。void backtrack (int t) if (tn) output(x); else for (int i=t;i=n;i+) swap(xt, xi); if (legal(t) backtrack(t+1); swap(xt, xi); 排列树的实现的伪代码如上所示。主要存在两个交换。第
11、一个交换是保存xt当前的状态,而后面一个交换则是回到xt刚才的状态。理解了这一点之后,回溯法求解旅行售货员问题的代码其实也就不难理解了。因为这里给的图的顶点比较少,无法直观的看出算法的时间性能。就回溯法求解旅行售货员问题,如果不考虑更新bestx所需的计算时间,则Backtrack需要O(n-1)!)计算时间。由于算法Backtrack在最坏情况下可能需要更新当前最优解 O(n-1)!)次,每次更新bestx需要O(n)计算时间,所以整个算法的计算时间复杂性为O(n!)。通过这次实验,编写了回溯法求解旅行售货员问题的代码,熟悉了回溯法求解问题的步骤,熟练掌握了回溯法,理解了排列树的问题,进一步
12、熟悉了旅行售货员问题的问题描述与解题思路。相信在以后的学习工作中,一定可以熟练使用回溯法求解问题,当然肯定可以使用回溯法求解旅行售货员问题。实验得分助教签名附录:完整代码#include #include#include#include#include using namespace std; /定义图的顶点数 const int N = 4; /*=定义Traveling类来存储的信息。=*/ template class Traveling template friend T TSP(T *a, int n); private: void Backtrack(int i); int n,
13、/ 图G的顶点数 *x, / 当前解 *bestx; / 当前最优解 Type *a, / 图G的领接矩阵 cc, / 当前费用 bestc; / 当前最优值 int NoEdge; / 无边标记 ; /*=Backtrack函数为递归算法。 当i=n时,当前扩展结点是排列树的叶结点的父结点。此时算法检测图G是否存在一条从顶点xn-1到顶点xn的边和一条从顶点xn到顶点1的边。如果这两条边都存在,则找到一条旅行售货员回路。此时,算法还需要判断这条回路的费用是否优于已找到的当前最优回路的费用bestc。如果是,则必须更新当前最优值bestc和当前最优解bestx。 当in时,当前扩展结点位于排列
14、树的第i-1层。图G中存在从顶点xi-1到顶点xi的边时,x1:i构成图G的一条路径,且当x1:i的费用小于当前最优值时算法进入排列树的第i层,否则将减去相应的子树。算法中用变量cc记录当前路径x1:i的费用。 =*/ template void Traveling:Backtrack(int i) /前扩展结点是排列树的叶结点的父结点 if (i = n) /检测是否存在一条从顶点xn-1到顶点xn的边和一条从顶点xn到顶点1的边 /存在且这条回路的费用小于已找到的最优费用 if (axn-1xn != 0 & axn1 != 0 & (cc + axn-1xn + axn1 bestc |
15、 bestc = 0) /记录最优解 for (int j = 1; j = n; j+) bestxj = xj;/更新最优费用 bestc = cc + axn-1xn + axn1; /前扩展结点位于排列树的第i-1层 else for (int j = i; j = n; j+) / 判断是否可进入xj子树 if (axi-1xj != 0 & (cc + axi-1xi bestc | bestc = 0) / 搜索子树 /交换 int temp=xi;xi=xj;xj=temp; /当前费用累加 cc += axi-1xi; /排列向右扩展,排列树向下一层扩展 Backtrack(
16、i+1); /当前费用减少 cc -= axi-1xi;/交换 temp=xi;xi=xj;xj=temp; /*=TSP函数进行初始化,并返回最短路径的长度。主要为使用Backtrack函数进行搜索。 =*/ template Type TSP(Type *a, int n) /定义traveling类型的变量Y Traveling Y; /初始化Y Y.n=n; Y.x=new intn+1; Y.bestx=new intn+1; /置x为单位排列 for(int i=1;i=n;i+) Y.xi=i; Y.a=a; Y.cc=0; Y.bestc=0; Y.NoEdge=0; /搜索x
17、2:n的全排列 Y.Backtrack(2); /输出最短回路 cout最短回路为:endl; for(int i=1;i=n;i+) coutY.bestxi ; coutY.bestx1endl; /删除动态内存分配 delete Y.x; Y.x=0; delete Y.bestx; Y.bestx=0; return Y.bestc; /*= Swap函数实现两个数值交换。 需要注意的是形参那里一定要使用&符号,不然的话修改之后的结果不会在其他函数中看到。 =*/ template inline void Swap(Type &a, Type &b) Type temp=a; a=b;
18、 b=temp; /*=main函数是主函数。实现输入输出,调用之前的分支限界法函数ShortesPaths记录源到各顶点的最短路径长度。并且同时在prev数组中记录其前驱结点。 根据图的prev数组,求出最短路径。 从终点开始,之后到终点的前驱结点,直至找到起点为止,就找出了到终点的路径。 将找到的到终点的路径,存储在trave_pre数组中。 因为trave_pre数组中存储的为倒序的路径,所以反向输出即为路径。=*/ int main() cout=endl;cout=回溯法求TSP问题=endl;cout=endl; /输出图的顶点个数 cout图的顶点个数为Nendl; int bestlength; /动态内存分配 int *a=new int*N+1; for(int i=0;i=N;i+) ai=new intN+1;/初始化 for(int i=0;i=N;i+)for(int j=0;jN;j+) aij=0; a12=30;a13=6;a14=4; a21=30;a23=5;a24=10; a31=6;a32=5;a34=20; a41=4;a42=10;a43=20; /开始
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030年中国蛋白酪氨酸激酶SYK行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国葡萄糖酸钠行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国药用高阻隔包装膜行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国节能三门蒸柜行业市场深度分析及发展趋势与投资研究报告
- 2025-2030年中国航空储能行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国自给式呼吸器行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国肺癌液体活检行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国羽毛枕行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国美乐琴行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国结构玻璃系统行业市场现状供需分析及投资评估规划分析研究报告
- 美术高考集训班协议合同
- 中国证券经营行业市场发展现状分析及发展趋势与投资前景研究报告
- 职业技术学院食品质量与安全专业《食品化学》课程标准
- 公共组织绩效评估-形考任务二(占10%)-国开(ZJ)-参考资料
- 贸易人居间合同协议
- 《肺结核的诊断与治疗》课件
- 陕西省咸阳市2025届高三下学期高考模拟检测(三)物理试题(含答案)
- 浙江省温州市2023-2024学年高一下学期期末考试语文试卷(含答案)
- (高清版)DB3301∕T 0411-2023 公共汽电车维修车间建设与管理规范
- 激光应用技术发展路径试题及答案
- 期权开户考试题及答案
评论
0/150
提交评论