稳定匹配问题(The Stable Matching/Marriage Problem)----java

本文介绍了一个基于StableMatching理论的编程问题,描述了如何根据给定的男性和女性的优先级列表,找到稳定匹配并输出指定男人的伴侣编号。给出了Java代码实现,包括优先级矩阵的读取和匹配过程的逻辑。
摘要由CSDN通过智能技术生成

一、问题

Description

The Stable Matching/Marriage Problem states that given N men and N women, where each person has ranked all members of the opposite sex in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners. If there are no such people, all the marriages are “stable”

Input

the input contains 1+2N Lines,for example:

2 1
1 0
0 1
0 1
0 1

the first line has two numbers,the first number N means we have N men and N women to match,the second number K( 0<= K <= N-1 ) stands for the man'number we choose to check your matching result.the rest 2N lines are the preference list of the n men(count from 0 to n-1) and then the n women(count from 0 to n-1)'sin the example shown above,the correct matching result is:(man 0,women 1) (man 1,women 0)when K=1,the output should be man 1's partner's number ,which is 0

中文说明:

输入有1+2N行,第一行有两个数组N和K,N代表有N个男人和N个女人,K用于输出结果,接下来的N行为N个男人(编号为0到N-1)的优先级列表,如1 0 代表该男人的优先级中,woman1优先于woman0再接下来的N行为N个女人人(编号同样为0到N-1)的优先级列表,如0 1代表该女人的优先级中man1优先于man1

输出应为一个数字,代表匹配完成后,编号为K的男人所匹配女人的编号,上面的例子中,由于稳定匹配为:(男人0,女人1) (男人1,女人0)而输入中K=1,则输入应为男人1的匹配对象女人0,输出为一个数字,即:0

Output

should be a number that which woman was match to the Kth man

see the description and output example for more details

Sample Input 1 

4 3
3 1 2 0
1 0 2 3
0 1 2 3
0 1 2 3 
0 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3

Sample Output 1

2

二、代码实现

import java.util.*;
public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();//男女数量为n
        int k = sc.nextInt();//第k
        int mprefer[][] = new int[n][n];//男生的偏爱表
        int wprefer[][] = new int[n][n];//女生的偏爱表


        for(int i = 0;i<n;i++){
            for(int j = 0;j<n;j++){
                mprefer[i][j] = sc.nextInt();
            }
        }

        //女的偏爱顺序
        for(int i = 0;i<n;i++){
            for(int j = 0;j<n;j++){
                wprefer[i][j] = sc.nextInt();
            }
        }

        int wpartner[] = new int[n];
        Arrays.fill(wpartner,-1);//将wpartner的值置为-1,代表没有伴侣

        boolean mFree[] = new boolean[n];
        Arrays.fill(mFree,false);//false代表男的自由


        int mfreecount = n;//自由男的数量

        while(mfreecount>0){//没有男的自由,都找到了伴侣,结束
            int m;//找到自由的男m,去表白
            for(m = 0;m<n;m++){
                if(mFree[m] == false){
                    break;
                }
            }
            for(int i = 0;i<n && mFree[m] == false;i++){//表白成功后mFree[m] == true,停止表白

                int w = mprefer[m][i];//男m向偏爱表的第i位表白

                if(wpartner[w] == -1){//如果女w没有伴侣
                    wpartner[w] = m;
                    mFree[m] = true;
                    mfreecount--;
                }else{//如果女w有伴侣m1,比较男m和男m1的优先级
                    int m1 = wpartner[w];
                    if(compare(wprefer,w,m,m1,n)){//男m靠前返回true
                        wpartner[w] = m;
                        mFree[m] = true;
                        mFree[m1] = false;
                    }
                }

            }

        }

        //输出伴侣为k的女生
        for(int i=0;i<n;i++){
            if(wpartner[i] ==k){
                System.out.println(i);
                break;
            }
        }

        sc.close();
    }

    public static boolean compare(int[][] wprefer,int w,int m,int m1,int n) {
        for(int i = 0;i<n;i++){//如果男m比较靠前,函数return ture 函数结束
            if(wprefer[w][i]==m){
                return true;
            }
            if(wprefer[w][i]==m1){
                return false;
            }
        }
        return false;
    }

}

提示:读者你好,如果有什么错误,请你提醒,我会及时修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

motu2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值