這篇部落格介紹了匈牙利演算法的操作步驟,不討論原理。
作用解決指派問題。所謂的指派問題就比如:甲乙丙三個人去做abc三件事情。每個人做每件事情所花的時間可能不一樣。每個人只能安排一件事情,問怎樣安排才能使三個人所工作的時間之和最小?
擴充套件成 n 個人 n 件事也可以,但要求是: 例項
甲乙丙中第i (i=1,2,3)
個人做abc中第j (j=1,2,3)
件事的時間為 aij。矩陣 a 如下
2 3 4
3 4 6
5 6 1
就是說甲做a事情要2分鐘,做b事情要3分鐘; 乙做c事情要6分鐘,以此類推。問怎樣安排才能使甲乙丙三人所用的時間最少?
下面用匈牙利演算法來解。
演算法目標
讓矩陣中出現 n 個滿足不同行不同列的 0。 上述問題就是要3個不同行不同列的0.
步驟概括
每行減去此行最小數
判斷是否達到演算法目標,如未達到演算法目標,繼續下一步。否則結束。
橫縱交替,從行開始。找出所有還沒有選中0
的行(具體見步驟例項),在此行後面打鉤; 把此行中有0
的列全打鉤。在打鉤的列中,如果有零,又在有0
的行打鉤,如此交替,直到不能再打鉤。
在沒有打鉤的行和打鉤的列上劃線,會得到發現所有的0
已經被劃去,如果沒有劃去,請檢查前面的步驟。此時剩下的所有元素中,找到最小值,就記為min
吧。
在第4步畫線的行減去min
(此時原來的0
變成-min
),再在畫線的列加上min
(此時矩陣中沒有了負數)。回到第 2 步。
步驟例項
對於之前的矩陣
2 3 4
3 4 6
5 6 1
每行減去此行最小值,由(1)變成(2),如圖:
2. 檢查發現沒有達到演算法目標,因為(2)中只有兩個不同行不同列的0
,圖中紅色的0
。沒有達到演算法目標。
3. 找出沒有選中0
的行,在後面畫勾,如圖(3)。
此行的0
在第1列,在第 1 列畫勾,如圖(4),發現第 1 列有兩個 0,其中第一行的 0 還沒有畫勾,於是在第 1 行後畫勾,如圖(5)。此時沒有勾可畫了,進行下一步。
4. 在沒有打鉤的行,即第 3 行,和打鉤的列,即第 1 列,劃線,會得到發現所有的0
已經被劃去。然後找出最小值min,此處min = 1
。如圖(6)
5. 在第4步未畫線的行減去min
,即在第1、2行減去 1,結果如圖(7)。再在畫線的列加上min
,即在第 1 列加上 1,結果如圖(8)。
6. 判斷發現(8)滿足演算法目標,當然也有圖(9)滿足演算法目標。
最後一公里
如圖(8),第1、2、3行的 0 分別在相應行的第 1 、2、3個,所以第 1 個人做第 1 件事,第 2 個人做第 2 件事,第 3 個人做第 3 件事。
圖(9)對應的是第 1 個人做第 2 件事,第 2 個人做第 1 件事,第 3 個人做第 3 件事。
帶入圖(1)計算可以知圖(8)和圖(9)所用的時間相同,都是(2+4+1 = 7)或 (3+3+1 = 7)分鐘。
我們把圖(8)和圖(9)的結果分別寫成
1 2 3
1 2 3
1 2 3
2 1 3
總結
要想最快掌握匈牙利演算法,就在看完我這篇部落格後自己默寫一篇。我就是這樣做的,現在感覺很好。教別人是一種很好的學習方式,沒人教就自己寫寫部落格分享嘍!你也可以自己算乙個例子試試,其實我已經幫你想好了:對於下面的矩陣,求最少工作量。(希望在你的手機或電腦螢幕上也能看到的矩陣排列得整齊,美感總是很重要的)
5 7 11 5 7
4 8 3 2 2
5 4 6 10 7
10 12 11 10 10
3 7 8 4 5
我得出的結果如下,也未必對,我沒有檢查:
1 2 3 4 5
4 5 2 3 1
文中若有不足之處,歡迎指正。 匈牙利演算法
匈牙利演算法 edmonds演算法 步聚 1 首先用 標記x中所有的非m頂點,然後交替進行步驟 2 3 2 選取乙個剛標記 用 或在步驟 3 中用 yi 標記 過的x中頂點,例如頂點xi,如果xi與y為同一非匹配邊的兩端點,且在本步驟中y尚未被標記過,則用 xi 去標記y中頂點y。重複步驟 2 直至...
匈牙利演算法
匈牙利演算法用來解決二分圖的最大匹配問題。乙個典型的最大匹配問題的描述如下 乙個公司有n項工作,m個員工。每個員工能勝任n項工作中的幾項 0 n 工作。問題是,如何分配才能使得被處理的工作數最大。當然,如果公司裡人員很多,每項工作都有很多員工可以勝任,那麼使每項工作都有人處理的方案是顯而易見的。但遇...
匈牙利演算法
二分圖匹配的演算法,二分圖就是把圖上的點分成兩個互不相交的點集,而圖中的邊的端點只能分別屬於這兩個點集.二分圖的匹配,就是婚配問題,左邊的點集男性,右邊的點集女性,然後相互配對 一夫一妻 最大匹配就是讓好事最多.匈牙利演算法可以實現這個東西.匈牙利演算法怎麼實現的這個東西.這個比較多.如下 incl...