找了很多講解km演算法的部落格,就只有這篇寫的最通俗易懂
本文**:
km演算法用來求二分圖最大權完美匹配。
本文配合該博文服用更佳:趣寫演算法系列之--匈牙利演算法
本文沒有給出km演算法的原理,只是模擬了一遍演算法的過程。另,博主水平較差,發現問題歡迎指出,謝謝!!!!
現在有n男n女,有些男生和女生之間互相有好感,我們將其好感程度定義為好感度,我們希望把他們兩兩配對,並且最後希望好感度和最大。
怎麼選擇最優的配對方法呢?
首先,每個女生會有乙個期望值,就是與她有好感度的男生中最大的好感度。男生呢,期望值為0,就是……只要有乙個妹子就可以啦,不挑~~
這樣,我們把每個人的期望值標出來。
接下來,開始配對。
配對方法:
我們從第乙個女生開始,分別為每乙個女生找物件。
每次都從第乙個男生開始,選擇乙個男生,使
男女兩人的期望和要等於兩人之間的好感度。
注意:每一輪匹配,每個男生只會被嘗試匹配一次!
具體匹配過程:
**********====為女1找物件***************
(此時無人配對成功)
根據 「男女兩人的期望和要等於兩人之間的好感度」的規則
女1-男1:4+0 != 3
女1-男3:4+0 == 4
所以女1選擇了男3
女1找物件成功
**********====為女1找物件成功**********==
**********====為女2找物件***************
(此時女1—男3)
根據配對原則,女2選擇男3
男3有主女1,女1嘗試換人
我們嘗試讓女1去找別人
嘗試失敗
為女2找物件失敗!
**********====為女2找物件失敗**********==
這一輪參與匹配的人有:女1,女2,男3。
怎麼辦???很容易想到的,這兩個女生只能降低一下期望值了,降低多少呢?
這輪
比如:女1選擇男1,期望值要降低1。 女2選擇男1,期望值要降低1。 女2選擇男2,期望值要降低2。
於是,只要期望值降低1,就有妹子可能選擇其他人。所以妹子們的期望值要降低1點。
同時,剛才被搶的男生此時非常得意,因為有妹子來搶他,於是他的期望值提高了1點(就是同妹子們降低的期望值相同)。
於是期望值變成這樣(當然,不參與剛才匹配過程的人期望值不變)
**********====繼續為女2找物件**********===
(此時女1—男3)
女2選擇了男1
男1還沒有被配對
女2找物件成功!
**********====為女2找物件成功**********===
**********====為女3找物件***************
(此時女1—男3,女2-男1)
女3沒有可以配對的男生……
女3找物件失敗
**********====為女3找物件失敗**********==
此輪只有女3參與匹配
此時應該為女3降低期望值
降低期望值1的時候,女3-男3可以配對,所以女3降低期望值1
**********====繼續為女3找物件**********==
(此時女1—男3, 女2-男1)
女3相中了男3
此時男3已經有主女1,於是女1嘗試換人
女1選擇男1
而男1也已經有主女2,女2嘗試換人
前面說過,每一輪匹配每個男生只被匹配一次
所以女2換人失敗
女3找物件再次失敗
**********====為女3找物件失敗**********==
這一輪匹配相關人員:女1,女2,女3,男1,男3
此時,只要女2降低1點期望值,就能換到男2
(前面提過 只要任意乙個女生能換到任意乙個沒有被選擇過的男生所需要降低的最小值)
我們把相應人員期望值改變一下
**********====還是為女3找物件**********==
(此時女1—男3, 女2-男1)
女3選擇了男3
男3有主女1,女1嘗試換人
女1換到了男1
男1已經有主女2,女2嘗試換人
女2換人男2
男2無主,匹配成功!!!
**********====為女3找物件成功**********===
匹配成功!!!撒花~~
到此匹配全部結束
此時女1-男1,女2-男2,女3-男3
好感度和為最大:9
雖然不停換人的過程聽起來很麻煩,但其實整個是個遞迴的過程,實現起來比較簡單。比較複雜的部分就是期望值的改變,但是可以在遞迴匹配的過程中順帶求出來。
模板(帶詳細注釋)(入門題:hdu2255(複雜度應該是o(n^3)
#include #include#include
using
namespace
std;
const
int maxn = 305
;const
int inf = 0x3f3f3f3f
;int love[maxn][maxn]; //
記錄每個妹子和每個男生的好感度
int ex_girl[maxn]; //
每個妹子的期望值
int ex_boy[maxn]; //
每個男生的期望值
bool vis_girl[maxn]; //
記錄每一輪匹配匹配過的女生
bool vis_boy[maxn]; //
記錄每一輪匹配匹配過的男生
int match[maxn]; //
記錄每個男生匹配到的妹子 如果沒有則為-1
int slack[maxn]; //
記錄每個漢子如果能被妹子傾心最少還需要多少期望值
intn;
bool dfs(int
girl)
} else
}return
false;}
intkm()
}//嘗試為每乙個女生解決歸宿問題
for (int i = 0; i < n; ++i) }}
//匹配完成 求出所有配對的好感度的和
int res = 0
;
for (int i = 0; i < n; ++i)
res +=love[ match[i] ][i];
return
res;
}int
main()
return0;
}
二分匹配演算法
匈牙利演算法求二分匹配 下 include includeusing namespace std int v 頂點數 vectorg max v 圖的鄰接表表示 int match max v 所匹配的頂點 bool used max v dfs 中用到的訪問標記 向圖中增加一條連線 u 和 v 的...
求最大權二分匹配的KM演算法
最大權二分匹配問題就是給二分圖的每條邊乙個權值,選擇若干不相交的邊,得到的總權值最大。解決這個問題可以用km演算法。理解km演算法需要首先理解 可行頂標 的概念。可行頂標是指關於二分圖兩邊的每個點的乙個值lx i 或ly j 保證對於每條邊w i j 都有lx i ly j w i j 0。如果所有...
KM演算法 帶權二分匹配 O n 3
include include include include include include include include include include include define ll long long using namespace std const ll maxn 550 cons...