設g=(v,e)是乙個無向圖。如頂點集v可分割為兩個互不相交的子集v1,v2,選擇這樣的子集中邊數最大的子集稱為圖的最大匹配問題(maximal matching problem)
如果乙個匹配中,|v1|<=|v2|且匹配數|m|=|v1|則稱此匹配為完全匹配,也稱作完備匹配。特別的當|v1|=|v2|稱為完美匹配。
趣寫演算法系列之–匈牙利演算法m是g的乙個匹配。
(m:)
m-交錯路:p是g的一條通路,如果p中的邊為屬於m中的邊與不屬於m但屬於g中的邊交替出現,則稱p是一條m-交錯路。例如:x1-y1-x3-y2
m-飽和點:對於v∈v(g),如果v與m中的某條邊關聯,則稱v是m-飽和點,否則稱v是非m-飽和點。如x2,x3,x4,x6,y1,y3,y4,y5都屬於m-飽和點,而其它點都屬於非m-飽和點。
m-可增廣路:p是一條m-交錯路,如果p的起點和終點都是非m-飽和點,則稱p為m-可增廣路。例如:x1-y1-x3-y2
求最大匹配的一種顯而易見的演算法是:先找出全部匹配,然後保留匹配數最多的。但是這個演算法的時間複雜度為邊數的指數級函式。因此,需要尋求一種更加高效的演算法。下面介紹用增廣路求最大匹配的方法(稱作匈牙利演算法,匈牙利數學家edmonds於2023年提出)。
由增廣路的定義可以推出下述三個結論:
1-p的路徑個數必定為奇數,第一條邊和最後一條邊都不屬於m。
2-將m和p進行取反操作可以得到乙個更大的匹配m'。
3-m為g的最大匹配當且僅當不存在m的增廣路徑。
在這個過程中,如何快速找出增廣路呢?⑴置m為空
⑵找出一條增廣路徑p,通過異或操作獲得更大的匹配m'代替m
⑶重複⑵操作直到找不出增廣路徑為止
這裡提供一種方法:如下圖所示,找乙個非m-飽和點,畫一棵m-交錯樹,如果能找到,就重複(2),不能找到演算法就可以結束咯~
//偽**
bool 尋找從k出發的增廣路}}
返回false;
}void 匈牙利hungary()
輸出 匹配數;
}
//c++**
//b[j]表示j的匹配物件,0表示未匹配
如圖g,比如我們現在進行find(x1);
x1會去找y1,但是發現b[y1]不是0了,於是遞迴進行find(x3),此時v[y1]=1,已經被標記,所以x3不能再找y1了,於是它找到了y2(當然,如果y2已經名花有主,那麼再次遞迴,讓y2的主另尋他歡)
在這個過程中,發生了這樣的事情:我們試圖將(x1, y1),(x3, y2)增加到m中,而將(x3,y1)從m中刪除——這正是在試圖用m』來代替m,一旦找到增廣路,返回true,則遞迴收縮回來,逐步執行b[j]=x來修改邊,如果找不到增廣路,返回false,則一切的修改都不會執行。
資料結構與演算法 演算法 演算法和資料結構
資料結構與演算法 演算法 好吧,在這裡,您被優秀或優秀的軟體開發人員所隔開。在這種情況下,我會告訴您一開始或至少在我的情況下,並且我知道大多數時候,對於我認識的大多數人,您會覺得自己是乙個無能的人或白痴。基本上,我怎麼可能不理解這一點,然後您會感到沮喪。在這種情況下,我會告訴您情況並不像您想的那麼糟...
資料結構與演算法課程設計 Prim演算法
題目 某地區經過對城鎮交通狀況的調查,得到現有城鎮間快速道路的統計資料,並提出 暢通工程 的目標,使整個地區任何兩個城鎮間都可以實現快速交通 但不一定有直接的快速道路相連,只要互相間接通過快 速路可達即可 現得到城鎮道路統計表,表中列出了任意兩城鎮間修建快速路的費用,以及該道路是否已經修通的狀態。現...
資料結構與演算法課程設計 Prim演算法
題目 某地區經過對城鎮交通狀況的調查,得到現有城鎮間快速道路的統計資料,並提出 暢通工程 的目標,使整個地區任何兩個城鎮間都可以實現快速交通 但不一定有直接的快速道路相連,只要互相間接通過快 速路可達即可 現得到城鎮道路統計表,表中列出了任意兩城鎮間修建快速路的費用,以及該道路是否已經修通的狀態。現...