zoukankan      html  css  js  c++  java
  • 【数学建模】——模拟退火算法(SAA)

    模拟退火算法(SAA)

    启发式算法

    什么是启发式算法?

    • 基于直观或经验而构造的算法
    • 是一种技术,在可接受的成本下去寻找最好的解

    启发式算法适用于什么场景

    • 寻找最优解
    • 如何平衡局部搜索与全局搜索;有效逃离局部最优解;

    还有哪些启发式算法?

    • 群体智能算法便是启发式算法

    • 动物

      • 粒子群优化,蚂蚁优化,鱼群算法,蜂群算法等;
    • 植物

      • 向光性算法,杂草优化算法,等等;
    • 人类

      • 和声搜索算法是较好的算法;

    模拟退火算法的基本原理

    思想

    • 借鉴固体的退火过程,当固体的温蒂较高的时候,内能比较大,固体内的粒子处于快速无序运动状态。温度降低,固体内能减少,粒子逐渐趋于有序,最终固体处于常温状态,内能达到最小,此时粒子最为稳定
    • 一开始为算法设定一个较高的值T(模拟温度),算法不稳定,选择当前较差解的概率很大;随着T的减小,算法趋于稳定,选择较差解的概率减小,最后,T降至终止迭代的条件,得到近似最优解。

    代码

    /*
    * J(y):在状态y时的评价函数值
    * Y(i):表示当前状态
    * Y(i+1):表示新的状态
    * r: 用于控制降温的快慢
    * T: 系统的温度,系统初始应该要处于一个高温的状态
    * T_min :温度的下限,若温度T达到T_min,则停止搜索
    */
    while( T > T_min )
    {
      dE = J( Y(i+1) ) - J( Y(i) ) ;
    
      if ( dE >=0 ) //表达移动后得到更优解,则总是接受移动
    Y(i+1) = Y(i) ; //接受从Y(i)到Y(i+1)的移动
      else
      {
    // 函数exp( dE/T )的取值范围是(0,1) ,dE/T越大,则exp( dE/T )也
    if ( exp( dE/T ) > random( 0 , 1 ) )
    Y(i+1) = Y(i) ; //接受从Y(i)到Y(i+1)的移动
      }
      T = r * T ; //降温退火 ,0<r<1 。r越大,降温越慢;r越小,降温越快
      /*
      * 若r过大,则搜索到全局最优解的可能会较高,但搜索的过程也就较长。若r过小,则搜索的过程会很快,但最终可能会达到一个局部最优值
      */
      i ++ ;
    }
    
    clear all; %清除所有变量
    close all; %清图
    clc ;      %清屏
    D = 10;
    Xs = 20;%%函数上限
    Xx =-20;%%函数下限
    %%%%%%%%%%%%%%%%%%%%冷却表参数%%%%%%%%%%%%%%%%%%%%%%%%%%
    L= 200;    %马尔可夫链长度
    K = 0.998;  %衰减参数
    S = 0.01;   %步长因子,就是每次解变化的大小
    T = 100;    % 初始温度
    YZ = 1e-8;  %容差
    P = 0;      %Metropolis过程接受点
    
    %%%%%%%%%%%%%%%%%随机选点初值设定%%%%%%%%%%%%%%%%%%%5
    PreX = rand(D,1)*(Xs-Xx)+Xx;%初始化矩阵D × 1的解
    PreBestX = PreX;%用于保存上一个最优的解
    PreX = rand(D,1)*(Xs-Xx)+Xx;
    BestX = PreX;%用于保存当前最优解
    %%%%%%%%%%%%%%%%%每迭代一次退火一次(降温),直到满足迭代条件为止%%%%%%%%%
    deta = abs(func1(BestX)-func1(PreBestX));%能量差值,适应度差值
    while (deta>YZ) && (T>0.001)
        T = K*T;%%降温
        %%%%%%%%%%%%在当前温度T下迭代次数%%%%%%%%%%%%
        for i = 1:L
            %%%%%%%%%%%%在此点附近随机选择下一点%%%%%%%%%%%%%%%
            %%%%%%%%%%%%根据当前条件产生一个新解%%%%%%%%%%%%%%%%%
            NextX  = PreX + S*(rand(D,1) * (Xs-Xx)+Xx);
            %%%%%%%%%%%%%%%边界条件处理%%%%%%%%%%%%%
            %%%%%%%%%%%%%%因为上一行代码是随机产生的数,判断产生的数,是否超过定义域范围,超过则重新产生一个数%%%%%%
            for ii = 1:D
                if NextX(ii) > Xs | NextX(ii) < Xx
                    NextX(ii) = PreX(ii) + S* (rand * (Xs-Xx)+Xx);
                end
            end
        %%%%%%%%%%%%%%是否全局最优解%%%%%%%%%%%%%%%%%%%%
        if (func1(BestX) > func1(NextX))
            %%%%%%%%%%%%%%%%%%%%保留上一个最优解%%%%%%%%%%%%%%5
            PreBestX = BestX;
            %%%%%%%%%%%%%%%%%此为新的最优解%%%%%%%%%%%%%%%%%
            BestX  = NextX;
        end
            %%%%%%%%%%%%%%%Metropolis过程%%%%%%%%%%%%%%%%%%%
        if(func1(PreX) - func1(NextX)>0)
            %%%%%%%%%%%%%%接受新解%%%%%%%%%%%%%
            PreX = NextX;
            P = P+1;
        else
            %%%%%%%%%%%%%%%%%%%求状态2接受的概率接受新解%%%%
            %%%%%%%%%%%%%%%%%%%随着越来越接近最优值的时候,接受较差的状态的概率越低%%%%%
            changer = -1 * (func1(NextX)-func1(PreX))/T;
            p1 = exp(changer);
            %%%%%%%%%%%%%%%%%%以一定概率接受较差的解%%%%%%%%%%%%%%%%%
            if p1 >rand
                PreX = NextX;
                P =P+1;
            end
        end
        trace(P+1) = func1(BestX);
        
        end
        deta = abs(func1(BestX) - func1(PreBestX));
    end
    
    %最小值的解
    BestX
    %解的适应度
    func1(BestX)
    figure
    plot(trace(2:end))
    xlabel('迭代次数')
    ylabel('目标函数值')
    title('适应度进化曲线')
    
    %%%%%%%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%%
    
    function result = func1(x)
    summ = sum(x.^2);
    result = summ;
    end
    
    

    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))]);%%num2str将数字转为字符数组
        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
    
    
    

    模拟退火算法的流程图

    参数讲解

    冷却进度表

    • 控制温度参数的初值T0

    • 控制温度T的衰减函数(温度的更新)

    • 马尔科夫链的长度Lk(迭代次数)

    • 控制参数T的终值(停止准则)

    Metropolis准则

    相似性对比

    优缺点

    优点

    • 高效地解决NP问题(TSP问题和0-1背包问题)
    • 相较于其他非线性与优化算法,模拟退火算法编程工作量小且易于实现

    缺点

    • 使用不当,可能陷入局部最优
    • 参数难以控制,所得结果可能为接近最优解但是并非最优解

    模拟退火算法的应用

    最优化

    求解函数最值问题

    • 用代码求解
    • 用工具箱求解
  • 相关阅读:
    myEclipse环境下配置springMvc项目,进行简单的请求
    自记录:git如何上传文档到git@osc
    java UDP网路编程
    Dom解析xml源代码
    SAX解析XML文件实例代码
    javaFile循环列出指定目录下的所有文件(源代码)
    javaIO流实现读写txt文件
    Java类之间的关联关系(转载)
    Python基本语法
    Python3.4入门之ifelse错误解决方案
  • 原文地址:https://www.cnblogs.com/pailang-lee/p/14353849.html
Copyright © 2011-2022 走看看