模擬退火演算法例項分析--Matlab演算法
模擬退火演算法(例項分析)–Matlab演算法
此篇文章為我一學長(Hong Yilin)所作,我又進行了一些加工,在此只為學習使用。
此篇為模擬退火演算法的例項分析,模擬退火演算法的理論講解見上一篇。
題目:我方有一個基地,經度和緯度為(70,40)。假設我方飛機的速度為 1000 公里/小時。
我方派一架飛機從基地出發,偵察完敵方所有目標,再返回原來的基地。在敵方每一目標點的偵察時間不計,
求該架飛機所花費的時間(假設我方飛機巡航時間可以充分長)。
敵方經度緯度如下:
[html] view plain copy print?- 表1 敵方100城市經緯度
- 經度 緯度 經度 緯度 經度 緯度 經度 緯度
- 53.7121 15.3046 51.1758 0.0322 46.3253 28.2753 30.3313 6.9348
- 56.5432 21.4188 10.8198 16.2529 22.7891 23.1045 10.1584 12.4819
- 20.1050 15.4562 1.9451 0.2057 26.4951 22.1221 31.4847 8.9640
- 26.2418 18.1760 44.0356 13.5401 28.9836 25.9879 38.4722 20.1731
- 28.2694 29.0011 32.1910 5.8699 36.4863 29.7284 0.9718 28.1477
- 8.9586 24.6635 16.5618 23.6143 10.5597 15.1178 50.2111 10.2944
- 8.1519 9.5325 22.1075 18.5569 0.1215 18.8726 48.2077 16.8889
- 31.9499 17.6309 0.7732 0.4656 47.4134 23.7783 41.8671 3.5667
- 43.5474 3.9061 53.3524 26.7256 30.8165 13.4595 27.7133 5.0706
- 23.9222 7.6306 51.9612 22.8511 12.7938 15.7307 4.9568 8.3669
- 21.5051 24.0909 15.2548 27.2111 6.2070 5.1442 49.2430 16.7044
- 17.1168 20.0354 34.1688 22.7571 9.4402 3.9200 11.5812 14.5677
- 52.1181 0.4088 9.5559 11.4219 24.4509 6.5634 26.7213 28.5667
- 37.5848 16.8474 35.6619 9.9333 24.4654 3.1644 0.7775 6.9576
- 14.4703 13.6368 19.8660 15.1224 3.1616 4.2428 18.5245 14.3598
- 58.6849 27.1485 39.5168 16.9371 56.5089 13.7090 52.5211 15.7957
- 38.4300 8.4648 51.8181 23.0159 8.9983 23.6440 50.1156 23.7816
- 13.7909 1.9510 34.0574 23.3960 23.0624 8.4319 19.9857 5.7902
- 40.8801 14.2978 58.8289 14.5229 18.6635 6.7436 52.8423 27.2880
- 39.9494 29.5114 47.5099 24.0664 10.1121 27.2662 28.7812 27.6659
- 8.0831 27.6705 9.1556 14.1304 53.7989 0.2199 33.6490 0.3980
- 1.3496 16.8359 49.9816 6.0828 19.3635 17.6622 36.9545 23.0265
- 15.7320 19.5697 11.5118 17.3884 44.0398 16.2635 39.7139 28.4203
- 6.9909 23.1804 38.3392 19.9950 24.6543 19.6057 36.9980 24.3992
- 4.1591 3.1853 40.1400 20.3030 23.9876 9.4030 41.1084 27.7149
表1 敵方100城市經緯度
經度 緯度 經度 緯度 經度 緯度 經度 緯度
53.7121 15.3046 51.1758 0.0322 46.3253 28.2753 30.3313 6.9348
56.5432 21.4188 10.8198 16.2529 22.7891 23.1045 10.1584 12.4819
20.1050 15.4562 1.9451 0.2057 26.4951 22.1221 31.4847 8.9640
26.2418 18.1760 44.0356 13.5401 28.9836 25.9879 38.4722 20.1731
28.2694 29.0011 32.1910 5.8699 36.4863 29.7284 0.9718 28.1477
8.9586 24.6635 16.5618 23.6143 10.5597 15.1178 50.2111 10.2944
8.1519 9.5325 22.1075 18.5569 0.1215 18.8726 48.2077 16.8889
31.9499 17.6309 0.7732 0.4656 47.4134 23.7783 41.8671 3.5667
43.5474 3.9061 53.3524 26.7256 30.8165 13.4595 27.7133 5.0706
23.9222 7.6306 51.9612 22.8511 12.7938 15.7307 4.9568 8.3669
21.5051 24.0909 15.2548 27.2111 6.2070 5.1442 49.2430 16.7044
17.1168 20.0354 34.1688 22.7571 9.4402 3.9200 11.5812 14.5677
52.1181 0.4088 9.5559 11.4219 24.4509 6.5634 26.7213 28.5667
37.5848 16.8474 35.6619 9.9333 24.4654 3.1644 0.7775 6.9576
14.4703 13.6368 19.8660 15.1224 3.1616 4.2428 18.5245 14.3598
58.6849 27.1485 39.5168 16.9371 56.5089 13.7090 52.5211 15.7957
38.4300 8.4648 51.8181 23.0159 8.9983 23.6440 50.1156 23.7816
13.7909 1.9510 34.0574 23.3960 23.0624 8.4319 19.9857 5.7902
40.8801 14.2978 58.8289 14.5229 18.6635 6.7436 52.8423 27.2880
39.9494 29.5114 47.5099 24.0664 10.1121 27.2662 28.7812 27.6659
8.0831 27.6705 9.1556 14.1304 53.7989 0.2199 33.6490 0.3980
1.3496 16.8359 49.9816 6.0828 19.3635 17.6622 36.9545 23.0265
15.7320 19.5697 11.5118 17.3884 44.0398 16.2635 39.7139 28.4203
6.9909 23.1804 38.3392 19.9950 24.6543 19.6057 36.9980 24.3992
4.1591 3.1853 40.1400 20.3030 23.9876 9.4030 41.1084 27.7149
分析:
1.實際距離的求解:
設A, B兩點的地理座標分別為(x1,y1), (x2,y2),過 A, B兩點的大圓的劣弧長即為兩點的實際距離。
以地心為座標原點o,以赤道平面為XOY平面,以0度經線圈所在的平面為XOZ平面建立三維直角座標系。
地球半徑為R=6370km。則 A, B兩點的直角座標分別為:
A( R*cos(x1)*cos(y1), R*sin(x1)*cos(y1), R*sin(y1) ) B( R*cos(x2)*cos(y2), R*sin(x2)*cos(y2), R*sin(y2) )
A、B兩點實際距離:
d=Rarccos[ cos(x1-x2)*cos(y1)*cos(y2) + sin(y1)*sin(y2) ]。
建立矩陣D,將所有點之間的距離存放進去。
問題轉化為從(70,40)出發,走遍所有點,並返回出發點。
2.關於Monte Carlo方法
本文中使用Monte Carlo方法先得到一個較小的sum,和一組S0。
3.演算法原理:
設S={s1,s2,…,sn}為所有可能的狀態所構成的集合, f:S—R為非負代價函式,
即優化問題抽象如下:尋找s*∈S,使得f(s*)=min f(si) 任意si∈S
具體步驟:
(1)給定一較高初始溫度T,隨機產生初始狀態S
(2)按一定方式,對當前狀態作隨機擾動,產生一個新的狀態S’
S’=S+sign(η).δ (其中δ為給定的步長, η為[-1,1]的隨機數 )
計算Δ=f(S’)-f(S)
(3)若Δ<0,則令S=S’,轉第(5)步
(4)若Δ≤0,則以概率exp(-Δ/T)接受S’,即S=S’
具體操作:產生一個在[0,1]上服從均勻分佈的隨機數x,若x<exp(-Δ/T),則S=S;否則S保持不變
(5)按一定方式降溫,使T≤Ti, 如: =αTi,習慣上取α∈(0.8,0.9999)
(6)檢查退火是否結束
是——轉向第(7)步
否——轉向第(2)步
(7)以當前Si作為最優解輸出
注:1、結束標誌:溫度是否小於某一閥值(迴圈次數)f的值變化是否明顯
2、初始溫度的高低:下降是否充分慢對結果有影響
4.演算法詳述:
首先給定一個初始溫度TO 和該優化問題的一個初始解 x(0),並由 x(0)生成下一個解 x’∈ N(x(0)),是否接受x’作為一個新解x(1)依賴於下面概率:
換句話說,如果生成的解 的函式值比前一個解的函式值更小,則接受x(1)=x ‘作為一個新解。否則以概率作為一個新解。
以此類推,在溫度T_i下,經過很多次的轉移之後,降低溫度T_i,得到T(i+1)<T(i)。在T(i+1)下重複上述過程。因此整個優化過程就是不斷尋找新解和緩慢降溫的交替過程。最終的解是對該問題尋優的結果。
在得到初始解之後,可以用2變換法,即交換兩個點之間的路線。設定T0為1,以0.001為降溫幅度,選擇終止溫度為e=10-30。執行程式碼,得到可行解,時間為43小時左右
演算法:
[plain] view plain copy print?- function Simulated_AnneALIng()
- %演算法:模擬退火演算法(Simulated AnneALIng)
- %敵方經度緯度資料見 sj.txt
- %% 清空
- clc,clear;
- %% 座標轉換,計算距離
- load sj.txt %載入敵方100個目標的資料,資料按照表格中的位置儲存在純文字檔案 sj.txt 中
- x=sj(:,1:2:8) ; x=x(:);%將4列變成1列
- y=sj(:,2:2:8) ; y=y(:);
- sj=[x y];
- d1=[70,40] ; sj=[d1;sj;d1] ;
- sj1=sj;
- sj=sj*pi/180;
- n=length(sj);
- d=zeros(n); %距離矩陣 d
- for i=1:n-1 %座標轉換為距離
- for j=i+1:n
- temp=cos(sj(i,1)-sj(j,1))*cos(sj(i,2))*cos(sj(j,2))+sin(sj(i,2))*sin(sj(j,2));
- d(i,j)=6370*acos(temp);
- end
- end
- d=d+d’ ; S0=[] ; Sum=inf;
- %% 設定初始解(MonteCarlo法)
- for j=1:1000
- S=[1,1+randperm(n-2),n]; temp=0; %用randperm函式隨機打亂2到(n-2)之間的數
- for i=1:n-1
- temp=temp+d(S(i),S(i+1));
- end
- if temp<Sum
- S0=S; Sum=temp;
- end
- end
- e=0.1^30; L=20000; at=0.999; T=1;%引數設定
- %% 退火過程
- for k=1:L %產生新解
- %隨機找兩個點來交換路線
- c=2+floor((n-2)*rand(1,2)); c=sort(c);
- c1=c(1);c2=c(2);
- df=d(S0(c1-1),S0(c2))+d(S0(c1),S0(c2+1))-d(S0(c1-1),S0(c1))-d(S0(c2),S0(c2+1));%計算代價函式值
- %接受準則
- if df<0 %路徑更短,接受新解
- S0=[S0(1:c1-1),S0(c2:-1:c1),S0(c2+1:n)];
- Sum=Sum+df ; T=T*at;%接受並降溫
- elseif exp(-df/T)>rand(1) %路徑沒變短,以一定概率接受新解
- S0=[S0(1:c1-1),S0(c2:-1:c1),S0(c2+1:n)];
- Sum=Sum+df ; T=T*at;
- end
- if T<e
- break;
- end
- end
- disp([‘最短巡航路徑長度:’,num2str(Sum),’km’]);
- disp([‘最短巡航路徑時耗:’,num2str(Sum/1000),’h’]);
- %% 畫圖
- hold on
- plot(sj1(1:101,1), sj1(1:101,2), ‘ko’);
- for i=1:101
- temp=[‘ ’,int2str(i)];
- text(sj1(i,1), sj1(i,2),temp);
- end
- for i=1:101
- plot(sj1(S0(i:i+1),1)’, sj1(S0(i:i+1),2)’,’k-‘);
- end
- title([‘近似路徑如下,巡航路徑長度:’,num2str(Sum),’km,’,’時耗:’,num2str(Sum/1000),’h’]);
- hold off
function Simulated_AnneALIng()
%演算法:模擬退火演算法(Simulated AnneALIng)
%敵方經度緯度資料見 sj.txt
%% 清空
clc,clear;
%% 座標轉換,計算距離
load sj.txt %載入敵方100個目標的資料,資料按照表格中的位置儲存在純文字檔案 sj.txt 中
x=sj(:,1:2:8) ; x=x(:);%將4列變成1列
y=sj(:,2:2:8) ; y=y(:);
sj=[x y];
d1=[70,40] ; sj=[d1;sj;d1] ;
sj1=sj;
sj=sj*pi/180;
n=length(sj);
d=zeros(n); %距離矩陣 d
for i=1:n-1 %座標轉換為距離
for j=i+1:n
temp=cos(sj(i,1)-sj(j,1))*cos(sj(i,2))*cos(sj(j,2))+sin(sj(i,2))*sin(sj(j,2));
d(i,j)=6370*acos(temp);
end
end
d=d+d' ; S0=[] ; Sum=inf;
%% 設定初始解(MonteCarlo法)
for j=1:1000
S=[1,1+randperm(n-2),n]; temp=0; %用randperm函式隨機打亂2到(n-2)之間的數
for i=1:n-1
temp=temp+d(S(i),S(i+1));
end
if temp<Sum
S0=S; Sum=temp;
end
end
e=0.1^30; L=20000; at=0.999; T=1;%引數設定
%% 退火過程
for k=1:L %產生新解
%隨機找兩個點來交換路線
c=2+floor((n-2)*rand(1,2)); c=sort(c);
c1=c(1);c2=c(2);
df=d(S0(c1-1),S0(c2))+d(S0(c1),S0(c2+1))-d(S0(c1-1),S0(c1))-d(S0(c2),S0(c2+1));%計算代價函式值
%接受準則
if df<0 %路徑更短,接受新解
S0=[S0(1:c1-1),S0(c2:-1:c1),S0(c2+1:n)];
Sum=Sum+df ; T=T*at;%接受並降溫
elseif exp(-df/T)>rand(1) %路徑沒變短,以一定概率接受新解
S0=[S0(1:c1-1),S0(c2:-1:c1),S0(c2+1:n)];
Sum=Sum+df ; T=T*at;
end
if T<e
break;
end
end
disp(['最短巡航路徑長度:',num2str(Sum),'km']);
disp(['最短巡航路徑時耗:',num2str(Sum/1000),'h']);
%% 畫圖
hold on
plot(sj1(1:101,1), sj1(1:101,2), 'ko');
for i=1:101
temp=[' ',int2str(i)];
text(sj1(i,1), sj1(i,2),temp);
end
for i=1:101
plot(sj1(S0(i:i+1),1)', sj1(S0(i:i+1),2)','k-');
end
title(['近似路徑如下,巡航路徑長度:',num2str(Sum),'km,','時耗:',num2str(Sum/1000),'h']);
hold off