1. 程式人生 > >演算法的樂趣實戰(1)--匈牙利演算法

演算法的樂趣實戰(1)--匈牙利演算法

在閱讀《演算法的樂趣》的時候,實在難以理解第七章中關於匈牙利演算法的描述,所以劣者在網上搜刮各種資料,整理如下,既為了自己複習之用,也為了後來者的方便

匈牙利演算法解決了舞伴的快速匹配問題,什麼是舞伴快速匹配問題呢?男女雙方都有各自的最優選擇名單,在一輪輪的選擇過後,最終會得到一個結果,這個過程就是快速匹配問題。

匈牙利演算法如下:

定義

struct tagMaxMatch
{
int edge[MAX][MAX];    //頂點和關係的圖
bool on_path[MAX];       //當前節點是否在增廣路徑上
int path[MAX];        //當前找到的增廣路徑(原來的yj在和誰配對?)
int max_match;    //如果最後!=MAX,就是查詢失敗
}

演算法如下

bool findPath(GRAPH_MATCH *match, int xi)//對於這個xi節點來說
{
    for(int jy=0;jy<MAX;jy++)
        {
        if((match->edge[xi][yj]==1) && (!match->on_path[yj])//如果真實存在這條路 && 這個點不在我的增廣路上
            match->on_path[yj]=true;
            if( (match->path[yj]==-1) || findPath(match,match->path[yj]) )
            //這個點正好是“新”點,或者讓這個點的原主人滾蛋,讓他去尋找“新“點
            {        //如果成功了
                match->path[yj]==xi;       //插上我的小旗,女伴是我的了
                return true;
            }
        }
 }
                

當然這個只是一個點作為起點的演算法,完整演算法需要遍歷所有的xi,同時注意每次遍歷前要將on_path歸零(為了讓其他人來把他踹開>_<)

演算法的複雜度:遍歷所有的邊O(E),所有的節點O(V),結果就是O(V*E),還挺高效

這個演算法講究的就是一個”將就“,有人來,那麼這個人就是上上賓,其他人都要依次讓一讓(按照演算法,退讓也有優先順序),大概也是一種中庸的社會態度吧。