模拟退火算法应用于最优排列问题和最优组合问题 之 排列篇

简介:
模拟退火算法应用于最优排列问题和最优组合问题 之 排列篇

一般学习模拟退火算法的时候,都是用全排列问题作为例子讲解,所谓全排列问题,就是说解的长度(或者步骤)是确定的,只不过排列顺序不同罢了,其中任何一种排列顺序都是问题的一个解,我们通过不断尝试不同的排列顺序,找到其中最优的一个。

 

TSP旅行商问题就是典型的全排列问题,所有的城市都是两两互联的,每个城市都要去一次(且只能去一次),先去那个后去那个,顺序不同只不过花费的代价不一样,但都是问题的一个解决方案。

 

注意:任何一种排列都是问题的一个解。这是一种很好的特性,这种情况下,可以直接应用典型的模拟退火算法。

 

模拟退火算法的核心就是对解的取舍。

 

第一步:首先生成一个初始解。

生成初始解的时候,你可以随机生成,也可以依照某种原则生成。无论怎样,反正就是一组排列。

当你把这组排列应用到问题域的时候, 会得到一个反馈的结果(也可以叫输出吧),比如说总花费、总路程之类的,一般我们希望这个结果越小(或者越大)越好。

这里,最优的输出值大概是多少,我们并不知道,甚至没有任何概念。

所以,应用这个初始解得到的输出,可能离目标很远,也可能离目标很近,哪怕他就在目的地门口,我们也一无所知。

 

第二步:变换解。

所谓变换解就是,我们把前一个解做一定的改变,具体怎么改变呢?

我要说取前一个解的领域,你可能会说我装逼(哈哈)。

其实想怎么变就怎么变,比如:将排列(即前一个解)中某两个元素的位置交换一下,再比如:将排列(即前一个解)从某个位置劈开,然后将两部分前后调换一下,再重新组合起来,等等。 

 

发挥你的想象,只要你每次都用同样的变换就行。另外,变换最起码要遵守问题描述,比如每个城市只能去一次,你不能变的去两次。

 

现在我们有了一个新的解。

如果把这个新的解应用的问题域上,同样也会得到一个反馈结果(输出),同样,我们还是不知道这个输出距离最终目标有多远。 

不管怎么样,我们至少可以确定一点,新解和旧解的输出肯定不同。

变换的核心思想就是:差之毫厘,谬之千里。

 

第三步:新解的取舍。 

现在我们有两个解和两个解的输出。虽然我们不知道最终目标输出是多少,但是哪个解的输出距离目标更近一点我们应该能看出来。

比如:旧解的输出是花费100元,新解的输出是花费80元。

如果像这样,新解比旧解“看上去”更好,我们就把新解作为当前解,回到第二步,用它再做新的变换。

注意:这里我用到一个“看上去”,确实是这样,只要看上去更好就行,你不用考虑更多,也许他可能要兜圈子。

 

如果新解比旧解看上去要差呢?扔了它?那就成了贪心算法了。模拟退火的核心就在这里,怎么取舍这个看上去差一点的解。

要说公式有点复杂,要说白了其实很简单,就是掷骰子。

骰子出大时候,我们就接受这个看上去差一点的解作为新的当前解,用它再做新的变换。

 

如果骰子出了小,那只有放弃他了,当前解不发生改变,还是前面的旧解,下一次变换只能

再次用他重新来一次。

当然这个骰子做了一点手脚,刚开始总是出大,后来大小出的差不多,再后来就总是出小了。具体原因大家自己看公式去吧。

 

这里想说一下,为什么我们要用一定的可能性来接受这个看上去差一点的解能?

因为这个解虽然差一点,但是也许只是看上去差一点, 作为下一个变换的起点,看上去差一点的解不见得比看上去好一点的解前途更差。

延安的共军和重庆的国军,你选哪个呢?身在其中,有时候骰子可能更靠谱一点。

 

第四步:循环。

现在,我们可能接受了变换解作为当前解;也可能放弃了变换解,当前解没发生变化,还是上一个解。 

不管怎么样,回到第二步,对当前解继续使用变换,取舍,循环下去。。。。。。。。

 

第五步:退出。

