匈牙利算法
定理一
设指派问题的效率矩阵为C=(cij)n×n,若将该矩阵的某一行或列的个元素都减去同一个常数t,得到新的效率矩阵C’=(c’ij)n×n,则以C’为效率矩阵的新指派问题与原指派问题的最优解相同,但其最优解比原最优解值减少t.
证明 根据指派问题的定义
z
′
=
∑
i
=
1
n
∑
j
=
1
n
c
i
j
′
x
i
j
z^{'}= \sum_{i=1}^n\sum_{j=1}^nc^{'}_{ij}x_{ij}
z′=i=1∑nj=1∑ncij′xij
= ∑ i = 1 , i ≠ k n ∑ j = 1 n c i j ′ x i j + ∑ j = 1 n c k j ′ x k j =\sum_{i=1,i≠k}^n\sum_{j=1}^nc^{'}_{ij}x_{ij}+\sum_{j=1}^nc^{'}_{kj}x_{kj} =i=1,i=k∑nj=1∑ncij′xij+j=1∑nckj′xkj
= ∑ i = 1 , i ≠ k n ∑ j = 1 n c i j x i j + ∑ j = 1 n ( c k j − t ) x k j =\sum_{i=1,i≠k}^n\sum_{j=1}^nc_{ij}x_{ij}+\sum_{j=1}^n(c_{kj}-t)x_{kj} =i=1,i=k∑nj=1∑ncijxij+j=1∑n(ckj−t)xkj
= ∑ i = 1 , i ≠ k n ∑ j = 1 n c i j x i j + ∑ j = 1 n c k j x k j − t ∑ j = 1 n x k j =\sum_{i=1,i≠k}^n\sum_{j=1}^nc_{ij}x_{ij}+\sum_{j=1}^nc_{kj}x_{kj}-t\sum_{j=1}^nx_{kj} =i=1,i=k∑nj=1∑ncijxij+j=1∑nckjxkj−tj=1∑nxkj
指派问题定义得第k个人只能在1...n项工作中选一个,所以最后一项为1 \text{指派问题定义得第k个人只能在1...n项工作中选一个,所以最后一项为1} 指派问题定义得第k个人只能在1...n项工作中选一个,所以最后一项为1
= z − t =z-t =z−t
定理2
若将指派问题的效率矩阵每一行及每一列分别减去其中得最小元素,则得到的新指派问题与原指派问题有相同得最优解。
新的C’中出现的元素c’ij=0表示第i个人去干第j项工作效率最好
独立零元素: 在效率矩阵C中,有一组处在不同行不同列的零元素,称为独立零元素组,此时其中每个元素称为独立零元素
例1:由效率矩阵得独立零元素组确定最优指派问题
C
=
[
5
0
2
0
2
3
0
0
0
5
6
7
4
8
0
0
]
C=\begin{bmatrix} 5 & 0 & 2 & 0\\ 2 & 3 & 0 & 0 \\ 0 & 5 & 6 & 7 \\ 4 & 8 & 0& 0 \end{bmatrix}
C=⎣⎢⎢⎡5204035820600070⎦⎥⎥⎤
$
X_{(1)}=\begin{bmatrix}
0 & 1 & 0 & 0\
0 & 0 & 0 & 1 \
1 & 0 & 0 & 0 \
0 & 0 & 1& 0
\end{bmatrix}
$
但有的问题中发现效率矩阵C独立零元素的个数不到n个,这样就无法求到最优指派方案,需要进一步的分析
定理3:效率矩阵C中独立零元素的最多个数等于能覆盖所有零元素的最少直线条数
例2:现有一个5×5的指派问题,其效率矩阵如下,求该指派问题
C
=
[
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=\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}
C=⎣⎢⎢⎢⎢⎡1287154791714109612677614610969109⎦⎥⎥⎥⎥⎤
匈牙利算法的求解步骤
① 变化效率矩阵,将各行各列都减去当前各行各列的最小元素
得到
C
1
=
[
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
]
C_{1}=\begin{bmatrix} 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{bmatrix}
C1=⎣⎢⎢⎢⎢⎡52090031086205030070620245⎦⎥⎥⎥⎥⎤
② 用圈零法求出新矩阵C1中独立零元素
- 进行行检验:对C1进行逐行检查,每行只有一个未标记的零元素时,用⚪将该元素圈起,然后将被圈起的零元素所在列的其他未标记的零元素用记号×划去 重复进行行检验直到每一行都没有未被标记的零元素或至少有两个未被标记的零元素为止
- 进行列检验:与行检验类似
③针对出现的3种情况进行试指派:
1每行具有圈0,个数m=n,则得到最优解
2存在未被标记的零元素,但他们所在行列中,未被标记的零元素均至少有两个,可得到最优解
3不存在违背标记过的零元素,但圈0个数m<n 进入第4步
④做最少直线覆盖当前所有零元素
(1)对C3中所有不含圈0元素的行打√
(2)对打√的行中所有零元素所在列打√
(3)对所有打√列中圈0元素所在行打√
(4)重复上述第(2)和(3)步,直到不能继续为止
(5)对未打√的每一行画一直线,对已打√的每一列画一纵线
⑤对矩阵C4做进一步交换以增加0元素
在未被直线覆盖过的元素中找出最小元素,将打√行的各元素减去这个最小元素,将打√列的个元素加上这个最小元素,(以避免出现负元素)注 这里的打√指的是第4步中的操作
⑥对已增加独立零元素的矩阵回到第2步再进行操作,知道出现圈0的个数m=n为止
如果是最大化指派问题
m a x ∑ i = 1 n ∑ j = 1 n c i j x i j max \sum_{i=1}^n\sum_{j=1}^nc_{ij}x_{ij} maxi=1∑nj=1∑ncijxij
s . t . ∑ j = 1 n = 1 s.t. \sum_{j=1}^n=1 s.t.j=1∑n=1
∑ i = 1 n = 1 \sum_{i=1}^n=1 i=1∑n=1
x i j = 0 或 1 x_{ij}=0或1 xij=0或1
m a x z = ∑ i = 1 n ∑ j = 1 n c i j x i j ⇒ m i n ( − z ) = ∑ i = 1 n ∑ j = 1 n ( − c i j ) x i j max \: z=\sum_{i=1}^n\sum_{j=1}^nc_{ij}x_{ij}\Rightarrow min \: (-z)=\sum_{i=1}^n\sum_{j=1}^n(-c_{ij})x_{ij} maxz=i=1∑nj=1∑ncijxij⇒min(−z)=i=1∑nj=1∑n(−cij)xij
不能直接使用匈牙利算法,因为它要求每个元素都非负
进行转化 在效率矩阵中找出一个最大元素M,并令
b
i
j
=
M
−
c
i
j
i
,
j
=
1
,
2
,
.
.
.
,
n
b_{ij}=M-c_{ij} \:\: i,j=1,2,...,n
bij=M−ciji,j=1,2,...,n
不难发现这两个问题等价