指派问题——航班安排问题的R实现

在生活中经常遇到这样的问题,某单位需完成n项任务,恰好有n个人可承担这些任务。由于每人的专长不同,各人完成任务不同(或所费时间),效率也不同。于是产生应指派哪个人去完成哪项任务,使完成n项任务的总效率最高(或所需总时间最小),这类问题称为指派问题或分派问题。

一、指派问题的数学模型

最优指派问题也称为最优匹配问题,它是运输问题的特殊情况。
例:有一份中文说明书,需译成英、日、德、俄、法5种文字,分别记作A、B、C、D、E。现有甲、乙、丙、丁、戊5人,他们将中文说明书翻译成不同语种的说明书所需时间如下表所示。问应指派何人去完成何工作,使所需总时间最少?

A B C D E
3 5 2 1 6
2 1 4 3 5
4 3 1 2 5
6 1 2 3 5
5 3 4 6 1

对应每个指派问题,需有类似上表那样的数表,称为效率矩阵或系数矩阵,其元素\(c_{ij}>0(i,j = 1,2,…,𝑛)\)表示指 派第\(i\)人去完成第\(j\)项任务时的效率(或时间、成本等)。

一般指派问题描述如下:
设有\(n\)个人,计划做\(n\)项工作,其中$ c_{ij}$ 表示第\(i\) 个人做第\(j\)项工作的收益,现求一种指派方式,使得每个人完成一项工作,总收益最大。
设决策变量为\(x_{ij}\), 当第\(i\)个人做第\(j\)项工作时,决策变量\(x_{ij}=1\);否则,决策变量\(x_{ij}=0\),因此最优指派问题可以写成0-1规划模型:

\[\max z =\sum^n_{i=1}\sum^n_{j=1}c_{ij}x_{ij}\\ s.t.\quad \sum^n_{j=1}x_{ij}=1,\quad i=1,2,3,\cdots,n\\\ \sum^n_{i=1}x_{ij}=1,\quad j=1,2,\cdots,n\\ x_{ij}=1 \quad or\quad 0,\quad i,j=1,2,\cdots,n \]

如果\(c_{ij}\)表示第\(i\)个人做第\(j\)项工作所用的花费,则目标函数为求最小。

二、航班安排问题

某航空公司经营 A、B、C 三个城市的航线,这些航线每天班次起飞与到达时间如下表。 设飞机在机场停留的损失费用大致与停留时间的平方成正比。又每架飞机从降落 到下班起飞至少需2小时准备时间,航班安排信息见下表,试决定一个使停留 费用损失为最小的分配飞行方案。

航班号 101 102 103 104 105 106 107 108 109 110 111 112 113 114
起飞城市 A A A A A B B B C C B B C C
起飞时间 9:00 10:00 15:00 20:00 22:00 4:00 11:00 15:00 7:00 15:00 13:00 18:00 15:00 7:00
到达城市 B B B C C A A A A A C C B B
到达时间 12:00 13:00 18:00 24:00:00 2:00 (次日) 7:00 14:00 18:00 11:00 19:00 18:00 23:00 20:00 12:00

【解析】该问题目标就是要减少机场停留时间,做好航班之间的衔接,下面分A、B、C三个城市考虑其损失费用。由表中数据可知,飞到A城市的航班有106、107、108、109和110,从A机场起飞的航班有101、102、103、104和105,下面计算他们续飞各种可能的费用,考虑109航班续接102航班的机场停留时间,109航班11.00到达A机场,102航班计划起飞时间为10.00,所以当天不能续飞,只能等到第二天起飞,要等待时间为23小时,费用为529K,其他情况同理计算,就得在A城市损失费用矩阵如下:

A城市损失费用:

起飞\到达 101 102 103 104 105
106 4k 9k 64k 169k 225k
107 361k 400k 625k 36k 64k
108 225k 256k 441k 4k 16k
109 484k 529k 16k 81k 121k
110 196k 225k 400k 625k 9k

因而可用指派问题进行求解,获得在A城市停留的最小费用。由于损失费用矩阵乘上同一个正数不影响其最优解,所以不用考虑损失费用的计量单位。
同理,B城市损失费用:

起飞\到达 106 107 108 111 112
101 256k 256k 256k 256k 256k
101 256k 256k 256k 256k 256k
102 225k 225k 225k 225k 225k
103 100k 100k 100k 100k 100k
113 64k 64k 64k 64k 64k

