暑期学校数学建模培训第二次模拟:2011年国赛试题,交巡警服务平台的设置与调度,这次是针对图论模型、优化模型的练习。模拟期间也是在CSDN查找了些许资料,现将自己组的论文上传上来为开源社区做微薄贡献。
该题我们组做的相对基础了些,主要原因在于“想法很不错,但程序实现不了”,不否认lingo在求解优化问题的给力,但是它属实太慢了,当数据量一大就很难得到全局最优解。关键还是得靠matlab的现代智能/启发式算法进行求解。经过对论文结构、模型的小改动避开了第四问最优化的问题,但确实不尽人意。也是在查阅了司守奎老师lingo相关书籍找到了该题lingo源代码,思路都相同,但是我的笔记本运行不出来结果,时间太长,不过司守奎老师的lingo书籍力赞。在本文最后给出lingo源代码供各路师生、朋友学习理解。
附录
程序一:第一问求全市582个路口任意两路口的最短距离Matlab代码
%% 1.前期数据处理,产生带权邻接矩阵
clear;
clc;
Adjacency_matrix=ones(582,582); %Adjacency_matrix 全市交通路口路口邻接矩阵
Data_1=xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls','全市交通路口路口数据','A2:C583');
Data_2=xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls','全市交通路口的路线','A2:B929');
for ii=1:582
for jj=1:582
Adjcaency_matrix(ii,jj)=inf; % 邻接矩阵
end
end
for ii=1:928
jj=1;
Adjcaency_matrix(Data_2(ii,jj),Data_2(ii,jj+1))=1;
end
%Coord 坐标
for ii=1:582
for aa=1:928
if Data_2(aa,1)==Data_1(ii,1)
x=Data_1(ii,2);
y= Data_1(ii,3);
xx=Data_1(Data_2(aa,2),2);
% Data_1(aa,2) 新点的行号
yy=Data_1(Data_2(aa,2),3);
Distance(aa,1)=sqrt((xx-x)^2+(yy-y)^2)*100;
end
end
end
Data_3=zeros(928,3);
for ii=1:928
jj=1;
Data_3(ii,jj)=Data_2(ii,jj);
Data_3(ii,jj+1)=Data_2(ii,jj+1);
Data_3(ii,jj+2)=Distance(ii,1);
Adjcaency_matrix(Data_3(ii,jj),Data_3(ii,jj+1))=Data_3(ii,jj+2);
end
for ii=1:582
for jj=1:582
if ii==jj
Adjcaency_matrix(ii,jj)=0;
end
end
end
for ii=1:582
for jj=1:582
if Adjcaency_matrix(ii,jj)~=inf
Adjcaency_matrix(jj,ii)=Adjcaency_matrix(ii,jj);
end
end
end
%% floyd算法
% a——赋权邻接矩阵
% D——距离矩阵
% R——最短路径矩阵
n=size(Adjcaency_matrix,1);
D=Adjcaency_matrix;
R = zeros(n,n);
for i=1:n
for j=1:n
if D(i,j)~=inf
R(i,j)=j;
end
end
end
for k=1:n
for i=1:n
for j=1:n
if D(i,k)+D(k,j)3000
result_1(jj,4)=1; % 超时记为1,否则为0
else
result_1(jj,4)=0;
end
end
end
end
程序2:第二问求20个平台封锁13路口的警力分配Lingo代码
model:
sets:
Plat/1..20/;
Kou/1..13/:T;
Assign(Plat,Kou):dis,x,Time;
endsets
data:
v=1000;
dis=@file('C:\Users\xxx\Desktop\1.txt');
!打开平台和路口的距离矩阵20*13;路径自行添加
@text('C:\Users\xxx\Desktop\2.txt')=@writefor(Assign(i,j)|x(i,j)#GT#0:'x(',i,',',j,')=',x(i,j),';');
Enddata
!min=aver;
min=TT;
aver=@sum(Kou(j):T(j))/@size(Kou);!平均时间;
!min=aver;
TT<=8.0156; ! 非线性化转化为线性化,时间约束转化为约束条件
@for(kou(j):T(j)=@sum(Plat(i):x(i,j)*dis(i,j))/v); !到第j个路口的时间;
@for(kou(j):T(j)=@sum(Plat(i):x(i,j)*dis(i,j))/v);
@for(kou(j):TT>=T(j));
@for(Plat(i):@sum(Kou(j):x(i,j))<=1); !第i个平台最多到一个路口;
@for(Kou(j):@sum(Plat(i):x(i,j))=1); !第j个路口恰好有一个平台到达;
@for(Assign(i,j):@bin(x(i,j)));
End
程序3:第三问平台增设个数及平台任务量标准差最小Lingo代码
!平台增设
model:
sets:
Plat/1..92/:Y;
Kou/1..92/:T;
Assign(Plat,Kou):dis,x;
endsets
data:
v=1000;
dis=@ole('C:\Users\许新立\Desktop\33.xlsx','dis'); !打开92*92个路口间的距离矩阵;
@text('C:\Users\许新立\Desktop\4.txt')=@writefor(Plat(i)|Y(i)#GT#0:'Y(',i,')=',Y(i),';');
@text('C:\Users\xxx\Desktop\5.txt')=@writefor(Assign(i,j)|x(i,j)#GT#0:'x(',i,',',j,')=',x(i,j),';');
enddata
min=k;
TT<=3;
@for(kou(j):T(j)=@sum(Plat(i):x(i,j)*dis(i,j))/v);!到第j个路口的时间;
@for(kou(j):TT>=T(j));
@for(Plat(i):@for(Kou(j):x(i,j)<=Y(i))); !第i个平台最多到一个路口;
@for(Kou(j):@sum(Plat(i):x(i,j))=1); !第j个路口恰好有一个平台到达;
@for(Plat(i)|i#LE#20:Y(i)=1); !前20个路口已经为平台;
@sum(Plat(i):Y(i))=20+k;
@for(Assign(i,j):@bin(x(i,j)));
@for(Plat(i):@bin(Y(i)));
End
结果:K 4.000000
!增设平台后最长时间
model:
sets:
Plat/1..92/:Y;
Kou/1..92/:T;
Assign(Plat,Kou):dis,x;
endsets
data:
v=1000;
dis=@ole('C:\Users\许新立\Desktop\33.xlsx','dis'); !打开92*92个路口间的距离矩阵;
@text('C:\Users\许新立\Desktop\4.txt')=@writefor(Plat(i)|Y(i)#GT#0:'Y(',i,')=',Y(i),';');
@text('C:\Users\许新立\Desktop\5.txt')=@writefor(Assign(i,j)|x(i,j)#GT#0:'x(',i,',',j,')=',x(i,j),';');
k=4; !增加平台数;
enddata
min=TT ;
@for(kou(j):T(j)=@sum(Plat(i):x(i,j)*dis(i,j))/v);!到第j个路口的时间;
@for(kou(j):TT>=T(j));
@for(Plat(i):@for(Kou(j):x(i,j)<=Y(i))); !第i个平台最多到一个路口;
@for(Kou(j):@sum(Plat(i):x(i,j))=1); !第j个路口恰好有一个平台到达;
@for(Plat(i)|i#LE#20:Y(i)=1); !前20个路口已经为平台;
@sum(Plat(i):Y(i))=20+k;
@for(Assign(i,j):@bin(x(i,j)));
@for(Plat(i):@bin(Y(i)));
End
结果:
TT 2.708314
!各平台任务流量方差最小
model:
sets:
lukou/1..92/:nj,g,z;
link(lukou,lukou):d,x;
endsets
data:
nj=@ole(C:\Users\许新立\Desktop\1.xlsx,A1:CN1); !读入发案次数数据;
d=@ole(C:\Users\许新立\Desktop\2.xlsx,A1:CN92); !读入A区92个顶点之间的最短距离矩阵;
enddata
submodel obj1:
min=u;
@for(lukou(i):@sum(lukou(j):nj(j)*x(i,j))<=u);
endsubmodel
submodel obj2:
min=@sum(lukou:(g-gb*z)^2)/24;
endsubmodel
submodel constr:
@for(lukou(i):g(i)=@sum(lukou(j):nj(j)*x(i,j)));
gb=@sum(lukou:nj)/24;
@for(link(i,j):x(i,j)<=z(i));
@for(lukou(j):@sum(lukou(i):x(i,j))=1);
@for(lukou(i)|i#le#20:x(i,i)=1; z(i)=1);
@for(link(i,j):d(i,j)*x(i,j)<=3*z(i));
@sum(lukou:z)=24;
@for(link:@bin(x));
@for(lukou:@bin(z));
endsubmodel
submodel str2:
@for(lukou(i):@sum(lukou(j):nj(j)*x(i,j))
程序4:求各区增设的平台数Lingo代码
(以B区为例,其他区相类似)
model:
sets:
Plat/1..73/:Y;
Kou/1..73/:T;
Assign(Plat,Kou):dis,x;
endsets
data:
v=1000;
dis=@ole('C:\Users\xxx\Desktop\b.xlsx','A1:BU73'); !打开73*73个路口间的距离矩阵;
@text('C:\Users\xxx\Desktop\4.txt')=@writefor(Plat(i)|Y(i)#GT#0:'Y(',i,')=',Y(i),';');
@text('C:\Users\xxx\Desktop\5.txt')=@writefor(Assign(i,j)|x(i,j)#GT#0:'x(',i,',',j,')=',x(i,j),';');
!k=2; !增加平台数;
enddata
min=k;
TT<3;
@for(kou(j):T(j)=@sum(Plat(i):x(i,j)*dis(i,j))/v);!到第j个路口的时间;
@for(kou(j):TT>=T(j));
@for(Plat(i):@for(Kou(j):x(i,j)<=Y(i))); !第i个平台最多到一个路口;
@for(Kou(j):@sum(Plat(i):x(i,j))=1); !第j个路口恰好有一个平台到达;
@for(Plat(i)|i#LE#8:Y(i)=1); !前8个路口已经为平台;
@sum(Plat(i):Y(i))=8+k;
@for(Assign(i,j):@bin(x(i,j)));
@for(Plat(i):@bin(Y(i)));
End
程序结果: k=2; 增加平台数
程序5:求最快围堵劫匪警力分配Matlab代码
%求给定t时的集合At,Bt,Ct,Pt(可选平台集合)
%给定时间t时
t=9.1; %给定时间
v=1000; %罪犯速度
At=[];
DAt=[];
num1=0;
%% step1 求t分钟内形成的范围At
for i=1:582
if A(i,pos)/v1