2017年"華為杯"數學建模E題畫出題目中給定的路網原圖
阿新 • • 發佈:2018-11-05
2017年中"華為杯"E題中的路網圖繪製實現
- 賽題已知條件
2017年"華為杯"研究生數學建模E題:多波次導彈發射中的規劃問題。賽題說明:某部參與作戰行動的車載發射裝置共有24臺,依據發射裝置的不同大致分為A、B、C三類,其中A、B、C三類發射裝置的數量分別為6臺、6臺、12臺,執行任務前平均部署在2個待機地域(D1,D2)。所屬作戰區域內有6個轉載地域(Z01~ Z06)、60個發射點位(F01~ F60),每一發射點位只能容納1臺發射裝置。各轉載地域最多容納2臺發射裝置,但不能同時作業,單臺轉載作業需時10分鐘。各轉載地域彈種類型和數量滿足需求。作戰區域道路示意圖如下圖所示。
- 本文實現思路
本博文嘗試將此圖用程式畫出來以備後續自適應的新增規劃路徑。思路:手動計算圖上62+2+60+6=130個節點的鄰接矩陣,使鄰接的兩點之間權值用距離表示,不連通的邊用inf表示。計算出來鄰接矩陣,同時又已知路網各個節點的位置座標即可實現上述路網圖的繪製。 - 已知的位置座標
%62個道路節點座標
J=[237,137;232,127;204,119;188,100;168,94;143,74;117,67;122,48;108,38;102,23;99,3;170,145;150,133;140,120;105,108;85,92;63,73;53,57;37,41;18,37;130,135;110,139;93,138;66,132;86,122;49,123;18,108;37,91;44,74;24,75;23,57;175,132;175,115;155,105;140,105;137,87;106,94;102,72;77,79;83,65;58,47;93,45;33,29;58,24;80,30;80,13;234,118;220,110;168,83;193,78;149,68;143,55;195,60;164,50;183,50;221,54;165,40;178,33;196,39;226,43;160,18;214,23]
Z=[205,92;159,62;143,38;108,80;55,38;62,105]%6個轉載區域位置座標
D=[121,8;193,137]%2個待機區域位置座標
%60個目標發射點
F=[135,142;127,143;124,129;115,130;105,130;108,145;90,145;72,142;60,139;70,121;100,121;53,132;37,127;25,120;15,115;7,105;28,106;24,90;45,90;49,82;16,76;15,70;14,56;168,126;165,117;165,105;145,113;132,100;130,94;130,80;110,100;114,90;95,90;95,77;106,63;86,75;72,70;74,60;79,53;68,46;46,20;59,15;77,5;240,127;240,107;230,100;220,98;158,77;176,75;206,77;184,62;215,62;227,64;206,46;231,49;232,37;148,15;170,17;201,22;224,20] - 鄰接矩陣的計算及表示
%62個道路節點座標 J=[237,137;232,127;204,119;188,100;168,94;143,74;117,67;122,48;108,38;102,23;99,3;170,145;150,133;140,120;105,108;85,92;63,73;53,57;37,41;18,37;130,135;110,139;93,138;66,132;86,122;49,123;18,108;37,91;44,74;24,75;23,57;175,132;175,115;155,105;140,105;137,87;106,94;102,72;77,79;83,65;58,47;93,45;33,29;58,24;80,30;80,13;234,118;220,110;168,83;193,78;149,68;143,55;195,60;164,50;183,50;221,54;165,40;178,33;196,39;226,43;160,18;214,23] Z=[205,92;159,62;143,38;108,80;55,38;62,105]%6個轉載區域位置座標 D=[121,8;193,137]%2個待機區域位置座標 %60個目標發射點 F=[135,142;127,143;124,129;115,130;105,130;108,145;90,145;72,142;60,139;70,121;100,121;53,132;37,127;25,120;15,115;7,105;28,106;24,90;45,90;49,82;16,76;15,70;14,56;168,126;165,117;165,105;145,113;132,100;130,94;130,80;110,100;114,90;95,90;95,77;106,63;86,75;72,70;74,60;79,53;68,46;46,20;59,15;77,5;240,127;240,107;230,100;220,98;158,77;176,75;206,77;184,62;215,62;227,64;206,46;231,49;232,37;148,15;170,17;201,22;224,20] length=zeros(130); data1=[D;Z;J;F]; save('data1.mat','data1'); %計算座標點之間的距離矩陣 for i=1:130 for j=1:130 length(i,j)=sqrt((data1(i,1)-data1(j,1))^2+(data1(i,2)-data1(j,2))^2); end end % 將存在的道路賦值到最後的賦權圖路徑矩陣彙總 length_last=zeros(130)+inf; %初始化 %-------------D1,D2的可行路線---------------------------- %% 鄰接矩陣:行標i<列表j.只管比當前點行標大的列標的連通性即可. % D1,D2,Z1,Z2,Z3,……,Z6,J1,J2,……,J70,F71,F72,F130. % 與D1聯通的是Z03,3+2=5;J09,9+8=17. %% length是距離矩陣,length(1,[5,17,18,19])選擇與D1聯通的點(即行標是1, %% 只管列標大於1的列且有聯通的列號來作為索引選擇距離矩陣中的元素) %% 建議寫下面的這個length_last距離矩陣,邊寫索引(1,[5,17,18,19]), %% 邊擦出原圖上的i代表的那個點 length_last(1,[5,17,18,19])=length(1,[5,17,18,19]); length_last(2,[10,11,20,40])=length(2,[10,11,20,40]); %----------------z1-z6的可行路線------------------------------ length_last(3,[12,56,58])=length(3,[12,56,58]); length_last(4,[59,60,62])=length(4,[59,60,62]); length_last(5,[1,17,60,65,69])=length(5,[1,17,60,65,69]); length_last(6,[15,45,46])=length(6,[15,45,46]); length_last(7,[49,52])=length(7,[49,52]); length_last(8,[24,33,34,36])=length(8,[24,33,34,36]); %---------------J1-J60的可行路線-------------------------------- length_last(9,10)=length(9,10); length_last(10,[2,9,11,55])=length(10,[2,9,11,55]); length_last(11,[2,10,12,40,41,56])=length(11,[2,10,12,40,41,56]); length_last(12,[11,13,41,58,3])=length(12,[11,13,41,58,3]); length_last(13,[12,14,42,57])=length(13,[12,14,42,57]); length_last(14,[13,15,44,59])=length(14,[13,15,44,59]); length_last(15,[14,16,6,60])=length(15,[14,16,6,60]); length_last(16,[15,17,50,60])=length(16,[15,17,50,60]); length_last(17,[16,18,53,1,5])=length(17,[16,18,53,1,5]); length_last(18,[17,19,53])=length(18,[17,19,53]); length_last(19,[18,1,54])=length(19,[18,1,54]); length_last(20,[21,40,2])=length(20,[21,40,2]); length_last(21,[20,22,40,29])=length(21,[20,22,40,29]); length_last(22,[21,23,29,43])=length(22,[21,23,29,43]); length_last(23,[22,24,33,45])=length(23,[22,24,33,45]); length_last(24,[23,25,8,47])=length(24,[23,25,8,47]); length_last(25,[24,26])=length(25,[24,26]); length_last(26,[25,27,37,49])=length(26,[25,27,37,49]); length_last(27,[26,28,39,51])=length(27,[26,28,39,51]); length_last(28,[27,39])=length(28,[27,39]); length_last(29,[21,30,71,72,73])=length(29,[21,30,71,72,73]); length_last(30,[29,31,74,75,76])=length(30,[29,31,74,75,76]); length_last(31,[30,32,77])=length(31,[30,32,77]); length_last(32,[31,33,34,78,79])=length(32,[31,33,34,78,79]); length_last(33,[32,31,23,8,80,81])=length(33,[32,31,23,8,80,81]); length_last(34,[8,32,35,82,83])=length(34,[8,32,35,82,83]); length_last(35,[34,36,84,85,86,87])=length(35,[34,36,84,85,86,87]); length_last(36,[88,89,37,38,8,33])=length(36,[88,89,37,38,8,33]); length_last(37,[36,38,26,39,90])=length(37,[36,38,26,39,90]); length_last(38,[36,37,39,91,92])=length(38,[36,37,39,91,92]); length_last(39,[37,38,27,28,93])=length(39,[37,38,27,28,93]); length_last(40,[20,4,40,41,11,94])=length(40,[20,4,40,41,11,94]); length_last(41,[11,12,40,42,95])=length(41,[11,12,40,42,95]); length_last(42,[41,43,13,44,96])=length(42,[41,13,43,44,96]); length_last(43,[22,42,97,98])=length(43,[22,42,97,98]); length_last(44,[14,42,99,100])=length(44,[14,42,99,100]); length_last(45,[23,6,101,102,103])=length(45,[23,6,101,102,103]); length_last(46,[6,50,104,105])=length(46,[6,50,104,105]); length_last(47,[24,48,106])=length(47,[24,48,106]); length_last(48,[47,50,107,108,109])=length(48,[47,50,107,108,109]); length_last(49,[7,26,110])=length(49,[7,26,110]); length_last(50,[46,48,16,45])=length(50,[46,48,16,45]); length_last(51,[27,52])=length(51,[27,52]); length_last(52,[7,53,51,111,112])=length(52,[7,53,51,111,112]); length_last(53,[17,18,50,52,54])=length(53,[17,18,50,52,54]); length_last(54,[19,52,53,113])=length(54,[19,52,53,113]); length_last(55,[10,56,114,115])=length(55,[10,56,114,115]); length_last(56,[3,55,11,117,116])=length(56,[3,55,11,117,116]); length_last(57,[13,58,118,119])=length(57,[13,58,118,119]); length_last(58,[3,12,57,61,120])=length(58,[3,12,57,61,120]); length_last(59,[4,14])=length(59,[4,14]); length_last(60,[4,15,16,5])=length(60,[4,15,16,5]); length_last(61,[58,63,67,54,121])=length(61,[58,63,67,54,121]); length_last(62,[4,63,65])=length(62,[4,63,65]); length_last(63,[61,67,66,62])=length(63,[61,67,66,62]); length_last(64,[68,122,123])=length(64,[68,122,123]); length_last(65,[62,66,5])=length(65,[62,66,5]); length_last(66,[67,63,65,69])=length(66,[67,63,65,69]); length_last(67,[61,63,66,70,124])=length(67,[61,63,66,70,124]); length_last(68,[70,64,125,126])=length(68,[70,64,125,126]); length_last(69,[5,66,127,128])=length(69,[5,66,127,128]); length_last(70,[67,68,129,130])=length(70,[67,68,129,130]); for i=1:130 length_last(i,i)=0; end save('length_last.mat','length_last');
- 繪製作戰區域道路示意圖
%62個道路節點座標
J=[237,137;232,127;204,119;188,100;168,94;143,74;117,67;122,48;108,38;102,23;99,3;170,145;150,133;140,120;105,108;85,92;63,73;53,57;37,41;18,37;130,135;110,139;93,138;66,132;86,122;49,123;18,108;37,91;44,74;24,75;23,57;175,132;175,115;155,105;140,105;137,87;106,94;102,72;77,79;83,65;58,47;93,45;33,29;58,24;80,30;80,13;234,118;220,110;168,83;193,78;149,68;143,55;195,60;164,50;183,50;221,54;165,40;178,33;196,39;226,43;160,18;214,23]
Z=[205,92;159,62;143,38;108,80;55,38;62,105]%6個轉載區域位置座標
D=[121,8;193,137]%2個待機區域位置座標
%60個目標發射點
F=[135,142;127,143;124,129;115,130;105,130;108,145;90,145;72,142;60,139;70,121;100,121;53,132;37,127;25,120;15,115;7,105;28,106;24,90;45,90;49,82;16,76;15,70;14,56;168,126;165,117;165,105;145,113;132,100;130,94;130,80;110,100;114,90;95,90;95,77;106,63;86,75;72,70;74,60;79,53;68,46;46,20;59,15;77,5;240,127;240,107;230,100;220,98;158,77;176,75;206,77;184,62;215,62;227,64;206,46;231,49;232,37;148,15;170,17;201,22;224,20]
%整個路網圖的鄰接矩陣
load length_last.mat
xd=D(:,1);yd=D(:,2);xj=J(:,1);yj=J(:,2);
xz=Z(:,1);yz=Z(:,2);xf=F(:,1);yf=F(:,2);
%======================用不同的符號標出各個不同的點=========================
%--------------------------待機區域D----------------------------------------
plot(xd,yd,'rp','linewidth',2,'MarkerSize',16, 'MarkerFaceColor','r');
for i=1:2
str3='D'; str4=num2str(i);
dot=[str3,str4];
text(xd(i)+2,yd(i)+2,dot);
end
legend('待機地域','道路節點','轉載地域','目標發射點','location','northwest');
hold on
%-----------------------------道路節點J------------------------------------
plot(xj,yj,'bo');
for i=1:62
str3='J'; str4=num2str(i);
dot=[str3,str4];
text(xj(i)+2,yj(i)+2,dot);
end
hold on
plot(xz,yz,'go','markersize',7, 'MarkerEdgeColor','g', 'MarkerFaceColor','g')
%------------------------轉載地域---------------------------------------
for i=1:6
str3='Z'; str4=num2str(i);
dot=[str3,str4];
text(xz(i)+2,yz(i)+2,dot);
end
hold on
plot(xf,yf,'ks')
%---------------------目標發射點------------------------------------
for i=1:60
str3='F'; str4=num2str(i);
dot=[str3,str4];
text(xf(i)+2,yf(i)+2,dot);
end
hold on
legend('待機地域','道路節點','轉載地域','目標發射點','location','northwest');
axis([0,250,0,150])
%==========================================================================
length_p=triu(length_last); % 取上三角矩陣矩陣
%非零和非inf的連點鍵直達的權重:find返回的是座標
[x,y]=find(length_p~=inf&length_p~=0); %得到所有可行路徑的序號
%拼接橫縱座標為171x2的矩陣
liebiao=[x,y]; %將需要放進一個列表中去
%% 注意位置座標的分段
%1-2為D,3-8為Z,9-70共62個為J,71-130共60個為F。
liebiaoj=liebiao(find(liebiao(:,2)>=9&liebiao(:,2)<=70),:); %提取出J所對應的列表
%% 矩陣的行列的順序重排
liebiaoj(:,[2,1])=liebiaoj(:,[1,2]);
liebiaoj(:,1)=liebiaoj(:,1)-8; %得到J的標號
%------------處理J和Z之間的可連線的座標------------------------------------
for i=1:length(liebiaoj)
if liebiaoj(i,2)>=3&&liebiaoj(i,2)<=8
liebiaoj(i,2)=liebiaoj(i,2)-2; %liebiaoj(i,2)放的是列號,是的列號下標從1開始
liebiaojz(i,:)=liebiaoj(i,:);
elseif liebiaoj(i,2)<=2
liebiaojd(i,:)=liebiaoj(i,:); %列號小於2說明是D的列號
elseif liebiaoj(i,2)>=9&&liebiaoj(i,2)<=70
liebiaoj(i,2)=liebiaoj(i,2)-8; %使J的列下標從1開始
liebiaojj(i,:)=liebiaoj(i,:)
end
end
liebiaojz(all(liebiaojz == 0, 2),:)=[];
Xjz=xj(liebiaojz(:,1),:);
Yjz=yj(liebiaojz(:,1),:);
Xz=xz(liebiaojz(:,2),:);
Yz=yz(liebiaojz(:,2),:);
for i=1:length(Xjz)
plot([ Xjz(i),Xz(i)],[Yjz(i),Yz(i)],'k-');
hold on
end
%-----------------處理J和d之間的可連線座標----------------------------------
liebiaojd(all(liebiaojd== 0, 2),:)=[];
Xjd=xj(liebiaojd(:,1),:);
Yjd=yj(liebiaojd(:,1),:);
Xd=xd(liebiaojd(:,2),:);
Yd=yd(liebiaojd(:,2),:);
for i=1:length(Xjd)
plot([ Xjd(i),Xd(i)],[Yjd(i),Yd(i)],'k-');
hold on
end
%----------------處理J和J之間的連線座標-----------------------------------
liebiaojj(all(liebiaojj == 0, 2),:)=[];
for i=1:length(liebiaojj)
a=liebiaojj(i,1)
b=liebiaojj(i,2) %列表jj中,第一列為J排序的座標,第二列為非排序的
if a>=1&&a<=11 %主幹道1資料處理
xzj(i)=xj(a);
yzj(i)=yj(a);
Xzj(i)=xj(b);
Yzj(i)=yj(b);
elseif a>=13&&a<=20 %主幹道2資料處理
xzj(i)=xj(a);
yzj(i)=yj(a);
Xzj(i)=xj(b);
Yzj(i)=yj(b)
else %非主幹道資料處理
Xjj(i)=xj(a);
Yjj(i)=yj(a);
xjjj(i)=xj(b);
yjjj(i)=yj(b);
end
end
for i=1:length(Xjj) %畫出非主幹道
plot([ Xjj(i),xjjj(i)],[Yjj(i),yjjj(i)],'k-');
hold on
end
for i=1:length(xzj) %主幹道處理
plot([xzj(i), Xzj(i)],[yzj(i),Yzj(i)],'b-','linewidth',2);
hold on
end
%------------處理J和f之間的可連線座標---------------------------------------
liebiaof=liebiao(find(liebiao(:,2)>=71),:); %找到列大於71的行對應的座標
liebiaof(:,1)=liebiaof(:,1)-8;
for i=1:length(liebiaof)
if liebiaof(i,2)>=71
liebiaof(i,2)=liebiaof(i,2)-70;
liebiaofj(i,:)=liebiaof(i,:);
end
end
Xfj=xf(liebiaofj(:,2),:);
Yfj=yf(liebiaofj(:,2),:);
Xj=xj(liebiaofj(:,1),:);
Yj=yj(liebiaofj(:,1),:);
for i=1:length(Xfj)
plot([ Xfj(i),Xj(i)],[Yfj(i),Yj(i)],'k-');
hold on
end
- 效果展示