中兴捧月-数字化婚配

一、标题:

    数字化婚姻配对尝试

二、题目:

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

为了模型简化,一个人的特性指标有三个,这里假设为财富、样貌、品格,每个指标均可取值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、循环该配对法则,直到最后一对男女配对成功。

三、初赛阶段要求:

1、编程语言为java,C++或C语言任意一种;运行环境windows。

2、能让用户输入自己的参数以及对各项数值的偏好,然后随机生成100位男性100位女性(包括用户在内。如果用为男性则为99男100女),数值全部随机但需满足题设限制。按照上述规则给出一个匹配结果呈现给用户。

3、若采用c/c++,要输出可执行程序;若采用java,给出jar和bat。

4、在匹配时,如果发现有多个满意度相同的对象,要求自身三个属性(财富,外貌,品格)总和大的优先,如果再相同则id小的优先。如果有2位女士的选票相同,优先级规则同上。请把主角的id置为最小值,以便在前2个条件相同情况下,主角可以优先选择。

5、程序读取指定的配置文件,获取样本,然后根据指定的输入,输出结果。同时会给出一组源数据和标准答案给学生自测。最后再让学生根据不同的,指定的输入,给出考试答案。

  请点击下载配置文件附件。附件中,male.txt,female.txt,players.txt 分别是男士样本、女士样本和主角样本各 100位。 男女样本中,每行都代表一位男士或女士的基本属性,从左到右依次是ID, 样貌,品格,财富 , 期望样貌,期望品格,期望财富,没有加入性别,需要在解析时手动添加,每个txt文本的性别都是一样的,请注意。另外,主角样本中没有ID属性,换成了性别属性,其中 0表示女性,1表示男性,其余属性依次为样貌,品格,财富,期望样貌 ,期望品格,期望财富。建议把主角的id都设置为 -1,以便满足优先选择的条件。

给出标准答案2组,用于考生自测:

1号主角(文本第一行),选择的对象属性为(6,18,82,87,3,10)

2号主角(文本第二行),选择的对象属性为(27,74,22,22,58,20)

同时要求考生输出9号主角(0,72,55,53,8,87,5),19号主角(0,11,4,63,22,60,18),47号主角(1,19,8,21,1,53,46),83号主角(1,23,11,17,58,31,11),99号主角(1,26,66,1,78,11,11)以及100号主角(0,68,28,19,43,11,46)的选择结果。

四、初赛阶段审核标准及评价细则

1. 功能分(40分)

如果学生最后答案错误,则该项得0分

如果答案正确,得40分

2. 代码质量分(30分)

可读性,整洁性,健壮性,可扩展性,封装性

3. 用户体验(10分)

界面美观,操作方便,有必要的信息提示

4. 代码文档质量(10分)

代码清晰,易读,注释完整

5. 单元测试(10分)

关键函数或容易出错部分应该有单元测试保证

person类

class Person{
    private int id;
    private int money;
    private int apperance;
    private int character;
    private int hopeMoney;
    private int hopeApperance;
    private int hopeCharacter;
    private int sex;
    public Person(int id,int money,int apperance,int character,int hopeMoney,int hopeapPerance,int hopeCharacter,int sex){
        this.id=id;
        this.money=money;
        this.apperance=apperance;
        this.character=character;
        this.hopeMoney=hopeMoney;
        this.hopeApperance=hopeapPerance;
        this.hopeCharacter=hopeCharacter;
        this.sex=sex;
    }



    public int getId() {
        return id;
    }



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



    public int getMoney() {
        return money;
    }



    public void setMoney(int money) {
        this.money = money;
    }



    public int getApperance() {
        return apperance;
    }



    public void setApperance(int apperance) {
        this.apperance = apperance;
    }



    public int getCharacter() {
        return character;
    }



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



    public int getHopeMoney() {
        return hopeMoney;
    }



    public void setHopeMoney(int hopeMoney) {
        this.hopeMoney = hopeMoney;
    }



    public int getHopeApperance() {
        return hopeApperance;
    }



    public void setHopeApperance(int hopeApperance) {
        this.hopeApperance = hopeApperance;
    }



    public int getHopeCharacter() {
        return hopeCharacter;
    }



    public void setHopeCharacter(int hopeCharacter) {
        this.hopeCharacter = hopeCharacter;
    }



    public int getSex() {
        return sex;
    }



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



    @Override
    public String toString() {
        return id+" ";
    }


}

将男女样本输入到arraylist中,网上找的一种方法,应该还有其它方法

