• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            A Za, A Za, Fighting...

            堅(jiān)信:勤能補(bǔ)拙

            [zz] 二分圖匹配的匈牙利算法

            二分圖指的是這樣一種圖:其所有的頂點(diǎn)分成兩個(gè)集合M和N,其中M或N中任意兩個(gè)在同一集合中的點(diǎn)都不相連。二分圖匹配是指求出一組邊,其中的頂點(diǎn)分別在兩個(gè)集合中,并且任意兩條邊都沒(méi)有相同的頂點(diǎn),這組邊叫做二分圖的匹配,而所能得到的最大的邊的個(gè)數(shù),叫做最大匹配。

            匈牙利算法。這個(gè)算法說(shuō)白了就是最大流的算法,但是它跟據(jù)二分圖匹配這個(gè)問(wèn)題的特點(diǎn),把最大流算法做了簡(jiǎn)化,提高了效率。匈牙利算法其實(shí)很簡(jiǎn)單,但是網(wǎng)上搜不到什么說(shuō)得清楚的文章。所以我決定要寫一下。
            最大流算法的核心問(wèn)題就是找增廣路徑(augment path)。匈牙利算法也不例外,它的基本模式就是:

            初始時(shí)最大匹配為空
            while 找得到增廣路徑
                do 把增廣路徑加入到最大匹配中去

            可見(jiàn)和最大流算法是一樣的。但是這里的增廣路徑就有它一定的特殊性,下面我來(lái)分析一下。
            (注:匈牙利算法雖然根本上是最大流算法,但是它不需要建網(wǎng)絡(luò)模型,所以圖中不再需要源點(diǎn)和匯點(diǎn),僅僅是一個(gè)二分圖。每條邊也不需要有方向。)

            圖1 圖2


            圖1是我給出的二分圖中的一個(gè)匹配:〔1,5〕和〔2,6〕。圖2就是在這個(gè)匹配的基礎(chǔ)上找到的一條增廣路徑:3->6->2->5->1->4。我們借由它來(lái)描述一下二分圖中的增廣路徑的性質(zhì):

            (1)有奇數(shù)條邊。
            (2)起點(diǎn)在二分圖的左半邊,終點(diǎn)在右半邊。
            (3)路徑上的點(diǎn)一定是一個(gè)在左半邊,一個(gè)在右半邊,交替出現(xiàn)。(其實(shí)二分圖的性質(zhì)就決定了這一點(diǎn),因?yàn)槎謭D同一邊的點(diǎn)之間沒(méi)有邊相連,不要忘記哦。)
            (4)整條路徑上沒(méi)有重復(fù)的點(diǎn)。
            (5)起點(diǎn)和終點(diǎn)都是目前還沒(méi)有配對(duì)的點(diǎn),而其它所有點(diǎn)都是已經(jīng)配好對(duì)的。(如圖1、圖2所示,〔1,5〕和〔2,6〕在圖1中是兩對(duì)已經(jīng)配好對(duì)的點(diǎn);而起點(diǎn)3和終點(diǎn)4目前還沒(méi)有與其它點(diǎn)配對(duì)。)
            (6)路徑上的所有第奇數(shù)條邊都不在原匹配中,所有第偶數(shù)條邊都出現(xiàn)在原匹配中。(如圖1、圖2所示,原有的匹配是〔1,5〕和〔2,6〕,這兩條配匹的邊在圖2給出的增廣路徑中分邊是第2和第4條邊。而增廣路徑的第1、3、5條邊都沒(méi)有出現(xiàn)在圖1給出的匹配中。)
            (7)最后,也是最重要的一條,把增廣路徑上的所有第奇數(shù)條邊加入到原匹配中去,并把增廣路徑中的所有第偶數(shù)條邊從原匹配中刪除(這個(gè)操作稱為增廣路徑的取反),則新的匹配數(shù)就比原匹配數(shù)增加了1個(gè)。(如圖2所示,新的匹配就是所有藍(lán)色的邊,而所有紅色的邊則從原匹配中刪除。則新的匹配數(shù)為3。)

            不難想通,在最初始時(shí),還沒(méi)有任何匹配時(shí),圖1中的兩條灰色的邊本身也是增廣路徑。因此在這張二分圖中尋找最大配匹的過(guò)程可能如下:

            (1)找到增廣路徑1->5,把它取反,則匹配數(shù)增加到1。
            (2)找到增廣路徑2->6,把它取反,則匹配數(shù)增加到2。
            (3)找到增廣路徑3->6->2->5->1->4,把它取反,則匹配數(shù)增加到3。
            (4)再也找不到增廣路徑,結(jié)束。

            當(dāng)然,這只是一種可能的流程。也可能有別的找增廣路徑的順序,或者找到不同的增廣路徑,最終的匹配方案也可能不一樣。但是最大匹配數(shù)一定都是相同的。

            對(duì)于增廣路徑還可以用一個(gè)遞歸的方法來(lái)描述。這個(gè)描述不一定最準(zhǔn)確,但是它揭示了尋找增廣路徑的一般方法:
            “從點(diǎn)A出發(fā)的增廣路徑”一定首先連向一個(gè)在原匹配中沒(méi)有與點(diǎn)A配對(duì)的點(diǎn)B。如果點(diǎn)B在原匹配中沒(méi)有與任何點(diǎn)配對(duì),則它就是這條增廣路徑的終點(diǎn);反之,如果點(diǎn)B已與點(diǎn)C配對(duì),那么這條增廣路徑就是從A到B,再?gòu)腂到C,再加上“從點(diǎn)C出發(fā)的增廣路徑”。并且,這條從C出發(fā)的增廣路徑中不能與前半部分的增廣路徑有重復(fù)的點(diǎn)。

            比如圖2中,我們要尋找一條從3出發(fā)的增廣路徑,要做以下3步:
            (1)首先從3出發(fā),它能連到的點(diǎn)只有6,而6在圖1中已經(jīng)與2配對(duì),所以目前的增廣路徑就是3->6->2再加上從2出發(fā)的增廣路徑。
            (2)從2出發(fā),它能連到的不與前半部分路徑重復(fù)的點(diǎn)只有5,而且5確實(shí)在原匹配中沒(méi)有與2配對(duì)。所以從2連到5。但5在圖1中已經(jīng)與1配對(duì),所以目前的增廣路徑為3->6->2->5->1再加上從1出發(fā)的增廣路徑。
            (3)從1出發(fā),能連到的不與自已配對(duì)并且不與前半部分路徑重復(fù)的點(diǎn)只有4。因?yàn)?在圖1中沒(méi)有與任何點(diǎn)配對(duì),所以它就是終點(diǎn)。所以最終的增廣路徑是3->6->2->5->1->4。

            但是嚴(yán)格地說(shuō),以上過(guò)程中從2出發(fā)的增廣路徑(2->5->1->4)和從1出發(fā)的增廣路徑(1->4)并不是真正的增廣路徑。因?yàn)樗鼈儾环锨懊嬷v過(guò)的增廣路徑的第5條性質(zhì),它們的起點(diǎn)都是已經(jīng)配過(guò)對(duì)的點(diǎn)。我們?cè)谶@里稱它們?yōu)?#8220;增廣路徑”只是為了方便說(shuō)明整個(gè)搜尋的過(guò)程。而這兩條路徑本身只能算是兩個(gè)不為外界所知的子過(guò)程的返回結(jié)果。
            顯然,從上面的例子可以看出,搜尋增廣路徑的方法就是DFS,可以寫成一個(gè)遞歸函數(shù)。當(dāng)然,用BFS也完全可以實(shí)現(xiàn)。

            至此,理論基礎(chǔ)部份講完了。但是要完成匈牙利算法,還需要一個(gè)重要的定理:

            如果從一個(gè)點(diǎn)A出發(fā),沒(méi)有找到增廣路徑,那么無(wú)論再?gòu)膭e的點(diǎn)出發(fā)找到多少增廣路徑來(lái)改變現(xiàn)在的匹配,從A出發(fā)都永遠(yuǎn)找不到增廣路徑。

            要用文字來(lái)證明這個(gè)定理很繁,話很難說(shuō),要么我還得多畫一張圖,我在此就省了。其實(shí)你自己畫幾個(gè)圖,試圖舉兩個(gè)反例,這個(gè)定理不難想通的。(給個(gè)提示。如果你試圖舉個(gè)反例來(lái)說(shuō)明在找到了別的增廣路徑并改變了現(xiàn)有的匹配后,從A出發(fā)就能找到增廣路徑。那么,在這種情況下,肯定在找到別的增廣路徑之前,就能從A出發(fā)找到增廣路徑。這就與假設(shè)矛盾了。)
            有了這個(gè)定理,匈牙利算法就成形了。如下:

            初始時(shí)最大匹配為空
            for 二分圖左半邊的每個(gè)點(diǎn)i
                do 從點(diǎn)i出發(fā)尋找增廣路徑。如果找到,則把它取反(即增加了總了匹配數(shù))。

            如果二分圖的左半邊一共有n個(gè)點(diǎn),那么最多找n條增廣路徑。如果圖中共有m條邊,那么每找一條增廣路徑(DFS或BFS)時(shí)最多把所有邊遍歷一遍,所花時(shí)間也就是m。所以總的時(shí)間大概就是O(n * m)。

            posted on 2010-10-20 15:13 simplyzhao 閱讀(204) 評(píng)論(0)  編輯 收藏 引用 所屬分類: G_其他

            導(dǎo)航

            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            統(tǒng)計(jì)

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            精品九九久久国内精品| 看全色黄大色大片免费久久久| 综合久久精品色| 亚洲精品白浆高清久久久久久| 国产精品久久一区二区三区| 一本大道加勒比久久综合| 亚洲欧洲久久久精品| 久久午夜羞羞影院免费观看| 欧美综合天天夜夜久久| 久久人人爽人人精品视频| 伊人久久大香线蕉av一区| 99久久精品免费看国产| 久久亚洲AV成人无码电影| 久久久精品视频免费观看| 国内精品久久久人妻中文字幕| 久久国产精品免费| 77777亚洲午夜久久多喷| 久久久不卡国产精品一区二区| 国产精品免费看久久久| 一本大道久久东京热无码AV | 国产综合成人久久大片91| 久久国产免费直播| 亚洲精品久久久www| 99热精品久久只有精品| 久久国产色AV免费观看| 午夜精品久久久久| 亚洲国产精品无码久久青草 | 久久精品国产99久久久古代| 久久久久这里只有精品| 久久99热这里只有精品国产 | 久久婷婷色综合一区二区| 国产精品热久久无码av| 久久国产高潮流白浆免费观看| 亚洲国产精品无码久久久不卡 | 99久久人妻无码精品系列 | 久久国产成人午夜AV影院| 久久96国产精品久久久| 日本强好片久久久久久AAA| 亚洲精品无码久久千人斩| 国产成人精品综合久久久| 狠狠色丁香久久婷婷综合|