07回溯法-旅行售货员问题

问题描述:
已知有m个城市,城市之间由n条不同长度的道路相连。一个售货员从一座城市出发,途径所有城市,并最终回到原点,设计算法计算售货员所走的最短路径结点。

问题分析:
从问题不难看出,此问题属于图中的最小哈密顿图问题。最直接的方法便是遍历找出所有能走完全部结点的道路,并选择其中最短的一条路作为答案。已知图的遍历方式有两种,深度遍历和广度遍历。而排列算法有perm算法,因此此处使用深度遍历+perm算法来寻找最小哈密顿图,这两种算法的组合便是回溯法:通过深度搜索来寻找答案,当发现其中一条道路行不通时,遍选择下一条路继续进行。

算法描述:
最短路径 = 已经走过的最短路径 + 当前要走的最短路径 + 以后要走的最短路径。
perm全排列算法流程:
1)交换A[0]和A[i]
2)对除A[0]以外元素进行perm()递归。
3)再次交换A[0]和A[i],防止下次执行顺序被打乱,出现重复排序。
4)对以上算法进行基于顶点数i的循环
(perm全排序算法具体讲解见:06递归算法-perm算法)

下面讲述如何通过对perm算法的改进实现回溯法:
由于该问题的解答需要获取到顶点结点,所以当perm算法中第i个结点完成交换后,在对从i+1到末尾顶点进行全排列之前,要获取到前一个边的长度,即在流程1与2中间加一个 cc+=A[i-1][i](cc表示已走的路,随着递归的进行而不断增加)。而当第2步实现以i为首的顶点路径集合的全排序后,由于需要回溯到i结点处(选择以i+1结点进行全排序),所以还需将之前增加的结点路径减去以实现回溯,即在流程2和3之间插入一句 cc-=A[i-1][i]。至此,对perm算法的全部改进主体工作完成。

笔记:(-from Tsinghua University算法导论课程)

旅行售货员问题代码:

void traveling(int i){if(i==n){//一次递归到底,结束当前递归if(A[x[i-1]][x[i]]!=Noedge && A[x[i]][x[1]]!=NULL && (cc+A[x[i-1]][x[i]]+A[x[i]][x[1]]<best||best == NULL) ){best = cc+A[x[i-1][x[i]]] + A[x[i]][x[1]];iscycle = true;for(int j=1;j<=n;j++)bestx[i] = x[j];}}else{for(int j=i;j<=n;j++){//对所有节点进行全排序if(A[x[i-1]][x[j]]!=Noedge && (cc+A[x[i-1]][x[j]]<best||best == Nodege)){//只有边存在且已走过的路经+当前要走的路径<最短路径时,才会执行语句,对后面路径进行全排列(注意和第一个if判断语句的区别)swap(x[i],x[j]);cc+=A[x[i-1]][x[i]];//新增边traveling(i+1);cc-=A[x[i-1]][x[i]];//回溯减去边swap(x[i],x[j]);}}}
}

20201010补充:
该算法本质是二叉树的深度遍历,而之所以使用到了perm算法对数字进行全排序,是因为该问题本身结构是由图构成,而后转化成二叉树,该二叉树并没用事先建立,也没有对图进行邻接矩阵设计,因此采用perm算法进行设计,本质是构造二叉树。
20201014补充:回溯法的构造解空间树分为排列树和子集树。当选项可以重复时,则解空间树为子集树,如01背包中,每项都可以选或者不选,最小重量机器设计中,每个零件都可以在所有供应商买到。当解空间不可以重复时,解空间树则为排列树,如旅行售货员问题中,每条道路不能重复走,羽毛球最佳配对问题中,队员不能重复选择。

回溯法设计步骤:
1 根据问题确定解空间树类型(子集树,排列树)以及分支情况。
2 确定显式约束(背包容量、总价格)和隐式约束(最大价值、最小重量),以设计限界函数。
3 确定需要更新的变量以及问题的解。

【算法导论07】回溯法-旅行售货员问题相关推荐

  1. 回溯法——旅行售货员问题

    旅行售货员问题即给几个地点,相互之间有路径,有每个路径对应的消耗的费用.我们将起点设为1,其他地点设为2,3,4-n.我们起初将所有路径费用都设置成∞,然后再输入 相通路径的费用,再更新费用值.我们以 ...

  2. 算法设计与分析——回溯法——旅行售货员问题

    #include<iostream> #include<bits/stdc++.h> using namespace std; const int noEdge=65535; ...

  3. 回溯法----旅行售货员问题

    一.问题 同文章 <分支限界法----旅行售货员问题> 二.代码实现 程序实现了 递归回溯 解决该问题 迭代回溯算法仍在考虑中... /************************** ...

  4. 0x08算法设计与分析复习(二):算法设计策略-回溯法2

    参考书籍:算法设计与分析--C++语言描述(第二版) 算法设计策略-回溯法 子集和数 问题描述 已知n个不同的正数wi(0≤i≤n−1)的集合,求该集合的所有满足条件的子集,使得每个子集中的正数之和等 ...

  5. 回溯法采用的搜索策略_五大常用算法之四:回溯法

    1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就"回溯"返回,尝试别的路径.回溯法是一种选优搜索法,按选优条件向 ...

  6. 0027算法笔记——【回溯法】回溯法与装载问题

    1.回溯法 (1)描述:回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法.  (2)原 ...

  7. 4.Python算法之试探算法思想(回溯法)

    1.什么是试探算法? 2.试探算法的解题的基本步骤 3.试探算法的思想 4.试探算法适合的问题 5.试探算法解决"八皇后"的问题 1.什么是试探算法?   试探算法也叫回溯法,试探 ...

  8. 五大常用算法之四:回溯法

    http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html 1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试 ...

  9. 【算法思想:回溯法】回溯算法入门级详解

    回溯法是一种非常重要的算法思想,在大厂面试中频繁出现,所以做了一个笔记,记录了一下. 回溯算法与深度优先遍历 以下是维基百科中「回溯算法」和「深度优先遍历」的定义. 回溯法 采用试错的思想,它尝试分步 ...

最新文章

  1. 判断为空:null、undefined、空字符串、中文空格
  2. “Uncaught TypeError: string is not a function”
  3. linux下git的HEAD,Git工具详解以及与GitHub的配合使用
  4. Objective C 错误整理
  5. 【通知】+ java基础提升篇:Java 序列化的高级认识
  6. 基于Apache POI 向xlsx写入数据
  7. 提交表单到mysql_node提交表单到mysql
  8. 从零开始学前端:函数 --- 今天你学习了吗?(JS:Day8)
  9. mysql叠加select,MySQL – 有效地将两个select语句组合成一个...
  10. 如何在Mac上的“活动监视器”中运行系统诊断?
  11. 第二十四周项目3-动态链表体验
  12. python文件操作方法seek_Python文件操作及seek偏移详解
  13. 7660生成负电压芯片
  14. 一文带你了解推荐系统常用模型及框架
  15. mac提示“已损坏,无法打开。 您应该将它移到废纸篓“的终极解决方案
  16. 什么是 AI(人工智能(Artificial Intelligence)
  17. c# 利用AForge.NET组件操作摄像头
  18. Gremlin-常用查询语句用法
  19. 小甲鱼零基础学习python-课后作业答案拓展阅读(无需下载)
  20. Mysql 数据实时同步hbase

热门文章

  1. auto与decltype
  2. 在线jquery引用地址
  3. Postgresql中plpgsql异常处理方法与实例(RAISE EXCEPTION)
  4. Django annotate
  5. .xml文件如何用excel作为默认打开方式
  6. docker安装redis教程
  7. 以JLable特性实现坦克大战(1)
  8. 传智播客设计学院简介
  9. springboot consumes和produces属性
  10. ]巧妙洗头,白发变黑发