近期我所理解的两个算法
简单理解爬山法:
从一个随机值开始,每次从临近解空间中选择最优解,直到达到局部最优解
简单理解模拟退火:(模拟金属退火,百度百科:将金属缓慢加热到一定温度,保持足够时间,然后以适宜速度冷却。目的是降低硬度,改善切削加工性;降低残余应力,稳定尺寸,减少变形与裂纹倾向;细化晶粒,调整组织,消除组织缺陷)
爬山法具有局限性,特别遇到临近解相同时,容易陷入局部最优。
模拟退火同样从一个随机值开始,从邻域选取一点Vn,
若得出更优解,则选Vn继续循环选择,若不是更优解,则以一定概率选择Vn
循环上一步一定次数
模拟退火几个要素:
T 初始温度
Tmin 最终温度
t 现在温度
k 降温速率
利用模拟退火可求出问题的可行解,虽然解不一定达到最优,但是能在有限的时间内求出较优解。
以下为模拟退火解决TSP,数据:eil51
参考:https://blog.csdn.net/qq_43245594/article/details/89342498
function sa()
clear;
iter =1;%迭代
k =0.98;%降温速率
T = 1000;%初始温度
Markov = 1000;%链长
Tmin = 1;%最后温度
t = T;%现在温度
load data.txt; %载入eil51数据
city = data;%存入city
n = size(city,1);%city数量
D = zeros(n,n);%存放距离
%储存城市与城市之间的距离
for i = 1:n
for j = 1:n
D(i,j) = sqrt((city(i,1)-city(j,1))^2 + (city(i,2)-city(j,2))^2)
end
end
%初始路线
route = 1:n;
%目前路线
route_now = route;
%最优结果(总路线长度),Inf无穷大
best_length = Inf;
%目前路线总长度
length_now = Inf;
%最优路线
best_route = route;
%开始降温
while t >= Tmin
for j = 1:Markov;
if(rand < 0.7) %两个城市交换
city1 = 0;
city2 = 0;
while(city1==city2 && city1>=city2)%循环直到两城市不等且city2大
city1 = ceil(rand*n);
city2 = ceil(rand*n);
end
%在路线中交换两城市位置
temp = route_now(city1)
route_now(city1) = route_now(city2)
route_now(city2) = temp;
else %两个区间交换
index = zeros(3,1)%3行1列矩阵
length_index = length(unique(index));%不重复元素个数
while (length_index < 3)%取三个不相同的城市
index = ceil([rand*n rand*n rand*n])
length_index = length(unique(index));
end
index_ = sort(index);%排好顺序
temp = route_now;
%两区间内容交换
%index_(1):城市1 类似于 城市1__@___城市2__&___城市3 交换@与&
temp(index_(1):index_(1)+(index_(3)-(index_(2)+1))) = route_now(index_(2)+1:index_(3))
temp(index_(1)+index_(3)-index_(2):index_(3)) = route_now(index_(1):index_(2))
route_now = temp;
end
length_new = 0;
route_new = [route_now route_now(1)];%后面加上第一个城市
%计算总长度
for j = 1:n
length_new = length_new +D(route_new(j),route_new(j+1));
end
if length_new < length_now %如果优化了
length_now = length_new;
route = route_now;
if length_new <best_length %优化了
iter = iter +1; %迭代次数+1
best_length = length_new;
best_route = route_now;
end
else
if rand<exp(-(length_new-length_now)/t) %一定概率
route = route_now;
length_now = length_new;
end
end
route_now = route;
end
t=t*k;%降温
end
Route=[best_route best_route(1)];
plot([city(Route ,1)], [city(Route ,2)],'o-');
disp('最优解为:')
disp(best_route)
disp('最短距离:')
disp(best_length)
disp('最优解迭代次数:')
disp(iter)
for i = 1:n
%对每个城市进行标号
text(city(i,1),city(i,2),[' ' num2str(i)]);
end
xlabel('城市位置横坐标')
ylabel('城市位置纵坐标')
title(['模拟退火算法(最短距离):' num2str(best_length) ''])
end
某次运行结果: