最近有需求,想了解一下匈牙利算法。
把自己的理解记录一下,大家一起交流学习。主要参考:
http://www.cse.ust.hk/~golin/COMP572/Notes/Matching.pdf
1 问题定义
左边有一堆工人,右边有一堆工作;每个工人只能选一个工作,每个工作只能一个工人去做,要怎样去匹配工人和工作把这个收益最大化。
上述为二分图(Bipartite Graph 大家可以自行Google),由点(Vertex)和边(Edge)组成。
不失一般性,假设一些虚拟工人、工作、以及工人与工作的连线,用虚线表示且对应的收益为0,将原图扩展成一个Complete Weighted Graph。
(后面考虑均为Complete Weighted Graph,为了描述清晰省略虚拟边。)
2 Kuhn-Munkres Theorem
匈牙利算法两个最重要的点:1)用点的收益代替边的收益,对问题进行转换;2)Kuhn-Munkres理论告诉我们什么时候可以找到最优匹配。
给点打标(Label),一个label l l l 表示给所有点标上一个值;如果 l ( x ) + l ( y ) ≥ w ( x , y ) , ∀ x , y ∈ V l(x) + l(y) \geq w(x,y), \forall x,y \in V l(x)+l(y)≥w(x,y),∀x,y∈V 成立,称这个标为Feasible Label。
给定Feasible Label l l l, E l E_l El为边的集合, E l = { ( x , y ) ∣ l ( x ) + l ( y ) = w ( x , y ) } E_l = \{(x,y) | l(x) + l(y) = w(x,y) \} El={(x,y)∣l(x)+l(y)=w(x,y)}。下图给了两个Feasible标 l 1 , l 2 l_1, l_2 l1,l2,以及对应的 E l 1 , E l 2 E_{l_1}, E_{l_2} El1,El2。
如果对应的匹配 ( x , y ) ∈ E l (x,y) \in E_l (x,y)∈El,则可以用两个点的label之和代替边的收益,即 l ( x ) + l ( y ) = w ( x , y ) l(x)+l(y)=w(x,y) l(x)+l(y)=w(x,y)。
如果给每个工人都匹配了一个工作,我们称为Perfect Matching;如果这个匹配的收益是最大的,我们称之为Optimal Matching。
上图最右是一个Feasible Label以及对应的
E
l
E_l
El,其中绿色的边表示一个Optimal Matching。
下面给出本文最重要的一个定理:
Theorem[Kuhn-Munkres]: 给定Feasible label l l l ,如果 M M M一个Perfect Matching并且 M ⊂ E l M \subset E_l M⊂El,那么 M M M也是Optimal Matching。
上述定理不难证明。因为 l l l 是Feasible label,任意其他匹配 M ′ M^\prime M′, w ( M ′ ) ≤ ∑ x ∈ V l ( x ) = w ( M ) w(M^\prime) \leq \sum_{x \in V} l(x) = w(M) w(M′)≤∑x∈Vl(x)=w(M)。
3 问题思考
如何找到一个Feasible Label l l l,并在对应的 E l E_l El中找到一个Perfect Matching,因为不是每个Feasible Label(如上图中)都能找到一个Perfect Matching。
不失一般性,从下图左开始,用左边每个点的最大收益给其打标 l l l。依次给 X 3 , X 2 X_3, X_2 X3,X2匹配 Y 1 , Y 2 Y_1, Y_2 Y1,Y2,当匹配 X 1 X_1 X1时发现 Y 2 Y_2 Y2已经被占用。这个时候有两个选择,1) X 1 X_1 X1换一个匹配;2) X 1 X_1 X1抢占 Y 2 Y_2 Y2, X 2 X_2 X2换一个匹配。
如下图中,存在四种选择,但要确保选择是当前最优的一种选择,且选择之后仍然存在一个Feasible Label l ′ l^\prime l′,所有的匹配仍在 E l ′ E_{l^\prime} El′中。
3.1 Improve Label
令
S
=
{
X
1
,
X
2
}
,
T
=
{
Y
2
}
S=\{X_1,X_2\}, T=\{Y_2\}
S={X1,X2},T={Y2};
令
Δ
=
m
i
n
x
∈
S
,
y
∉
T
{
l
(
x
)
+
l
(
y
)
−
w
(
x
,
y
)
}
\Delta = min_{x \in S,y \notin T }\{l(x)+l(y)-w(x,y)\}
Δ=minx∈S,y∈/T{l(x)+l(y)−w(x,y)};
l
′
(
v
)
=
{
l
(
v
)
−
Δ
v
∈
S
l
(
v
)
+
Δ
v
∈
T
l
(
v
)
o
t
h
e
r
w
i
s
e
l^\prime(v)= \begin{cases} l(v) - \Delta & v \in S\\ l(v) + \Delta & v \in T\\ l(v) & otherwise \end{cases}
l′(v)=⎩⎪⎨⎪⎧l(v)−Δl(v)+Δl(v)v∈Sv∈Totherwise
根据上述操作,找到点 Y 3 Y_3 Y3对应的边, Δ = l ( X 2 ) + l ( Y 2 ) − w ( X 2 , Y 3 ) = 2 \Delta = l(X_2)+l(Y_2)-w(X_2,Y_3)=2 Δ=l(X2)+l(Y2)−w(X2,Y3)=2。更新 X 1 , X 2 , Y 2 X_1,X_2,Y_2 X1,X2,Y2的label得到 l ′ l^\prime l′,如下图右。
由 l → l ′ l \rightarrow l^\prime l→l′, l ′ l^\prime l′仍是一个Feasible label,且 E l ′ E_{l^\prime} El′与 E l E_l El相比,多了一条边如下图右(可能多条);其他已有匹配不变, { l ( x ) + l ( y ) = w ( x , y ) , ∀ ( x , y ) ∈ M } \{l(x)+l(y)=w(x,y),\forall(x,y) \in M\} {l(x)+l(y)=w(x,y),∀(x,y)∈M}。
3.2 解题思路
以上图为例子,介绍解题思路。
-
选取 x x x为某个未匹配的点, S S S为 x x x在 E l E_l El中左侧关联点的集合, T T T为 x x x在 E l E_l El中右侧关联点的集合。
如上图 X 1 X_1 X1为未匹配的点,其中上图中, S = { X 1 , X 2 } , T = { Y 2 } S=\{X_1,X_2\}, T=\{Y_2\} S={X1,X2},T={Y2};上图右, S = { X 1 , X 2 } , T = { Y 2 , Y 3 } S=\{X_1,X_2\}, T=\{Y_2,Y_3\} S={X1,X2},T={Y2,Y3} -
如果存在 y ∈ T y \in T y∈T没有配匹配,则我们一定能找到 p a t h = x → y 1 → x 1 → y 2 → x 2 → . . . → y n → x n → y path=x \rightarrow y_1 \rightarrow x_1 \rightarrow y_2 \rightarrow x_2\rightarrow ... \rightarrow y_n \rightarrow x_n \rightarrow y path=x→y1→x1→y2→x2→...→yn→xn→y,然后给 x x x找到匹配。
(如上图右, p a t h = X 1 → Y 2 → X 2 → Y 3 , path=X_1 \rightarrow Y_2 \rightarrow X_2 \rightarrow Y_3, path=X1→Y2→X2→Y3,令 X 1 X_1 X1匹配 Y 2 Y_2 Y2, X 2 X_2 X2匹配 Y 3 Y_3 Y3) -
如果所有 y ∈ T y \in T y∈T都有匹配,我们一定能找到 Δ = m i n x ∈ S , y ∉ T { l ( x ) + l ( y ) − w ( x , y ) } \Delta = min_{x \in S,y \notin T }\{l(x)+l(y)-w(x,y)\} Δ=minx∈S,y∈/T{l(x)+l(y)−w(x,y)}和对应的点 y ′ ∉ T y^\prime \notin T y′∈/T ;
Improve label l → l ′ l \rightarrow l^\prime l→l′,更新 S S S和 T T T(把 y ′ y^\prime y′加入 T T T),回到步骤0。
(如上图中,找到 Δ = 2 \Delta = 2 Δ=2和点 Y 3 Y_3 Y3)
通过Improve Label操作,我们总是能增加一个点 y ′ ∉ T y^\prime \notin T y′∈/T到集合 T T T,重复直到集合 T = Y T=Y T=Y,那么一定存在一个点 y ∈ T y \in T y∈T没有被匹配,那么我们一定能找到一条path让 x x x找到匹配。
所以每次迭代,最多进行
V
V
V次Improve Label操作,我们就能在某个Feasible lable对应的
E
l
E_l
El中,为
x
x
x找到匹配。
迭代
V
V
V次,即可为每个点
x
x
x找到匹配。这样我们找到了某个
E
l
E_l
El下的Perfect Matching,即Optimal Matching。
4 匈牙利算法
给定Feasible lable
l
l
l 和对应的
E
l
E_l
El。
定义点
u
∈
V
u \in V
u∈V的邻居点集合:
N
l
(
u
)
=
{
v
∣
(
u
,
v
)
∈
E
l
}
N_l(u)=\{v | (u, v) \in E_l\}
Nl(u)={v∣(u,v)∈El};
定义点集合
S
⊂
V
S \subset V
S⊂V的邻居点集合:
N
l
(
S
)
=
∪
u
∈
S
N
l
(
u
)
N_l(S)=\cup_{u \in S}N_l(u)
Nl(S)=∪u∈SNl(u);
- 初始化label l,在 E l E_l El下初始化匹配M
- 如果M是perfect matching,找到最优解;
否则,选择一个未匹配的点 x ∈ X x \in X x∈X,令 S = { x } , Y = { ∅ } S=\{x\},Y=\{\empty \} S={x},Y={∅}- 如果 N l ( s ) = T N_l(s) = T Nl(s)=T,找到 Δ = m i n x ∈ S , y ∉ T { l ( x ) + l ( y ) − w ( x , y ) } \Delta = min_{x \in S,y \notin T }\{l(x)+l(y)-w(x,y)\} Δ=minx∈S,y∈/T{l(x)+l(y)−w(x,y)},improve l → l ′ l \rightarrow l^\prime l→l′;
如果 N l ( s ) ≠ T N_l(s) \neq T Nl(s)=T,选一个 y ∉ T y \notin T y∈/T
- 如果 y y y没有被匹配,找一条path,为 x x x找到匹配,回到步骤2
- 如果 y y y与 z z z匹配,更新 S = S ∪ { z } S=S \cup \{z\} S=S∪{z}, T = T ∪ { y } T=T \cup \{y\} T=T∪{y},回到步骤3
5复杂度分析
每次迭代,为一个点 x x x找到匹配 O ( V ) O(V) O(V)。
为 x x x找匹配时,Improve Label会增加一点进 T T T,最多更新 V V V次, O ( V ) O(V) O(V)。
Improve Label时,需要找到 Δ = m i n x ∈ S , y ∉ T { l ( x ) + l ( y ) − w ( x , y ) } \Delta = min_{x \in S,y \notin T }\{l(x)+l(y)-w(x,y)\} Δ=minx∈S,y∈/T{l(x)+l(y)−w(x,y)}, O ( V ) O(V) O(V)。
总是,算法复杂度为 O ( V 3 ) O(V^3) O(V3)。