public static ArrayList<Person> PersonList(String filePath,int sex) throws FileNotFoundException
        {   Scanner in = null;
            ArrayList<Person> people = new ArrayList<Person>();         
                in = new Scanner(new File(filePath));           
            while (in.hasNextLine()) {
                String i = in.nextLine();
                String[] split = i.split(",");
                people.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 people;
        }

将主角样本放入arraylist

public static ArrayList<Person> PlarList(String filePath1) throws FileNotFoundException{
         Scanner in=null;
         ArrayList<Person> people=new ArrayList<Person>();
         in=new Scanner(new File(filePath1));
         while(in.hasNextLine()){
             String i = in.nextLine();
             String[] split=i.split(",");
             people.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])));
         }



         return people;

     }

计算分数的函数

/**根据o2的要求计算o1的分数
*/
 public static int  score(Person o1 ,Person o2)
        {
            int t=o1.getApperance()*o2.getHopeApperance()+o1.getMoney()*o2.getHopeMoney()+o1.getCharacter()*o2.getHopeCharacter();
            return t;
        }

优先级函数

/**o1的优先级比o2的高
*/
private static boolean youxian(Person o1, Person o2)
        {
            int t1 = o1.getApperance()+o1.getCharacter()+o1.getMoney();
            int t2 = o2.getApperance()+o2.getCharacter()+o2.getMoney();
            if(t1>t2) {//先比较分数
                return true;
            }
             if(t1<t2) {
                return false;
            }
           if(t1==t2){//如果分数相同,则id小的优先
               if(o1.getId()<o2.getId()){
                   return true;
               }
           }
           return false;
        }

配对函数

/**
 * @author wz
 * @param male 100个男生样本
 * @param female  100个女生样本
 * @param player   每次进入的主角
 * 
 * */

     public static void compare(ArrayList<Person>male,ArrayList<Person> female,Person player){
     //先确定主角的性别,把他放入男生样本或者女生样本中
        int sex=player.getSex();
        if(sex==0){
            female.add(player);
        }else{
        male.add(player);
        }
        Person maxboy=null;//每次配对后最受欢迎的男生
        Person maxgirl=null;//每次配对后最受欢迎的女生
        /**
         * 算出女生被男生选择的次数
         * */
for(int p=0;p<100;p++){

    HashMap<Person,Integer> manlike=new HashMap<Person,Integer>();//女生被选次数
        HashMap<Person,Person> manwoman=new HashMap<Person,Person>();//统计每个女生的追求者
        Person best=null;
    for (int i = 0; i < male.size(); i++) {      
         Person man = male.get(i);
             int max = -100;      
         for (int j = 0; j < female.size(); j++) {           
             Person woman = female.get(j);           
             int score = score(woman, man);
             if (score > max) {
                 max = score;
                 best = woman;
             }
             if((score==max&&youxian(woman,best))){
                 max = score;
                 best = woman;
             }
         }

    if(!manlike.containsKey(best)){
                manlike.put(best, 0);
            }
            if(manlike.containsKey(best)){
                manlike.put(best, manlike.get(best)+1);

            }
            manwoman.put(man, best);

        }

        /**
         * 找到男生最喜欢的女生
         * */
        int tmp=0;

        Iterator<Map.Entry<Person, Integer>> iterator=manlike.entrySet().iterator();

        while(iterator.hasNext()){
            Entry<Person, Integer> next = iterator.next();
            if(next.getValue()>tmp){
                tmp=next.getValue();
                maxgirl=next.getKey();          
            }
            if(next.getValue()==tmp&&youxian(next.getKey(),maxgirl)){
                tmp=next.getValue();
                maxgirl=next.getKey();  

            }

        }
/**
 * 被挑选次数最多的女生选择男生
 * */       

    Iterator<Entry<Person, Person>> iterator2 = manwoman.entrySet().iterator();
    ArrayList<Person> t1=new ArrayList<Person>();//选择某个女生的全部男生,女生在其中挑选
    while(iterator2.hasNext()){
        Entry<Person, Person> next = iterator2.next();
        if(next.getValue()==maxgirl){
            t1.add(next.getKey());
        }
    }
    int maxscore=0;
        for(int k=0;k<t1.size();k++){

        if(score(t1.get(k), maxgirl)>maxscore){
            maxboy=t1.get(k);
            maxscore=score(t1.get(k), maxgirl);
        }
        if(score(t1.get(k), maxgirl)==maxscore&&youxian(t1.get(k), maxboy)){
            maxboy=t1.get(k);
            maxscore=score(t1.get(k), maxgirl);
        }}
    /**如果男士或者女士的id为-1,则进行输出,如果没有-1,则什么也不输出,进入下个循环
    */  
if(maxboy.getId()==-1){
    System.out.println(-1+" ,"+maxgirl.getId());

}
if(maxgirl.getId()==-1){
    System.out.println(maxboy.getId()+" ,"+-1);

}
/**完成一次循环从男女样本中删除已经配对的男女
*/
female.remove(maxgirl);
male.remove(maxboy);

 }
    }

主函数

