稳定婚姻匹配问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://mp.csdn.net/mdeditor/100522971#

稳定匹配婚姻问题

1. 算法描述
有n个男人,还有n个女人,男人心目中有自己的心上人列表,从最喜欢的女神一直排列下去,而女人心中也有相同的列表。怎样分配才是稳定的?
2. 算法分析
假设有五个男人(A),五个女人(B),他们对五位异性的偏好程度用矩阵表示。0-4代表不同男人和女人,同一行表示一个男人,序号的先后表示喜爱的程度
男人偏爱矩阵:
0 1 2 4 3(表示0号男生喜欢的先后顺序是 0号女生 1号女生 2号女生 4号女生 3号女生)
0 2 1 3 4
4 0 2 1 3
2 1 3 0 4
2 0 1 3 4
女人偏爱矩阵:
4 0 1 3 2
3 1 2 0 4
3 2 1 4 0
0 1 3 2 4
2 3 4 1 0
算法求解过程
1、对每 个a∈A. 选取a最偏爱的一 个b∈B
■若b还未配对,那么可将a与b配对
■若b已和另一个a’∈A配对,且b偏爱a大于
a’, 那么可将a与b配对, 此时a变成未配对的
■若b已和另一个a’ ∈A配对, 且b偏爱a’大于a,那么转a下一个偏爱的b
2、当男生全部都分配之后结束,否则转第一步

3. 代码

#include <stdio.h>
#define n 5
int man[n][n];
int woman[n][n];
int flag,sign;
int m,s;
int boy[n];
void creat()
{   int i,j;
    printf("请输入男生偏好矩阵:\n");
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        scanf("%d",&man[i][j]);
    }
    printf("请输入女生偏好矩阵:\n");
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        scanf("%d",&woman[i][j]);
    }
    for(i=0;i<n;i++)
        boy[i]=-1;//下标代表第几号男生,数组值代表匹配到的女生号,初始值为-1,表示未分配。
}//输入矩阵
void display()
{
    int i,j;
    printf("男生偏好矩阵:\n");
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {printf("%4d",man[i][j]);
        }
        printf("\n");
    }
    printf("女生偏好矩阵:\n");
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {printf("%4d",woman[i][j]);
        }
        printf("\n");
    }
}//输出矩阵
void ifalloc(int x,int y)
{
    int i,k;
    for(i=0;i<n;i++)
    {
        if(man[x][y]==boy[i]&&i!=x)
        {
            sign=i;flag=1;//sign保存女生当前匹配的男生序号
            break;
        }
        else
            flag=0;
    }
}//判断男生当前想选择的女生是否被匹配
void find(int x,int y)
{
    int i;
    for(i=0;i<n;i++)
    {
        if(sign==woman[man[x][y]][i])
            m=i;//现在已匹配男生的偏爱程度
        else
            {
            if(x==woman[man[x][y]][i])
               s=i;//对当前男生的偏爱程度
               else
                continue;
            }
    }
}//判断女生对当前男生和现在已匹配男生的偏爱程度
void allocation()
{
    int i,j;
    for(i=0;i<n;i++)
    for(j=0;j<n;j++)
     {
        {
           ifalloc(i,j);
        if(flag==0)
           {
               boy[i]=man[i][j];//如果该女士没有被其他男生选择,则分配给当前男生
               break;
           }
        else
        {
         find(i,j);
         if(s<m)
         {
             boy[i]=man[i][j];//如果女生更喜欢当前男生,则把女生分配给当前男生
             boy[sign]=-1;
             break;
             }

         else
         {
             continue;//如果女生更喜欢已分配男生,则当前男生按偏爱程度继续选择女生
         }
        }
        }
     }
}
void ifnull()
{
        while(boy[0]==-1||boy[1]==-1||boy[2]==-1||boy[3]==-1||boy[4]==-1)
        {
            allocation();
        }//如果有男生没有分配到女生,则继续分配直到分配完成
}
void print()
{
    int i;
    for(i=0;i<n;i++)
    {
        printf("%d",boy[i]);
    }
}
void main()
{
    creat();
    display();
    allocation();
    ifnull();
    print();
}

4. 测试结果
在这里插入图片描述
结果是31420,表示匹配为:
0号男生和3号女生配对
1号男生和1号女生配对
2号男生和4号女生配对
3号男生和2号女生配对
4号男生和0号女生配对

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值