二分圖匹配算法總結

二分圖匹配算法總結
二分圖最大匹配的匈牙利算法 二分圖是這樣一個圖,它的頂點可以分類兩個集合X和Y,所有的邊關聯在兩個頂點中,恰好一個屬於集合X,另一個屬於集合Y。 
最大匹配:圖中包含邊數最多的匹配稱爲圖的最大匹配。 
完美匹配:如果所有點都在匹配邊上,稱這個最大匹配是完美匹配。  
最小覆蓋: 最小覆蓋要求用最少的點(X集合或Y集合的都行)讓每條邊都至少和其中一個點關聯。
可以證明:最少的點(即覆蓋數)=最大匹配數  
最小路徑覆蓋:  用盡量少的不相交簡單路徑覆蓋有向無環圖G的所有結點。解決此類問題可以建立一個二分圖模型。把所有頂點i拆成兩個:X結點集中的i和Y結點集中的i',如果有邊i->j,則在二分圖中引入邊i->j',設二分圖最大匹配爲m,則結果就是n-m。 最大獨立集問題:  在N個點的圖G中選出m個點,使這m個點兩兩之間沒有邊.求m最大值. 如果圖G滿足二分圖條件,則可以用二分圖匹配來做.最大獨立集點數 = N - 最大匹配數 一、匈牙利算法 設G=(V,{R})是一個無向圖。如頂點集V可分割爲兩個互不相交的子集,並且圖中每條邊依附的兩個頂點都分屬兩個不同的子集。則稱圖G爲二分圖。    
v       給定一個二分圖G,在G的一個子圖M中,M的邊集{E}中的任意兩條邊都不依附於同一個頂點,則稱M是一個匹配。 
v       選擇這樣的邊數最大的子集稱爲圖的最大匹配問題(maximal matching problem) 
v       如果一個匹配中,圖中的每個頂點都和圖中某條邊相關聯,則稱此匹配爲完全匹配,也稱作完備匹配。 最大匹配在實際中有廣泛的用處,求最大匹配的一種顯而易見的算法是:先找出全部匹配,然後保留匹配數最多的。但是這個算法的複雜度爲邊數的指數級函數。因此,需要尋求一種更加高效的算法。 匈牙利算法是求解最大匹配的有效算法,該算法用到了增廣路的定義(也稱增廣軌或交錯軌):若P是圖G中一條連通兩個未匹配頂點的路徑,並且屬M的邊和不屬M的邊(即已匹配和待匹配的邊)在P上交替出現,則稱P爲相對於M的一條增廣路徑。 由增廣路徑的定義可以推出下述三個結論: 
v       1.   P的路徑長度必定爲奇數,第一條邊和最後一條邊都不屬於M。 
v       2.   P經過取反操作(即非M中的邊變爲M中的邊,原來M中的邊去掉)可以得到一個更大的匹配M’。 
v       3.   M爲G的最大匹配當且僅當不存在相對於M的增廣路徑。 從而可以得到求解最大匹配的匈牙利算法: 
v       (1)置M爲空 
v       (2)找出一條增廣路徑P,通過取反操作獲得更大的匹配M’代替M 
v       (3)重複(2)操作直到找不出增廣路徑爲止 二、KM算法: 二分圖最優匹配:對於二分圖的每條邊都有一個權(非負),要求一種完備匹配方案,使得所有匹配邊的權和最大,記做最優完備匹配。(特殊的,當所有邊的權爲1時,就是最大完備匹配問題) 解二分圖最優匹配問題可用窮舉的方法,但窮舉的效率=n!,所以我們需要更加優秀的算法。 先說一個定理:設M是一個帶權完全二分圖G的一個完備匹配,給每個頂點一個可行頂標(第i個x頂點的可行標用lx[i]表示,第j個y頂點的可行標用ly[j]表示),如果對所有的邊(i,j) in G,都有lx[i]+ly[j]>=w[i,j]成立(w[i,j]表示邊的權),且對所有的邊(i,j) in M,都有lx[i]+ly[j]=w[i,j]成立,則M是圖G的一個最優匹配。 Kuhn-Munkras算法(即KM算法)流程: 
v       (1)初始化可行頂標的值 v       (2)用匈牙利算法尋找完備匹配 
v       (3)若未找到完備匹配則修改可行頂標的值 
v       (4)重複(2)(3)直到找到相等子圖的完備匹配爲止 KM算法主要就是控制怎樣修改可行頂標的策略使得最終可以達到一個完美匹配,首先任意設置可行頂標(如每個X節點的可行頂標設爲它出發的所有弧的最大權,Y節點的可行頂標設爲0),然後在相等子圖中尋找增廣路,找到增廣路就沿着增廣路增廣。而如果沒有找到增廣路呢,那麼就考慮所有現在在匈牙利樹中的X節點(記爲S集合),所有現在在匈牙利樹中的Y節點(記爲T集合),考察所有一段在S集合,一段在not T集合中的弧,取       delta = min {l(xi)+l(yj)-w(xi,yj) , | xi in S, yj   in not T}    。明顯的,當我們把所有S集合中的l(xi)減少delta之後,一定會有至少一條屬於(S, not T)的邊進入相等子圖,進而可以繼續擴展匈牙利樹,爲了保證原來屬於(S,T )的邊不退出相等子圖,把所有在T集合中的點的可行頂標增加delta。隨後匈牙利樹繼續擴展,如果新加入匈牙利樹的Y節點是未蓋點,那麼找到增廣路,否則把該節點的對應的X匹配點加入匈牙利樹繼續嘗試增廣。 複雜度分析:由於在不擴大匹配的情況下每次匈牙利樹做如上調整之後至少增加一個元素,因此最多執行n次就可以找到一條增廣路,最多需要找n條增廣路,故最多執行n^2次修改頂標的操作,而每次修改頂標需要掃描所有弧,這樣修改頂標的複雜度就是O(n^2)的,總的複雜度是O(n^4)的。      對於not T的每個元素yj,定義鬆弛變量slack(yj) =min{l(xi)+l(yj)-w(xi,yj), | xi in S},很明顯每次的delta = min{slack(yj), | yj   in not T},每次增廣之後用O(n^2)的時間計算所有點的初始slack,由於生長匈牙利樹的時候每條弧的頂標增量相同,因此修改每個slack需要常數時間(注意在修改頂標後和把已蓋Y節點對應的X節點加入匈牙利樹的時候是需要修改slack的)。這樣修改所有slack值時間是O(n)的,每次增廣後最多修改n次頂標,那麼修改頂標的總時間降爲O(n^2),n次增廣的總時間複雜度降爲O(n^3)。事實上這樣實現之後對於大部分的數據可以比O(n^4)的算法快一倍左右。 利用二分圖匹配的匈牙利算法和KM算法,我們可以求解大部分的關於二分圖的問題,它們提供了求解最大匹配和最優匹配的有效算法,在具體編程時我們只要多注意優化,我們就可以得出求解這類問題的有效方法,從而可以對這類實際問題進行有效合理的解決。 
另一種說法: KM算法(轉)       
KM算法是通過給每個頂點一個標號(叫做頂標)來把求最大權匹配的問題轉化爲求完備匹配的問題的。設頂點Xi的頂標爲A[i],頂點Yi的頂標爲B [i],頂點Xi與Yj之間的邊權爲w[i,j]。在算法執行過程中的任一時刻,對於任一條邊(i,j),A[i]+B[j]>=w[i,j]始終 成立。KM算法的正確性基於以下定理:    若由二分圖中所有滿足A[i]+B[j]=w[i,j]的邊(i,j)構成的子圖(稱做相等子圖)有完備匹配,那麼這個完備匹配就是二分圖的最大權匹配。   這個定理是顯然的。因爲對於二分圖的任意一個匹配,如果它包含於相等子圖,那麼它的邊權和等於所有頂點的頂標和;如果它有的邊不包含於相等子圖,那麼它的邊權和小於所有頂點的頂標和。所以相等子圖的完備匹配一定是二分圖的最大權匹配。    初始時爲了使A[i]+B[j]>=w[i,j]恆成立,令A[i]爲所有與頂點Xi關聯的邊的最大權,B[j]=0。如果當前的相等子圖沒有完備匹配,就按下面的方法修改頂標以使擴大相等子圖,直到相等子圖具有完備匹配爲止。    我們求當前相等子圖的完備匹配失敗了,是因爲對於某個X頂點,我們找不到一條從它出發的交錯路。這時我們獲得了一棵交錯樹,它的葉子結點全部是X頂點。現在我們把交錯樹中X頂點的頂標全都減小某個值d,Y頂點的頂標全都增加同一個值d,那麼我們會發現:  兩端都在交錯樹中的邊(i,j),A[i]+B[j]的值沒有變化。也就是說,它原來屬於相等子圖,現在仍屬於相等子圖。  兩端都不在交錯樹中的邊(i,j),A[i]和B[j]都沒有變化。也就是說,它原來屬於(或不屬於)相等子圖,現在仍屬於(或不屬於)相等子圖。  X端不在交錯樹中,Y端在交錯樹中的邊(i,j),它的A[i]+B[j]的值有所增大。它原來不屬於相等子圖,現在仍不屬於相等子圖。  X端在交錯樹中,Y端不在交錯樹中的邊(i,j),它的A[i]+B[j]的值有所減小。也就說,它原來不屬於相等子圖,現在可能進入了相等子圖,因而使相等子圖得到了擴大。    現在的問題就是求d值了。爲了使A[i]+B[j]>=w[i,j]始終成立,且至少有一條邊進入相等子圖,d應該等於min{A[i]+B[j]-w[i,j]|Xi在交錯樹中,Yi不在交錯樹中}。    以上就是KM算法的基本思路。但是樸素的實現方法,時間複雜度爲O(n4)——需要找O(n)次增廣路,每次增廣最多需要修改O(n)次頂 標,每次修改頂標時由於要枚舉邊來求d值,複雜度爲O(n2)。實際上KM算法的複雜度是可以做到O(n3)的。我們給每個Y頂點一個“鬆弛量”函數 slack,每次開始找增廣路時初始化爲無窮大。在尋找增廣路的過程中,檢查邊(i,j)時,如果它不在相等子圖中,則讓slack[j]變成原值與A [i]+B[j]-w[i,j]的較小值。這樣,在修改頂標時,取所有不在交錯樹中的Y頂點的slack值中的最小值作爲d值即可。但還要注意一點:修改 頂標後,要把所有的slack值都減去d。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章