第二次结对编程作业——毕设导师智能匹配

本文介绍了一个基于Java的学生导师互选系统实现方法。通过模拟学生填报志愿、导师选择学生等过程,最终实现智能匹配。在经过几轮选择后,系统会自动为未匹配的学生进行分配。

结对学生:翁祖航(031402515),毛仲杰(031402517)

实现方法

我们组用java模拟导师,学生互选的过程。

coding.net链接

开发语言:java

开发工具:eclipse

主要的代码及含义如下(数据库截图只含有部分).
1.InitTS类

该类中主要模拟学生,导师互选时填表的过程。由java生成随机数据插入到数据库中,作为输入数据。

输入的数据主要包括

1.初始生成所有的学生信息(学号,绩点),所有的导师(工号,设置的学生数量).
/*
     * 初始化学生表。 生成随机数据,模拟随机生成studentNum个学生(随机生成绩点).
     */
    public void initStudent() {
        DeleteAll("student");
        for (int i = 0; i < studentNum; i++) {
            int score = new Random().nextInt(100);
            int studentID = i + 1;
            insertStudent(studentID, score);
        }
    }

    /*
     * 向导师表中 插入导师的工号,学生数量。
     */
    public void insertTeacher(int teacherID, int studentNum) {
        String insertT = "insert into teacher(teacherID,studentNum) values('" + teacherID + "','" + studentNum + "')";
        try {
            s.execute(insertT);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /*
     * 初始化导师表。 随机生成导师的学生数量信息。
     * 注意:如果随机生成的导师的所有学生数量小于目标的学生数量,则重新生成。
     */
    public void initTeacher() {
        DeleteAll("teacher");
        ArrayList<Integer> arrayList = new ArrayList<>();
        int count = 0;
        do {
            count = 0;
            arrayList.clear();
            for (int i = 0; i < teacherNum; i++) {
                int num = new Random().nextInt(9);
                arrayList.add(num);
                count += num;
            }

        } while (count < studentNum);
        for (int i = 0; i < teacherNum; i++) {
            int studentNum = arrayList.get(i);
            insertTeacher(i + 1, studentNum);
        }
    }
    /*
     * 调用以上的 两个方法,初始化学生,老师信息。
     */
    public void initGenerateTS() {
        initStudent();
        initTeacher();
    }
2.模拟学生填报志愿。学生填报5个志愿(由系统随机生成5个志愿导师的ID).
    /*
     * 向targetTeacher表中插入学生工号,5个志愿导师的工号。
     */
    public void insertTargetTeacher(int studentID, int[] targetTeacher) {
        String insertTarT = "insert into targetTeacher(studentID,targetTeacher1,targetTeacher2,targetTeacher3,targetTeacher4,targetTeacher5)"
                + "values('" + studentID + "','" + targetTeacher[0] + "','" + targetTeacher[1] + "','" + targetTeacher[2]
                + "','" + targetTeacher[3] + "','" + targetTeacher[4] + "')";
        try {
            s.execute(insertTarT);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /*
     * 模拟 学生选5个志愿的过程。
     * 1.获得所有未被导师选中的学生列,以此选中其中一个学生。
     * 2.这个学生从导师列(学生数未满)的导师中选择5个导师。
     * 3.相应的导师更新他的待选学生列。
     */
    public void chooseTargetTeacher() {
        DeleteAll("targetTeacher");
        for (int i = 0; i < studentList.size(); i++) {
            Student current_studnet = studentList.get(i);// 获得当前的学生。
            ArrayList<Teacher> target_teacher_list = current_studnet.getTarget_teacher();// 获得学生的目标导师队列。
            target_teacher_list.clear();// 将当前学生的目标导师队列清空。
            int[] targetTeacher = new int[5];
            int bound = teacherList.size();// 获得剩余的导师数量。
            for (int j = 0; j < 5; j++) {
                int target_teacher_index = new Random().nextInt(bound);// 随机生成选导师的序号。
                Teacher target_teacher = teacherList.get(target_teacher_index);// 获得目标导师
                targetTeacher[j] = target_teacher.getTeacherID();//添加选中导师的id。
                target_teacher_list.add(target_teacher); // 学生填志愿成功,目标导师队列添加导师对象。
                target_teacher.getAll_selected_student().add(studentList.get(i));// 导师的对象中添加预选的学生对象。
            }
            insertTargetTeacher(current_studnet.getStudnetID(),targetTeacher);
        }
    }
3.模拟导师选择学生。导师从选自己的学生队列中选中自己喜欢的学生。
/*
     * 向targetStudent表中添加导师的选中学生的工号。
     */
    public void insertTargetStudent(int teacherID,int[] targetStudent)
    {
        String insertTarS = "insert into targetStudent(teacherID,targetStudent1,targetStudent2,targetStudent3,targetStudent4,targetStudent5,targetStudent6,"
                + "targetStudent7,targetStudent8) values('"+teacherID+"','"+targetStudent[0]+"','"+targetStudent[1]+"','"+targetStudent[2]+"','"+targetStudent[3]+"','"
                        +targetStudent[4]+"','"+targetStudent[5]+"','"+targetStudent[6]+"','"+targetStudent[7]+"')";
        try {
            s.execute(insertTarS);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /*
     * 
     * 模拟导师选学生的过程。
     * 1.获得学生数还未满的导师列,依次选中其中一个导师。
     * 2.获得当前导师的待选学生列,随机生成此次要选的学生人数,随机从学生列中选中几名学生。
     * 3.选中的学生往待选的导师列中添加学生。
     */
    public void chooseTargetStudent() {
        DeleteAll("targetStudent");
        for (int i = 0; i < teacherList.size(); i++) {
            Teacher current_teacher = teacherList.get(i);// 获取当前导师
            ArrayList<Student> all_selected_student = current_teacher.getAll_selected_student();// 获得该导师的待选学生队列
            int leavednum = current_teacher.getLeavednum();// 当前导师还能选几个学生
            int randomcount = new Random().nextInt(leavednum + 1);// 随机生成这个导师要选多少个学生。
            int[] targetStudent = new int[8];
            for (int j = 0; j < randomcount; j++) {
                int bound = all_selected_student.size();// 待选学生队列的学生数量。
                if (bound == 0) {
                    break;
                }
                int index = new Random().nextInt(bound);// 随机生成选中的学生序号。
                Student selected_student = all_selected_student.get(index);// 选中的学生。
                targetStudent[j] = selected_student.getStudnetID();//添加选中学生的id。
                selected_student.getAll_selected_teacher().add(current_teacher);// 选中的学生添加备选的导师队列。
                all_selected_student.remove(index);// 选中的学生从备选的学生队列中删除;
            }
            insertTargetStudent(current_teacher.getTeacherID(),targetStudent);
        }
    }
4.模拟学生选择目标导师。(因为存在多个导师同时选中一个学生的情况)。学生从自己的待选导师列表中选择一个导师。
/*
     * 模拟学生最后选导师的过程(因为同时可能由几个导师同时选中一个学生)
     * 1.获得当前还未选中导师的学生列,依次选中其中一个学生。
     * 2.从当前学生的待选导师列中,随机选择一位导师。
     * 
     */
    public void chooseTeacher(Student student) {
        ArrayList<Teacher> all_selected_teacher = student.getAll_selected_teacher();// 待选的导师队列。
        int bound = all_selected_teacher.size();// 待选的导师人数。
        if (bound > 0) {
            int teacher_index = new Random().nextInt(bound);// 选中的导师序号
            Teacher target_teacher = all_selected_teacher.get(teacher_index);// 选中的导师。
            int leaved_num = target_teacher.getLeavednum() - 1;// 导师的剩余学生人数减1
            target_teacher.setLeavednum(leaved_num);
            if (leaved_num == 0) {
                target_teacher.setLeavednum(0);// 设置导师的剩余学生人数为0
                teacherList.remove(target_teacher);// 导师的剩余学生人数为0,从备选的导师队列中删除。
            }
            studentList.remove(student);// 学生选中导师,从备用的学生序列中删除。
            student.setFinished_teacher(target_teacher);// 学生的导师对象确立。
            target_teacher.getStudent_list().add(student);// 导师的所带学生对象确立。
            updateStudent(student);
            updateTeacehr(target_teacher);
        }
    }
    /*
     * 所有学生选中自己的导师。
     */
    public void chooseAllTargetTeacher() {
        for (int i = 0; i < studentList.size(); i++) {
            int current_size = studentList.size();
            Student student = studentList.get(i);
            chooseTeacher(student);
            if (current_size != studentList.size()) {
                i--;
            }
        }
        initAllSelectedeTS();
    }
2.BackGround类

BackGround类主要模拟后台数据库的数据获取和处理。

1.从数据库中获取学生和导师的信息,存储到Arraylist中。
/*
     * 从数据库中获取学生,教师信息,生成ArrayList队列
     * 
     */
    public void initTS(InitTS TS) throws SQLException {
        this.initTS = TS;
        String getStudent = "select studentID,score from student";
        String getTeacher = "select teacherID,studentNum from teacher";
        ResultSet resultSetStudent = s.executeQuery(getStudent);
        while (resultSetStudent.next()) {
            int studentID = resultSetStudent.getInt("studentID");
            int score = resultSetStudent.getInt("score");
            Student student = new Student(studentID, score);
            select_student_list.add(student);
            select_student_list_spare.add(student);
        }
        ResultSet resultSetTeacher = s.executeQuery(getTeacher);
        while (resultSetTeacher.next()) {
            int teacherID = resultSetTeacher.getInt("teacherID");
            int teacherNum = resultSetTeacher.getInt("studentNum");
            Teacher teacher = new Teacher(teacherID, teacherNum);
            select_teacher_list.add(teacher);
            select_teacher_list_spare.add(teacher);
        }
        TS.setStudentList(select_student_list_spare);
        TS.setTeacherList(select_teacher_list_spare);
        TS.setPreStudentList(select_student_list);
        TS.setPreTeacherList(select_teacher_list);
    }
2.实现最后阶段的系统的智能分配。
/*
     * 系统后台实现的自动分配算法。
     * 1.按照绩点将落选的学生队列重新排列。
     * 2.依次选择其中的一位学生,获得他的5个目标志愿导师,若他的导师还有剩余的学生名额则选中该导师。
     * 3.剩下是目标导师的名额已经分配完的落选学生,系统为其自动分配。
     * 
     */
    public void autoDistribute() {
        Collections.sort(select_student_list_spare);// 为落选的学生排序。
        for (int i = 0; i < select_student_list_spare.size(); i++) {
            Student student = select_student_list_spare.get(i);// 当前的学生
            ArrayList<Teacher> target_teacher = student.getTarget_teacher();// 学生的5个目标导师。
            for (int j = 0; j < 5; j++) {
                Teacher teacher = target_teacher.get(j);// 学生的当前目标导师。
                if (teacher.getLeavednum() > 0) {
                    teacher.getStudent_list().add(student);// 导师所带的学生队列添加该学生。
                    student.setFinished_teacher(teacher);// 学生的目标导师确立下来。
                    select_student_list_spare.remove(student);
                    int leaved_num = teacher.getLeavednum() - 1;// 导师的剩余学生数量减1.
                    teacher.setLeavednum(leaved_num);// 设置导师的剩余学生数量。
                    if (leaved_num == 0) {
                        select_teacher_list_spare.remove(teacher);// 从备用的导师队列中删除导师。
                    }
                    i--;
                    initTS.updateStudent(student);
                    initTS.updateTeacehr(teacher);
                    break;
                }
            }
        }
        for (int i = 0; i < select_student_list_spare.size(); i++) {
            Student student = select_student_list_spare.get(i);// 当前的学生
            int bound = select_teacher_list_spare.size();
            int teacherIndex = new Random().nextInt(bound);
            Teacher teacher = select_teacher_list_spare.get(teacherIndex);// 学生的当前目标导师。
            if (teacher.getLeavednum() > 0) {
                teacher.getStudent_list().add(student);// 导师所带的学生队列添加该学生。
                student.setFinished_teacher(teacher);// 学生的目标导师确立下来。
                select_student_list_spare.remove(student);
                int leaved_num = teacher.getLeavednum() - 1;// 导师的剩余学生数量减1.
                teacher.setLeavednum(leaved_num);// 设置导师的剩余学生数量。
                if (leaved_num == 0) {
                    select_teacher_list_spare.remove(teacher);// 从备用的导师队列中删除导师。
                }
                initTS.updateStudent(student);
                initTS.updateTeacehr(teacher);
                i--;
                break;
            }
        }
    
    }
3.MainTest类(主函数,模拟学生导师互选的整个过程)
public class MainTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        InitTS initTS = new InitTS(30,100); 
        initTS.initGenerateTS();//模拟生成Teacher表,student表。
        BackGround backGroud = new BackGround();
        try {
            backGroud.initTS(initTS);//后台调用数据库中 teacher表,student表 生成相应的Arraylist队列。
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        /*
         * 模拟第一轮 学生选导师,导师选学生的过程。
         */
        initTS.chooseTargetTeacher();//学生填写5个志愿导师的工号。
        initTS.chooseTargetStudent();//导师填写想要带的学生学号。
        initTS.chooseAllTargetTeacher();//学生从待选的导师队列中选择一个导师(学生可能有很多导师
        /*
         * 模拟第二轮 学生选导师,导师选学生的过程。
         */
        initTS.chooseTargetTeacher();
        initTS.chooseTargetStudent();
        initTS.chooseAllTargetTeacher();
        /*
         * 模拟第三轮 学生先选导师,然后系统按照绩点分配。
         */
        initTS.chooseTargetTeacher();
        backGroud.autoDistribute();//系统自动分配。
        
    }
}
输入输出的数据库部分截图:

student表:
1019982-20160929003611047-233907756.png

teacher表:
1019982-20160929003641438-1298790229.png

targetStudent表:
1019982-20160929003707813-449152701.png

targetTeacehr表:
1019982-20160929003723813-1542682101.png

对算法的评价:

在学生数100,导师人数30的情况下,在经过两轮的选择后大概在10±5的范围内。在第三轮系统分配阶段,在全部学生按照绩点分配后,仍然有一部分学生由于目标的5个导师名额全部分配完而落选。这部分学生一般在5范围内。但系统还是会随机将这些学生分配给名额有剩的导师,这一部分学生相当于完全由系统分配。
不过鉴于整个过程都是系统生成的随机数据,所以个人认为不具备什么参考价值。。。。。。。

本次结对的感受:

由于github,git,coding.net在开发前期基本没有使用过,因为都是同学,开发过程都是在一起做,没有体现出明显的版本的迭代开发,只在最后的完成品出来后,将全部的文件提交上去而已,目前虽然只接触了使用了1,2天,不过确实功能强大,很好用。只不过git bash的使用还不怎么熟练,经常出现一些解决不了的情况。

转载于:https://www.cnblogs.com/MR-ZH/p/5918484.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值