数学建模| 快速入门(以华为杯2019F题为例)
数学建模快速入门(华为杯2019F题为例)
参考论文
参考了两篇华为杯2019F题的优秀论文。
Gurobi软件+规划模型:https://github.com/qssxbhxy/2019GMCM
Dijkstra+蚁群算法:https://max.book118.com/html/2021/0910/7014030133004002.shtm
本篇文章建模思路参考第一篇,第二篇只是作为建模思路提了一下。建议配合第一篇参考的论文来读这篇文章。
华为杯2019F题第一问为例
读题——筛选出有用的信息
题目:多约束条件下智能飞行器航迹快速规划
背景:飞行器在飞行的时候不能对自身精准定位,所以在飞行过程中需要误差矫正才不会偏离航线。
飞行时候的约束条件:
- 飞行器在空间飞行过程中需要实时定位,其定位误差包括垂直误差和水平误差。飞行器每飞行 1m ,垂直误差和水平误差将各增加 δ delta δ个专用单位,以下简称单位。当垂直误差和水平误差均小于 θ theta θ个单位时,飞行器才能够按照规划路径飞行。
- 飞行器在飞行过程中需要对定位误差进行校正。飞行区域中存在一些安全位置(称之为校正点)可用于误差校正,当飞行器到达校正点即能够根据该位置的误差校正类型进行误差校正。
- 在出发地A点,飞行器的垂直和水平误差均为0。
- 飞行器在垂直误差校正点进行垂直误差校正后,其垂直误差将变为0,水平误差保持不变。相反,飞行器在水平误差校正点进行水平误差校正后,其水平误差将变为0,垂直误差保持不变。
- 飞行器在每个矫正点能进行误差矫正是有条件的。当飞行器的垂直误差不大于 α 1 alpha_1 α1个单位,水平误差不大于 α 2 alpha_2 α2个单位时才能进行垂直误差校正。当飞行器的垂直误差不大于 β 1 beta_1 β1个单位,水平误差不大于 β 2 beta_2 β2个单位时才能进行水平误差校正。
- 飞行器无法完成即时转弯(飞行器前进方向无法突然改变),假设飞行器的最小转弯半径为200m。
总结:飞行器要从A点飞到B点,中途要经过很多误差矫正点来保证航线不偏离。每个矫正点有矫正条件,要求垂直和水平误差不超过多少,同时垂直/水平矫正点只能矫正垂直/水平误差。飞行器在飞行的时候,不能立马转弯。
问题分析——搞清楚目标和要求
第一问:
针对附件1和附件2中的数据分别规划满足约束条件时飞行器的航迹,并且综合考虑以下优化目标(目标):
(A)航迹长度尽可能小;(B)经过校正区域进行校正的次数尽可能少。
并讨论算法的有效性和复杂度。
其中附件1数据的参数为:
α
1
=
25
,
α
2
=
15
,
β
1
=
20
,
β
2
=
25
,
θ
=
30
,
δ
=
0.001
alpha_1=25,alpha_2=15,beta_1=20,beta_2=25,theta=30,delta=0.001
α1=25,α2=15,β1=20,β2=25,θ=30,δ=0.001
附件2中数据的参数为:
α
1
=
20
,
α
2
=
10
,
β
1
=
15
,
β
2
=
20
,
θ
=
20
,
δ
=
0.001
alpha_1=20,alpha_2=10,beta_1=15,beta_2=20,theta=20,delta=0.001
α1=20,α2=10,β1=15,β2=20,θ=20,δ=0.001
请绘出两个数据集的航迹规划路径,并将结果(即飞行器从起点出发经过的误差校正点编号及校正前误差)依次填入航迹规划结果表,放于正文中,同时将两个数据集的结果填入附件3的Sheet1和Sheet2中。
附件1和附件2(样式):
编号,X坐标(单位: m),Y坐标(单位:m),Z坐标(单位: m),校正点类型(1表示垂直误差校正点,0表示水平误差校正点,第一个是A点,最后一个是B点)。
航迹规划结果表(样式):
校正点编号 | 校正前垂直误差 | 校正前水平误差 | 校正点类型 |
---|---|---|---|
0 | 0 | 0 | 出发点A |
N 1 N_1 N1 | ** | ||
N 2 N_2 N2 | ** | ||
… | … | … | … |
N n N_n Nn | 终点B |
解析题目:
- 数据:附件1和附件2给出来的是三维空间中,A点、B点以及矫正点的信息。附件1和附件2相当于是两个不同的三维条件。
- 目标:分别在附件1和附件2条件下,求出满足题目提到的约束条件下的最优解,这个最优解是路径和矫正次数都尽可能小。
- 输入:附件1和附件2的信息,问题中对应的数据参数。
- 输出:附件1和附件2对应的航迹规划结果表,算法的有效性和复杂度分析。
- 规范:附件1和附件2航迹规划结果表要放到正文,还要分别填入附件3的Sheet1和Sheet2中
做到这一步,其实就知道题目要我们干什么了,也知道具体的要求是什么了。
建立模型——将实际问题转化为数学问题
判断题目类型
如何思考:在选题的时候,其实就应该判断出来,例如有些题目会直接写什么的优化。这题从题目上看,就能看出来和图论有关,而图论是优化题中的一种。
判断题目类型:这是优化中的图论问题。
模型假设
之前是写ACM算法,很多问题都抽象好了问题和数据,但是数学建模是把实际问题抽象为数学问题,需要自己补全抽象的这一部分信息。
如何思考:在自己思考的理想状态下,思考和现实中情况的区别,并在假设的时候把这个理想状态说明清楚。既然要抽象为图论问题,那么肯定是不考虑飞行器的大小的,把飞行器当成一个质点来考虑。飞行路径既然可以按照时间乘以路径的直线来算,那么在飞行每两个点之间肯定是匀速直线,意味着也没有也没有障碍物。路径长度尽可能小,意味着在到达一个矫正点就拐弯直接去下一个矫正点,需要忽略转弯引起的轨迹变化。
模型假设:为了便于问题的研究,对题目中某些条件进行简化以及合理的假设。
- 不考虑飞行器的大小的,把飞行器当成一个质点来考虑。
- 飞行器在飞行途中不会遇到障碍物。
- 为了路径长度尽可能小,所以在到达一个矫正点就拐弯直接去下一个矫正点。
- 为了方便计算,在出发点、终点和矫正点之间直线匀速飞行,也忽略转弯引起的轨迹变化。
数据处理
如何思考:
- 数据分布: 画出附件1和附件2的三维散点图,观察数据的分布,看看有没有异常的数据。
- 邻接距离矩阵:解决图论问题,那就需要把数据转为图的存储方式,通常由邻接距离矩阵和邻接表的形式,这里每个点之间其实都可以有直接路径(最理想,每个矫正点误差条件很高的情况下),所以用邻接距离矩阵是比较方便的。
- 无向图:图分为有向图和无向图,就是每个点之间路径是否具有方向,这里明显是无向图。
数据分布:画出附件1和附件2的三维散点图,可以发现是个稠密图,A和B分别在图的两端,所以所有点基本都是有可能用上的,不能人为的“剪枝”。
构建邻接距离矩阵:数据一共有n个点(A点、B点、矫正点),那么需要用一个 n × n 矩阵的形式来表示各个顶点间的邻接关系。把这些点抽象成图中顶点,它们之间路径长为顶点之间边的权重,飞行器最短航线就等于求这个图的最短路。
剪枝优化:题目中有个约束条件,矫正点需要满足误差条件才能矫正,飞行器需要满足误差条件才不会偏离航线。根据这两个条件可以把邻接矩阵中不满足条件的路径剔除。
- 飞行器每飞行 1m ,垂直误差和水平误差将各增加 δ delta δ个专用单位。
- 当垂直误差和水平误差均小于 θ theta θ个单位时,飞行器才能够按照规划路径飞行。
- 当飞行器的垂直误差不大于 α 1 alpha_1 α1个单位,水平误差不大于 α 2 alpha_2 α2个单位时才能进行垂直误差校正。当飞行器的垂直误差不大于 β 1 beta_1 β1个单位,水平误差不大于 β 2 beta_2 β2个单位时才能进行水平误差校正。
最终的邻接距离矩阵:
S
=
(
s
i
j
)
n
×
n
S=(s_{ij})_{n×n}
S=(sij)n×n,其中n为矫正点数加2,因为还有个A点和B点。
s
i
j
=
{
实际距离
,
起点
o
r
矫正点
c
i
到终点
o
r
矫正点
c
j
,
i
≠
j
+
∞
,
未从起点
o
r
矫正点
c
i
到终点
o
r
矫正点
c
j
s_{ij}= begin{cases} 实际距离, 起点or矫正点c_i到终点or矫正点c_j,ineq j \ +infty, 未从起点or矫正点c_i到终点or矫正点c_j end{cases}
sij={实际距离,起点or矫正点ci到终点or矫正点cj,i=j+∞,未从起点or矫正点ci到终点or矫正点cj
因为自身顶点不能相连,所以
i
≠
j
ineq j
i=j。矩阵里面的值“
+
∞
+infty
+∞”表示两个点之间没有直接路径,“实际距离”表示两个点之间有直接路径。其中
s
i
j
s_{ij}
sij可以表示飞行器飞行中网络图的边的权重。
航迹规划模型建立
题目目标:飞行器在从起点 A 到终点 B 飞行过程中需要满足飞行路程最短的同时,尽可能经过少的飞行误差校正节点。
如何思考:
在遇到一道题前,应该先想想最暴力的方法是什么?那肯定是把所有能从A到B的路径都找出来,然后都比较一遍取出比较。比较的思路有两种,一种比较的时候可以是优先路径最短,另一种是优先矫正点最少。可以把两个思路下的都求出来做对比,选择最能够型能够兼顾航迹长度和校正点个数。但是暴力的话,题目中的数据很多,例如附件一610个矫正点,如果图矫正点之间全连结,复杂度是
O
(
n
n
)
O(n^n)
O(nn),比赛期间估计根本算不完。
如果是在比赛中可以先去搜索看看有什么相关的论文作为参考,因为这次这个比赛已经结束了,我就直接看了两篇优秀论文为参考。这是一个多目标规划问题,要同时兼顾路径尽可能短和经过矫正点尽可能少。目前看了两个优秀论文,一个思路是分别求单个目标最优,用Dijkstra求最短路径,用蚁群算法求最少矫正点,然后两个结果对比一下。另一个是合到,把最短路径和最少矫正点的目标函数放在一起,然后通过调参来求解。
本文章思路以第二种为参考,该思路的优秀论文和程序在github有公开,链接:https://github.com/qssxbhxy/2019GMCM。
航迹规划模型建立:
飞行器在飞行过程中,经过矫正点
c
i
c_i
ci到矫正点
c
j
c_j
cj,表示选中飞行网络图中
s
i
j
s_{ij}
sij加入最优飞行路径中,否则不加入。所以航迹规划问题可以转化为0-1整数规划问题,就是矫正点在最优飞行路径中要么选要么不选。
因此,最短路的目标函数:
m
i
n
∑
(
i
,
j
)
∈
E
s
i
j
x
i
j
(
x
i
j
表示
0
和
1
)
minsum_{(i,j)in E}s_{ij}x_{ij}(x_{ij}表示0和1)
min(i,j)∈E∑sijxij(xij表示0和1)
约束条件:
- 无向图:
∑ ( i , j ) ∈ E x i j = ∑ ( j , k ) ∈ E x j k , ∀ j ≠ A , B sum_{(i,j)in E}x_{ij}=sum_{(j,k)in E}x_{jk},forall jnot=A,B (i,j)∈E∑xij=(j,k)∈E∑xjk,∀j=A,B - 起飞点A:
∑ ( A , j ) ∈ E x A j = 1 , ∑ ( j , A ) ∈ E x j A = 0 sum_{(A,j)in E}x_{Aj}=1,sum_{(j,A)in E}x_{jA}=0 (A,j)∈E∑xAj=1,(j,A)∈E∑xjA=0 - 终点B:
∑ ( j , B ) ∈ E x j B = 1 , ∑ ( B , j ) ∈ E x B j = 0 sum_{(j,B)in E}x_{jB}=1,sum_{(B,j)in E}x_{Bj}=0 (j,B)∈E∑xjB=1,(B,j)∈E∑xBj=0 - 从i点到j点,水平误差:
I i h i + δ s i j − h j ⩽ ( 1 − x i j ) M I_i h_i+delta s_{ij} -h_j leqslant (1-x_{ij})M Iihi+δsij−hj⩽(1−xij)M
I i I_i Ii表示i点是什么类型的矫正,1垂直,0水平。
h i h_i hi表示i点水平偏移量。
M是给定很大的正数。 - 从i点到j点,垂直误差:
( 1 − I i ) v i + δ s i j − v j ⩽ ( 1 − x i j ) M (1-I_i )v_i+delta s_{ij} -v_j leqslant (1-x_{ij})M (1−Ii)vi+δsij−vj⩽(1−xij)M
v i v_i vi表示i垂直偏移量。 - 垂直矫正点:
v i ⩽ α 1 , h i ⩽ α 2 , i ∈ V v_i leqslant alpha_1,h_i leqslant alpha_2,iin V vi⩽α1,hi⩽α2,i∈V - 水平矫正点:
v i ⩽ β 1 , h i ⩽ β 2 , i ∈ H v_i leqslant beta_1,h_i leqslant beta_2,iin H vi⩽β1,hi⩽β2,i∈H
由于目标不但要路径尽可能小,还要路径点最少,可以在最短路径目标函数基础上加入路径点数的惩罚项来约束。因此,最终的目标函数为:
m
i
n
∑
(
i
,
j
)
∈
E
s
i
j
x
i
j
+
K
∑
(
i
,
j
)
∈
E
x
i
j
minsum_{(i,j)in E}s_{ij}x_{ij}+Ksum_{(i,j)in E}x_{ij}
min(i,j)∈E∑sijxij+K(i,j)∈E∑xij
K为惩罚系数。
航迹规划模型:(目标函数+约束条件)
m
i
n
∑
(
i
,
j
)
∈
E
s
i
j
x
i
j
+
K
∑
(
i
,
j
)
∈
E
x
i
j
minsum_{(i,j)in E}s_{ij}x_{ij}+Ksum_{(i,j)in E}x_{ij}
min(i,j)∈E∑sijxij+K(i,j)∈E∑xij
s
.
t
.
{
∑
(
i
,
j
)
∈
E
x
i
j
=
∑
(
j
,
k
)
∈
E
x
j
k
,
∀
j
≠
A
,
B
∑
(
A
,
j
)
∈
E
x
A
j
=
1
,
∑
(
j
,
A
)
∈
E
x
j
A
=
0
∑
(
j
,
B
)
∈
E
x
j
B
=
1
,
∑
(
B
,
j
)
∈
E
x
B
j
=
0
I
i
h
i
+
δ
s
i
j
−
h
j
⩽
(
1
−
x
i
j
)
M
(
1
−
I
i
)
v
i
+
δ
s
i
j
−
v
j
⩽
(
1
−
x
i
j
)
M
v
i
⩽
α
1
,
h
i
⩽
α
2
,
i
∈
V
v
i
⩽
β
1
,
h
i
⩽
β
2
,
i
∈
H
s.t. begin{cases} sum_{(i,j)in E}x_{ij}=sum_{(j,k)in E}x_{jk},forall jnot=A,B \ sum_{(A,j)in E}x_{Aj}=1,sum_{(j,A)in E}x_{jA}=0 \ sum_{(j,B)in E}x_{jB}=1,sum_{(B,j)in E}x_{Bj}=0 \ I_i h_i+delta s_{ij} -h_j leqslant (1-x_{ij})M \ (1-I_i )v_i+delta s_{ij} -v_j leqslant (1-x_{ij})M \ v_i leqslant alpha_1,h_i leqslant alpha_2,iin V \ v_i leqslant beta_1,h_i leqslant beta_2,iin H end{cases}
s.t.⎩
⎨
⎧∑(i,j)∈Exij=∑(j,k)∈Exjk,∀j=A,B∑(A,j)∈ExAj=1,∑(j,A)∈ExjA=0∑(j,B)∈ExjB=1,∑(B,j)∈ExBj=0Iihi+δsij−hj⩽(1−xij)M(1−Ii)vi+δsij−vj⩽(1−xij)Mvi⩽α1,hi⩽α2,i∈Vvi⩽β1,hi⩽β2,i∈H
模型求解——实际求解的细节
如何思考:前面模型建立是把目标函数和约束用数学的语言表达出来,这一步则是把具体如何去求解前面的模型过程解释出来,要用一些具体实际计算出来的数值作为说明。
先说数据预处理,数据量有多大、处理之后有多大、具体如何处理的。
模型和算法的具体实现,除了用语言描述,还可以用step1、step2…stepn或者
流程图描述。如果是用了现成的库,可以把用了什么厂商的库说一下。
模型和算法具体运行的情况,迭代了多少次、花了多少时间、不同调参下的数据结果、如何选择出最好的结果。这里可以用一些图和表辅助论文的表达。
下面具体举例,以前面模型建立的文章的数据为主。
数据预处理:前面模型建立提到了数据处理,会对邻接距离矩阵进行剪枝。没做剪枝处理前,附件1的边数为374544。附件1中,假设飞行器从i点飞到j点,满足j属于垂直矫正点,那么
δ
s
i
j
⩽
min
{
α
1
,
α
2
}
delta s_{ij} leqslant min{alpha_1,alpha_2}
δsij⩽min{α1,α2};满足j属于水平矫正点,那么
δ
s
i
j
⩽
min
{
β
1
,
β
2
}
delta s_{ij} leqslant min{beta_1,beta_2}
δsij⩽min{β1,β2}。通过计算附件1,垂直矫正点边长不能超过15000m,水平矫正点长度不能超过20000m。同时到达终点的时候,垂直和水平误差都要小于
θ
=
30
theta=30
θ=30,也就是到达终点边长不能超过30000m。剪枝后,附件1中的边数降为31266。可以看出来,“剪枝”处理数据大大减少了边长数量,从而加快了模型的求解。
解释:通过前面这段对附件1数据处理的内容,可以看得出来其实就是模型建立中的数据处理部分,具体处理又说了一边,然后拿出实际处理中具体的数据。
模型的实现:数据预处理后,把附件1剪枝后的数据,带入模型,利用Python调用Gurobi优化软件进行求解。调参,发现惩罚系数K取0和10000的时候,K取0表示距离优先,K取10000表示顶点个数优先。
K | 矫正点数 | 路径长度 |
---|---|---|
10000 | 8 | 104861 |
0 | 9 | 103517 |
路径长度差别不大,取K为10000的时候,能够同时兼顾矫正点数和路径长度。
解释:说一下用了什么东西完成的,Python+Gurobi;如何完成的,把预处理后的数据放入模型,然后调参,发现K取10000最好。
模型运行的情况:附件1求解,总共求解时间为15.11秒。
解释:运行用了多少时间,训练多少轮次,程序迭代多少次什么都可以写,最好有程序具体截图。
结果分析——展示结果回答问题的要求
题目要求:附件1和附件2对应的航迹规划结果表,算法的有效性和复杂度分析。
如何思考:回顾一下前面题目分析中,分析出来题目要求我们要回答的是什么,也就是题目要求。一个是两个附件对应的航迹规划结果表,以及算法的有效性和复杂度分析。根据模型求解出来数据,按照航迹规划结果表格式要求,把结果放在论文中。算法的有效性指的是算法的每一个步骤都应当能有效地执行,并得到确定的结果。这个应该有个明确的答案结果就可以了。复杂度分析,一个是空间复杂度,一个时间复杂度。把剪枝前后的空间规模都说一下,然后时间复杂度说一下,最后说一下总体用时。最后还可以加个总结作为结尾。
感想
- 参考:看了这两篇论文,他们都会有参考文献,所以在比赛的时候,可以先去搜索一下相关论文,作为自己解题思路的参考。
- 结果:除了自己算,还可以去网上看看一些数据作为参考,很多比赛题目数据都是来源于实际的,这些可以作为自己答案的辅助验证。
- 论文:优秀论文读下来,其实论文写作就是把程序解答过程进行数学化的描述。由于阅卷的人会有那种数学系的,步要图方便用计算机语言去表述,适当的时候需要用图表、流程图辅助表达。
- 假设:因为数学建模是把实际的问题抽象为数学问题,所以需要进行一些模型理想化的假设。除了一开始就做好假设,后面也根据问题的需要补充假设。
- 与ACM的不同:ACM是把实际问题抽象好了,数学建模需要自己把实际的问题进行数学抽象;ACM通常都是单目标问题,因为机器判题需要唯一的解,但数学建模其实并不一定有唯一的解。