指派问题与匈牙利法讲解
指派問題概述:
實際中,會遇到這樣的問題,有n項不同的任務,需要n個人分別完成其中的1項,每個人完成任務的時間不一樣。于是就有一個問題,如何分配任務使得花費時間最少。
通俗來講,就是n*n矩陣中,選取n個元素,每行每列各有1個元素,使得和最小。
如下圖:
指派問題性質:
指派問題的最優解有這樣一個性質,若從矩陣的一行(列)各元素中分別減去該行(列)的最小元素,得到歸約矩陣,其最優解和原矩陣的最優解相同.
匈牙利法:
12 | 7 | 9 | 7 | 9 |
8 | 9 | 6 | 6 | 6 |
7 | 17 | 12 | 14 | 9 |
15 | 14 | 6 | 6 | 10 |
4 | 10 | 7 | 10 | 9 |
1.行歸約:
每行元素減去該行的最小元素
5 | 0 | 2 | 0 | 2 |
2 | 3 | 0 | 0 | 0 |
0 | 10 | 5 | 7 | 2 |
9 | 8 | 0 | 0 | 4 |
0 | 6 | 3 | 6 | 5 |
2.列歸約:
每列元素減去該列的最小元素
5 | 0 | 2 | 0 | 2 |
2 | 3 | 0 | 0 | 0 |
0 | 10 | 5 | 7 | 2 |
9 | 8 | 0 | 0 | 4 |
0 | 6 | 3 | 6 | 5 |
3.試指派:
(1)找到未被畫線的含0元素最少的行列,即,遍歷所有未被畫線的0元素,看下該0元素所在的行列一共有多少個0,最終選取最少個數的那個0元素。
(2)找到該行列中未被畫線的0元素,這就是一個獨立0元素。對該0元素所在行和列畫線。
5 | 0 | 2 | 0 | 2 |
2 | 3 | 0 | 0 | 0 |
0 | 10 | 5 | 7 | 2 |
9 | 8 | 0 | 0 | 4 |
0 | 6 | 3 | 6 | 5 |
5 | 0 | 2 | 0 | 2 |
2 | 3 | 0 | 0 | 0 |
0 | 10 | 5 | 7 | 2 |
9 | 8 | 0 | 0 | 4 |
0 | 6 | 3 | 6 | 5 |
5 | 0 | 2 | 0 | 2 |
2 | 3 | 0 | 0 | 0 |
0 | 10 | 5 | 7 | 2 |
9 | 8 | 0 | 0 | 4 |
0 | 6 | 3 | 6 | 5 |
5 | 0 | 2 | 0 | 2 |
2 | 3 | 0 | 0 | 0 |
0 | 10 | 5 | 7 | 2 |
9 | 8 | 0 | 0 | 4 |
0 | 6 | 3 | 6 | 5 |
(3)暫時不看被線覆蓋的元素,重復(1)(2)直到沒有線可以畫。
(4)根據(2)找到的0元素個數判斷,找到n個獨立0元素則Success,小于n個則Fail.(本例子中,n=5,可以看到,第一次試指派之后,獨立0元素有4個,不符合)
4.畫蓋0線:
目標:做最少的直線數覆蓋所有0元素,直線數就是獨立0元素的個數。
注意:這跟3的線不同;不能用貪心法去畫線,比如
1 0 0
1 1 0
1 0 1
若先畫橫的,則得畫3條線,實際只需2條;若先畫豎的,將矩陣轉置后同理。
步驟3得出的獨立0元素的位置
5 | 0 | 2 | 0 | 2 |
2 | 3 | 0 | 0 | 0 |
0 | 10 | 5 | 7 | 2 |
9 | 8 | 0 | 0 | 4 |
0 | 6 | 3 | 6 | 5 |
(1)對沒有獨立0元素的行打勾、
(2)對打勾的行所含0元素的列打勾
(3)對所有打勾的列中所含獨立0元素的行打勾
(4)重復(2)(3)直到沒有不能再打勾
(5)對打勾的列和沒有打勾的行畫畫線,這就是最小蓋0線。
5 | 0 | 2 | 0 | 2 | |
2 | 3 | 0 | 0 | 0 | |
0 | 10 | 5 | 7 | 2 | √ |
9 | 8 | 0 | 0 | 4 | |
0 | 6 | 3 | 6 | 5 | √ |
√ |
5 | 0 | 2 | 0 | 2 | |
2 | 3 | 0 | 0 | 0 | |
0 | 10 | 5 | 7 | 2 | √ |
9 | 8 | 0 | 0 | 4 | |
0 | 6 | 3 | 6 | 5 | √ |
√ |
5.更新矩陣:
(1)對沒有被線劃到的數中,找到最小的數。
(2)對沒有被線劃到的數中,減去最小的數。
(3)對被2條線劃到的數中,加上最小的數。
7 | 0 | 2 | 0 | 2 |
4 | 3 | 0 | 0 | 0 |
0 | 8 | 3 | 5 | 0 |
11 | 8 | 0 | 0 | 4 |
0 | 4 | 1 | 4 | 3 |
6.重復3-5直到成功。
0 | 1 | 0 | 0 | 0 |
0 | 0 | 1 | 0 | 0 |
0 | 0 | 0 | 0 | 1 |
0 | 0 | 0 | 1 | 0 |
1 | 0 | 0 | 0 | 0 |
sum = 7+6+9+6+4 = 32
匈牙利算法(Hungarian Algorithm)
分配問題:假設有N個人N個任務,每個任務可以分配給任意不同的人,不同的人對不同的任務需要花費的代價也不相同,那么如何分配才能使花費總代價最少。假設現在有三個任務,三個人,每個人完成每個任務的代價矩陣如下(代價可以是時間或者金錢等):
怎么才能找到一個分配方法使得任務花費代價最小呢?
匈牙利算法就是用來解決分配問題的一種方法,它基于理論:如果代價矩陣的某一行或某一列同時加或減某個數,則這個新的代價矩陣的最優分配任然是原代價矩陣的最優分配。
算法步驟(假設矩陣為NxN方陣):
1.對于矩陣的每一行,減去其中最小的元素
2.對于矩陣的每一列,減去其中最小的元素
3.用最少的水平線或垂直線覆蓋矩陣中所有的0
4.如果線的數量等于N,則找到了最優分配,算法結束,否則進入步驟5
5.找到沒有被任何線覆蓋的最小元素,每個沒被線覆蓋的行減去這個元素,個被線覆蓋的列加上這個元素,返回步驟3
繼續拿上面的例子演示:
1.每一行減去其最小元素得到:
2.每一列減去其最小元素得到:
3.用最少的水平線或者垂直線覆蓋所有的0得到:
4.線的數量為2,小于3,進入第五步:
5.現在沒被覆蓋的最小元素是5,沒被覆蓋的行(第一和第二行)減去5,得到:
6.被覆蓋的列(第一列)加上5,得到:
7.回到步驟3,用最少的線覆蓋所有0:
8.線的數量=3,算法結束,很顯然,第一個任務給第二人,第二個任務給第一人,第三個任務給第三人,總代價最小(0+0+0):
9.所以原矩陣最小代價為(40+20+25=85):
總結
以上是生活随笔為你收集整理的指派问题与匈牙利法讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Baumer工业相机堡盟工业相机如何通过
- 下一篇: Java语言-小学数学练习