模拟退火算法

来源:互联网 发布:python 验证码识别库 编辑:程序博客网 时间:2024/06/08 18:52

一、模拟退火算法简介

      

模拟退火算法(Simulated  Annealing, SA)是一种通用的随机搜索算法,是对局部搜索算法的扩展。与一般局部搜索算法不同,SA以一定的概率选择邻域中目标值相对较小的状态,是一种理论上的全局最优算法
模拟退火算法是源于对热力学中退火过程的模拟,在某一给定初温下,通过缓慢下降温度参数,使算法能够在多项式时间内给出一个近似最优解

二、模拟退火算法与金属退火过程对比

   

物理退火过程:

加温过程----固态溶解为液态的过程,分子的分布从有序的晶体态转化为无序的液态,消除原有的非均匀态。

等温过程----在退火中,需要保证系统在每一个温度下都达到充分的平衡状态。

冷却过程----液态凝固成固态晶体的过程。系统能量逐渐下降,从而得到低能有序的晶体结构。

模拟退火过程:

设定初始高温,相当于物理退火的加温过程。初始温度要足够高,在实际应用中,要根据以往的经验,通过反复实验来确定T0的值。

热平衡达到,相当于物理退火的等温过程。是指在一个给定温度下,SA用特殊的抽样策略进行随机搜索,最终达到平衡状态的过程。这是SA算法的内循环过程。

降温函数,相当于物理退火的冷却过程。用来控制温度的下降方式,这是SA算法的外循环过程。常用的降温函数有Tk+1=Tk-DT,Tk+1=Tk*r,其中r∈(0.95,0.99)。

  1953年,Metropolis等提出了一种重要性采样法(Metropolis准则),即以概率接受新状态
   Metropolis准则

   在温度t,由当前状态i产生新状态j,两者的能量分别为Ei 和 Ej ,若Ei >Ej ,则接受新状态j为当前状态;否则,以一定概率:

         

 来接受状态j,其中k为Boltzmann常数。当这种过程多次重复后,系统将趋于能量较低的平衡态。

  三、模拟退火算法流程图

  


  四、模拟退火算法求解TSP问题

   

 

  参数的设定

 •初始解:随机选定一条路径,如[A,B,C,D,E,A]
 •初始温度T0=100
 •终止温度Tf=20
 •降温函数Tk+1=Tk-DTDT=40
 •热平衡达到:内循环次数n=3


代码实现如下:
%======================================================================================
   %%%一个旅行商人要拜访全国31个省会城市,需要选择最短的路径%%%%


%%%模拟退火算法解决TSP问题%%%%%%%

clear all; %清除所有变量
close all; %清图
clc ;      %清屏
C=[
1304 2312;
3639 1315;
4177 2244;
3712 1399;
3488 1535;
3326 1556;
3238 1229;
4196 1004;
4312 790;
4386 570;
3007 1970;
2562 1756;
2788 1491;
2381 1676;
1332 695;
3715 1678;
3918 2179;
4061 2370;
3780 2212;
3676 2578;
4029 2838;
4263 2931;
3429 1908;
3507 2367;
3394 2643;
3439 3201;
2935 3240;
3140 3550;
2545 2357;
2778 2826;
2370 2975
];%31个省会坐标


n=size(C,1); %TSP问题的规模,即城市数目
T=100*n;     %初始温度
L=100;       %马尔科夫链的长度
K=0.99;      %衰减参数


%%%城市坐标结构体%%%%%%%
city=struct([]);


for i=1:n
    city(i).x=C(i,1);
    city(i).y=C(i,2);
end


l=1;        %统计迭代次数
len(l)=func5(city,n); %每次迭代后路线的长度


figure(1);

while T>0.001
    %%%%%%%%%%%%%%%多次迭代扰动,温度降低前多次试验%%%%%%%%
    for i=1:L
    %%%%%%%%%%%%%%%计算原路线总距离%%%%%%%%%
    len1=func5(city,n);
    %%%%%%%%%%%%%%%产生随机扰动%%%%%%%%%
    %%%%%%%%%%%%%%%随机置换两个不同的城市的坐标%%%%%%%%%
    p1=floor(1+n*rand);
    p2=floor(1+n*rand);
    while p1==p2
        p1=floor(1+n*rand);
        p2=floor(1+n*rand);
    end
    tmp_city=city;
    %%交换元素
    tmp=tmp_city(p1);
    tmp_city(p1)=tmp_city(p2);
    tmp_city(p2)=tmp;
    %%%%%%%%%%%%%%%计算新路线总距离%%%%%%%%%
    len2=func5(tmp_city,n);
    %%%%%%%%%%%%%%%新老距离的差值,相当于能量%%%%%%%%%
    delta_e=len2-len1;
    %%%%%%%%%%%%%%%新路线好于旧路线,用新路线替代旧路线%%%%%%%%%
    if delta_e<0
        city=tmp_city;
    else
        %%%%%%%%%%%%%%%以一定概率选择是否接受%%%%%%%%%
        if exp(-delta_e/T)>rand()
            city=tmp_city;
        end
    end
    end
     l=l+1;          %迭代次数加1
     
     %%%%%%%%%%%%%%%计算新路线的距离%%%%%%%%%
     len(l)=func5(city,n);
     %%%%%%%%%%%%%%%温度不断下降%%%%%%%%%
     T=T*K;
     for i=1:n-1
         plot([city(i).x,city(i+1).x],[city(i).y,city(i+1).y],'bo-');
         hold on;
     end
      plot([city(n).x,city(1).x],[city(n).y,city(1).y],'ro-');
      
      title(['优化最短距离:',num2str(len(l))]);
         hold off;
         pause(0.005);
end
  
  figure(2)
  plot(len);
  xlabel('迭代次数');
  ylabel('目标函数值');
  title('适应度进化曲线');

%计算距离的函数
function len=func5(city,n)
 len=0;
 for i=1:n-1
    len=len+sqrt((city(i).x-city(i+1).x)^2+(city(i).y-city(i+1).y)^2);
 end
   len=len+sqrt((city(n).x-city(1).x)^2+(city(n).y-city(1).y)^2);
end
%=========================================================================================

原创粉丝点击