Gale-Shapley 稳定匹配算法的C++实现
背景简述
Gale-Shapley 算法是针对稳定匹配问题提出的一种经典算法。
背景资料:考虑n对男女的配对,其中每个男生有一个心仪女生排序,而每个女生也有一个心仪男生排序。每个男生、女生都想匹配到自己最心仪的异性,但现实情况中上总会有一个男生(或女生)至少是两个女生的共同的最心仪对象。那么就需要找到一种折中的匹配方式,使得配对后的每对伴侣都不会再因追求更好伴侣,而产生配对破裂,即一种稳定的匹配。
稳定匹配的内涵
即每对配对成功的情侣,总是存在这种情况:
以情侣中的男性 X 举例,假如他的配偶不是他最心仪的异性 A,A 的当前配偶是Y,Y 在 A 心目中排序要比 X 高。那么 A 就不会舍弃当前配偶 Y,而去与 X 进行配对。假设 X 的当前配偶为 B , 同样的,所有在 X 的心目中比 B排名靠前的异性,都是这种情况,那么 B就是 X所能配到的稳定配偶;类似的,B 的稳定配偶也是 X。 则这一对配对就是稳定的。
Gale-Shapley 算法的伪码表示
Initialize each person to be free.
while (some man is free and hasn’t proposed to every woman)
{
Choose such a man m
w = 1st woman on m’s list to whom m has not yet proposed
if (w is free)
assign m and w to be engaged
else if (w prefers m to her fiancé m’)
assign m and w to be engaged, and m’ to be free
else
w rejects m
}
Gale-Shapley 算法的C++实现
实现思路
设置一个男生求婚函数,每次求婚时调用此函数,对其心仪女生进行降序求婚,直至该男生求婚成功;
设置一个女生判断函数,判断此次是否接受该男生的求婚,值得注意一点是,当女生抛弃当前对象而接受目前求婚对象时,函数应将该被抛弃的男生号码以某种形式传出;
设定一个男生待匹配队列 unpaired_man[n];
最开始将所有男生都装入此队列;
每次将队列头部的男生取出,调用求婚函数进行求婚,而被求婚女生则调用判断函数,当发生女生需要抛弃当前对象时,函数应接受到被抛弃男生的号码,将其配偶情况及配对情况进行重置,并压入队列尾部。
循环操作,直至男生待匹配队列为空,则匹配完成。
代码段
#include "stdafx.h"
#include <queue>
#include <iostream>
#include <Windows.h>
using namespace std;
class man
{
int m[5];
int m_ID;
bool is_married ;
int proposal_count;
int married_ID ;
friend class woman;
friend void GS_Matching(man* _M, woman *_WM);//进行GS算法配对
friend void func(man *_m); //输出每个男生的配对信息
public:
void propose(woman &_wm, man *_M); //男生的求婚函数,每次对一个女生求婚
man(int *_m, int _m_ID) // 构造函数对男生进行初始化
{
for(int i=0; i<5; i++)
{
m[i]=*_m; _m++;}
m_ID = _m_ID;
is_married = 0;
proposal_count = 0;
married_ID = 0;
}
man(){
}
void printInfo(man _M)//输出每个男生的心仪女生信息
{
cout<<"这是第"<<_M.m_ID<<"个男生"<<endl;
cout<<"他的排序是"<<_M.m[0]<<" "<<_M.m[1]<<" "<<_M.m[2]<<" "<<_M.m[3]<<" "<<_M.m[4]<<" "<<endl;
}
};
class woman
{
int wm[5];
int w_ID;
bool is_married;
int current_manID;
int unlucky_m;
friend class man;
friend void GS_Matching(man* _M, woman *_WM);//进行GS算法配对
friend void func(woman *_wm); //输出女生的配对信息
public:
woman(int *_wm, int _wm_ID)
{
for