人工智能---模拟退火算法

摘要

TSP问题是著名的NP完全问题。为了在有限的时间和空间内求得这类问题的较优解一般可以采用各种启发式搜索的方法。我们分别使用了爬山算法和模拟退火算法对TSP进行求解,并对这两种算法的效果进行了对比。总体来说,模拟退火算法能够在更大的邻域范围内找到更好的解。

导言

  • TSP问题(Traveling Salesman Problem,即旅行商问题)是历史上著名的NP完全问题。问题可简单描述为:给定N个城市之间的距离,有一旅行商要从某一城市出发走遍所有的城市,最终回到出发城市,并且除第一个城市外每个城市只能走一遍,要求找出一个合适的路线使得路径最短。这是一个复杂的组合优化问题,若使用穷举法,当城市个数为N时,可行解的个数达到了(N - 1)!/2,当问题规模较大的时候(如N=50),求解时间变得不可接受。因此随着城市数量的增多,任何TSP算法最坏情况下的运行时间都有可能随着城市数量的增多超多项式(可能是指数)级别增长。因此穷举法在时间上是不可行的。
  • 而TSP问题在若干领域都有一些应用,如企划、物流、芯片制造。稍作修改,就是DNA测序等许多领域的一个子问题。在目前已经有了大量的启发式和精确方法,可以完全求解城市数量上万的实例,甚至能在1%误差范围内估计上百万个城市的问题。
  • 求解TSP问题的算法大致可以分为两类,一类是跟问题特征相关的局部启发式搜索算法,如分支定界,动态规划等,这类算法一般能得到最优解,但时间上往往不可行;另一类是独立于问题的智能优化算法,能够在一定精度范围内接近甚至求得最优解,如禁忌搜索算法、模拟退火算法、蚁群优化算法、遗传算法、微粒群算法等。
    我们所采用的算法是模拟退火算法。模拟退火是一种通用的概率算法,常用来在一定时间内寻找在一个很大搜寻空间中的近似最优解。它源于固体退火原理的通用概率演算法,利用Metropolis算法并适当地控制温度的下降过程实现模拟退火,从而达到求解全局优化解的目的。

实验过程

问题描述:

我们所选取的TSP问题规模为198个城市,且任意两个城市之间的往返距离相等,问题输入为198个城市的坐标,输出为最佳路径及其总距离。

状态表示

路径表示:198个城市编号(0-197)按一定顺序排列构成的数组,且数组的第一个元素总为编号0(假设从城市0出发,最终回到城市0),城市编号在数组中的顺序即该城市在路径上的顺序。
当前解:(路径,总距离)

采用多种邻域操作的局部搜索算法:

  • 我们以爬山算法为例实现了局部搜索算法,算法从某一随机解开始,每次迭代通过多种邻域操作产生包含若干新解的邻域,若该邻域中最好的解比当前解更好则更新当前解,否则保持当前解。迭代次数超过设定次数或找到足够好的解时算法终止。
  • 我们总共设计了三种邻域操作,且每种邻域操作所需的参数均为一组随机下标(x,y)来产生新的路径,记路径为path。
    • 邻域操作1:交换路径上的两个点,即path[x]和path[y]。
    • 邻域操作2:对path[x:y](假设x < y)之间的所有点进行逆序,即路径上某一段的所有点path[x],path[x + 1],…,path[y - 1], path[y]的顺序会颠倒,变成path[y],path[y - 1],…,path[x + 1],path[x]。
    • 邻域操作3:将某个点往前移(下标变小)一段距离,假设x < y,则将路径上的点path[y]移动至path[x]的位置,原来的path[x]到path[y - 1]之间的点则往后移一个位置。
  • 以上三种邻域操作均比较简单,便于实现路径总距离的增量计算,提高效率。

模拟退火算法

在局部搜索的基础加上模拟退火策略可以改进算法的效果,迭代过程是模拟退火算法的核心步骤,分为新解的产生和接受新解两部分

  • 由一个产生函数从当前解产生一个位于解空间的新解;为便于后续的计算和接受,减少算法耗时,通常选择由当前新解经过简单地变换即可产生新解的方法,如对构成新解的全部或部分元素进行置换、互换等,注意到产生新解的变换方法决定了当前新解的邻域结构,因而对冷却进度表的选取有一定的影响。
    产生函数即由上面提到的三种邻域操作完成,产生函数每次会比较三种邻域操作得到新解的好坏(总距离越小越好),并选择最好的新解。

  • 计算与新解所对应的目标函数差。因为目标函数差仅由变换部分产生,所以目标函数差的计算最好按增量计算。事实表明,对大多数应用而言,这是计算目标函数差的最快方法。
    以上三种邻域操作均只涉及到与path[x]和path[y]相邻的边的变化,因此在增量计算时考虑这四条相邻边即可。设与点path[x]相邻的两条边长度之和为neighbor_dis(x, path),与点path[y]相邻的两条边长度之和为neighbor_dis(y,path),新解的路径记为new_path,总距离为new_dis,依然假设x < y则:
    对于邻域操作1和2,new_dis = old_dis + neighbor_dis(x,new_path) + neighbor_dis(y,new_path) - neighbor_dis(x,old_path) - neighbor_dis(y,old_path)
    对于邻域操作3,new_dis = old_dis - neighbor_dis(y,old_path) - dis(x,x - 1) + neighbor_dis(x,new_path) + dis(y, y + 1)。

  • 判断新解是否被接受,判断的依据是一个接受准则,最常用的接受准则是Metropolis准则:若Δt′<0则接受S′作为新的当前解S,否则以概率exp(-Δt′/T)接受S′作为新的当前解S。

  • 当新解被确定接受时,用新解代替当前解,这只需将当前解中对应于产生新解时的变换部分予以实现,同时修正目标函数值即可。此时,当前解实现了一次迭代。可在此基础上开始下一轮试验。而当新解被判定为舍弃时,则在原当前解的基础上继续下一轮试验。

  • 降温过程:算法采取指数降温,每次降温都将旧的温度乘以一个固定的小于1的系数得到新问题,直到最终温度达到某一阈值算法终止。每迭代若干次数便会降温一次。该过程可由以下几个参数控制:初温,终温,每轮降温迭代次数。

结果分析

局部搜索

我们的爬山算法输入参数有两个,一个是最大搜索次数,另一个是内循环次数,经过多次实验,我们设置最大搜索次数为400,内循环次数为200。
在这里插入图片描述
最终跑的结果为17107,精度约8.4%。

在调试算法的过程中还发现使用多种邻域操作能改善爬山算法的效果。多种邻域操作能够提供比较丰富的新解,有可能提高发现好解的概率。
不足和改进

模拟退火搜索

模拟退火算法的参数包括初温,末温,降温速率,内循环次数,经过多次试验,我们设置初温为100,末温为0.01,降温速率为0.98,内循环次数为200可以得到比较好的结果。

代码

链接:TSPSA

猜你喜欢

转载自blog.csdn.net/qq_36347365/article/details/87008078
今日推荐