运筹优化 | 模拟退火算法解决旅行商问题详解

一、题目

        我方有一个基地,经度和纬度为(70,40)。假设我方飞机的速度为 400km/h。我方派一架飞机从基地出发,侦察完所有目标,再返回原来的基地。在每一目标点的侦察时间不计.求该架飞机所花费的时间(假设我方飞机巡航时间可以充分长)。经纬度数据如下图,可复制数据见文末。

f38de7995aa74527966e6f6ebe6f2926.png

e6ee3525ff364eb4bbb98a0d35bea2f6.png  

二、题目解析

0883ff81cc044b1e806b8b4fe0d82a80.png

f420ec680f1142649347c8fd713ff3a1.png

cacc3affe84943c59f69005aafe30539.png         对于实际距离交换法路径差的理解如下: 

e27213f6076f4f5cb17f435491fb3992.jpeg

代码如下:

clear;clc
sj=xlsread("sj.xlsx");% 加载excel数据 

x=sj(:,1);% 第一列为经度
y=sj(:,2);% 第二列为纬度
dl=[70,40];% 起点坐标
sj=[dl;sj;dl];
% 我们设置第一行为起点,最后一行还是起点,从起点出发遍历100个坐标,又回到起点,共102个坐标

sj=sj*pi/180;% 角度制转化为弧度制
d=zeros(102,102);% 初始化距离矩阵
% a向量和b向量夹角的余弦值等于 a向量点乘b向量 除以 a向量的模乘上b向量的模
% 那么a向量与b向量的夹角等于arccos(a向量点乘b向量 除以 a向量的模乘上b向量的模)
% 由于扇形弧长等于夹角乘半径
for i=1:101
    for j=i+1:102
        d(i,j)=6370*acos(cos(sj(i,1)-sj(j,1))* cos(sj(i,2))* cos(sj(j,2))+sin(sj(i,2))*sin(sj(j,2)));
    end
end
d=d+d';% 距离矩阵为对称矩阵,让其完整

path=[];% 初始化路径矩阵,这个不能用zeros去初始化
long=inf;% 长度初始化

rand('state',sum(clock));% 用年月日时分秒的和来设置随机流
% 产生较好的初始解:path数组和long
% 其判断的根据在于long尽可能接近最短巡航长度,从而在模拟退火过程中更容易找到全局最优解
for j=1:10000% 模拟1万次 
    path0=randperm(102);% 把1到102的整数随机打乱
    temp=0;
    for i=1:101
        temp=temp+d(path0(i),path0(i+1));
    end
    if temp<long% 一直更新较小的值
        path=path0;
        long=temp;
    end
end

T=1;% 初始温度
e=0.1^30;% 终止温度
L=20000;% 迭代次数
at=0.999;% 温度衰减系数

for k=1:L% 退火过程
    c=2+floor(100*rand(1,2));
    % rand生成0-1之间的随机数,乘上100并且向下取整是避免出现小数以及大于100的情况
    % 由于MATLAB下标从1开始,并且下面的路径差里面的下标还有减1,所以加2是为了避免出现小于等于0的情况
    c=sort(c);
    % 生成两个下标,让它们交换
    u=c(1);
    v=c(2);
    % 路径差
    df=d(path(u -1),path(v)) +d(path(u),path(v +1)) - d(path(u -1),path(u))-d(path(v),path(v+1));
    if df<0% 路径差小于0代表新路径长度小于原路径长度,那么接受
        path=[path(1:u -1),path(v:-1:u),path(v +1:102)];
        long =long +df;
    elseif rand<=exp(-df/T)% 如果不满足if的条件,那么执行elseif:生成的随机数小于概率
        path=[path(1:u -1),path(v:-1:u),path(v +1:102)];% 那就接受
    end
    T=T*at;% 此时更新温度(退火)
    if T<e% 温度到达终止温度,结束退火过程
        break;
    end
end

path,long % 输出路径数组和最短巡航长度
time=long/1000% 输出最短巡航时间
xx=sj(path,1);
yy=sj(path,2);
plot(xx,yy,'-*')

结果如下:

此次模拟的最短路径长度为: 4.5687e+04 km 

最短时间为:114.218 h

经纬度数据如下:

53.712115.3046
56.543221.4188
20.10515.4562
26.241818.176
28.269429.0011
8.958624.6635
8.15199.5325
31.949917.6309
43.54743.9061
23.92227.6306
51.17580.0322
10.819816.2529
1.94510.2057
44.035613.5401
32.1915.8699
16.561823.6143
22.107518.5569
0.77320.4656
53.352426.7256
51.961222.8511
46.325328.2753
22.789123.1045
26.495122.1221
28.983625.9879
36.486329.7284
10.559715.1178
0.121518.8726
47.413423.7783
30.816513.4595
12.793815.7307
30.33136.9348
10.158412.4819
31.48478.964
38.472220.1731
0.971828.1477
50.211110.2944
48.207716.8889
41.86713.5667
27.71335.0706
4.95688.3669
21.505124.0909
17.116820.0354
52.11810.4088
37.584816.8474
14.470313.6368
58.684927.1485
38.438.4648
13.79091.951
40.880114.2978
39.949429.5114
8.083127.6705
1.349616.8359
15.73219.5697
6.990923.1804
4.15913.1853
15.254827.2111
34.168822.7571
9.555911.4219
35.66199.9333
19.86615.1224
39.516816.9371
51.818123.0159
34.057423.396
58.828914.5229
47.509924.0664
9.155614.1304
49.98166.0828
11.511817.3884
38.339219.995
40.1420.303
6.2075.1442
9.44023.92
24.45096.5634
24.46543.1644
3.16164.2428
56.508913.709
8.998323.644
23.06248.4319
18.66356.7436
10.112127.2662
53.79890.2199
19.363517.6622
44.039816.2635
24.654319.6057
23.98769.403
49.24316.7044
11.581214.5677
26.721328.5667
0.77756.9576
18.524514.3598
52.521115.7957
50.115623.7816
19.98575.7902
52.842327.288
28.781227.6659
33.6490.398
36.954523.0265
39.713928.4203
36.99824.3992
41.108427.7149
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值