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

结对学生:翁祖航(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的使用还不怎么熟练,经常出现一些解决不了的情况。

原文地址:https://www.cnblogs.com/MR-ZH/p/5918484.html