稳定婚姻问题

婚姻匹配问题是2012年诺贝尔经济学奖获得者L.S.shapley以及 D.Gale在1962年给出的。据说这也是shapley得到诺贝尔经济学奖重要贡献之一。

问题:

稳定婚姻问题是一个很有意思的匹配问题,有n位男士和n位女士,每一个人都对每个异性有一个喜好度的排序,代表对他的喜爱程度,现在希望给每个男士找一个女士作配偶,使得每人恰好有一个异性配偶。如果男士u和女士v不是配偶但喜欢对方的程度都大于喜欢各自当前配偶的程度,则称他们为一个不稳定对。稳定婚姻问题就是希望找出一个不包含不稳定对的方案。

算法:

先对所有男士进行落选标记,称其为自由男。当存在自由男时,进行以下操作:
①每一位自由男在所有尚未拒绝她的女士中选择一位被他排名最优先的女士;
②每一位女士将正在追求她的自由男与其当前男友进行比较,选择其中排名优先的男士作为其男友,即若自由男优于当前男友,则抛弃前男友;否则保留其男友,拒绝自由男。
③若某男士被其女友抛弃,重新变成自由男。
C语言代码如下:
#include<malloc.h>
#include<stdio.h>

typedef struct node {
	bool ready;
	int *p;
	int spouse;
} status, *identify;

typedef struct {
	int num;
	identify man;
	identify woman;
} table, *tablep;

tablep init_alloc(int num);
void init_dgree(tablep tableshow);
void stable_mar(tablep tableshow);
int compwoman(int mani, int manj, tablep tableshow, int womannum);
void print(tablep tableshow);

int main()
{
	int num; //ÈËÊý

	tablep tableshow;
	printf("please input the num of the people\n");
	scanf("%d", &num);
	tableshow = init_alloc(num);
	init_dgree(tableshow);
	stable_mar(tableshow);
	print(tableshow);
	return 0;
}

tablep init_alloc(int num) //Ϊÿһžö²ÎÓëÕß·ÖÅä¿ÕŒä
{
	int i;
	tablep tableshow;
	tableshow = (tablep)malloc(sizeof(table));
	tableshow->woman = (identify)calloc(num, sizeof(status));//Å®
	for(i = 0; i < num; i++) {
		tableshow->woman[i].p = (int*)malloc(sizeof(int)*num);
		tableshow->woman[i].spouse = -1;
	}

	tableshow->man = (identify)calloc(num, sizeof(status));//ÄÐ
	for(i = 0; i < num; i++) { 
		tableshow->man[i].p = (int*)malloc(sizeof(int)*num);
		tableshow->man[i].spouse = -1;
	}
	tableshow->num = num;	
	return tableshow; 
}

void init_dgree(tablep tableshow) //Æ«ºÃ³õÊŒ»¯
{
	int i, j;

	printf("please input the rank of all the man\n");	
	for(i = 0; i < tableshow->num; i++) { 
		printf("the num %d\n", i);
		for(j = 0; j < tableshow->num; j++)
			scanf("%d", &tableshow->man[i].p[j]);
	}
	
	printf("please input the rank of all the woman\n");
	for(i = 0; i < tableshow->num; i++) {
		printf("the num %d\n", i);
		for(j = 0; j < tableshow->num; j++)
			scanf("%d", &tableshow->woman[i].p[j]);
	}
}

void stable_mar(tablep tableshow)//Îȶš»éÒöËã·š
{
	int i;
	int numstack = tableshow->num - 1;
	int mannum;
	int spouse;

	int *manset = (int*)malloc(sizeof(int)*tableshow->num);
	for(i = 0; i < tableshow->num; i++) 
		manset[i] = i;
	int *top = &manset[tableshow->num - 1];
	while(numstack >= 0) {
		mannum = *(top--);
		numstack--;
		i = 0;
			while ((tableshow->woman[tableshow->man[mannum].p[i]].ready == 1) && (compwoman(mannum, tableshow->woman[tableshow->man[mannum].p[i]].spouse, tableshow, tableshow->man[mannum].p[i]) < 0)) 
				i++;
			tableshow->man[mannum].spouse = tableshow->man[mannum].p[i];
			tableshow->woman[tableshow->man[mannum].p[i]].ready = 1;
			spouse = tableshow->woman[tableshow->man[mannum].p[i]].spouse;
	        tableshow->woman[tableshow->man[mannum].p[i]].spouse = mannum;
			if((compwoman(mannum, spouse, tableshow, tableshow->man[mannum].p[i])) > 0 && spouse != -1) {
				top++;
				*top = spouse;
				numstack++;
			}
	}
}

int compwoman(int mani, int manj, tablep tableshow, int womannum)//
{
	int k = 0;
	while((tableshow->woman[womannum].p[k] != mani) && (tableshow->woman[womannum].p[k] != manj))
		k++;
	if(tableshow->woman[womannum].p[k] == mani)
		return 1;
	else return -1;
}

void print(tablep tableshow)
{
	int i = 0;

	for(; i < tableshow->num; i++) 
		printf("%d-%d\n", i, tableshow->man[i].spouse);
}
	




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值