指派问题匈牙利解法以及其优化

指派问题匈牙利解法以及其优化

本人第一次写blog,难免有不足之处,还请大家不吝指正。

1、问题的提出

简单的说,n个人恰好分别承担n个任务,每个人对于不同的任务效率不同;我们的目的就是为使任务完成效率尽可能的高。
例如:有4个工人,要分别指派他们完成4项不同的工作,每人做各项工作所消耗的时间如下表所示,问应如何指派工作,才能使总的消耗时间为最少。
指派问题匈牙利解法以及其优化_第1张图片
若用0-1整数规划问题的常规思路来解,即:

解:令 xij = 1(第 i人完成第j项工作)或0(第 i人不进行第j项工作).于是得到一个0–1整数规划问题

Min z=15X11+18X12+21X13+24X14+19X21+23X22+22X23+18X24+26*X31
+17X32+16X33+19X34+19X41 +21X42+23X43+17*X44
使得:指派问题匈牙利解法以及其优化_第2张图片
Xij只能取0或者1,i,j = 1,2,3,4
最终变成一个线性规划的问题,最终将有4个x的值为1,其对应的下标便是最终的指派。

2、指派问题一般形式

设有 n 个资源(人或机器等)A1, A2, …, An,分配做 n 件事B1, B2, … Bn,要求每件事必须使用1个资源,且不同事件由不同资源完成。已知 Ai 做 Bj的效率(如劳动工时、成本、创造价值等)为cij 。问如何进行指派可使总工作效率最佳?
其中我们称Cij为效率矩阵,问题数学模型为:
指派问题匈牙利解法以及其优化_第3张图片

3、匈牙利解法相关概念与证明

几个基础概念 解答
提出者及时间 1955年,库恩(W.W.Kuhn)利用匈牙利数学家康尼格(D.König)关于矩阵中独立零元素定理,提出了一种指派问题算法,被称为匈牙利解法。
定理1 设 C=(cij)是一个效率矩阵,若可行解x*=(xij)的 n个1所对应的 n个 C=(cij)均为0,则x* 是最优解。(若都为零,最终代价为0,定为最优)
定理2 设给定了以 C=(cij)为效率矩阵的指派问题 G,现将 C的元素cij 改变为: c ′ ( i j ) = c ( i j ) − a i − b i ; a i 与 b i 为 常 数 c'(ij)=c(ij)-a_i-b_i;a_i与b_i为常数 c(ij)=c(ij)aibiaibi则C’=c’ij为效率矩阵的指派问题G’与G有相同的最优解

定理1与2则为匈牙利法的根基所在,他通过一定的操作将效率矩阵的部分元素化为0,如果存在一组0,这组0满足:1、0的个数等于矩阵的阶数(即等于任务数);2、这组0中任意两个0不同行不同列;那么这组0所对应的分配方式即为最优解
证明过程如下:
指派问题匈牙利解法以及其优化_第4张图片
个人理解:按照指派问题的定义,在效率矩阵中每行每列都有且仅有一个数,他相对于其他数小,则最终所耗最小

这里给一个简单的例子:
例:效率矩阵 C = [ 2 3 5 7 3 5 2 8 9 5 7 8 2 2 3 9 ] C= \begin{bmatrix} 2& 3 & 5&7 \\ 3&5&2&8 \\ 9&5&7&8 \\ 2&2&3&9\\ \end{bmatrix} C=2392355252737889
第1,2,3,4行分别减去2,2,5,2,得到:
C ‘ = [ 0 1 3 5 1 3 0 6 4 0 2 3 0 0 1 7 ] C‘= \begin{bmatrix} 0& 1 & 3&5 \\ 1&3&0&6 \\ 4&0&2&3 \\ 0&0&1&7\\ \end{bmatrix} C=0140130030215637
再对第四列减去3,得到:
C ‘ ′ = [ ( 0 ) 1 3 2 1 3 ( 0 ) 3 4 0 2 ( 0 ) 0 ( 0 ) 1 4 ] C‘'= \begin{bmatrix} (0)& 1 & 3&2 \\ 1&3&(0)&3\\ 4&0&2&(0) \\ 0&(0)&1&4\\ \end{bmatrix} C=(0)140130(0)3(0)2123(0)4
则显然X11=X23=X34=X42=1,是最优解,最小费用为2+2+8+2=14
##4、匈牙利解法步骤
在这之前先解释一下什么是独立0元素个数,设矩阵C中含有0元素,那么划去C中所有0元素所需的最少直线数等于C中独立0元素的个数。

