// 标题是糊弄人的

1. 问题引入

给出一张图,求其最短哈密尔顿回路,也就是 “旅行商问题”(Traveling Saleman Problem,TSP)

假设有一个旅行商人要拜访 $n$个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。

路径的选择目标是要求得的路径路程为所有路径之中的最小值。

这是一个著名的 NP-C(NP 完全)问题,也就是说——爆搜不可避

爆搜很简单,枚举一个排列表示第 $1, 2, 3, …, n$个经过的点,再判断距离就行了,取最小值

但是这样复杂度是 $O(n!)$级别的,即使 $n \leq 20$都是不可接受的

对于 $n \leq 20$左右的数据,可以用状态压缩动态规划求解,复杂度 $n ^ 2 2 ^ n$,可能需要常数上的优化

2. 模拟退火

模拟退火将热力学的理论应用到统计学中,一开始温度高,分子能量大,移动范围广,可以防止停留在局部最优解

到后面一步步降温,移动范围逐渐收敛,最终获取到的解一般较优

模拟退火解决 TSP 问题大概分为如下几部:

根据当前路径,随机生成一个新路径

比较当前路径与新路径,若新路径较优,则接受新路径,把当前路径替换成新路径

否则以 $e ^ {\Delta / T}$的概率接受新路径,其中 $\Delta$表示新路径长度与当前路径长度的差(为负数),$T$表示当前温度

若温度低于设定的最低温度,则退出算法,否则降低温度,并回到第一步继续迭代

生成新解一般就是随机一对 $a, b$,然后交换当前路径的第 $a$个和第 $b$个点作为新路径

初始温度 $T _ 0$需要足够大,比如最大边权的 $3$倍

每次降温就是 $T’ = T \times k$,$k$是个常数,一般取什么 $0.99$之类的,看情况而定

经过实验,直接迭代收敛太快了,效果不是很好,可以对于每个温度进行多次迭代

这些参数取什么可以用暴力对拍看正确率找

例题:Hie with the Pie POJ – 3311

题意大概就是给 $n + 1$个点($n \leq 10$),求每个点至少经过一次的最短回路长度(每个点可以经过多次)

(边权我试了一下,是 $\leq 1000$的)

可以经过多次并没有什么不同,用 floyd 求出两点之间最短距离以后就没有必要经过某个点两次了,于是上模拟退火

调参其实挺难搞的,因为有多组数据,所以正确率要求很高

代码中添加了优化:若发现迭代多次一直都没取到更优值,则跳出迭代直接降温

代码:

3. 蚁群算法

蚁群算法(AntColonyOptimization,ACO),是一种用来在图中寻找优化路径的机率型算法。

这里有一个蚁群算法的演示:Github 仓库

它的灵感来源于蚁群寻找食物的过程,因为往往一只蚂蚁并没有太多 “智能” 的表现,而蚁群往往有 “智能” 的动作,比如大部分都趋向于食物

这是因为它们在移动的路径上会留下 “信息素”,它们会更大概率沿着信息素更浓的路径行走

而路径越短,信息素就会越浓

这很符合 TSP 问题的要求

蚁群算法流程大概如下:

初始化算法

派出一只蚂蚁,随机一个点作为蚂蚁的起点

对于蚂蚁当前所在的点,根据所有后继边的信息素浓度以及长度根据公式计算出访问每个后继节点的概率

用轮盘法随机出下一步走到哪个节点

重复 3,4 步,直到所有节点都访问了一次

计算回路长度,计算经过的边的信息素增加量

所有边上的信息素都会蒸发一定比例使算法收敛,增加经过的边的信息素

回到第 2 步,进行下一轮迭代

当然第二步只派出一只蚂蚁正确率是很低的,一般要派出节点数数倍的蚂蚁,精度要求越高就要派出更多蚂蚁

首先讲一下怎么计算后继节点访问概率

有这么几个基本的算法参数:

$\alpha$,表示信息素重要程度

$\beta$,表示能见度重要程度,能见度指的是边长的倒数

$\rho$,蒸发率

若当前第 $k$个蚂蚁在点 $x$,$x, y$之间的信息素浓度为 $\tau _ {xy}$,$x, y$之间的能见度为 $\eta _ {xy}$,与 $x$相连且未访问的集合为 $\mathrm {allowed} _ x$,那么访问接下来 $y$的概率为:

