zoukankan      html  css  js  c++  java
  • 模拟退火算法

    模拟退火(SA)

    物理过程由以下三个部分组成

    1.加温过程 问题的初始解

    2.等温过程 对应算法的Metropolis抽样的过程

    3.冷却过程 控制参数的下降

    默认的模拟退火是一个求最小值的过程,其中Metropolis准则是SA算法收敛于全局最优解的关键所在,Metropolis准则以一定的概率接受恶化解,这样就使算法跳离局部最优的陷进

     1.模拟退火算法求解一元函数最值问题

    使用simulannealbnd - Simulated annealing algorithm工具箱

    求y=sin(10*pi*x)./x;在[1,2]的最值

    下图是用画图法求出最值的

    x=1:0.01:2;
    y=sin(10*pi*x)./x;
    figure
    hold on
    plot(x,y,'linewidth',1.5);
    ylim([-1.5,1.5]);
    xlabel('x');
    ylabel('y');
    title('y=sin(10*pi*x)/x');
    [maxVal,maxIndex]=max(y);
    plot(x(maxIndex),maxVal,'r*');
    text(x(maxIndex),maxVal,{['x:' num2str(x(maxIndex))],['y:' num2str(maxVal)]});
    [minVal,minIndex]=min(y);
    plot(x(minIndex),minVal,'ro');
    text(x(minIndex),minVal,{['x:' num2str(x(minIndex))],['y:' num2str(minVal)]});
    hold off;
    

    用模拟退火工具箱来找最值

    求最小值

    function fitness=fitnessfun(x)
    fitness=sin(10*pi*x)./x;
    end
    

     

     求最大值

    function fitness=fitnessfun(x)
    fitness=-sin(10*pi*x)./x;
    end
    

    Optimization running.
    Objective function value: -0.9527670052175917
    Maximum number of iterations exceeded: increase options.MaxIterations.
    用工具箱求得的最大值为0.9527670052175917

     2.二元函数优化

    [x,y]=meshgrid(-5:0.1:5,-5:0.1:5);
    z=x.^2+y.^2-10*cos(2*pi*x)-10*cos(2*pi*y)+20;
    figure
    mesh(x,y,z);
    hold on
    xlabel('x');
    ylabel('y');
    zlabel('z');
    title('z=x^2+y^2-10*cos(2*pi*x)-10*cos(2*pi*y)+20');
    maxVal=max(z(:));
    [maxIndexX,maxIndexY]=find(z==maxVal);%返回z==maxVal时,x和y的索引
    for i=1:length(maxIndexX)
        plot3(x(maxIndexX(i),maxIndexY(i)),y(maxIndexX(i),maxIndexY(i)),maxVal,'r*');
        text(x(maxIndexX(i),maxIndexY(i)),y(maxIndexX(i),maxIndexY(i)),maxVal,{['x:' num2str(x(maxIndexX(i)))] ['y:' num2str(y(maxIndexY(i)))] ['z:' num2str(maxVal)] });
    end
    hold off;
    

     

    function fitness=fitnessfun(x)
    fitness=-(x(1).^2+x(2).^2-10*cos(2*pi*x(1))-10*cos(2*pi*x(2))+20);
    end
    

     Optimization running.
    Objective function value: -80.50038894455415
    Maximum number of iterations exceeded: increase options.MaxIterations.
    找到的最大值:80.50038894455415

     3.解TSP问题

    (用的数据和前几天用遗传算法写TSP问题的数据一致,但是结果比遗传算法算出来效果差很多,不知道是不是我写错了,怀疑人生_(:з」∠)_中。。。

    x=[41 94;37 84;54 67;25 62;7 64;2 99;68 58;71 44;54 62;83 69;64 60;18 54;22 60;
      83 46;91 38;25 38;24 42;58 69;71 71;74 78;87 76;18 40;13 40;82 7;62 32;58 35;45 21;41 26;44 35;4 50];
    d=distance(x);%计算距离矩阵
    n=size(d,1);%城市的个数
    T0=1e50;%初始温度
    Tend=1e-30;%终止温度
    L=2;%各温度下的迭代次数
    q=0.95;
    %计算迭代的次数 T0 * (0.95)^x = Tf
    time=ceil(double(solve([num2str(T0) '*(0.9)^x=' num2str(Tend)])));%计算迭代的参数
    count=0;
    obj=zeros(time,1);
    path=zeros(time,n);
    %随机产生一条初始路线
    journey=randperm(n);
    rlength=pathlength(d,journey);
    drawpath(journey,x,rlength);
    disp('初始种群中的一个随机值:');
    outputpath(journey);
    disp(['初始路径总距离:',num2str(rlength)]);
    index=0;
    %迭代优化
    while T0>Tend
        count=count+1;
        %产生新解
        newjourney=NewAnswer(journey);
        [journey,r]=Metropolis(journey,newjourney,d,T0);
        %记录每次迭代的最优路线
        if count==1||r<obj(count-1)
         obj(count)=r;
         index=count;
        else
            obj(count)=obj(count-1);
        end
         path(count,:)=journey;
         T0=T0*q;
         
         disp(['第' num2str(count) '代最优解' num2str(path(count,:))] );
         disp(['总距离:',num2str(obj(count))]);
    end
        figure
        plot(1:count,obj);
        xlabel('迭代次数');
        ylabel('距离');
        title('优化过程');
    grid on;
    s=path(index,:);
    a=pathlength(d,s);
    drawpath(path(index,:),x,a);
    disp('最优解');
    p=outputpath(s);
    disp(['总距离:',num2str(a)]);
    
    function d=distance(citys)
    %输入 各城市的位置坐标
    %输出 两两城市之间的距离
    n=size(citys,1);
    d=zeros(n,n);
    for i=1:n
        for j=1:n
            d(i,j)=((citys(i,1)-citys(j,1))^2+(citys(i,2)-citys(j,2))^2)^0.5;
            d(j,i)=d(i,j);
        end
    end
    
    function [s,r]=Metropolis(s1,s2,d,t)
    %s1 当前解
    %s2 新解
    %d 距离矩阵
    %t 温度
    %s 下一个当前解
    %r 下一个当前解的路线距离
    r1=pathlength(d,s1);%计算s1路线长度
    n=size(d(2));%城市的个数
    r2=pathlength(d,s2);%计算s2路线长度
    dc=r2-r1;%计算能力之差
    
    %比前一个解更优接受新解,没有前一个解以一定概率接受新解
    if dc<0 
        s=s2;
        r=r2;
    elseif exp(-dc/t)>0 % 以exp(-dC/T)概率接受新路线
            a=exp(-dc/t)*100;
            test(1:100)=0;
            test(1:a)=1;
            r=round(99*rand+1);
            pcc=test(r);
            if pcc==1
            s=s2;
            r=r2;
            else
                s=s1;
                r=r1;
            end
        else
            s=s1;
            r=r1;
    end
    end
    
    function s2=NewAnswer(s1)
    %随机产生新的解
    %s1 当前解
    %s2 新解
    n=length(s1);
    s2=s1;
    a=round(rand(1,2)*(n-1)+1);
    s2(a(2))=s1(a(1));
    w=s1(a(2));
    s2(a(1))=w;
    
    function p=outputpath(route)
    %给R末端添加起点R(1)
    route=[route,route(1)];
    n=length(route);
    p=num2str(route(1));
    for i=2:n
    p=[p,'->',num2str(route(i))];
    end
    disp(p);
    
    function dis=pathlength(d,route)
    %计算起点与终点之间的距离
    %d 城市间距离
    %route 路线
    dis=0;
    n=length(d);
    for i=1:n-1
        j=route(i);
        k=route(i+1);
       dis=dis+d(route(j),route(k));
       
    end
    j=route(n);
    dis=dis+d(route(1),route(j));
    
    function drawpath(route,citys,s)
    %传入参数 路线 城市坐标 
    figure
    plot([citys(route, 1); citys(route(1), 1)], [citys(route, 2); citys(route(1), 2)], 'o-');
    grid on
     
    %给每个地点标上序号
    for i = 1: size(citys, 1)
        text(citys(i, 1), citys(i, 2), ['   ' num2str(i)]);
    end
     
    text(citys(route(1), 1), citys(route(1), 2), '       起点');
    text(citys(route(end), 1), citys(route(end), 2), '       终点');
    text(10,20,['距离长度:' num2str(s) 'km']);
    xlabel('x/km');
    ylabel('y/km');
    

     

     

  • 相关阅读:
    VS2010,VS2012,VS2013中,无法嵌入互操作类型“……”,请改用适用的接口的解决方法
    安装MySQL遇到的常见英文翻译
    IIS站点报拒绝访问Temporary ASP.NET Files的解决办法
    【教程】教你解决“Windows 资源保护找到了损坏文件但无法修复其中某些文件”的问题【转载】
    .net中使用XPath语言在xml中判断是否存在节点值的方法
    join 子句(C# 参考)
    sql:inner join,left join,right join,full join用法及区别
    xslt中substring 函数的用法
    如何查看mysql数据库表所使用的引擎(转载)
    FusionCharts 更新 chart data 数据
  • 原文地址:https://www.cnblogs.com/zuiaimiusi/p/11318501.html
Copyright © 2011-2022 走看看