zoukankan      html  css  js  c++  java
  • 稳定匹配问题(脱单就靠这波了)

    稳定匹配问题之三国

    首先,我们先看看问题:

    有n个男人和n个女人(n>=2),每个男人对所有女人有一个好感度排名,每个女人对所有男人也有一个好感度排名。将男女两两配对,得到n对男女,称之为一个完美匹配。如果有一组男女A和B,他们在匹配中没有被配对,且对对方的好感度均大于对现有配偶的好感度(男人A觉得女人B好过现在的妻子C,女人B觉得A好过现在的丈夫D),则称之为一个不稳定配对。如果一个完美匹配中没有不稳定配对,则称改匹配为一个稳定匹配。

    男对女|女对男
    左图是男对女的好感度,右图是女对男的好感度
    思路:
    首先,拿到这个题,一次性写出是不现实的,也就是说,这其实也就是一个不断尝试的过程,也就是说,我们匹配之后,需要对已经匹配的序列确保排序没有问题,达到稳定匹配,当然想选择和自己最喜欢的人在一起了,但是,最为上帝,得考虑到全局,也就是说大家尽量都是彼此更爱的人,没有一个你爱的人他身边的人更爱的你身边的人,你身边的人更爱他身边的人。哈哈哈哈,有点绕了。但是我们的目的也就是找出一个稳定匹配。

    #include<stdio.h>
    #include<stdlib.h>
    #define num 5
    
    int m[num][num]={{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}};
    //男生对女生的偏爱程度
    int w[num][num]={{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}};
    //女生对男生的偏爱程度
    int s1[num]={-1,-1,-1,-1,-1};    //男生是否配对  -1否 其它为配对女生的序号
    int s2[num]={-1,-1,-1,-1,-1};    //女生是否配对  -1否 其它为配对男生的序号
    void output() //输出两个偏好矩阵
    {
        printf("男:0->吕布,1->刘备,2->孔明,3->周瑜,4->曹操
    ");
        printf("女:0->貂蝉,1->大乔,2->小乔,3->尚香,4->阿丑
    ");
        int i,j;
        printf("男生偏好矩阵:
    ");
        for(i=0;i<num;i++)
        {
            printf("男%d:",i);
            for(j=0;j<num;j++)
            {
                printf("% d",m[i][j]);
            }
            printf("
    ");
        }
        printf("女生偏好矩阵:
    ");
        for(i=0;i<num;i++)
        {
            printf("女%d:",i);
            for(j=0;j<num;j++)
            {
                printf("% d",w[i][j]);
            }
            printf("
    ");
        }
    }
    
    void match()    //匹配
    {
        int i,j,k;
        int old, now;
        for(i=0;i<num;i++){
            if(s1[i]==-1){    //该男生没有有匹配对象
                for(j=0;j<num;j++)
                {
                    if(s2[m[i][j]]==-1){ //如果心仪女神没有配对,则配对
                        s1[i]=m[i][j];
                        s2[m[i][j]]=i;
                        break;
                    }else{  //如果心仪女神有配对
                        old=now=-1;
                        //寻找女生现男友在女生心仪对象列表的下标
                        for(k=0;k<num;k++)
                            if(w[m[i][j]][k]==s2[m[i][j]])
                                old = k;
                        //寻找当前男生在女生心仪对象列表的下标
                        for(k=0;k<num;k++)
                            if(w[m[i][j]][k]==i)
                                now = k;
                        if(old>now){ //如果女生更加偏爱该男生,则换对象
                            s1[i]=m[i][j];  //当前男生
                            s2[m[i][j]]=i;
                            s1[w[m[i][j]][old]]=-1; //前男友
                            break;
                        }
                         //如果女生更加偏爱现在男生,则替换下一个女生
                    }
                }
            }
        }
        for(i=0;i<num;i++)    //是否所有的男生都配对完成
        {
            if(s1[i]==-1){
                match();
                break;
            }
        }
    }
    void display()  //输出配对完成后的男女搭配
    {
        int i;
        printf("man —— woman
    ");
        for(i=0;i<num;i++)
        {
            printf(" %d  ——  %d
    ",i,s1[i]);
        }
    }
    int main()
    {
        output();
        match();
        display();
    }
    

    注释写了大致的算法逻辑部分,应该可以看懂的

  • 相关阅读:
    springboot 多日志
    物联⽹项目框架
    IDEA 行注释、块注释、方法或类说明注释。
    c#监听tomcat服务
    active mq start
    物联网使用启动命令 Redis activemq
    最新通达OA11.6文件删除+任意文件上传rce漏洞复现
    KTS7 kibana模板
    C/C++ 程序反调试的方法
    友情链接
  • 原文地址:https://www.cnblogs.com/Indomite/p/14195239.html
Copyright © 2011-2022 走看看