$$p _ {xy} ^ {k} = {\frac {(\tau _ {xy}^{\alpha })(\eta _ {xy}^{\beta })}{\sum _ {z\in \mathrm {allowed} _ {x}}(\tau _ {xz}^{\alpha })(\eta _ {xz}^{\beta })}}$$

公式中分子是信息素浓度的 $\alpha$次方乘以能见度的 $\beta$次方

分母就是所有分子之和

然后再 rand 一个 $[0, 1]$之间的随机数,就能选出后继节点了

(如果所有边的浓度都为 0,就随便选一个了)

可以发现 $\alpha$的取值越大,信息素占比越大;$\beta$的取值越大,能见度占比越大

这个值一般就取 $\alpha = \beta = 1$或者 $\alpha = 1, \beta = 2$,需要玄学调参

关于信息素的更新,首先是初始化算法的时候需要设定一个初始信息素浓度,这个浓度太大会导致新增的信息素没什么用,太小会导致过快结束算法,陷入局部最优解。

这个值可以先跑一遍贪心算出一个答案,然后参照这个答案设定

怎么设定呢?根据路径越长信息素浓度越低的规则,某只蚂蚁走过的回路长度为 $length$的话,那么它对走过的路径的信息素浓度的贡献为 $\frac 1 {length}$

因此初始浓度可以设定为 $\frac M {length}$,其中 $M$表示每批蚂蚁个数

然后根据这个规则,每批蚂蚁走过以后每条边的信息素增加量也是能算出来的

为了精度可以使每次增加的信息浓度乘上一个常数

注意是:

$M$只蚂蚁都跑一遍,并记录每条边的信息素增量,但并不加上去

所有蚂蚁都跑完后,每条边都蒸发一定比例

蒸发完后再增加

这个蒸发率 $\rho$一般是取 $50\%$到 $80\%$,蒸发比例越大收敛越快

每次把每条边的信息素浓度都乘以 $1 – \rho$,就能逐渐让访问频率高的边的浓度与其他边的浓度差更大,最后其他边的浓度一般会降为 0

一般迭代次数就是 $500$到 $1000$次

这样正确率还是比较高的,答案也还比较优秀

例题:售货员的难题 LUOGU – 1171

这个就是 TSP 裸题了

$n \leq 20$,$1$秒钟,状态压缩动态规划是很吃力的

(但是好像有不少的搜索过了,还挺快的_(:з」∠)_)

于是就上蚁群咯!比状压还是快多了

调参心累啊.jpg

4. 总结

除了这两种近似算法,还有很多其他的算法能应用于 TSP,例如遗传算法,就没有去仔细研究了

由于状压和搜索只能处理 $n$很小的情况,因此在实际生活中并没有太大用武之地

而近似算法虽然无法保证得出最优解,但是误差也不会太大,而且可以处理点数很多的情况(维基百科上表示有启发式算法可以算出 $10 ^ 6$级别的近似解了,并且误差是有保证的)

竞赛中随机算法也还是有应用场景的,比如可以先用蚁群算法算出较优解,然后用于搜索的剪枝之类的

值得一提的是,由于 POJ 那题有多组数据,我暂时没能用蚁群算法 AC;而 LUOGU 那题模拟退火只能拿到 80 分左右,因此有时候可以考虑把多种近似算法放到一起,取最优解,应该能进一步提升正确率

