匈牙利算法--過程圖解
轉自:http://wanzhenjie88.blog.163.com/blog/static/4066646920077131486697/
轉載:
以下算法可把G中任一匹配M擴充為最大匹配,此算法是Edmonds於1965年提出的,被稱為匈牙利算法,其步驟如下:
(1)首先用(*)標記X中所有的非M-頂點,然后交替進行步驟(2),(3)。
(2)選取一個剛標記(用(*)或在步驟(3)中用(yi)標記)過的X中頂點,例如頂點xi,然后用(xi)去標記Y中頂點y,如果xi與y為同一非匹配邊的兩端點,且在本步驟中y尚未被標記過。重復步驟(2),直至對剛標記過的X中頂點全部完成一遍上述過程。
(3)選取一個剛標記(在步驟(2)中用(xi)標記)過的Y中結點,例如yi,用(yi)去標記X中結點x,如果yi與x為同一匹配邊的兩端點,且在本步驟中x尚未被標記過。重復步驟(3),直至對剛標記過的Y中結點全部完成一遍上述過程。
(2),(3)交替執行,直到下述情況之一出現為止:
(Ⅰ)標記到一個Y中頂點y,它不是M-頂點。這時從y出發循標記回溯,直到(*)標記的X中頂點x,我們求得一條交替鏈。設其長度為2k+1,顯然其中k條是匹配邊,k+1條是非匹配邊。
(Ⅱ)步驟(2)或(3)找不到可標記結點,而又不是情況(Ⅰ)。
(4)當(2),(3)步驟中斷於情況(Ⅰ),則將交替鏈中非匹配邊改為匹配邊,原匹配邊改為非匹配邊(從而得到一個比原匹配多一條邊的新匹配),回到步驟(1),同時消除一切現有標記。
(5)對一切可能,(2)和(3)步驟均中斷於情況(Ⅱ),或步驟(1)無可標記結點,算法終止(算法找不到交替鏈)。
我們不打算證明算法的正確性,只用一個例子跟蹤一下算法的執行,來直觀地說明這一點。

(1)置M = Æ,對x1-x6標記(*)。
(2)找到交替鏈(x1, y1)(由標記(x1),(*)回溯得),置M = {(x1, y1)}。
(3)找到交替鏈(x2, y2)(由標記(x2),(*)回溯得),置M = {(x1, y1), (x2, y2),}。
(4)找到交替鏈(x3, y1, x1, y4)(如圖9.4所示。圖中虛線表示非匹配邊,細實線表示交替鏈中非匹配邊,粗實線表示匹配邊),因而得M = {(x2, y2), (x3, y1),(x1, y4)}。
(5)找到交替鏈(x4, y3)(由標記(x4),(*)回溯得),置M = {(x2, y2), (x3, y1),(x1, y4), (x4, y3)}。
(6)找到交替鏈(x5, y4, x1, y1, x3, y7)(如圖9.5所示,圖中各種線段的意義同上),因而得
M = {(x2, y2), (x4, y3),(x5, y4), (x1, y1), (x3, y7)}
即為最大匹配(如圖9.6所示)。