同理,C城市损失费用:

起飞\到达 109 110 113 114
104 49k 225k 225k 49k
105 25k 169k 169k 25k
111 169k 441k 441k 169k
112 64k 256k 256k 64k

三、航班安排的R实现

调用R语言程序包“lpsolve”,求解上面三个指派问题的最优解,得出航班安排方案。

3.1 A城市费用

library(lpSolve)
a1 = c(4, 9, 64, 169,225)
a2 = c(361, 400, 625, 36, 64)
a3 = c(225, 256, 441, 4, 16)
a4=c(484, 529, 16, 81, 121)
a5=c(196, 225, 400, 625, 9)
cost = rbind(a1,a2,a3,a4,a5)
colnames(cost)=c("101","102","103","104","105")
rownames(cost)=c("106","107","108","109","110")

assign.sol<-lp.assign(cost.mat=cost,direction="min")
assign.sol$solution
colnames(assign.sol$solution)=c("101","102","103","104","105")
rownames(assign.sol$solution)=c("106","107","108","109","110")
assign.sol$solution
assign.sol$objval
assign.sol$solution    #最优指派方案
   101 102 103 104 105
106   0   1   0   0   0
107   0   0   0   1   0
108   0   0   0   0   1
109   0   0   1   0   0
110   1   0   0   0   0
assign.sol$objval     #最优值
273
起飞\到达 101 102 103 104 105
106 0 1 0 0 0
107 0 0 0 1 0
108 0 0 0 0 1
109 0 0 1 0 0
110 1 0 0 0 0

3.2 B城市费用

library(lpSolve)
a1 = c(256, 529, 9, 625, 36)
a2 = c(225, 484, 4, 576, 25)
a3 = c(100, 289, 441, 361, 576)
a4=c(64, 225, 361, 289, 484)
a5=c(256, 529, 9, 625, 36)
cost = rbind(a1,a2,a3,a4,a5)
colnames(cost)=c("106","107","108","111","112")
rownames(cost)=c("101","102","103","113","114")

assign.sol<-lp.assign(cost.mat=cost,direction="min")
colnames(assign.sol$solution)=c("106","107","108","111","112")
rownames(assign.sol$solution)=c("101","102","103","113","114")
assign.sol$solution
assign.sol$objval
assign.sol$solution
    106 107 108 111 112
101   0   0   0   0   1
102   1   0   0   0   0
103   0   1   0   0   0
113   0   0   0   1   0
114   0   0   1   0   0
assign.sol$objval
  848
起飞\到达 106 107 108 111 112
101 0 0 0 0 1
102 1 0 0 0 0
103 0 1 0 0 0
113 0 0 0 1 0
114 0 0 1 0 0

3.3 C城市费用

library(lpSolve)
a1 = c(49, 225, 225, 49)
a2 = c(25, 169, 169, 25)
a3 = c(169, 441, 441, 169)
a4=c(64, 256, 256, 64)
cost = rbind(a1,a2,a3,a4)
colnames(cost)=c("109","110","113","114")
rownames(cost)=c("104","105","111","112")

assign.sol<-lp.assign(cost.mat=cost,direction="min")
colnames(assign.sol$solution)=c("109","110","113","114")
rownames(assign.sol$solution)=c("104","105","111","112")
assign.sol$solution
assign.sol$objval
assign.sol$solution
    109 110 113 114
104   0   1   0   0
105   0   0   1   0
111   1   0   0   0
112   0   0   0   1
assign.sol$objval
  627
起飞\到达 109 110 113 114
104 0 1 0 0
105 0 0 1 1
111 0 0 0 0
112 1 0 0 0

所以使停留费用损失最小的方案为:
101(A)→110(C) →104(A) →107(B) →103(A) →109(C) →112(B) →101(A)
102(A) →106(B) →102(A)
105(A) →108(B) →114(C) →111(B) →113(C) →105(A)
损失费:273K+848K+627K=1748K

参考文献

  1. 航班指派问题
  2. 运输问题和指派问题—R实现
  3. python的scipy(匈牙利算法)解决教学任务指派问题
posted @ 2023-04-19 10:40  郝hai  阅读(474)  评论(0编辑  收藏  举报