最短汉密尔顿回路算法c语言,【算法】浅谈最短哈密尔顿回路类问题的两种近似算法...相关推荐

  1. trainlm算法c语言,粒子群优化的BP神经网络模型对C、Mn两种元素收得率的预测

    粒子群优化的BP神经网络模型对C.Mn两种元素收得率的预测 来源:用户上传 作者: 摘 要:本文首先对数据进行处理,利用收得率公式求出历史收得率:并利用已知的影响元素收得率的主要影响因素结合BP神经网 ...

  2. 哈密尔顿道路与哈密尔顿回路

    简介 1857年爱尔兰数学家哈密尔顿发明了"周游世界"玩具,用一个正十二面体的20个顶点表示世界上20个大城市,30条棱代表这些城市之间的道路.要求游戏者从任意一个城市(即顶点)出 ...

  3. java哈密尔顿回路算法,用回溯方法求哈密尔顿回路——java求解

    // 哈密尔顿回路问题 public class Hamilton { // 图中顶点个数为n,图的邻接矩阵为c[][],存放回路的顶点序号x[],在这里,n个顶点的标号是:0,1,2,...,n-1 ...

  4. 哈密尔顿算法matlab,复杂制造过程最优哈密尔顿圈算法的MATLAB仿真与分析.doc

    摘要:当今的工业制造过程越来越复杂,产品生产批量化,单个产品组成零部件数量庞大,加工需要多道工序,且工序间连续性强,整个制造过程属于离散制造,这样必然会使生产制造过程复杂化.在这种情况下,加工方案的制 ...

  5. 什么是哈密尔顿回路/路径?

    一:哈密尔顿回路与哈密尔顿路径 1859 年,爱尔兰数学家哈密尔顿(Hamilton)提出了一个"周游世界"的游戏: 在一个正十二面体的二十个顶点上,标注了伦敦,巴黎,莫斯科等世界 ...

  6. 哈密尔顿回路(旅行售货员问题)

    哈密尔顿回路(旅行售货员问题) 哈密顿图(哈密尔顿图)(英语:Hamiltonian path,或Traceable path)是一个无向图,由天文学家哈密顿提出,由指定的起点前往指定的终点,途中经过 ...

  7. 用mips汇编实现哈密尔顿回路

    用mips汇编实现哈密尔顿回路. 哈密顿回路是一个非常经典的问题 题目难度不大,虽然是np的但是只需要你写一个非多项式的实现算法. 我们先回顾一下怎么用c++实现 #include <bits/ ...

  8. 欧拉回路和哈密尔顿回路

    "哈密尔顿回路问题"与"欧拉回路问题"看上去十分相似,然而却是完全不同的两个问题."哈密尔顿回路问题"是访问除原出发结点以外的每个结点一次且 ...

  9. “欧拉回路”与“哈密尔顿回路”

    1.欧拉回路 17世纪的东普鲁士有一座哥尼斯堡(Konigsberg)城(现为俄国的加里宁格勒(Kaliningrad)城),城中有一座奈佛夫(Kneiphof)岛,普雷格尔(Pregol)河的两条支 ...

最新文章

  1. python messagebox输出_python 3.4 中原来的tkinter组件的tkMessageBox变成啥了?
  2. Codeforces Gym 101473D Folding Machine (暴力搜索)
  3. 爱前端2018全栈大前端_启动2018年前端工具调查
  4. html网页的结构框架代码
  5. Python基础----列表
  6. 多分类支持向量机及其Python实现
  7. java上下文_Java,gRPC和上下文传播(Java, gRPC and Context propagation)
  8. 分立元器件——电感器
  9. EMV规范(五)——脱机数据认证
  10. 《Java语言程序设计与数据结构》编程练习答案(第七章)(一)
  11. 使用vue做一个“淘宝“项目——2
  12. Redis 取消保护模式
  13. iOS开发常用代码片段:总有你用得上的功能
  14. 打印图案系列(菱形、X形、箭形、空心正方形)
  15. 电脑开机密码忘记,如何修改电脑密码?
  16. HWSWP和BSWP
  17. Linux系统:基础IO
  18. html 获取电脑ip地址,笔记本自动获取ip地址怎么设置?
  19. 微软流媒体框架DirectShow
  20. 计算机组成原理:比较SRAM和DRAM存储器

热门文章

  1. 财务应付结算系统设计-应付款和付款单(含付款风险控制)
  2. C#(Csharp)环境配置
  3. Oracle初学者入门指南-什么是Metalink -MOS ?
  4. SCI写作助手网站收集
  5. 在 Android 模拟器上运行 ARM 应用
  6. 百度坐标转gps坐标_论文推荐 | 明锋:GPS坐标时间序列分析研究
  7. 警惕不良商家利用Panasonic SDFormatter 软件对SD/TF卡容量造假
  8. 在后台运行rtorrent
  9. 安装Ubuntu 14.10后要做的事(下)—— 开发工具篇
  10. 【python】导航