public static void main(String[] args) throws FileNotFoundException {

       for(int i=0;i<100;i++){
            String filePath="C:\\Users\\wz\\Desktop\\婚配\\上课资料\\Java男女匹配作业(集合部分大作业)\\作业\\male.txt";
            ArrayList<Person> male=PersonList(filePath, 1);
            String filePath1="C:\\Users\\wz\\Desktop\\婚配\\上课资料\\Java男女匹配作业(集合部分大作业)\\作业\\female.txt";
            ArrayList<Person> female=PersonList(filePath1, 0);
            String filePath2="C:\\Users\\wz\\Desktop\\婚配\\上课资料\\Java男女匹配作业(集合部分大作业)\\作业\\players.txt";
            ArrayList<Person> player=PlarList(filePath2);
            System.out.println("第"+(i+1)+"组主角进入");
            compare(male, female, player.get(i));

       }

}   

运行结果

第1组主角进入
-1 ,28
第2组主角进入
33 ,-1
第3组主角进入
4 ,-1
第4组主角进入
11 ,-1
第5组主角进入
46 ,-1
第6组主角进入
65 ,-1
第7组主角进入
-1 ,39
第8组主角进入
-1 ,41
第9组主角进入
49 ,-1
第10组主角进入
-1 ,80
第11组主角进入
-1 ,36
第12组主角进入
-1 ,23
第13组主角进入
-1 ,29
第14组主角进入
-1 ,86
第15组主角进入
36 ,-1
第16组主角进入
-1 ,98
第17组主角进入
-1 ,11
第18组主角进入
-1 ,76
第19组主角进入
20 ,-1
第20组主角进入
-1 ,47
第21组主角进入
-1 ,77
第22组主角进入
41 ,-1
第23组主角进入
-1 ,20
第24组主角进入
57 ,-1
第25组主角进入
-1 ,45
第26组主角进入
-1 ,39
第27组主角进入
-1 ,36
第28组主角进入
-1 ,9
第29组主角进入
-1 ,22
第30组主角进入
79 ,-1
第31组主角进入
-1 ,45
第32组主角进入
-1 ,86
第33组主角进入
22 ,-1
第34组主角进入
-1 ,34
第35组主角进入
45 ,-1
第36组主角进入
97 ,-1
第37组主角进入
67 ,-1
第38组主角进入
-1 ,13
第39组主角进入
-1 ,39
第40组主角进入
-1 ,60
第41组主角进入
-1 ,15
第42组主角进入
56 ,-1
第43组主角进入
-1 ,97
第44组主角进入
26 ,-1
第45组主角进入
71 ,-1
第46组主角进入
-1 ,27
第47组主角进入
第48组主角进入
85 ,-1
第49组主角进入
-1 ,97
第50组主角进入
-1 ,46
第51组主角进入
-1 ,49
第52组主角进入
4 ,-1
第53组主角进入
-1 ,35
第54组主角进入
27 ,-1
第55组主角进入
65 ,-1
第56组主角进入
77 ,-1
第57组主角进入
-1 ,73
第58组主角进入
-1 ,94
第59组主角进入
-1 ,83
第60组主角进入
52 ,-1
第61组主角进入
48 ,-1
第62组主角进入
-1 ,53
第63组主角进入
2 ,-1
第64组主角进入
-1 ,12
第65组主角进入
-1 ,78
第66组主角进入
-1 ,84
第67组主角进入
-1 ,69
第68组主角进入
97 ,-1
第69组主角进入
26 ,-1
第70组主角进入
-1 ,97
第71组主角进入
71 ,-1
第72组主角进入
-1 ,78
第73组主角进入
1 ,-1
第74组主角进入
-1 ,28
第75组主角进入
55 ,-1
第76组主角进入
-1 ,28
第77组主角进入
-1 ,10
第78组主角进入
-1 ,81
第79组主角进入
-1 ,87
第80组主角进入
74 ,-1
第81组主角进入
-1 ,63
第82组主角进入
33 ,-1
第83组主角进入
第84组主角进入
79 ,-1
第85组主角进入
66 ,-1
第86组主角进入
9 ,-1
第87组主角进入
66 ,-1
第88组主角进入
-1 ,58
第89组主角进入
37 ,-1
第90组主角进入
14 ,-1
第91组主角进入
-1 ,21
第92组主角进入
54 ,-1
第93组主角进入
-1 ,78
第94组主角进入
77 ,-1
第95组主角进入
78 ,-1
第96组主角进入
-1 ,94
第97组主角进入
53 ,-1
第98组主角进入
-1 ,56
第99组主角进入
-1 ,45
第100组主角进入
14 ,-1


这个结果和答案对了一下,应该是没啥毛病的
另外我这个数据结构没选好,跑1000组数据的时候跑了接近30分钟,效率很低

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值