演算法的樂趣實戰(1)--匈牙利演算法
阿新 • • 發佈:2018-12-13
在閱讀《演算法的樂趣》的時候,實在難以理解第七章中關於匈牙利演算法的描述,所以劣者在網上搜刮各種資料,整理如下,既為了自己複習之用,也為了後來者的方便
匈牙利演算法解決了舞伴的快速匹配問題,什麼是舞伴快速匹配問題呢?男女雙方都有各自的最優選擇名單,在一輪輪的選擇過後,最終會得到一個結果,這個過程就是快速匹配問題。
匈牙利演算法如下:
定義
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),還挺高效
這個演算法講究的就是一個”將就“,有人來,那麼這個人就是上上賓,其他人都要依次讓一讓(按照演算法,退讓也有優先順序),大概也是一種中庸的社會態度吧。