中兴捧月-数字化婚姻配对


题目:

建立一个模型,来模拟推导社会男女择偶过程。

为了模型简化,一个人的特性指标有三个,这里假设为财富、样貌、品格,每个指标均可取值1-100之间任意数字。同样也对这3项指标有自己的需求。这3个需求值取值范围都在1-98间,当然三者的和必须为100.所以任意一个人可以用以下数组来表述:

G(A、B、C、A1、B1、C1)G代表男,M代表女。

举例G11(80、50、40、10、30、60),表示男11号,拥有财富80、样貌50、品格40,对异性品格的偏好为:财富在乎程度百分之10、样貌在乎程度百分之30、品格在乎程度百分之60。

同样为了模型简化,假设信息是完全对称的,即是说,每个人都能一眼就能看清楚任意一个人的财富、样貌、品格。

还是为了模型简化,我建模所用样本为男女各100个,即男女人数相同。

每个人对异性的满意度将如下定义:每个偏好指标与异性的对应的禀赋指标相乘,三个指标的乘积再相加,即他(她)对某个异性的满意度。

举例G11(80、50、40、10、30、60)对M(50、60、80、40、10、50)的满意度为:

(10*50+30*60+60*80)= 7100分

相对的 MM 对 GG的满意度则为:

(40*80+10*50+50*40) = 5700分

好了,配对活动开始,设计的配对法则如下:

1、100个男方,顺序,轮流从0号到99号女方中挑选自己最满意的一位,然后向她发出配对邀请。

2、接受邀请最多的女方开始行动,对这些邀请的男性中,选择最满意的一位。

3、那么这两位配对成功,剔除出样本,剩下的99对继续这样配对。

4、循环该配对法则,直到最后一对男女配对成功。

Person类

public class Person {
    private Integer  id; //标识
    private Integer  appearance; //样貌
    private Integer  character;  //品格
    private Integer  wealth; //财富
    private Integer  expectAppearance; //期望样貌
    private Integer  expectCharacter;  //期望品格
    private Integer  expectWealth; //期望财富
    private Integer  sex; //性别