指派问题匈牙利解法以及其优化_第5张图片
这里独立0个数为3
step 1:每行减去该行的最小数, 每列减去该列的最小数,使矩阵每行每列均有0元素
step 2:从单个0元素的行(列)开始,给0加圈,记作这里写图片描述,然后划去所在列(行)的其它0元素,记为;重复进行,直到处理完所有列(行)的单个0元素;
若还存在没有画圈的0元素(同行或同列中的0元素多于1个),则从剩余的0元素最少的行(列)开始,选0元素画圈,然后划掉同行同列的其它0元素,反复进行,直到所有0元素均被圈出或划掉为止;
这里写图片描述元素的数目m=n,则该指派问题的最优解已经得到,否则转入Step 3;

step3 设有 m小于n 个这里写图片描述, 找最少覆盖所有0的直线
1) 对没有这里写图片描述的行打√
2) 对已打√行中含所在列打√
3)对已打√列中含这里写图片描述◎所在行打√
4) 重复2)~3), 直至没有要打√的行和列为止 5) 对没有打√的行划横线, 对打√的列划竖线 得到最少覆盖所有0的直线数l。
若l小于n,则转Step 4;若l=n,则转Step 2重新派;
step 4 设未被这些直线覆盖的元素中的最小值为a。 对未划线的行减去a,划线的列加上a。转Step 2。

例:效率矩阵如下
指派问题匈牙利解法以及其优化_第6张图片
step 1:每行减去该行最小元素
指派问题匈牙利解法以及其优化_第7张图片
step 2和step 3:l<4,在没划线的元素里,最小元素为2
指派问题匈牙利解法以及其优化_第8张图片
step 4:未划线行减去2,划线列加2,并执行step 2
指派问题匈牙利解法以及其优化_第9张图片
所以我们得到2个最优指派方案: 1)甲—B ,乙—D,丙—E,丁—C,戊—A; 2)甲—B,乙—C,丙—E,丁—D,戊—A。所需总时间为 Min z=7+6+9+6+4=32单位时间。

5、匈牙利解法的优化

基本思想:
在进行step1时就使得step2出现的这里写图片描述元素个数m等于矩阵阶数n的几率为1的函数值达到最大。
具体步骤如下:
step 0:观察每行最小元素个数总和r(sum)和每列最小元素个数总和c(sum)。注意:这里说的每行最小元素个数总和中最小元素是在每行的前提下!
step 1:当 r(sum)>=c(sum),则先从系数矩阵的每列减去该列的最小元素,再从所得系数矩阵的每行元素中减去该行的最小元素。反之如果当
r(sum)<=c(sum),则先从系数矩阵的每行减去该行的最小元素,再从所得系数矩阵的每列元素中减去该列 的最小元素。
其他步骤同匈牙利法。

以上例作为参考:
[ 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 ] \begin{bmatrix} 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{bmatrix} 1287154791714109612677614610969109
在执行step0时,第一行最小元素为7,并且有两个;第二行最小元素为6,并且有三个;第三行最小元素为7,并且有一个;第四行最小元素为6,并且有两个;第五行最小元素为4,并且有一个;所以r(sum)=2+3+1+2+1=9;同理,c(sum)=1+1+2+2+1=7;所以应该先从系数矩阵的每列元素中减去该列的最小元素,再从所得系数矩阵的每行元素中减去该行的最小元素。
指派问题匈牙利解法以及其优化_第10张图片
通过step2,很容易得到:
指派问题匈牙利解法以及其优化_第11张图片
所以我们得到2个最优指派方案: 1)甲—B ,乙—D,丙—E,丁—C,戊—A; 2)甲—B,乙—C,丙—E,丁—D,戊—A。所需总时间为 Min z=7+6+9+6+4=32单位时间。

经过1340次这种实例分析,有1267次是步骤优化后大大减少了计算量,73次是本身就无法优化的问题,计算量等于原计算量。

参考文献:
袁迁.刘舒燕.YUAN Qian.LIU Shu-yan 关于匈牙利法的优化[期刊论文]-武汉理工大学学报2007(3)

你可能感兴趣的:(算法,算法,博客,优化)