$2$ 種類のグループ(男女など)の間での安定マッチングを求めるアルゴリズム. このような問題を安定結婚問題とも言う.
男女それぞれが相手のグループのメンバーに対しての優先順位を持っているとする. ここである男 $i$, 女 $j$ について $i$ が $j$ よりも優先順位の低いメンバーとマッチングしていて, $j$ も $i$ より優先順の低いメンバーとマッチングしているとき、このようなペアを blocking pair とする.
このような blocking pair の存在しないマッチングを安定マッチングと呼ぶ. このようなマッチングは常に存在することが GaleSharpley のアルゴリズムから構成的に分かる.
元論文は "College Admissions and the Stability of Marriage" [Gale Sharpley 1962]
(関数)
solve$(mpref, wpref)$ : 優先度の高い順に相手の ID を格納した行列を $2$ つ渡す(男性が申し込む場合の実装である).
時間計算量: $\O (n^2)$
- class GaleSharpley
- {
- public:
- GaleSharpley(){}
- vector<int> solve(const vector<vector<int> >& mpref, const vector<vector<int> >& wpref)
- {
- int n = mpref.size();
- vector<vector<int> > worder(n, vector<int>(n));
- stack<int> single;
- for(int i = 0; i < n; ++i){
- single.push(i);
- for(int j = 0; j < n; ++j){
- worder[i][wpref[i][j]] = j;
- }
- }
- vector<int> id_pos(n, 0);
- vector<int> wtom(n, -1);
- while(!single.empty()){
- int man = single.top();
- single.pop();
- while(true){
- int woman = mpref[man][id_pos[man]++];
- if(wtom[woman] < 0){
- wtom[woman] = man;
- break;
- }else if(worder[woman][wtom[woman]] > worder[woman][man]){
- single.push(wtom[woman]);
- wtom[woman] = man;
- break;
- }
- }
- }
- vector<int> mtow(n);
- for(int i = 0; i < n; ++i)
- mtow[wtom[i]] = i;
- return mtow;
- }
- };
verify していません(verify 問題を知らない)