Initialize all men and women to free
while there exist a free man m who still has a woman w to propose to
{
w = m's highest ranked such woman to whom he has not yet proposed
if w is free
(m, w) become engaged
else some pair (m', w) already exists
if w prefers m to m'
(m, w) become engaged
m' becomes free
else
(m', w) remain engaged
}
bool woman_prefer(int prefer[2*N][N],int woman,int man1,int man2)
{
for(int i = 0; i < N; i++)
{
//if we encounter man1 first, which indicates man1 ranks higher than man2
if(prefer[woman][i] == man1)
return true;
if(prefer[woman][i] == man2)
return false;
}
}
void stable_marriage(int prefer[2*N][N])
{
//stores partner of woman, this is our output array that stores paing infor
//the value of w_partner[i] indicates the partner assigned to woman N+i.Note that
//the woman number between N and 2N-1,the value -1 indicates that (N+i)th woman is free
int w_partner[N];
memset(w_partner,-1,sizeof(w_partner));
queue<int> free_man;//it stores the no. of free man
for(int i = 0; i < N; i++)
free_man.push(i);
//the proposed indice of man, proposed_indice[i] means the highest indice of
//woman which he has proposed to before
int proposed_indice[N];
memset(proposed_indice,-1,sizeof(proposed_indice));
while(!free_man.empty())
{
int man = free_man.front();
free_man.pop();//弹出一个free man
//this indice of highest ranked woman who has not been proposed
int index_propose = ++proposed_indice[man];
//the woman who has not been proposed by this man
int woman = prefer[man][index_propose];
//if this woman is free, then they are engaged
if(w_partner[woman-N] == -1)
{
w_partner[woman-N] = man;
}
// if this woman has a partner
else
{
int man_other = w_partner[woman-N];
//if this woman prefer man to man_other,then the woman engaged
//man and dumped man_other
if(woman_prefer(prefer,woman,man,man_other))
{
w_partner[woman-N] = man;
free_man.push(man_other);
}
else
free_man.push(man);
}
}
cout << " woman man " << endl;
for(int i = 0; i < N; i++)
cout << " " << i+N <<"\t"<< w_partner[i] << endl;
}
int main()
{
/*int prefer[2*N][N] ={{7, 5, 6, 4},
{5, 4, 6, 7},
{4, 5, 6, 7},
{4, 5, 6, 7},
{0, 1, 2, 3},
{0, 1, 2, 3},
{0, 1, 2, 3},
{0, 1, 2, 3}};*/
int prefer[2*N][N] ={{7, 5, 6, 9,8},
{5, 8,9, 6, 7},
{9,5, 8, 6, 7},
{8, 5, 6, 7,9},
{9,8,7,6,5},
{0, 1, 2, 3,4},
{0, 1,4, 2, 3},
{4,0, 1, 2, 3},
{0, 1, 4, 3,2},
{4,3,2,1,0}};
stable_marriage(prefer);
return 0;
}
分析:每次man从他的prefer list中寻找一个然后求婚,这样求婚对数最大为n^2,每次迭代消除一对所以循环的最大次数为O(n^2)。故算法肯定收敛。而一旦某个woman配对成功后就永远保持配对(但可以换配偶),所以最终肯定是n对。而且肯定是stable的,用反证法即可证明.