    public Person(Integer id, Integer appearance, Integer character, Integer wealth, Integer expectAppearance, Integer expectCharacter, Integer expectWealth, Integer sex) {
        this.id = id;
        this.appearance = appearance;
        this.character = character;
        this.wealth = wealth;
        this.expectAppearance = expectAppearance;
        this.expectCharacter = expectCharacter;
        this.expectWealth = expectWealth;
        this.sex = sex;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getAppearance() {
        return appearance;
    }

    public void setAppearance(Integer appearance) {
        this.appearance = appearance;
    }

    public Integer getCharacter() {
        return character;
    }

    public void setCharacter(Integer character) {
        this.character = character;
    }

    public Integer getWealth() {
        return wealth;
    }

    public void setWealth(Integer wealth) {
        this.wealth = wealth;
    }

    public Integer getExpectAppearance() {
        return expectAppearance;
    }

    public void setExpectAppearance(Integer expectAppearance) {
        this.expectAppearance = expectAppearance;
    }

    public Integer getExpectCharacter() {
        return expectCharacter;
    }

    public void setExpectCharacter(Integer expectCharacter) {
        this.expectCharacter = expectCharacter;
    }

    public Integer getExpectWealth() {
        return expectWealth;
    }

    public void setExpectWealth(Integer expectWealth) {
        this.expectWealth = expectWealth;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

IO读取文本文件

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class IOFile {

    public static ArrayList<Person> read(String fileName, Integer sex) throws IOException {
        //文件路径
        String filePath = "D:\\Download\\attachment\\"+fileName;
        ArrayList<Person> peopleArr = new ArrayList<Person>();
        BufferedReader br = new BufferedReader(new FileReader(filePath));
        String str = "";
        String[] split = null;
        //判断是否是players文件
        if(sex == null){
            while ((str = br.readLine()) != null) {
                split = str.split(",");
                peopleArr.add(new Person(-1,
                        Integer.parseInt(split[1]),
                        Integer.parseInt(split[2]),
                        Integer.parseInt(split[3]),
                        Integer.parseInt(split[4]),
                        Integer.parseInt(split[5]),
                        Integer.parseInt(split[6]),
                        Integer.parseInt(split[0])));
            }
        }else {
            while ((str = br.readLine()) != null) {
                split = str.split(",");
                peopleArr.add(new Person(Integer.parseInt(split[0]),
                        Integer.parseInt(split[1]),
                        Integer.parseInt(split[2]),
                        Integer.parseInt(split[3]),
                        Integer.parseInt(split[4]),
                        Integer.parseInt(split[5]),
                        Integer.parseInt(split[6]),
                        sex));
            }
        }
        return peopleArr;
    }
}

Match类

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class Match {
    //匹配成功的Map集合
    static HashMap<Person,Person> maleFemale = new HashMap<Person,Person>();
    static HashMap<Person,Person> FemaleMale = new HashMap<Person,Person>();
    //心仪女生Map集合
    static HashMap<Person,ArrayList<Person>> femaleMap;
    //挑选规则
    public static void rule(ArrayList<Person> femaleArr, ArrayList<Person> maleArr, Person players){
        //添加主角
        if(players.getSex() == 0)
            femaleArr.add(players);
        else
            maleArr.add(players);
        //循环该规则 直到匹配结束
        for(int i = 0;i < 100;i++) {
            //男选女环节(选择环节)
            femaleMap = Match.select(femaleArr, maleArr);
            //统计最受欢迎的女生
            Person popularFemale = Match.Statistics(femaleMap);
            //女选男环节 返回最受欢迎的女生的心仪男生
            Person frontBoy = Match.personSelect(popularFemale, femaleMap.get(popularFemale));
            //剔除
            femaleArr.remove(popularFemale);
            maleArr.remove(frontBoy);
            //添加到匹配成功集合
            maleFemale.put(popularFemale, frontBoy);
            FemaleMale.put(frontBoy, popularFemale);
        }
        //在匹配成功的集合查询players主角
        if(maleFemale.containsKey(players)){
            System.out.println(players.getId()+" : "+maleFemale.get(players).getId());
        }else if(FemaleMale.containsKey(players)){
            System.out.println(FemaleMale.get(players).getId()+" : "+players.getId());
        }else{
            System.out.println("无结果");
        }
    }
    
    //选择环节
    public static HashMap<Person,ArrayList<Person>> select(ArrayList<Person> femaleArr, ArrayList<Person> maleArr){
        //心仪女生Map集合
        HashMap<Person,ArrayList<Person>> femaleMap = new HashMap<Person,ArrayList<Person>>();
        for(int i = 0;i < maleArr.size();i++){
            Person male = maleArr.get(i);
            //男女匹配 返回当前male的心仪女生
            Person frontGirl = Match.personSelect(male,femaleArr);  
            //判断femaleMap的key是否已经存在 存在的话,先取出再put
            if(femaleMap.containsKey(frontGirl)){   
            	//取出value
                ArrayList<Person> maleArrVal  = femaleMap.get(frontGirl); 
                maleArrVal.add(male);
                femaleMap.put(frontGirl,maleArrVal);
            }else{
            	//没有key不存在 则直接put
                ArrayList<Person> maleArrVal = new ArrayList<>(); 
                maleArrVal.add(male);
                femaleMap.put(frontGirl,maleArrVal);
            }
        }
        return femaleMap;
    }

    //匹配环节
    public static Person personSelect(Person person,ArrayList<Person> personArr){
    	//最高匹配度
        int matchValMax = 0;  
        //心仪人  
        Person frontPerson = null;  
        for(int i = 0;i < personArr.size();i++){
        	//当前进行匹配的人
            Person p = personArr.get(i);    
            //匹配度
            int matchValue = Match.Satisfied(person,p);  
            if(matchValue > matchValMax){
                matchValMax = matchValue;
                frontPerson = p;
            }else if(matchValue == matchValMax){    //如果心仪人和进行匹配的人匹配度相等 则进行择优
                if(Match.priority(frontPerson,p))
                    frontPerson = p;
            }
        }
        return frontPerson;
    }

    //统计最受欢迎的女生
    public static Person Statistics(HashMap<Person,ArrayList<Person>> femaleMap){
        int sizeMax = 0;
        Person femaleMax = null;
        for (Map.Entry<Person,ArrayList<Person>> entry : femaleMap.entrySet()) {
            Person female = entry.getKey();	
            //选择该女生的人数
            int size = entry.getValue().size(); 
            if(size > sizeMax){
                sizeMax = size;
                femaleMax = female;
            }else if(size == sizeMax){
                if(Match.priority(femaleMax,female))
                    femaleMax = female;
            }
        }
        return femaleMax;
    }

    //满意度
    public static int Satisfied(Person person1,Person person2){
        return  person1.getExpectAppearance() * person2.getAppearance() +
                person1.getExpectCharacter() *  person2.getCharacter() +
                person1.getExpectWealth() *  person2.getWealth();
    }

    //优先度
    public static boolean priority(Person person1,Person person2){
        int attribute = person1.getAppearance() + person1.getCharacter() + person1.getWealth();
        int attribute2 = person2.getAppearance() + person2.getCharacter() + person2.getWealth();
        //判断两人的属性和大小
        if(attribute < attribute2)
            return true;
        //如果相等 则取id小的人
        if(attribute == attribute2)
            return person1.getId() > person2.getId();
        return false;
    }

    public static void main(String[] args) throws IOException {
        //文件名
        String femaleFile = "female.txt";
        String maleFile = "male.txt";
        String playersFile = "players.txt";

        //Person集合(0为女,1为男,null为主角)
        ArrayList<Person> femaleArr = IOFile.read(femaleFile,0);
        ArrayList<Person> maleArr = IOFile.read(maleFile,1);
        ArrayList<Person> playersArr = IOFile.read(playersFile,null);
		//依次添加主角
        for(int i = 0;i < playersArr.size();i++){
            Person players =  playersArr.get(i);
            //挑选匹配
            Match.rule((ArrayList<Person>) femaleArr.clone(),(ArrayList<Person>) maleArr.clone(),players);
        }
    }
}


你可能感兴趣的:(集合)