蓋爾沙普利算法,可以用來解決徵婚交友的穩定匹配問題。
#include <stdio.h>
#include <stdlib.h>
#define MALE_NUM (3)
#define FEMALE_NUM (MALE_NUM)
/**
male female
a(edf) d(abc)
b(efd) e(cba)
c(fed) f(bac)
find stable match
*/
#define NO_MATCH_IDX (0xff)
struct partner
{
char name[64];
int mate;
int prefer[3];
int matched;
};
struct partner males[3] =
{
{"a", NO_MATCH_IDX, {1,0,2}, 0},
{"b", NO_MATCH_IDX, {1,2,0}, 0},
{"c", NO_MATCH_IDX, {2,1,0}, 0},
};
struct partner females[3] =
{
{"d", NO_MATCH_IDX, {0,1,2}, 0},
{"e", NO_MATCH_IDX, {2,1,0}, 0},
{"f", NO_MATCH_IDX, {1,0,2}, 0},
};
int girl_has_mate(int girl)
{
return females[girl].matched;
}
void print_match()
{
int i = 0;
for (i = 0; i < FEMALE_NUM; i++)
{
if (girl_has_mate(i))
{
printf("%s<--->%s\n", females[i].name, males[females[i].mate].name);
}
}
}
int get_girl_prefer_degree(int girl, int boy)
{
int i = 0;
int degree = -1;
for (i = 0; i < MALE_NUM; i++)
{
if (females[girl].prefer[i] == boy)
{
degree = i;
}
}
return degree;
}
int girl_prefer_this_boy(int girl, int boy)
{
int prefer = 0;
int mate_degree = get_girl_prefer_degree(girl, females[girl].mate);
int boy_degree = get_girl_prefer_degree(girl, boy);
if (boy_degree < mate_degree)
{
prefer = 1;
}
return prefer;
}
int male_select(int boy, int girl)
{
int i = girl;
if (girl_has_mate(i))
{
if (girl_prefer_this_boy(i, boy))
{
males[boy].mate = i;
males[boy].matched = 1;
/**girl's mate is free*/
males[females[i].mate].matched = 0;
males[females[i].mate].mate = NO_MATCH_IDX;
/**girl select new mate*/
females[i].mate = boy;
females[i].matched = 1;
}
}
else
{
males[boy].mate = i;
males[boy].matched = 1;
females[i].mate = boy;
females[i].matched = 1;
}
return 0;
}
int male_match(int boy)
{
int i = 0;
for (i = 0; i < FEMALE_NUM; i++)
{
int girl = males[boy].prefer[i];
male_select(boy, girl);
if (males[boy].matched)
{
break;
}
}
return 0;
}
int find_unmatched()
{
int find_idx = NO_MATCH_IDX;
int i = 0;
for (i = 0; i < MALE_NUM; i++)
{
if (males[i].matched == 0)
{
find_idx = i;
break;
}
}
return find_idx;
}
int gale_sap_male_first()
{
int boy = 0;
do
{
male_match(boy);
boy = find_unmatched();
}while(boy != NO_MATCH_IDX);
print_match();
return 0;
}
int main()
{
gale_sap_male_first();
getchar();
return 0;
}