对于限制全部或部分决策变量取离散非负整数值的线性规划, 称之整数线性规划, 简称整数规划. 整数规划的一种特殊情形是 0 − 1 0-10−1 整数规划, 它的决策变量仅限于 0 或 1, 简称 0 − 1 0-10−1 规划.
指派模型是一种重要的 0 − 1 0-10−1 规划模型,指派模型又叫分配模型,指有各种不同的资源将分派给各种不同的用途,以寻求一种最优的分配方案。要求使有限的资源达到最经济的运用,取得最大的经济效果。这里的资源可以是人力,材料、工件、设备等; 用途可以是待用设备、待完成工作、待加工的工件等。资源与用途之间是一一对应的,即当某种资源分配给某种用途之后,这种资源就不能再分配给别的用途了,同样,这种用途也不能再占用别的资源了。
标准指派模型
标准指派问题的一般提法是:拟分派n个人 A1, A2,⋯,An去完成n项工作B1,B2,⋯,Bn,要求每项工作需且仅需一个人去完成,每个人需完成且仅需完成一项工作。已知人Ai完成工作Bj的时间或费用等成本型指标值为cij,则应如何指派才能使总的工作效率最高?
引入 0 − 1 决策变量
x
i
j
=
{
1
,
指派
A
i
去完成工作
B
j
0
,
否则
i
,
j
=
1
,
2
,
.
.
.
,
n
x_{ij}= \begin{cases} 1,\quad 指派A_i去完成工作B_j\\ 0, \quad 否则 \end{cases} \quad i,j = 1, 2, ..., n
xij={1,指派Ai去完成工作Bj0,否则i,j=1,2,...,n
则标准指派问题的数学模型为
m
i
n
z
=
∑
i
=
1
n
∑
i
=
1
n
c
i
j
x
i
j
,
min\quad z = \sum_{i = 1}^{n}\sum_{i = 1}^{n}c_{ij}x_{ij},
minz=i=1∑ni=1∑ncijxij,
s
.
t
.
{
∑
j
=
1
n
x
i
j
=
1
,
i
=
1
,
2
,
.
.
.
n
,
∑
i
=
1
n
x
i
j
=
1
,
j
=
1
,
2
,
.
.
.
n
,
x
i
j
=
0
或
1
,
i
,
j
=
1
,
2
,
.
.
.
n
s.t. \begin{cases} \sum_{j = 1}^{n}x_{ij}= 1,\quad i=1,2,...n,\\ \sum_{i = 1}^{n}x_{ij}= 1,\quad j=1,2,...n,\\ x_{ij}= 0或1,\quad i,j=1,2,...n \end{cases}
s.t.⎩
⎨
⎧∑j=1nxij=1,i=1,2,...n,∑i=1nxij=1,j=1,2,...n,xij=0或1,i,j=1,2,...n
称 C = (cij)n×n 为效率矩阵,模型的最优解也可以用n阶方阵 X∗ 的形式来表示,称之指派问题的最优解方阵。最优解方阵一定是一个置换矩阵,即矩阵的每一行、每一列都恰好有一个“1”,其余元素均为0。
匈牙利算法
基本原理
- 定理1
设效率矩阵 C = (cij)n×n 中任何一行(列)的各元素都减去一个常数k(可正可负)后得到的新矩阵为 B = (bij)n×n,则以 B = (bij)n×n 为效率矩阵的指派问题与原问题有相同的最优解,但其最优值比原问题的最优值小k - 定理2(独立零元素定理)
若一方阵中的一部分元素为0,一部分元素为非0,则覆盖方阵内所有0元素的最少直线数恰好等于那些位于不同行、不同列的0元素的最多个数。
匈牙利算法步骤
-
第一步 变换指派问题的系数矩阵 (cij) 为 (bij),使在 (bij) 的各行各列中都出现0元素
- 从 (cij) 的每行元素都减去该行的最小元素
- 再从所得新系数矩阵的每列元素中减去该列的最小元素
e.g.
( C i j ) = [ 12 7 9 7 9 8 9 6 6 6 7 17 12 14 9 15 14 6 6 10 4 10 7 10 9 ] (C_{ij}) = \left[ \begin{matrix} 12&7&9&7&9\\ 8&9&6&6&6\\ 7&17&12&14&9\\ 15&14&6&6&10\\ 4&10&7&10&9 \end{matrix} \right] (Cij)=⎣ ⎡1287154791714109612677614610969109⎦ ⎤
每行分别 −7, −6, −7, −6, −4 ⟶
[ 5 0 2 0 2 2 3 0 0 0 0 10 5 7 2 9 8 0 0 4 0 6 3 6 5 ] \left[ \begin{matrix} 5&0&2&0&2\\ 2&3&0&0&0\\ 0&10&5&7&2\\ 9&8&0&0&4\\ 0&6&3&6&5 \end{matrix} \right] ⎣ ⎡52090031086205030070620245⎦ ⎤
每列都 −0 ⟶
[ 5 0 2 0 2 2 3 0 0 0 0 10 5 7 2 9 8 0 0 4 0 6 3 6 5 ] \left[ \begin{matrix} 5&0&2&0&2\\ 2&3&0&0&0\\ 0&10&5&7&2\\ 9&8&0&0&4\\ 0&6&3&6&5 \end{matrix} \right] ⎣ ⎡52090031086205030070620245⎦ ⎤ -
第二步 进行试指派,以寻求最优解
在 (bij) 中找尽可能多的独立0元素,若能找出n个独立0元素,就以这n个独立0元素对应解矩阵 (xij) 中的元素为1,其余为0,这就得到最优解找独立0元素:
- 从只有一个0元素的行(列)开始,给这个0元素加圈,记作⌾。然后划去⌾所在列(行)的其它0元素,记作⌽;这表示这列所代表的任务已指派完,不必再考虑别人了
- 给只有一个0元素的列(行)中的0元素加圈,记作⌾;然后划去⌾所在行的0元素,记作⌽
- 反复进行以上两步,直到尽可能多的0元素都被圈出和划掉为止
e.g. 续上例
[ 5 0 2 0 2 2 3 0 0 0 0 10 5 7 2 9 8 0 0 4 0 6 3 6 5 ] \left[ \begin{matrix} 5&0&2&0&2\\ 2&3&0&0&0\\ 0&10&5&7&2\\ 9&8&0&0&4\\ 0&6&3&6&5 \end{matrix} \right] ⎣ ⎡52090031086205030070620245⎦ ⎤
⟶
[ 5 ⌾ 2 ⌽ 2 2 3 ⌽ ⌽ ⌾ ⌾ 10 5 7 2 9 8 ⌾ ⌽ 4 ⌽ 6 3 6 5 ] \left[ \begin{matrix} 5&⌾&2&⌽&2\\ 2&3&⌽&⌽&⌾\\ ⌾&10&5&7&2\\ 9&8&⌾&⌽&4\\ ⌽&6&3&6&5 \end{matrix} \right] ⎣ ⎡52⌾9⌽⌾310862⌽5⌾3⌽⌽7⌽62⌾245⎦ ⎤ -
第三步 作最少的直线覆盖所有0元素,以确定该系数矩阵中能找到最多的独立元素数
- 对没有⌾的行打 √
- 在已经打 √ 的行中含有的0元素的列打 √
- 在已经打 √ 的列中含⌾元素的行打 √
- 重复前两个操作直到没有打 √ 的行列为止
- 对没有打 √ 的行画一横线,有打 √ 的列画一纵线,这就覆盖所有0元素的最少直线数。令这一直线数为l。
若 l < n,说明必须再换当前的系数矩阵,才能找到n个独立的0元素,转到第四步。
-
第四步 在没有被直线覆盖的部分中找出最小元素
- 打 √ 行每个元素减去这一最小元素,在打 √ 列的每个元素加上这一最小元素,以保证原来0元素不变,得到新系数矩阵
- 若得到n个独立的0元素,则已得到最优解,否则转回第二步
e.g. 续上例, 得
[ 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 ] \left[ \begin{matrix} 0&1&0&0&0\\ 0&0&1&0&0\\ 0&0&0&0&1\\ 0&0&0&1&0\\ 1&0&0&0&0 \end{matrix} \right] ⎣ ⎡0000110000010000001000100⎦ ⎤
或
[ 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 ] \left[ \begin{matrix} 0&1&0&0&0\\ 0&0&0&1&0\\ 0&0&0&0&1\\ 0&0&1&0&0\\ 1&0&0&0&0 \end{matrix} \right] ⎣ ⎡0000110000000100100000100⎦ ⎤
即求得2个最优指派方案:
(1) A1 − B2, A2 − B3, A3 − B5, A4 − B4, A5 − B1;
(2) A1 − B2, A2 − B4, A3 − B5, A4 − B3, A5 − B1。
所需时间为 m i n z = 7 + 6 + 9 + 6 + 4 = 32 min\quad z = 7 + 6 + 9 + 6 + 4 = 32 minz=7+6+9+6+4=32
非标准型的指派问题
匈牙利算法的条件是:模型求最小值,效率 cij ≥ 0,对非标准的指派问题可转化为标准形式,方法如下
转化为标准形式:
- 人数和事数不相等的指派问题:
人少事情多,虚拟“人”,做各事的费用系数为0;
人多事情少,虚拟“事”,各人做的费用系数为0。 - 对于求极大化的问题,只要系数矩阵变换为 B = (M − cij)n×n
- 一个人可以做几件事情的指派问题:
将该人化作相同的几个“人”来接受指派,费用一样 - 某事一定不能由某人做的指派问题,费用系数为“M”,然后用匈牙利算法来求解