模拟退火算法编码比较简单,而且容易调试,所以应用比较广泛。算法的思想可以参考这篇:模拟退火算法的基本思想和算法流程
直接给出源代码:
主程序:
clear all;
close all;
clc;
%% 参数设置
t_0 = 1e100; %初始温度
t_f = 1e-90; %终止温度
num_gen = 100;
num_swap=2;
num_city = 48;
[len_side,city] = City(num_city); %城市坐标
cool_rate = 0.85;
solu = randperm(num_city);
t_k = t_0;
min_fit = zeros(2,2693);
j=1;
fit0=Fitness(solu,len_side);
min_fit(1,j)=j;
min_fit(2,j)=fit0;
%% 开始循环
while t_k > t_f %循环条件,把降温底线作为条件
for i = 1 : num_gen %循环次数
pre_fit = Fitness(solu,len_side); %旧适应度值
temp_solu = Move(solu,num_swap);
%随机n次交换
temp_fit = Fitness(temp_solu,len_side); %新距离和
diff = temp_fit - pre_fit; %产生误差
if diff < 0
%距离变小,直接接受,不用考虑
solu = temp_solu; %接受
else
if rand() < exp(-diff/(t_k)) %否则,以一定的概率接受
solu = temp_solu; %概率符合了,进来接受
end
end
end
last_fit=Fitness(solu,len_side);
t_k = t_k*cool_rate; %降温过程
j=j+1;
min_fit(1,j)=j;
min_fit(2,j)=last_fit;
end
%% 输出结果
temp_fit = last_fit/sqrt(10);
fprintf('\t\t\t最小值 = % 3.4f\n',temp_fit);
figure
plot(min_fit(1,:),min_fit(2,:),'k');
move函数:
function s = Move(solu,n)
s = solu;
len=length(solu);
for i = 1 : n
spot1 = round((len-1)*rand())+1;%生成随机交换点(1~30之间
spot2 = round((len-1)*rand())+1;
temp = s(1,spot1); %交换操作
s(:,spot1) = s(:,spot2);
s(:,spot2) = temp;
end
end
city函数
function [Len,city_loc]=City(n)
Len=zeros(n,n);%Len是一个30*30的矩阵,city_location是一个30行两列的矩阵
if n==30
city=[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];%30 cities d'=423.741 by D B Fogel
end
if n ==48
city=[6734 1453;2233 10;5530 1424;401 841;3082 1644;7608 4458;7573 3716;
7265 1268;6898 1885;1112 2049;5468 2606;5989 2873;4706 2674;4612 2035;6347 2683;
6107 669;7611 5184;7462 3590;7732 4723;5900 3561;4483 3369;6101 1110;5199 2182;
1633 2809;4307 2322;675 1006;7555 4819;7541 3981;3177 756;7352 4506;7545 2801;3245 3305;
6426 3173;4608 1198;23 2216;7248 3779;7762 4595;7392 2244;3484 2829;6271 2135;
4985 140;1916 1569;7280 4899;7509 3239;10 2676;6807 2993;5185 3258;3023 1942]
end
for i=1:n-1
for j=i+1:n
Len(i,j)=((city(i,1)-city(j,1))^2+(city(i,2)-city(j,2))^2)^0.5;
Len(j,i)=Len(i,j);
end
end
city_loc=city;
end
Fitness函数
%-------------函数说明----------------
% 距离计算函数
% 输入变量:
% inputcities:原来的地点顺序和位置
% 输出变量:
% d:顺序相加的距离和
%---------------------------------------
function fit = Fitness(s,len_side) %城市距离求和
fit=0;
len=size(len_side,1);
for i = 1:(len-1)
fit = fit+len_side(s(i),s(i+1));
end
fit = fit + len_side(s(len),s(1)); %相邻两个点的距离
end