這個演算法其實在學匈牙利演算法時就看過了,不過當時沒搞懂???
現在一看,其實還挺好理解的。
km演算法是求最大權完備匹配,事實上它同時能處理最小權完備匹配(把邊權取反)和非完備匹配(新增原本不存在的邊且邊權賦值為0),另外還在一位神犇的部落格裡了解到,如果我想要邊權之積最大,則每條邊權取自然對數,然後求最大和權匹配,求得的結果a再算出e^a就是最大積匹配。至於精度問題則。。。不知所措。
km演算法是通過給每個頂點乙個標號(叫做頂標)來把求最大權匹配的問題轉化為求完備匹配的問題的。設頂點xi的頂標為a[i],頂點yi的頂標為b[i],頂點xi與yj之間的邊權為w[i,j]。在演算法執行過程中的任一時刻,對於任一條邊(i,j),a[i]+b[j]>=w[i,j]始終成立,初始a[i]為與xi相連的邊的最大邊權,b[j]=0。km演算法的正確性基於以下定理:
設 g(v,e) 為二部圖, g』(v,e』) 為二部圖的子圖。如果對於 g』 中的任何邊[x,y]滿足, a(x)+ b(y)== wx,y,我們稱 g』(v,e』) 為 g(v,e) 的等價子圖或相等子圖(是g的生成子圖)。
若由二分圖中所有滿足a[i]+b[j]=w[i,j]的邊(i,j)構成的子圖(稱做相等子圖)有完備匹配,那麼這個完備匹配就是二分圖的最大權匹配。
因為對於二分圖的任意乙個匹配,如果它包含於相等子圖,那麼它的邊權和等於所有頂點的頂標和;如果它有的邊不包含於相等子圖,那麼它的邊權和小於所有頂點的頂標和(即不是最優匹配)。所以相等子圖的完備匹配一定是二分圖的最大權匹配。
初始時為了使a[ i ]+b[j]>=w[i,j]恆成立,令a[ i ]為所有與頂點xi關聯的邊的最大權,b[j]=0。如果當前的相等子圖沒有完備匹配,就按下面的方法修改頂標以使擴大相等子圖,直到相等子圖具有完備匹配為止。
若求當前相等子圖的完全匹配失敗了,則必須修改頂標。而此時我們會得到一棵交錯樹。現在我們把交錯樹中x頂點的頂標全都減小某個值d,y頂點的頂標全都增加同乙個值d,顯然相等子圖只有可能被擴大。
而一次修改,至少有一條邊進入相等子圖,d應該等於:
min。
樸素的做法是o(n^4),主要因為列舉d的複雜度很大,為o(n^2)。
若我們給每個y頂點乙個「鬆弛量」函式slack,每次開始找增廣路時初始化為無窮大。在尋找增廣路的過程中,檢查邊(i,j)時,如果它不在相等子圖中,則讓slack[j]變成原值與a[ i ]+b[j]-w[i,j]的較小值。這樣,在修改頂標時,取所有不在交錯樹中的y頂點的slack值中的最小值作為d值即可。但還要注意一點:修改頂標後,要把所有的不在交錯樹中的y頂點的slack值都減去d。這樣就能做到o(n)找到d,使時間複雜度降到o(n^3)
km演算法雖然應用比費用流小,但是程式設計複雜度低,也便於理解,而且也能為學習費用流做基礎,個人感覺還是很有必要學會km演算法的。
演算法學習 KM演算法
km演算法 用於求二分圖的最佳完美匹配 即權值最大的完美匹配 如果你也是個剛來學習km演算法的人 大概的用途肯定還是知道的吧 還是直接說重點吧 首先 理解km演算法前 必須有以下3個概念 1.可行頂標 對於乙個賦值二分圖g x,y,e,w x,y 代表二分圖的兩邊頂點標號 e代表邊 w代表邊的權值 ...
Hash演算法學習小記(一)
關於hash演算法的應用是十分廣泛的,其中的最簡單的原因就是我們生活的這個時代每天都在產生著巨大複雜資料,但是對於我們有價值的資料的挖掘和儲存一直是乙個難點。如何把我們找到和我們密切相關的且有價值的資料一直是電腦科學面臨的關鍵問題。hash演算法從某種角度講,其實就是為了解決這一問題,儘管效果會因具...
帶花樹演算法學習小記
眾所周知,帶花樹演算法用來解決一般圖最大匹配問題。因為人很菜理解不清楚,所以建議對板理解。以下都是本人的感性理解,有不嚴謹的說法請包涵。同樣是找增廣路。增廣路定義為一條路徑 p 1,p 2,dots,p k 滿足 p 2,p 3 匹配,p 4,p 5 匹配 p p 匹配。p 1 和 p k 不在匹配...