提纲
- 1.前言
- 2.模型和代码
1.前言
由于课程作业需要,作为小白一枚的我只能学习一些求解(非)线性规划的软件,包括Lingo、Matlab。其中,Lingo编程较为简单,可以快速入门。Matlab也不是很难,但自己去查阅网上纷繁复杂的资源颇为费时,所以将自己这几天摸索的结果记录下来。希望可以帮助一些有缘人。本篇主要介绍Lingo怎么写模型,以2011年高教社杯全国大学生数学建模竞赛B题—交警服务平台的设置与调度提供的数据为例进行建模与分析。
**数据介绍:**该数据集给出了某个城市A城区的交通路口以及交巡警平台信息,包括路口位置、路线的起点和终点路口节点、路口节点的发案率(每个路口平均每天的发生报警案件数量)、交巡警平台所在路口节点以及出入各个区的路口节点。该城区有92个路口节点(记为1-92),20个交巡警路口平台(记为1-20)。
2.模型和代码
2.1 假设、符号
此例子涉及的假设有:
- 交巡警警车在市区道路的行驶速度恒为60km/h(虽然现实并非如此);
- 在报警事件发生时,交巡警应尽量在3分钟之内到达。
表1 符号定义表
符号 | 含义 |
---|---|
m | 交巡警服务平台个数,例子中m= 20 |
n | 交通路口节点个数,例子中n= 92 |
v | 交巡警警车在市区道路的行驶速度,v=60 km/h |
c n j cn_j cnj | 第j个节点事件发生率(每个路口平均每天的发生报警案件数量) |
x i j x_{ij} xij | 第i个平台是否管辖第j个节点,0-1变量 |
w i j w_{ij} wij | 最短距离是否小于最长响应时间对应的距离,例子中为3km |
注:已经使用python的networkx包all_pairs_dijkstra_path_length函数计算交巡警服务平台到各个路口节点的最短距离(此函数背后的算法是Dijkstra算法)。由于篇幅限制,此处不予以展示。
2.2 模型
模型原则:尽量满足3分钟到达报警现场,对于一些特殊节点(所有平台都无法做到3分钟到达,也就是所有平台到该节点的最短距离都大于3km),安排离它们最近的服务平台管辖,以便尽快响应报警事件。
表2 特殊路口节点管辖安排
交通路口节点标号 | 归属的服务平台标号 | 最近距离(km) |
---|---|---|
28 | 15 | 4.75 |
29 | 15 | 5.70 |
38 | 16 | 3.41 |
39 | 2 | 3.68 |
61 | 7 | 4.19 |
92 | 20 | 3.60 |
接下来,我们以最大工作量与最小工作量之差最小化为目标建立数学模型,具体模型如下:
m
i
n
z
=
m
a
x
(
q
i
)
−
m
i
n
(
q
i
)
(
1
)
min z=max(q_i)-min(q_i)\ \ (1)
minz=max(qi)−min(qi) (1)
s
.
t
.
q
i
=
∑
j
=
1
n
x
i
j
c
n
j
,
i
∈
I
1
(
2
)
s.t. q_i=\sum_{j=1}^{n}{x_{ij}cn_j},\ i\in\ I_1\ (2)
s.t.qi=∑j=1nxijcnj, i∈ I1 (2)
x
15
,
28
=
x
15
,
29
=
x
16
,
38
=
x
2
,
39
=
x
7
,
61
=
x
20
,
92
=
1
(
3
)
x_{15,28}=x_{15,29}=x_{16,38}=x_{2,39}=x_{7,61}=x_{20,92}=1\ (3)
x15,28=x15,29=x16,38=x2,39=x7,61=x20,92=1 (3)
∑
i
=
1
m
x
i
j
=
1
,
j
∈
J
1
(
4
)
\sum_{i=1}^{m}{x_{ij}}=1,\ j\in\ J_1\ (4)
∑i=1mxij=1, j∈ J1 (4)
∑
i
=
1
m
w
i
j
x
i
j
=
1
,
j
∉
(
28
,
29
,
38
,
39
,
61
,
92
)
(
5
)
\sum_{i=1}^{m}{w_{ij}x_{ij}}=1,\ j\notin\ {(28,29,38,39,61,92)}\ (5)
∑i=1mwijxij=1, j∈/ (28,29,38,39,61,92) (5)
x
i
j
=
0
或
1
,
i
∈
I
1
,
j
∈
J
1
(
6
)
x_{ij}=0或1,\ i\in\ I_1,j\in\ J_1\ (6)
xij=0或1, i∈ I1,j∈ J1 (6)
I
1
=
1
,
2
,
.
.
.
,
20
(
7
)
I_1={1,2,...,20}\ (7)
I1=1,2,...,20 (7)
J
1
=
1
,
2
,
.
.
.
,
92
(
8
)
J_1={1,2,...,92}\ (8)
J1=1,2,...,92 (8)
约束(2)计算i平台的工作量,式子(3)记录特殊节点的分配结果,式子(4)保证每个路口j都有其管辖的平台,式子(5)保证非特殊交通路口节点能被其管辖平台3分钟到达,式子(6)说明 x i j x_{ij} xij为0-1变量。
2.3 代码
- Lingo注释:!开头而且;结尾
- 代码主要分为三部分:
- 变量,以sets:开头,endsets结尾
- 数据,以data:开始,enddata结尾
- 读取外部数据,使用excel选中需要选取的数据,在excel中点击公式-自定义名称(如下面的crimerate和 w i j w_{ij} wij)
- 目标函数和约束
- 主要涉及@sum,@for,也就是加总、循环,以式子(2)为例
- 加总:@sum(node_j(j):x(i,j)cn(j))
- 循环:式子(2)其实是i个式子,给出q的i个值,因此需要for循环,语法具体为
@for (station_i(i):
q(i)=@sum(node_j(j):x(i,j)*cn(j))
)
进一步地,去掉一部分下标(加入 i ≠ 28 a n d i ≠ 29 i\neq28 and i\neq29 i=28andi=29):
@for (station_i(i)|i#ne#28 #and# i#ne#29:
q(i)=@sum(node_j(j):x(i,j)*cn(j))
)
model:
title based on work rate;
sets:
station_i /1..20/ :q; !建立1行20列的数组,变量有工作量,命名为q;
node_j /1..92/: cn; !建立1行92列的数组,变量有案发率,命名为cn;
ij(station_i,node_j):x,w; !建立20行92列矩阵,使用前两个组合即可,变量有x,w;
endsets
data:
cr=@ole('C:\Users\xxx\Desktop\crimedata.xls','crimerate'); !各个路口案发率数据;
w=@ole('C:\Users\xxx\Desktop\distance.xls','wij'); !各个路口案发率数据;
enddata
min=(@max(station_i(i):q(i))-@min(station_i(i):q(i)));
@for (station_i(i):q(i)=@sum(node_j(j):x(i,j)*cr(j)));
x(15,28)=1;
x(15,29)=1;
x(16,38)=1;
x(2,39)=1;
x(7,61)=1;
x(20,92)=1;
!特殊点分配;
@for(node_j(j)|j #ne#28 #and# j#ne#29 #and# j#ne#38 #and# j#ne#39 #and# j#ne#61 #and# j#ne#92:@sum(station_i(i):x(i,j))=1); !保证每个路口都被一个服务站管理;
@for(node_j(j)|j #ne#28 #and# j#ne#29 #and# j#ne#38 #and# j#ne#39 #and# j#ne#61 #and# j#ne#92:@sum(station_i(i):w(i,j)*x(i,j))=1); !保证未分配路口到平台的距离小于3km;
@for(ij:@bin(x));!0-1变量;
end
提示:此模型是个非线性模型,使用Lingo求解时间非常长。最好使用Lingo求解线性规划。