数学建模:整数规划—指派模型与匈牙利算法

对于限制全部或部分决策变量取离散非负整数值的线性规划, 称之整数线性规划, 简称整数规划. 整数规划的一种特殊情形是 0 − 1 0-1 01 整数规划, 它的决策变量仅限于 0 或 1, 简称 0 − 1 0-1 01 规划.

指派模型是一种重要的 0 − 1 0-1 01 规划模型,指派模型又叫分配模型,指有各种不同的资源将分派给各种不同的用途,以寻求一种最优的分配方案。要求使有限的资源达到最经济的运用,取得最大的经济效果。这里的资源可以是人力,材料、工件、设备等; 用途可以是待用设备、待完成工作、待加工的工件等。资源与用途之间是一一对应的,即当某种资源分配给某种用途之后,这种资源就不能再分配给别的用途了,同样,这种用途也不能再占用别的资源了。

标准指派模型

标准指派问题的一般提法是:拟分派 n n n 个人 A 1 , A 2 , ⋯   , A n {A_1},{A_2}, \cdots ,{A_n} A1,A2,,An 去完成 n n n 项工作 B 1 , B 2 , ⋯   , B n {B_1},{B_2}, \cdots ,{B_n} B1,B2,,Bn,要求每项工作需且仅需一个人去完成,每个人需完成且仅需完成一项工作。已知人 A i {A_i} Ai 完成工作 B j {B_j} Bj 的时间或费用等成本型指标值为 c i j {c_{ij}} cij ,则应如何指派才能使总的工作效率最高?

引入 0 − 1 0-1 01 决策变量
x i j = { 1 ,  指派  A i  去完成工作  B j , 0 ,  否则,  i , j = 1 , 2 , ⋯   , n . x_{i j}=\left\{\begin{array}{ll} 1, & \text { 指派 } A_{i} \text { 去完成工作 } B_{j}, \\ 0, & \text { 否则, } \end{array} \quad i, j=1,2, \cdots, n .\right. xij={1,0, 指派 Ai 去完成工作 Bj, 否则i,j=1,2,,n.

则标准指派问题的数学模型为
min ⁡ z = ∑ i = 1 n ∑ j = 1 n c i j x i j , 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 , \begin{gathered} &\min \quad z=\sum_{i=1}^{n} \sum_{j=1}^{n} c_{i j} x_{i j}, \\ & { s.t. }\left\{\begin{array}{l} \sum_{j=1}^{n} x_{i j}=1, \quad i=1,2, \cdots, n, \\ \sum_{i=1}^{n} x_{i j}=1, \quad j=1,2, \cdots, n, \\ x_{i j}=0 \text { 或 } 1, \quad i, j=1,2, \cdots, n, \end{array}\right. \end{gathered} minz=i=1nj=1ncijxij,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 = ( c i j ) n × n {\mathbf{C}} = {({c_{ij}})_{n \times n}} C=(cij)n×n 为效率矩阵,模型的最优解也可以用 n n n 阶方阵 X ∗ {{\mathbf{X}}^*} X 的形式来表示,称之指派问题的最优解方阵。最优解方阵一定是一个置换矩阵,即矩阵的每一行、每一列都恰好有一个“ 1 1 1 ”,其余元素均为 0 0 0

匈牙利算法

基本原理

定理 1 设效率矩阵 C = ( c i j ) n × n {\mathbf{C}} = {({c_{ij}})_{n \times n}} C=(cij)n×n 中任何一行(列)的各元素都减去一个常数 k k k(可正可负)后得到的新矩阵为 B = ( b i j ) n × n {\mathbf{B}} = {({b_{ij}})_{n \times n}} B=(bij)n×n,则以 B = ( b i j ) n × n {\mathbf{B}} = {({b_{ij}})_{n \times n}} B=(bij)n×n 为效率矩阵的指派问题与原问题有相同的最优解,但其最优值比原问题的最优值小 k k k

定理 2 (独立零元素定理) 若一方阵中的一部分元素为 0 0 0,一部分元素为非 0 0 0,则覆盖方阵内所有 0 0 0 元素的最少直线数恰好等于那些位于不同行、不同列的 0 0 0 元素的最多个数。

匈牙利算法步骤

第一步 变换指派问题的系数矩阵 ( c i j ) (c_{ij}) (cij) ( b i j ) (b_{ij}) (bij),使在 ( b i j ) (b_{ij}) (bij) 的各行各列中都出现 0 0 0 元素

  • ( c i j ) (c_{ij}) (cij) 的每行元素都减去该行的最小元素
  • 再从所得新系数矩阵的每列元素中减去该列的最小元素

e . g . e.g. 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 ] \left(\mathbf{C}_{i j}\right)=\left[\begin{array}{ccccc} 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{array}\right] (Cij)=1287154791714109612677614610969109

每行分别 − 7 , − 6 , − 7 , − 6 , − 4 −7, −6, −7, −6, −4 7,6,7,6,4 ⟶ \longrightarrow

[ 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 ] \begin{gathered} \left[\begin{array}{ccccc} 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{array}\right]\\ \end{gathered} 52090031086205030070620245

每列都 − 0 -0 0 ⟶ \longrightarrow

[ 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{array}{ccccc} 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{array}\right] 52090031086205030070620245

第二步 进行试指派,以寻求最优解

( b i j ) \left(b_{i j}\right) (bij) 中找尽可能多的独立 0 元素, 若能找出 n n n 个独立 0 元素, 就以这 n n n 个独立 0 元素对应解矩阵 ( x i j ) \left(x_{i j}\right) (xij) 中的元素为 1 , 其余为 0 , 这就得到最优解

找独立 0 \mathbf{0} 0 元素:

  • 从只有一个 0 0 0 元素的行(列)开始, 给这个 0 0 0 元素加圈, 记作 ◎ ◎ )。然后划去 ◎ ◎ 所在列 (行) 的其它 0 {0} 0 元素, 记作 ∅ \varnothing ; 这表示这列所代表的任务已指派完, 不必再考虑别人了
  • 给只有一个 0 0 0 元素的列 (行) 中的 0 0 0 元素加圈,记作 ◎ ◎ ;然后划去 ◎ ◎ 所在行的 0 0 0 元素,记作 ∅ \varnothing
  • 反复进行以上两步,直到尽可能多的 0 0 0 元素都被圈出和划掉为止

e . g . e.g. 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{array}{ccccc} 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{array}\right] 52090031086205030070620245

⟶ \longrightarrow

[ 5 ◎ 2 ∅ 2 2 3 ∅ ∅ ◎ ◎ 10 5 7 2 9 8 ◎ ∅ 4 ∅ 6 3 6 5 ] \left[\begin{array}{ccccc} 5 & ◎ & 2 & \varnothing & 2 \\ 2 & 3 & \varnothing & \varnothing & ◎ \\ ◎ & 10 & 5 & 7 & 2 \\ 9 & 8 & ◎ & \varnothing & 4 \\ \varnothing & 6 & 3 & 6 & 5 \end{array}\right] 52931086253762245

第三步 作最少的直线覆盖所有 0 0 0 元素,以确定该系数矩阵中能找到最多的独立元素数

  • 对没有 ◎ ◎ 的行打 √
  • 在已经打 √ 的行中含有的 0 0 0 元素的列打 √
  • 在已经打 √ 的列中含 ◎ ◎ 元素的行打 √
  • 重复前两个操作直到没有打 √ 的行列为止
  • 对没有打 √ 的行画一横线,有打 √ 的列画一纵线,这就覆盖所有 0 0 0 元素的最少直线数。令这一直线数为 l l l
    l < n l<n l<n, 说明必须再换当前的系数矩阵,才能找到 n n n 个独立的 0 0 0 元素,转到第四步。

第四步 在没有被直线覆盖的部分中找出最小元素

  • 打 √ 行每个元素减去这一最小元素,在打 √ 列的每个元素加上这一最小元素,以保证原来 0 0 0 元素不变,得到新系数矩阵
  • 若得到 n n n 个独立的 0 0 0 元素,则已得到最优解,否则转回第三步

e . g . e.g. 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{array}{lllll} 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{array}\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{array}{lllll} 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{array}\right] 0000110000000100100000100

