• 高级软件工程团队结对作业(学生部门智能匹配)


    部门与学生的智能匹配的程序

    结对成员

    170320053 林静

    170327109 张梨贤


    2.输入数据

    关键数据样例: (https://files.cnblogs.com/files/zlxbky/import.pdf)

    考虑因素:

    20个部门
    部门编号(唯一确定值),部门编号先事先设定好,就把部门编号固定为A10000~A10019,下面学生的意愿还要用到,所以用一个字符串数组存起来;
    部门需要的学生数上限:由于限定范围在0~15,所以就是直接随机产生0~15的一个随机数;
    部门的特点标签:事先设定多个标签,用数组存起来。生成部门对象时,随机生成3个0-便签数组之间的不重复的数字,在根据数字作为数组下标到标签数组里面找到该标签并输出。
    部门常规活动时间:这个的处理方式跟标签类似。考虑到实际情况,部门的活动时间大多是在“10:30~11:30”,“16:30~18:00”,“20:00~21:30”三个时间段,所以我们先预设了21个时间段,一周7天,每天三个,共21个,并用数组存起来。随机生成3个0-时间数组之间的不重复的数字,在根据数字作为数组下标到时间数组里面找到该时间并输出。
    300个学生
    部门编号(唯一确定值):学生编号先事先设定好,就把学生编号固定为1703271000~1703271299,用一个字符串数组存起来;
    绩点成绩,单个,数值(随机生成一个0-10之间的浮点类型数值);
    兴趣标签,多个,字符(学生的兴趣标签一定是所有部门特点标签里面的)
    意向志愿,每个学生有不多于5个的部门意愿(不能空缺);
    空闲时间段,多个,字符。
    
    • 部门

    部门编号:部门编号唯一,从A10000到A10019

    部门需要的学生数上限:限定范围定为0-15,即随机产生0-15中的一个数字

    部门的特点标签:生成部门对象时,随机生成3个0-便签数组之间的不重复的数字,在根据数字作为数组下标到标签数组里面找到该标签并输出。

    部门常规活动时间:随机生成3个0-时间数组之间的不重复的数字,在根据数字作为数组下标到时间数组里面找到该时间并输出。

    • 学生

    学生编号:学生编号唯一,学生编号先事先设定好,就把学生编号固定为1703271000~1703271299,用一个字符串数组存起来;

    学生名字:从姓氏数组中随机产生一个姓,以及从名字数组中随机产生两个字,组合成名字。
    绩点成绩:随机生成绩点成绩,从高到低排序,当意愿相同时优先考虑绩点高的学生

    兴趣标签:在生成学生对象时,随机生成3个不重复的兴趣标签。

    部门意愿:在生成学生对象时,随机生成1-5个部门意愿。

    空闲时间段:在生成学生对象时,随机生成3个不重复的空闲时间段。

    3.匹配算法

    数据模型

    类图

    流程图

    算法匹配过程

    • Step1:生成300个学生对象(其中包含学号,姓名,兴趣标签,空闲时间段等基础数据)和部门对象(其中包含部门编号,部门标签,常规活动时间段)。
    • Step2:为了不让后生成的学生的优先级过低导致不能进入部门,首先根据绩点进行从高到低进行排序,绩点高的有优先选择权。
    • Step3:在第二步的前提下,以第一志愿优先原则:遍历其第一志愿,当第一志愿对应的部门的人数没有满的情况下,进行匹配判断,匹配判断分为以下两步:
    • Step 3.1 进行时间判断,将学生的空闲时间段与部门的常规活动时间段进行匹配,当三个时间段中有1个时间段互相匹配,进行下一步判断。
    • Step 3.2 时间判断满足的情况下,进行标签匹配。将学生的兴趣标签与部门的标签进行一一对比,当3个兴趣标签中有1个互相匹配,即满足判断,更新学生信息与部门信息(学生:加入部门信息、加入部门数 部门:成员信息、部门人数、部门人数上限等。
    • Step4 对所有的学生,依旧按照成绩排名遍历其所有志愿,当其志愿对应的部门的人数没有满的情况下,进行匹配判断,匹配判断分为以下两步:同上。
    • Step 5 直到遍历完所有学生的所有部门意愿为止,匹配算法截止。

    结果分析

    部门纳新比例稳定在70%左右。因为纳新部门人数是随机生成的,所有每次的数据量不同,录取比例基本稳定在70%左右。

    条件 学生人数 部门纳新人数 加入学生数 部门招收比例 输出匹配学生文件路径 输出匹配部门文件路径
    绩点+时间+标签 300 119 81 68% https://files.cnblogs.com/files/zlxbky/output_conditionS.pdf) https://files.cnblogs.com/files/zlxbky/output_conditionD.pdf)

    4.关键代码解释

    • 实体类(entity)
    • 全局类(global)
    • 方法类(method)
    • 程序入口(main)

    实体类(学生类和部门类)

    /*学生实体类*/
        private String St_id; //学号
        private String St_name;  //名字
        private float St_grade;  //绩点
        private int [] St_volunter = new int[5];  //学生志愿
        private String [] St_interest=new String [5]; //兴趣标签
        private String [] St_time=new String [5]; //可用时间段
        private List<Dept> myDept = new ArrayList<Dept>(); //当前学生所在部门
    
    /*部门实体类*/
        private  String Dept_id;  //部门编号
        private String [] Dept_tags=new String [5];  //部门标签
        private String [] Dept_time=new String [5];   //部门时间
        private int Dept_num; //部门人数
        private List<Student> myStudent = new ArrayList<Student>(); //当前部门下的学生
    

    生成学生和部门对象的程序

    /*生成学生对象*/
    public  String createSid(int i){.....}//生成学生学号
    public String createSname(){....}//生成学生名字
    public int[] creatVolunter(){....}//生成学生部门志愿数组
    public float createGrade(){....}//生成学生绩点
    public String[] createStime(){....}//生成学生空闲时间
    public String[] createStags(){....}//生成学生兴趣标签
    public List<Student> createAllStudent(String Sid[],Float SGrade[]){....}//生成学生对象列表
    
    /*生成部门对象*/
    public  String createDid(int i){.....}//生成部门编号
    public String[] createDtime(){....}//生成部门常规活动时间
    public String[] createDtags(){....}//生成部门标签
    public List<Dept> createAllDept(){....}//生成部门对象列表
    

    全局类

    public class Global {
        public static List<Student> studentList;
        public static List<Dept> deptList;
        public static List<Student> tempdeptList;
         public static Map<Float,String> map;
    }
    

    对绩点进行排序

    /*对学生绩点进行降序排序*/
    public class SetStudentGrade {
    
        public  static  Map<Float,String> setStudentGrade( ){
    
            Map<Float,String> map = new TreeMap<Float,String >(
                    new Comparator<Float>() {
                        public int compare(Float obj1, Float obj2) {
                            // 降序排序
                            return obj2.compareTo(obj1);
                        }
                    });
    
            for (int i = 0; i < Global.tempdeptList.size(); i++) {
                String id = Global.tempdeptList.get(i).getSt_id();
                map.put(Global.tempdeptList.get(i).getSt_grade(),id );
            }
            return map;
        }
    
    }
    
    

    匹配方法

    public class Matching {
        public static void allocteStudent(int round) {.....}
        }
    
    

    输出工具类

    public class PrintUtils {
        //打印所有的学生对象
        public static void printStudent(List<Student> stulist) throws IOException {....}
        //打印所有的部门对象
        public static  void printDept(List<Dept> deptlist,int d_num[])throws IOException{....}
         //打印部门纳新总人数和匹配人数
        public static  void printNum(List<Dept> deptlist,int d_num[])throws IOException{....}
        //打印匹配好的学生对象
        public static  void printStudentDept(List<Student> studentList)throws IOException{....}
    
    

    结对感受

    由于上一次的结对作业仅仅是原型设计,实现起来可谓是尽情发挥自己的想象力了。然而这次涉及到真正的代码实现,那就产生了较大的难度了。首先,结对作业给我很大的感觉就是要提前规划好个人的分工,不然到了最后会手忙脚乱。其次,要注意代码的规范性问题。结对作业不比个人项目,只要自己看懂就好了,结对作业可能需要你适当的写上注释必要时候可能还需要文档吧。不然看对方的代码真的又耗时又痛苦。而且,结对作业不比个人项目,个人项目由于缺少了那份团队意识感,可能会相拖沓,而结对作业会催促着你早点完成自己的部分不要拖队友的后腿。其实这样的结对编程在实验室项目当中已经有所体验了,所以在实施上没有遇到特别大的难度。

  • 相关阅读:
    LDAP安装配置(windows)
    chrome postman插件手动安装
    mabatis insert into on duplicate key
    ZOJ 3641 <并查集+STL>
    ZOJ 3633 <rmq 重点在于转化>
    POJ 2817 状态DP 字符串找最多的重复
    POJ 2771 简单二分图匹配
    POJ 1149 最大流<建图> PIGS
    POJ 3692 二分图最大独立点集
    POJ 2239 简单的二分图求最大匹配
  • 原文地址:https://www.cnblogs.com/linlkg/p/7726506.html
Copyright © 2020-2023  润新知