結對學生:翁祖航(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的使用還不怎麼熟練,經常出現一些解決不了的情況。