即求得2个最优指派方案:
(1) A 1 − B 2 , A 2 − B 3 , A 3 − B 5 , A 4 − B 4 , A 5 − B 1 A_1 - B_2, A_2 - B_3, A_3-B_5, A_4-B_4, A_5-B_1 A1B2,A2B3,A3B5,A4B4,A5B1
(2) A 1 − B 2 , A 2 − B 4 , A 3 − B 5 , A 4 − B 3 , A 5 − B 1 A_1 - B_2, A_2 - B_4, A_3-B_5, A_4-B_3, A_5-B_1 A1B2,A2B4,A3B5,A4B3,A5B1
所需时间为 min ⁡ z = 7 + 6 + 9 + 6 + 4 = 32 \min z=7+6+9+6+4=32 minz=7+6+9+6+4=32

非标准型的指派问题

匈牙利算法的条件是: 模型求最小值, 效率 c i j ≥ 0 c_{i j} \geq 0 cij0,对非标准的指派问题可转化为标准形式,方法如下

转化为标准形式:

  1. 人数和事数不相等的指派问题:
    人少事情多,虚拟“人”,做各事的费用系数为0;
    人多事情少,虚拟“事”,各人做的费用系数为0。
  2. 对于求极大化的问题,只要系数矩阵变换为 B = ( M − c i j ) n × n B=(M-c_{ij})_{n \times n} B(Mcij)n×n
  3. 一个人可以做几件事情的指派问题:
    将该人化作相同的几个“人”来接受指派,费用一样
  4. 某事一定不能由某人做的指派问题,费用系数为“ M M M”, 然后用匈牙利算法来求解
  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值