詳細介紹匈牙利算法步驟

這篇博客介紹了匈牙利算法的操作步驟,不討論原理。

作用

解決指派問題。所謂的指派問題就比如:甲乙丙三個人去做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.

步驟概括

  1. 每行減去此行最小數
  2. 判斷是否達到算法目標,如未達到算法目標,繼續下一步。否則結束。
  3. 橫縱交替,從行開始。找出所有還沒有選中0的行(具體見步驟實例),在此行後面打鉤; 把此行中有0的列全打鉤。在打鉤的列中,如果有零,又在有0的行打鉤,如此交替,直到不能再打鉤。
  4. 沒有打鉤的行和打鉤的列上劃線,會得到發現所有的0已經被劃去,如果沒有劃去,請檢查前面的步驟。此時剩下的所有元素中,找到最小值,就記爲min吧。
  5. 在第4步畫線的行減去min(此時原來的0變成-min),再在畫線的列加上min(此時矩陣中沒有了負數)。回到第 2 步。

步驟實例

對於之前的矩陣

2 3 4
3 4 6
5 6 1
  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

文中若有不足之處,歡迎指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章