1. 程式人生 > >2017年"華為杯"數學建模E題畫出題目中給定的路網原圖

2017年"華為杯"數學建模E題畫出題目中給定的路網原圖

2017年中"華為杯"E題中的路網圖繪製實現

  1. 賽題已知條件
    2017年"華為杯"研究生數學建模E題:多波次導彈發射中的規劃問題。賽題說明:某部參與作戰行動的車載發射裝置共有24臺,依據發射裝置的不同大致分為A、B、C三類,其中A、B、C三類發射裝置的數量分別為6臺、6臺、12臺,執行任務前平均部署在2個待機地域(D1,D2)。所屬作戰區域內有6個轉載地域(Z01~ Z06)、60個發射點位(F01~ F60),每一發射點位只能容納1臺發射裝置。各轉載地域最多容納2臺發射裝置,但不能同時作業,單臺轉載作業需時10分鐘。各轉載地域彈種類型和數量滿足需求。作戰區域道路示意圖如下圖所示。
    作戰區域道路示意圖
  2. 本文實現思路
    本博文嘗試將此圖用程式畫出來以備後續自適應的新增規劃路徑。思路:手動計算圖上62+2+60+6=130個節點的鄰接矩陣,使鄰接的兩點之間權值用距離表示,不連通的邊用inf表示。計算出來鄰接矩陣,同時又已知路網各個節點的位置座標即可實現上述路網圖的繪製。
  3. 已知的位置座標
    %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]
  4. 鄰接矩陣的計算及表示
%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');
  1. 繪製作戰區域道路示意圖
%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
  1. 效果展示
    繪製的路網資訊圖