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


    结对学生:翁祖航(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表:

    teacher表:

    targetStudent表:

    targetTeacehr表:

    对算法的评价:

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

    本次结对的感受:

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

  • 相关阅读:
    查看数据库表中的数据
    exec和execsql
    CPI
    百度硬盘可以检索的字节测试
    HDU2095
    Vigenere密码
    斌神无所不能
    HDU p1017
    POJ1316
    head区的代码详解
  • 原文地址:https://www.cnblogs.com/MR-ZH/p/5918484.html
Copyright © 2020-2023  润新知