匈牙利算法與KM算法

  1. 匈牙利算法的概述

    用來解決二分圖中的最優分配問題的算法,也就是圖論中尋找最大匹配的算法。

  2. 從實際問題的角度理解(\(\mbox{KM}\)算法)

    1. 第(1)步:找到每個成員的長處,即尋找各個成員完成各任務的最短耗時。將成本矩陣的各行減去該行的最小值,找出各行的“0”;

    2. 第(2)步:找到各任務的最佳人選,即尋找各任務分配給各成員完成的最短耗時。將(1)中處理後的成本矩陣的各列減去該列的最小值,找出各列的“0”;

    3. 第(3)步:成員和任務的禮讓原則。相對不能“將就”的成員和任務優先選擇。

      1. 成員禮讓原則。尋找長處最少的成員,先把他的長處分配給他,因爲長處越多的成員越容易調配。在(2)中處理後的成本矩陣中找到含有“0”最少的行,然後將該行的“0”畫上圈(記爲\(\circledcirc\)),同時由於一個任務同一時刻只能由一個成員完成,故劃去其所在列的其他“0”(記爲\(\phi\));
      2. 任務禮讓原則。尋找最佳成員最少的任務,先把它的最佳成員分配給它,原因同(3)。在(3)中處理後的成本矩陣中找到含有“0”最少的列,然後將該列的“0”畫上圈(記爲\(\circledcirc\)),同時由於一個成員同一時刻只能完成一個任務,故劃去其所在行的其他“0”(記爲\(\phi\));
    4. 第(4)步:尋找犧牲的成員和任務。方法爲打鉤劃線法。

      1. 打鉤。對(3)中處理後的成本矩陣中不含“\(\circledcirc\)”的行打鉤(尋找犧牲成員\(M_1\)),然後對該行中含有“\(\phi\)”的列打鉤(尋找該成員與其他成員相沖突的任務\(T_1\)),再對該打鉤列中含有“\(\circledcirc\)”的行打鉤(尋找完成該衝突任務\(T_1\)的其他成員\(M_2\))。若\(M_2\)中還有與其他成員衝突的任務,則重複上述步驟,反之則結束打鉤過程;
      2. 劃線。尋找有任務衝突的所有成員,然後提取出他們無衝突的任務,爲之後的重新分配)做準備。對未打鉤的行(無任務衝突的成員)和已打鉤的列(衝突任務)劃線排除。
    5. 第(5)步:重新調度分配。找到所有有任務衝突的成員,標記出他們的無衝突任務,最後選擇耗時最少的任務作爲“激勵”/“懲罰”因子。在(4)中處理後的成本矩陣中尋找未被劃線元素的最小值,然後對打鉤行減去這個最小值、對打鉤列增加這個最小值。

      1. 對打鉤行減去這個最小值:在增加“0”的同時也能對沖突成員的無衝突任務進行“激勵”。如果這次分配失敗,則下一次分配時這些任務會更先被分配;
      2. 對打鉤列增加這個最小值:在保證任務耗時非負的同時也能對有衝突任務進行“懲罰”。如果這次分配失敗,則下一次分配時這些任務會更後被分配;
    6. 第(6)步:如果出現各行各列都只有一個“\(\circledcirc\)”則說明分配成功,否則分配失敗,重複(4)~(6)。

  3. 從圖論理論的角度理解(匈牙利算法)

    1. 專有名詞解釋

      1. 匹配\(\mbox{M}\):是邊集\(\mbox{E}\)的一個無環子集,且它的任意兩條邊在圖\(\mbox{G}\)中都不相鄰;
      2. \(\mbox{M}\)的飽和頂點\(\nu\)\(\exists{e}\in{M}\)與頂點\(\nu\)關聯;
      3. \(\mbox{M}\)的非飽和頂點\(\nu\)\(\forall{e}\in{M}\)不與頂點\(\nu\)關聯;
      4. 最大匹配\(\mbox{M}\):所有匹配中邊數最多的匹配方案;
      5. 完美匹配\(\mbox{M}\):某個匹配包含了圖\(\mbox{G}\)中所有的頂點;
    2. 交錯路徑

      \(M\)是圖\(G\)某匹配,若某路徑在\(M\)\(G-M\)中交替出現,則將這條路徑稱爲\(M\)交錯路徑。

    3. 增廣路徑

      如果一條\(M\)交錯路徑的起點和終點都是\(M\)非飽和頂點,則稱爲\(M\)增廣路徑。

    4. 算法步驟

      img
    5. 我的理解

      1. 算法的目標

        任取一個\(M(X)\)非飽和頂點\(x_0\)作爲“入射源點”,經過或者不經過\(M\)匹配中的“反射”,最後需要找到一個\(M(Y)\)非飽和頂點\(y_0\)作爲“出射終點”,這樣一條“反射光線”被稱爲“\(M\)增廣路徑”。

      2. 算法的遍歷思想

        有點兒類似於層序遍歷的思想。將\(N(S)\)作爲訪問備選方案,將其中已經訪問過的\(Y\)做上標記(用集合\(T\)表示),以便後續不再重複訪問(\(y\in{N(S)-T}\))。

        在訪問\(Y\)中結點之前必須對\(N(S)\)做判斷,查看是否全被訪問過(即\(N(S)\subseteq{T}\)),而對於每一個被訪問的\(Y\)結點都會判斷其是否屬於\(M(Y)\)飽和頂點:

        1. 如果屬於\(M(Y)\)飽和頂點:將與之\(M\)匹配的\(X_i\)併入\(S\),並將\(y\)併入訪問標記\(T\)中;
        2. 如果不屬於\(M(Y)\)飽和頂點:必然存在一條增廣路徑\(P(x_0,y_0)\)\(M=M\oplus{E(P)}\)
      3. 如何獲取增廣路徑

        可以用\(\mbox{DFS}\)(深度優先搜索)算法。

  4. 賦權二部圖最大匹配\(\mbox{Kuhn-Munkres}\)算法

    1. 頂點標號與可行頂點標號

      \(G\)的頂點標號\(l\)是從頂點集到正整數集的一個映射。用\(l(\nu)\)\(G\)上頂點\(\nu\)的標號,邊\(<\nu_1,\nu_2>\)的權重用\(\omega(\nu_1\nu_2)\)表示。如果對於賦權二部圖\(G\)中的每一條邊\(<x,y>\)都有\(l(x)+l(y)\ge\omega(xy)\),則稱這個標號\(l\)是圖\(G\)的一個可行頂點標記。

      其意義在於權重\(\omega(xy)\)是固定的,只有頂點的標號是隨意初始化的。

      每次訪問\(y\)都需要對其施加“懲罰”(\(+\)\(\alpha_l\),而對與之匹配的\(x\)施加“激勵”(\(-\)\(\alpha_l\)

      通常選擇\(l(x_i)=\underset{y\in{Y}}{\max}{(\omega(xy))}\)\(l(y_i)=0\),然後通過不斷地調整\(l(x)\)\(l(y)\)使得\(l(x)+l(y)\rightarrow\omega(xy)\)

    2. 相等子圖的概念以及推論

      1. 相等子圖

        \(E_l=\{xy\in{E(G)|l(x)+l(y)=\omega(xy)}\}\)(也就是匹配),則\(G(E_l)\)\(G\)\(l\)相等子圖\(G_l\)

      2. 定理推論

        相等子圖\(G_l\)的完美匹配,亦是\(G\)的最大權完美匹配。

    3. \(\mbox{KM}\)算法優化方法及步驟

      1. 如果\(\norm{X}\neq\norm{Y}\),則給\(G(X,Y)\)添加一些頂點和權爲0的邊,使其成爲賦權二部圖。

      2. \(G\)中任意一可行頂點標號開始,求出相等子圖\(G_l\)(初始化一個匹配\(M\))。

      3. \(G_l\)中執行匈牙利算法,觀察是否能夠輸出一個完美匹配\(M\)

        1. 如果可以求得完美匹配\(M\),則將其輸出並停止;

        2. 否則重新對頂點標號賦值:所有訪問過的\(y\)都需要對其施加“懲罰”(\(+\)\(\alpha_l\),而與它們匹配的\(x\)施加“激勵”(\(-\)\(\alpha_l\),其餘的頂點標號不變。

          \[\alpha_l\overset{\Delta}{=}\underset{x\in{S},y\notin{T}}{\min}{\{l(x)+l(y)-\omega(xy)\}},其中S=\mbox{visited}_x,T=\mbox{visited}_y \]

          也就是說使得\(\mbox{visited}_{x}\)有更多的\(y\)與之匹配,而限制\(\mbox{visited}_y\)的匹配數量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章