匈牙利算法
Hungarian Algorithm
The Hungarian matching algorithm , also called the Kuhn-Munkres algorithm, is a $O\big(|V|^3\big)$algorithm that can be used to find maximum-weight matchings in bipartite graphs , which is sometimes called the assignment problem . A bipartite graph can easily be represented by an adj matrix, where the weights of edges are the entries. Thinking about the graph in terms of an adjacency matrix is useful for the Hungarian algorithm.
The Hungarian Algorithm for Graphs
Given: the labeling $l$, an equality graph $G_l=(V, E_l)$, an initial matching $M$ in $G_l$, and an unmatched vertex $u \in V$ and $u \notin M$
Augmenting the matching
-
A path is augmenting for $M$ in $G_l$ if it alternates between edges in the matching and edges not in the matching, and the first and last vertices are free vertices, or unmatched, in $M$. We will keep track of a candidate augmenting path starting at the vertex $u$.
-
If the algorithm finds an unmatched vertex $v$, add on to the existing augmenting path $p$ by adding the $u$ to $v$ segment.
-
Flip the matching by replacing the edges in $M$ with the edges in the augmenting path that are not in $M$ (in other words, the edges in $\left.E_l-M\right)$.
Improving the labeling
- $S \subseteq X$ and $T \subseteq Y$, where $S$ and $T$ represent the candidate augmenting alternating path between the matching and the edges not in the matching.
- Let $N_l(S)$ be the neighbors to each node that is in $S$ along edges in $E_l$ such that $N_l(S)=\{v \mid \forall u \in S:(u, v) \in E_l\}$.
- If $N_{l}(S)=T$, then we cannot increase the size of the alternating path (and therefore can’t further augment), so we need to improve the labeling.
- Let $\delta_{l}$ be the minimum of $l(u)+l(v)-w(u, v)$ over all of the $u \in S$ and $v \notin T$.
- Improve the labeling $l$ to $l^{\prime}$ :
-
If $r \in S$, then $l^{\prime}®=l®-\delta_{l}$,
-
If $r \in T$, then $l^{\prime}®=l®+\delta_{l}$.
-
If $r \notin S$ and $r \notin T$, then $l^{\prime}®=l®$.
$l^{\prime}$ is a valid labeling and $E_{l} \subset E_{l^{\prime}}$.
Putting it all together: The Hungarian Algorithm
- Start with some matching $M$, a valid labeling $l$, where $l$ is defined as the labelling $\forall x \in X, y \in Y \mid l(y)=0, l(x)=\max _{y \in Y}(w(x, y))$.
- Do these steps until a perfect matching is found (when $M$ is perfect):
- (a) Look for an augmenting path in $M$.
- (b) If an augmenting path does not exist, improve the labeling and then go back to step (a).
Python Implementation:
1 | TOLERANCE = 1e-6 # everything below is considered zero |