KM算法(理解篇)


轉載:https://www.cnblogs.com/logosG/p/logos.html(很好,很容易理解)

一、匈牙利算法

匈牙利算法用於解決什么問題?

匈牙利算法用於解決二分圖的最大匹配問題。

什么是二分圖?我們不妨來考慮這樣一個問題,在一家公司里,有員工A,B,C,有三種工作a,b,c,如果員工和工作之間有線相連,則代表員工能勝任這份工作。

figure1.1

如圖所示,員工A能勝任a,c工作,員工B能勝任a,b,c工作,而員工C只能勝任c工作。

上圖就是所謂的“二分圖”(請忽略圖中箭頭),簡單的說,上圖可划分為兩個集合{員工},{工作},兩個集合之間的元素可以相連,同一個集合內的元素不能相連。

下面請解決這樣一個問題:請給出一個方案,讓盡可能多的員工有不同的工作做。“匈牙利算法”的出現就是為了解決這個問題。

下面給出這個問題的解決方案:(讀者看到這里可能會想,解決這個問題不是很簡單嗎?A→a,B→b,C→c不就好了?請注意:任何算法的給出都是為了規整化一個問題的解決步驟,其目的是為了在問題規模越來越大時算法對其仍然適用,如果公司有10個員工或者更多,讀者想必不能一眼看出答案,此時,算法的作用便體現出來了。)

我們先幫A找工作做,不妨先幫A連上a(紅線表示此時兩者已經匹配),表示A去做a工作。

  

接下來我們幫B找工作做,B的第一條線跟a相連,B也想做工作a。

這時候就發生了沖突(collision),如何解決呢?

匈牙利算法”指出 通過一條增廣路徑,通過取反操作,我們就能匹配更多的點。

什么是增廣路徑?增廣路徑是指,由一個未匹配的頂點開始,經過若干個匹配頂點,最后到達對面集合的一個未匹配頂點的路徑,即這條路徑將兩個不同集合的兩個未匹配頂點通過一系列匹配頂點相連。

比如此題中,B想做工作a,於是A想着換一個工作,我們連上A,c。

 

如圖,B→a→A→c 其中B,c未匹配,A,a已匹配,按照定義,這就是一條增廣路徑,我們對其進行取反操作,就變成了下圖。

 

取反操作為我們帶來了什么?原本只有一邊匹配,現在有兩邊匹配了,而且沖突也解決了,這就是匈牙利算法的妙處,我們能通過不停的尋找這樣一條增廣路徑,從而找到二分圖的最大匹配

下面我們繼續尋找增廣路徑。

最終,我們得到了一個最大匹配:A匹配a,B匹配b,C匹配c,就算集合中的元素很多很多,我們仍能通過匈牙利算法得到該二分圖的最大匹配。

二、KM算法


現在我們來考慮另外一個問題:如果每個員工做每件工作的效率各不相同,我們如何得到一個最優匹配使得整個公司的工作效率最大呢?

這種問題被稱為帶權二分圖的最優匹配問題,可由KM算法解決。

比如上圖,A做工作a的效率為3,做工作c的效率為4......以此類推。

不了解KM算法的人如何解決這個問題?我們只需要用匈牙利算法找到所有的最大匹配,比較每個最大匹配的權重,再選出最大權重的最優匹配即可。這不失為一個解決方案,但是,如果公司員工的數量越來越多,此種算法的實行難度也就越來越大,我們必須另辟蹊徑:KM算法。

KM算法解決此題的步驟如下所示:

1.首先對每個頂點賦值,將左邊的頂點賦值為最大權重,右邊的頂點賦值為0。

如圖,我們將頂點A賦值為其兩邊中較大的4。

2.進行匹配,我們匹配的原則是:只與權重相同的邊匹配,若是找不到邊匹配,對此條路徑的所有左邊頂點-1,右邊頂點+1,再進行匹配,若還是匹配不到,重復+1和-1操作。(這里看不懂可以跳過,直接看下面的操作,之后再回頭來看這里。)

對A進行匹配,符合匹配條件的邊只有Ac邊。

匹配成功!

接下來我們對B進行匹配,頂點B值為3,Bc邊權重為3,匹配成~ 等等,A已經匹配c了,發生了沖突,怎么辦?我們這時候第一時間應該想到的是,讓B換個工作,但根據匹配原則,只有Bc邊 3+0=0 滿足要求,於是B不能換邊了,那A能不能換邊呢?對A來說,也是只有Ac邊滿足4+0=4的要求,於是A也不能換邊,走投無路了,怎么辦?

從常識的角度思考:其實我們尋找最優匹配的過程,也就是幫每個員工找到他們工作效率最高的工作,但是,有些工作會沖突,比如現在,B員工和A員工工作c的效率都是最高,這時我們應該讓A或者B換一份工作,但是這時候換工作的話我們只能換到降低總體效率值的工作,也就是說,如果令R=左邊頂點所有值相加,若發生了沖突,則最終工作效率一定小於R,但是,我們現在只要求最優匹配,所以,如果A換一份工作降低的工作效率比較少的話,我們是能接受的(對B同樣如此)。

在KM算法中如何體現呢?

現在參與到這個沖突的頂點是A,B和c,令所有左邊頂點值-1,右邊頂點值+1,即 A-1,B-1. c+1,結果如下圖所示。

我們進行了上述操作后會發現,若是左邊有n個頂點參與運算,則右邊就有n-1個頂點參與運算,整體效率值下降了1*(n-(n-1))=1,而對於A來說,Ac本來為可匹配的邊,現在仍為可匹配邊(3+1=4),對於B來說,Bc本來為可匹配的邊,現在仍為可匹配的邊(2+1=4),我們通過上述操作,為A增加了一條可匹配的邊Aa,為B增加了一條可匹配的邊Ba。

現在我們再來匹配,對B來說,Ba邊 2+0=2,滿足條件,所以B換邊,a現在為未匹配狀態,Ba匹配!

我們現在匹配最后一條邊C,Cc 5+1!=5,C邊無邊能匹配,所以C-1。

現在Cc邊 4+1=5,可以匹配,但是c已匹配了,發生沖突,C此時不能換邊,於是便去找A,對於A來說,Aa此時也為可匹配邊,但是a已匹配,A又去找B。

  

B現在無邊可以匹配了,2+0!=1 ,現在的路徑是C→c→A→a→B,所以A-1,B-1,C-1,a+1,c+1。如下圖所示。

對於B來說,現在Bb 1+0=1 可匹配!

使用匈牙利算法,對此條路徑上的邊取反。

如圖,便完成了此題的最優匹配。

讀者可以發現,這題中沖突一共發生了3次,所以我們一共降低了3次效率值,但是我們每次降低的效率值都是最少的,所以我們完成的仍然是最優匹配

這就是KM算法的整個過程,整體思路就是:每次都幫一個頂點匹配最大權重邊,利用匈牙利算法完成最大匹配,最終我們完成的就是最優匹配


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM