算法笔记_138:稳定婚姻问题(Java)

目录

1 问题描述

2 解决方案

 


1 问题描述

何为稳定婚姻问题?

有一个男士的集合Y = {m1,m2,m3...,mn}和一个女士的计划X = {n1,n2,n3,...,nn}。每一个男士有一个排序的列表,把女士按照潜在的优先级进行排序。同样,每一个女士也有一个男士的优先级列表。现在,把男士和女士进行配对,要求尽可能的符合优先级的要求。使得最终的配对结果,男士对女士都可接受,不会出现拒绝的情况,即每对男士和女士都是稳定的。

 


2 解决方案

上述对于稳定婚姻问题的解释有点牵强,具体可以看一下下面截图:

 

 

下面代码所使用的男士和女士集合数据是上图的实例,即男士3人,女士3人。

具体代码如下:

 

package com.liuzhen.practice;

import java.util.Scanner;

public class Main {
    
    public void getResult(int[][] boys, int[][] girls) {
        int[] result = new int[boys.length];
        int[] used = new int[girls.length];   //最终女士配对的男士
        for(int i = 0;i < girls.length;i++) {
            used[i] = -1;
            result[i] = -1;
        }
        int count = 0;   //统计已完成配对个数
        while(count < boys.length) {
            for(int i = 0;i < boys.length;i++) {
                if(result[i] != -1)   //当男士i已完成配对时,进行下一个男士配对
                    continue;
                for(int j = 0;j < boys[0].length;j++) {
                    if(used[boys[i][j]] == -1) {
                        used[boys[i][j]] = i;       //女士boys[i][j]与男士i配对
                        result[i] = boys[i][j];    //男士i和女士boys[i][j]配对
                        break;  //男士i完成配对,退出循环
                    } else {
                        int temp = 0, temp1 = 0;
                        for(;temp < girls[0].length;temp++) {  //求出男士i在女士boys[i][j]心中的优先级
                            if(girls[boys[i][j]][temp] == i)
                                break;
                        }
                        for(;temp1 < girls[0].length;temp1++) { //求出当前女士已配对男士在其心中的优先级
                            if(girls[boys[i][j]][temp1] == used[boys[i][j]])
                                break;
                        }
                        if(temp < temp1) {  //当男士i比目前已与女士配对的男士优先级要高时
                            result[used[boys[i][j]]] = -1;   //已配对男士被踢
                            used[boys[i][j]] = i;    //当前女士的配偶换成男士i
                            result[i] = boys[i][j];
                            break;       //男士i完成配对,退出循环
                        }
                    }
                }
            }
            count = 0;
            for(int i = 0;i < used.length;i++) {
                if(used[i] != -1)
                    count++;
            }
        }
        //打印出结果
        for(int i = 0;i < result.length;i++)
            System.out.println("男士"+i+"和女士"+result[i]+"配对");
        return;
    }
    
    public static void main(String[] args) {
        Main test = new Main();
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[][] boys = new int[n][n];         //男士的心中对象优先级
        int[][] girls = new int[n][n];        //女士的心中对象优先级
        for(int i = 0;i < n;i++) { 
            int one = in.nextInt();   //优先级为1
            int two = in.nextInt();   //优先级为2
            int three = in.nextInt();  //优先级为3
            boys[i][0] = one;
            boys[i][1] = two;
            boys[i][2] = three;
        }
        for(int i = 0;i < n;i++) {
            int one = in.nextInt();   //优先级为1
            int two = in.nextInt();   //优先级为2
            int three = in.nextInt();  //优先级为3
            girls[i][0] = one;
            girls[i][1] = two;
            girls[i][2] = three;
        }
        test.getResult(boys, girls);
    }
}

 

运行结果:

3
1 0 2
1 2 0
2 1 0
1 2 0
2 0 1
1 2 0
男士0和女士0配对
男士1和女士2配对
男士2和女士1配对

 

 

 

参考资料:

   1.《算法设计与分析基础》第3版  Anany Levitin 著   潘彦 译

 

posted @ 2017-04-20 13:10  舞动的心  阅读(783)  评论(0编辑  收藏  举报