前面我们说过,一般情况下我们不知道最终目标是多少,如果知道的话,比如花费40元,如果某一个解的输出得到了这个花费40元,那么你的算法就可以退出了。这个解就是一个最优解(因为他的输出你确定是最优的)。

但是一般情况下我们不知道最终目标说多少,怎么办呢?

前面我们分析过,虽然有时候通过骰子,我们可能会接受一些看上去差一点的解,但是经过许多次循环以后,我们获得的当前解还是越来越好的

由于这样一个趋势,程序运行一段时间以后,我们无论再怎么变换出新解,也得不到更好的输出。

但是骰子还会让我们接受一些差解,那不就死循环了吗?

别忘了,骰子也有一个趋势,就是到后来就总是出小,即不再接受差解。

 

这样,找不出更好的解,也不再接受差解,如果当前解经过长时间都没发生改变,比如说100000次循环都没变,那么我们就可以认为当前解就是比较优秀的解了,可以退出了。

 

还有一种类似的方法是看输出。比如,初解的输出是100元,过了一会得到一个更好的值80元,再过一会又得到一个更好的值40元,然后经过长时间的运算也没找到更好的输出,那么40元输出对应的那个解就是比较优秀的解。

 

最后一个问题:是最优解吗?

回答:保证是比较优秀的解;很可能是最优解,但不能保证。哪怕你得到40元这个当前最好输出以后又运行了1年,没有找到更好的输出,也不能保证40元对应的解就是最优解(也许他真的就是)。

 

最优解有时候就像本拉登,天天在你身边,你也不一定认得出来。 

 

//==========================================

本文转自左洸博客园博客,原文链接:http://www.cnblogs.com/myqiao/archive/2011/05/17/2049416.html,如需转载请自行联系原作者

目录
相关文章
|
12天前
|
存储 监控 算法
员工上网行为监控中的Go语言算法:布隆过滤器的应用
在信息化高速发展的时代,企业上网行为监管至关重要。布隆过滤器作为一种高效、节省空间的概率性数据结构,适用于大规模URL查询与匹配,是实现精准上网行为管理的理想选择。本文探讨了布隆过滤器的原理及其优缺点,并展示了如何使用Go语言实现该算法,以提升企业网络管理效率和安全性。尽管存在误报等局限性,但合理配置下,布隆过滤器为企业提供了经济有效的解决方案。
54 8
员工上网行为监控中的Go语言算法:布隆过滤器的应用
|
12天前
|
存储 缓存 算法
探索企业文件管理软件:Python中的哈希表算法应用
企业文件管理软件依赖哈希表实现高效的数据管理和安全保障。哈希表通过键值映射,提供平均O(1)时间复杂度的快速访问,适用于海量文件处理。在Python中,字典类型基于哈希表实现,可用于管理文件元数据、缓存机制、版本控制及快速搜索等功能,极大提升工作效率和数据安全性。
49 0
|
2月前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法与应用
探索人工智能中的强化学习:原理、算法与应用
|
2月前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
52 1
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
67 1
|
2月前
|
缓存 算法 网络协议
OSPF的路由计算算法:原理与应用
OSPF的路由计算算法:原理与应用
66 4
|
2月前
|
机器学习/深度学习 监控 算法
基于反光衣和检测算法的应用探索
本文探讨了利用机器学习和计算机视觉技术进行反光衣检测的方法,涵盖图像预处理、目标检测与分类、特征提取等关键技术。通过YOLOv5等模型的训练与优化,展示了实现高效反光衣识别的完整流程,旨在提升智能检测系统的性能,应用于交通安全、工地监控等领域。
|
2月前
|
存储 算法 网络协议
OSPF的SPF算法介绍:原理、实现与应用
OSPF的SPF算法介绍:原理、实现与应用
94 3
|
2月前
|
算法 调度
基于遗传模拟退火混合优化算法的车间作业最优调度matlab仿真,输出甘特图
车间作业调度问题(JSSP)通过遗传算法(GA)和模拟退火算法(SA)优化多个作业在并行工作中心上的加工顺序和时间,以最小化总完成时间和机器闲置时间。MATLAB2022a版本运行测试,展示了有效性和可行性。核心程序采用作业列表表示法,结合遗传操作和模拟退火过程,提高算法性能。
|
2月前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
53 0

热门文章

最新文章