dijkstra算法c++_Matlab 二维模拟退火算法最优路径(主程序)
這部分承接Dijkstra算法的基礎之上,先算出單源最短路徑(綠線),
之后把經過的每個虛線段分成1000份,它們的基準點分別是b1、b2等
隨機產生一系列1000的數字排列成1*6的矩陣代入模擬退火算法
利用這些坐標計算出每個線段上的分點,然后計算距離找到更短的路徑不斷迭代,最后畫出結果(藍線)
NO.1? 主程序代碼如下所示,子函數的放在另外一篇文章中
----------------------------------
%% 二維模擬退火算法尋優
clc;
clear all
tic;
%% 初始作圖
position = load('barrier.txt'); %障礙物頂點和邊界點
%描述起點和終點
S = [20,180];
T = [160,90];
scatter([S(1),T(1)],[S(2),T(2)],'filled','d','LineWidth',1.5);
set(gca,'xtick',0:20:200)? ?%橫坐標刻度
title('Dijkstra算法演示','fontsize',12)
hold on
grid on
% 圖形標注
text(S(1)+2,S(2),'S');
text(T(1)+2,T(2),'T');
%% 描繪障礙物圖形填充
fill(position(1:4,1),position(1:4,2),[1,0.87059,0.67843]);??
fill(position(5:8,1),position(5:8,2),[1,0.87059,0.67843]);
fill(position(9:12,1),position(9:12,2),[1,0.87059,0.67843]);
fill(position(13:15,1),position(13:15,2),[1,0.87059,0.67843]);
% 下載鏈路端點數據
L = load('lines.txt');? ?
%L矩陣根據position里面的端點編號來,第一行是編號1和16坐標的點相連
%% 描繪線及中點,注意plot([x1,x2],[y1,y2])
v = zeros(size(L));
for i=1:size(L,1)
? ? plot([position(L(i,1),1),position(L(i,2),1)],[position(L(i,1),2)...
? ? ? ? ,position(L(i,2),2)],'color','black','LineStyle','--');
? ? v(i,:) = (position(L(i,1),:)+position(L(i,2),:))/2;
? ? plot(v(i,1),v(i,2),'*');
? ? text(v(i,1)+2,v(i,2),strcat('v',num2str(i)));? %標記中點
end
%% 計算路徑距離(中點和起終點之間)
sign = load('matrix.txt');? %節點間是否可到達,所有中點加上起點和終點
[n,m]=size(sign);
c = zeros(size(sign));
position_all = [S;v;T];
for i = 1:n
? ? for j = 1:m
? ? ? ? if sign(i,j) == 1
? ? ? ? ? ? c(i,j) = sqrt(sum((position_all(i,:)-position_all(j,:)).^2));
? ? ? ? end
? ? end
end
c(c==0) = inf;
for i=1:n
? ? c(i,i)=0;? ? ? ? %對角線變零,其實這段不要也行,不會利用到對角線數據
end
%% 描繪可行路徑
for i=1:n
? ? for j=i:m
? ? ? ? if sign(i,j)==1
? ? ? ? ? ? plot([position_all(i,1),position_all(j,1)],[position_all(i,2),position_all(j,2)],...
? ? ? ? ? ? ? ? ? ? 'color','black','Linewidth',1,'LineStyle','-');
? ? ? ? ? ? text((position_all(i,1)+position_all(j,1))/2,(position_all(i,2)+position_all(j,2))/2,char(vpa(c(i,j),4)),...
? ? ? ? ? ? 'color','red', 'fontsize',8)? ? ? ? ?
? ? ? ? end
? ? end
end
%dijkstra算法產生初始路徑
[path,distance_ori] = Dijkstra(c,n,position_all);
%% 算法的初始設置
n = 999;? %分割線段,產生99個斷點
path_base = path(2:end-1);
z = length(path_base);
%找到分段的基準點和另外一個端點,用以劃分
position_base = position(L(path_base-1,1),:);
position_end = position(L(path_base-1,2),:);
for i=1:size(position_base,1)
? ? scatter(position_base(i,1),position_base(i,2),'filled','d');
? ? if i == 6
? ? ? ? text(position_base(i,1)+6,position_base(i,2),strcat(',b',num2str(i)),'color','b');
? ? else
? ? ? ? text(position_base(i,1)+2,position_base(i,2),strcat('b',num2str(i)),'color','b');
? ? end
end
T0 = 1000;? ? ?%初始的溫度
Tend = 1e-5;? ? ?%結束時的溫度
Loop = 200;? ? ?%內循環次數(鏈長)
q = 0.95;? ?%降溫速率
S1 = unidrnd(n,[1,z]);? ? ? %初始解的產生
temproute = zeros(Loop,z);? %用于記錄最優路線
tempdis = zeros(Loop,1);? %用于記錄距離
syms x
eqn = T0 * q^x == Tend;? ? %降溫的方程計算出迭代次數
Time = ceil(double(solve(eqn, x)));
Route_best = zeros(Time,z); %最優路線的記錄
Length_best = zeros(Time,1);? %最優路線值記錄
Length_ave = zeros(Time,1);? %此溫度下平均值情況
count = 0;? %計數的初始值
holdcount = 1;? ? ?%計次保持的次數
while T0 > Tend
? ? count = count+1;? ? %更新迭代次數
? % 某一個溫度下先循環鏈長次
? ? for k = 1:Loop? ? ?
? ? ? ? S2 = NewAnswer2(S1);? %產生新解?
? ? ? ? [S1,R] = Metropolis_version2(S1,S2,position_base,position_end,T0,n); %Metropolis算法判斷
? ? ? ? temproute(k,:) = S1;? ? ? ? %記錄下路線和距離
? ? ? ? tempdis(k,:) = R;
? ? end
? ? ?[min_length,min_index] = min(tempdis);? %記錄下這時候最短距離的值和索引
? ?%% 參照蟻群算法最優值記錄的方法(僅作參考)
%? ? ? ? Route_best(count,:) = temproute(min_index,:);
%? ? ? ? Length_best(count) = min_length;
%? ? ? ? Length_ave(count) = mean(tempdis);?
? ?%% 另外一種記錄方法
? ? ? ?if count==1 || min_length
? ? ? ? ? ?Length_best(count) = min_length;
? ? ? ? ? ?holdcount = 1;? ? %重置記錄次數
? ? ? ? ? % Route_best(count,:) = temproute(min_index,:);
? ? ? ?else?
? ? ? ? ? ?Length_best(count) = Length_best(count-1);? %如果當前溫度最優大于上一輪的,則保持
? ? ? ? ? ? holdcount = holdcount + 1;
? ? ? ? ? ? ? if holdcount == 200? ?%如果200次數據無變化則跳出循環
? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? end
? ? ? ?end
? ? ? ?Length_ave(count) = mean(tempdis);? ? ? ? ? ? %每次溫度下路線的平均值
? ? ? ?Route_best(count,:) = temproute(min_index,:);
? ? ? T0 = q * T0;? ?%降溫
end
%% 找到結果里面最優值
? ?Length_best(Length_best==0)=inf;
? ?Length_ave(Length_ave==0)=inf;?
? ?[value,min_index] = min(Length_best);? ?%找出最優值當中的最小值(因為有可能一直保持后跳出)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?%所以要找不為零的那個
? ?Length_ave_final = min(Length_ave);
? ?Route_final = Route_best(min_index,:);
?%% 作出最終結果圖以及最終結果顯示
?m=n+1;
?best_fen = zeros(z,2);
? for j = 1:z
? ? ?mm = Route_final(j)/(m-Route_final(j));? ?%計算比例和分點的坐標
? ? ?best_fen(j,1) = (position_base(j,1)+mm*position_end(j,1))/(1+mm);
? ? ?best_fen(j,2) = (position_base(j,2)+mm*position_end(j,2))/(1+mm);
? end
? SA_location = [S;best_fen;T];
?% pause(1)
? plot(SA_location(:,1),SA_location(:,2),'b--s','Linewidth',2);
%命令窗口的結果
if value < distance_ori
? ? disp(['環游城市的最短距離:' num2str(value)]);
else
? ? disp('算法尋優失敗');
end
toc
figure()
%subplot(1,2,1)
% plot(Length_best,'color','black','LineWidth',1)
% text(min_index+5,value+5,num2str(value))
% xlabel('迭代次數','FontSize',11)
% ylabel('最短距離收斂軌跡','FontSize',11)
% grid on?
% subplot(1,2,2)
plot(Length_ave,'color','black','LineWidth',1)
xlabel('迭代次數','FontSize',11)
ylabel('平均距離收斂軌跡','FontSize',11)
grid on
----------------------------------
(每次都能輸出比Dijkstra更優解,但結果還不是非常的穩定。綜合效率、結果優劣等各要素考量,需要不斷調整算法參數)
總結
以上是生活随笔為你收集整理的dijkstra算法c++_Matlab 二维模拟退火算法最优路径(主程序)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 购买电脑桌时需要注意什么购买电脑桌时需要
- 下一篇: xp/win7/win8/win10系统