爬山法和模拟退火算法(SA)简单解析以及模拟退火解决TSP问题matlab实现

近期我所理解的两个算法

简单理解爬山法:

从一个随机值开始,每次从临近解空间中选择最优解,直到达到局部最优解

简单理解模拟退火:(模拟金属退火,百度百科:将金属缓慢加热到一定温度,保持足够时间,然后以适宜速度冷却。目的是降低硬度,改善切削加工性;降低残余应力,稳定尺寸,减少变形与裂纹倾向;细化晶粒,调整组织,消除组织缺陷)

爬山法具有局限性,特别遇到临近解相同时,容易陷入局部最优。

模拟退火同样从一个随机值开始,从邻域选取一点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        

某次运行结果:

猜你喜欢

转载自blog.csdn.net/mxxxkuku/article/details/101480973