模拟退火代码超通俗解释(MATLAB)

主程序(旅行商问题)

clc;clear;
%模拟退火 旅行商问题
n=20;%城市个数
temp=100*n;%初始温度
G=100;%实验次数(随机搜索)

%随机初始化城市坐标(实际问题时,应该输入实际的每个城市坐标)
city=struct([]);
for i =1:n
    city(i).x=floor(1+100*rand());
    city(i).y=floor(1+100*rand());
end
l=1;len(l)=computer_tour(city,n);%计算当前路线总长度(即目标函数)
%因为此程序核心是不断改变各城市在city结构组(数组)的位置(行数)
%city中是一行对应一个城市,20个城市共20行,初始状态是城市随机排下来
%类似于一直改变20个城市排序,寻找最佳的排序,让总路线最短
netplot(city,n);%画出当前的旅行路线
while temp>0.001  %停止迭代的温度即当温度低于0.001时,停止运行
    for i=1:G  %降温之前多次实验
        len1=computer_tour(city,n);%计算当前路线总长度
        tmp_city=perturb_tour(city,n);%随机置换city中两个城市坐标
        len2=computer_tour(tmp_city,n);%计算被随机置换后的路线总长度
        d_len=len2-len1;%新的长度减原来长度,它们的差值
        if d_len<0   %小于0说明len2小于len1,即新的总长度更短
            city=tmp_city;%因为新的城市排序更优,将新路线替代旧路线
        else   %即大于等于0,即新路线没有旧路线长度短,没有好于旧路线
            if exp(-d_len/temp)>rand()  %模拟退火算法的核心,一定概率防止陷入局部最优解
                %概率选择是否接受新的路线
                %当d_len不变,temp温度越低,执行此步骤的概率也就越低,越不太可能接受新路线
                %当temp不变,d_len越大,执行此步骤的概率越低,越不太可能接受新路线
                city=tmp_city;
            end
        end
    end
    l=l+1;%统计while循环迭代次数
    len(l)=computer_tour(city,n);%存储每一次迭代的路线总长度
    temp=temp*0.99;% while循环每迭代一次,降温一次
end
figure;
netplot(city,n);%画出最终路线
% 因为城市坐标是随机生成的,所以每次运行画出来的图的路线总长度都是不一样的
figure;
plot(len);%画出路线总长度变化趋势
%因为随着while迭代,temp温度会越来越多,“概率选择是否接受新的路线”的可能性也会变得极低,
% 所以不太可能突变了,而是慢慢趋于平稳

辅助function程序

computer_tour.m

function len=computer_tour(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);
%因为此程序核心是不断改变各城市在city结构组(数组)的位置(行数)
%city中是一行对应一个城市,20个城市共20行,初始状态是城市随机排下来
%类似于一直改变20个城市排序,寻找最佳的排序,让总路线最短
end

netplot.m

function netplot(city,n)
hold on 
% 可视化路线,将行走路线画出来
for i =1:n-1
    plot(city(i).x,city(i).y,"r*");%画出每个城市的点位(散点图)
    line([city(i).x city(i+1).x],[city(i).y city(i+1).y]);%用线将每个城市相连接
end
plot(city(n).x,city(n).y,"r*");
line([city(n).x city(1).x],[city(n).y city(1).y]);%%for循环无法将城市起点与终点连接,所以这里另外连接
hold off
end

perturb_tour.m

function city=perturb_tour(city,n)
%随机置换两个不同城市的坐标,p1和p2用来随机选2个不同城市用来置换
p1=floor(1+n*rand());%产生的随机数范围是1~n,为整数,因为共n个城市
p2=floor(1+n*rand());
while p1==p2  
    p1=floor(1+n*rand());
    p2=floor(1+n*rand());%防止无效置换,确保打乱了城市在原city中的顺序
end
tmp=city(p1);%提前储存p1城市坐标,因为到下一行原p1城市坐标会被改变
city(p1)=city(p2);%让p1城市坐标换成p2城市坐标
city(p2)=tmp;%让p2城市坐标换成p1城市坐标
end

运行结果:

 

  • 7
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
m .\anneal.m .\berkeley.m .\COPYRIGHT.txt .\dispEh.m .\dispEt.m .\dispMat.m .\ensembleInit.m .\examples .\........\chemcluster .\........\...........\clusterdistances.m .\........\...........\clusterplot.m .\........\...........\cluster_cost.m .\........\...........\cluster_init.m .\........\...........\cluster_new.m .\........\...........\cluster_perturb.m .\........\...........\test_all.m .\........\...........\try_me.m .\........\graphbipart .\........\...........\bipart_cost.m .\........\...........\bipart_init.m .\........\...........\bipart_new.m .\........\...........\bipart_perturb.m .\........\...........\try_me.m .\........\proteinfold .\........\...........\sequence_cost.m .\........\...........\sequence_init.m .\........\...........\sequence_new.m .\........\...........\sequence_perturb.m .\........\...........\try_me.m .\........\README.txt .\........\seismicdecon .\........\............\decon_cost.m .\........\............\decon_init.m .\........\............\decon_new.m .\........\............\decon_perturb.m .\........\............\eventparts.m .\........\............\eventplot.m .\........\............\modelparts.m .\........\............\modelplot.m .\........\............\modelsignal.m .\........\............\README.txt .\........\............\try_me.m .\........\spinglass .\........\.........\Jcoord.m .\........\.........\spin_cost.m .\........\.........\spin_init.m .\........\.........\spin_new.m .\........\.........\spin_perturb.m .\........\.........\try_me.m .\........\tsp .\........\...\route_cost.m .\........\...\route_init.m .\........\...\route_new.m .\........\...\route_perturb.m .\........\...\try_me.m .\franz.m .\geman.m .\geometric.m .\hartley.m .\historyupdate.m .\hoffmann.m .\metropolis.m .\metropoliswalk.m .\mktemplate.m .\nextstate.m .\plotBins.m .\randomwalk.m .\README.txt .\retrospect.m .\satools.m .\satoolsversion.m .\stillinger3Dpoints.m .\szu.m .\template_cost.txt .\template_init.txt .\template_new.txt .\template_perturb.txt .\template_try_me.txt .\TfinalNstop.m .\thermospeedHC.m .\thermospeedR.m .\threshold.m .\TinitAccept.m .\TinitT0.m .\TinitWhite.m .\TM.m .\tsallis.m

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PlatinumA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值