31402631 王淩傑
03140264 李烈争
Coding.net連結
問題描述
- 目标
實作一個畢業生導師智能配置設定的程式.
- 輸入
老師:30人、老師要求選擇的學生數:0~8
學生:100人、績點、學生的五個志願
- 輸出
根據輸入的資訊,輸出選擇的結果,要求一個學生隻能有一個老師,一個老師可以有
0~8個學生,未配置設定的老師和學生。盡可能少的學生和老師未比對。
問題分析
第一次讨論的時候,我們打算将各種因素綜合起來,合并成老師-學生互相選擇的一個權重
然後進行配置設定,這時候就遇到了下面的問題。影響選擇的因素有學生的績點,志願,老師的
意願。在多因素下如何配置設定各個因素的權重?這個問題讨論了很久,建一個數學模型?有點
困難?各因素乘上一個比例系數,比例系數該如何确定?人為确定嗎?如何保證客觀公正合理
?比對一般都是對兩個對象建立聯系并賦予一定的權值,來展現關系的優先。那麼又回到上
面的問題。回過頭将導師配置設定的流程走一遍發現,其實我們不用考慮這樣問題。
在流程圖中,老師同意學生的選擇,對老師來說,不管學生績點的高低,都是他想要的學生,
是以從老師的角度看,不用管這些學生的先後順序。但從學生的角度看,績點某種程度上展現
這個學生那麼多個學期的努力。故按績點将所有學生排序,将績點高的學生優先配置設定,然後再
按志願順序配置設定還有名額的老師。執行三輪配置設定,若還有學生沒有選到老師則進行人工幹預。
(不過這個機率很低)。
編碼環境
Visual Studio 2015
MySql
Navicat For MySql
語言:C#、SQL
代碼分析
主函數
static void Main(string[] args)
{
int ResultCount =0; //結果個數
int StudentCount =100; //學生個數
int TeacherCount = 30; //教師個數
DeleteData(); //清空資料
Console.WriteLine("清空資料成功");
RandomStudent(StudentCount); //随機生成學生
Console.WriteLine("随機學生成功");
RandomTeacher(TeacherCount); //随機生成教師
Console.WriteLine("随機教師成功");
Console.ReadLine();
//第一輪選擇
StudentChoice("choice");
Console.WriteLine("第一輪學生選導師成功");
TeacherChoice("choice");
Console.WriteLine("第一輪導師選學生成功");
Console.ReadLine();
//第二輪選擇
ResultCount = MySqlReadReturnCount("SELECT * FROM result");//擷取結果個數
//判斷所有學生是否都已經配置設定完畢
if (ResultCount < StudentCount)
{
StudentChoice("secondchoice");
Console.WriteLine("第二輪學生選導師成功");
TeacherChoice("secondchoice");
Console.WriteLine("第二輪導師選學生成功");
}
else
{
Console.WriteLine("選擇導師完畢");
}
Console.ReadLine();
ResultCount = MySqlReadReturnCount("SELECT * FROM result");//擷取結果個數
//判斷所有學生是否都已經配置設定完畢
if (ResultCount < StudentCount)
{
StudentChoice("thirdchoice");
Console.WriteLine("第三輪學生選導師成功");
TeacherChoice("thirdchoice");
Console.WriteLine("第三輪導師選學生成功");
}
else
{
Console.WriteLine("選擇導師完畢");
}
Console.ReadLine();
}
主要函數分析
随機數的生成
private static void RandomTeacher(int TeacherNumber)//随機生成老師
{
string InsertString;
string TmpID;
string TmpStudentCount;
try
{
for (int i = 0; i < TeacherNumber; i++)
{
TmpStudentCount = NewStudentCount();//随機生成預選學生數
TmpID = NewID();//根據時間随機生成ID
InsertString = "INSERT INTO teacher(TeacherID,StudentCount,ChoiceStudentCount) VALUE('" + TmpID + "','" + TmpStudentCount + "', '0' )";
MySqlWrite(InsertString);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void RandomStudent(int StudentNumber)//随機生成學生
{
string InsertString;
string TmpID;
string TmpGPA;
try
{
for (int i = 0; i < StudentNumber; i++)
{
TmpGPA = NewGPA();//随機生成績點
TmpID = NewID();//随機生成ID
InsertString = "INSERT INTO student(StudentID,GPA,IsSelect) VALUE('" + TmpID + "','" + TmpGPA + "', '0' )";
MySqlWrite(InsertString);
}
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
模拟師生互選函數
private static void StudentChoice(string TableName)//模拟學生選擇導師 TableName為進行配置設定操作的表名
{
//string SelectString = "select * from teacher order by rand() limit 5";
string SelectTeacherString = "SELECT * FROM teacher WHERE StudentCount != ChoiceStudentCount";
string SelectStudentString = "SELECT * FROM student WHERE IsSelect ="+0;
int Count = MySqlReadReturnCount(SelectTeacherString);//還未選滿的老師個數
Console.WriteLine(Count);
int StudentCount = MySqlReadReturnCount(SelectStudentString);//還未選中學生的個數
string[] TeacherID = new string[5];
string TmpID;
string[] StudentID = MySqlReadArray(SelectStudentString, "StudentID");//擷取還未被選中的學生ID
//每個學生選5個志願
for(int i = 0;i<StudentCount;i++)// StudentCount 為學生個數
{
TeacherID = MySqlReadRandom(SelectTeacherString, "TeacherID", Count,5);//擷取随機的五個志願老師ID
for (int f = 0; f < WillCount; f++)//WillCount 為志願個數
{
TmpID = NewID();//生成ChoiceID
string InsertString = "INSERT INTO "+ TableName + "(ChoiceID,StudentID,TeacherID,WillNumber,IsSelect) VALUE('" + TmpID + "','" + StudentID[i] + "','" + TeacherID[f] + "','"+(f+1).ToString()+ "','" + 0 + "')";
MySqlWrite(InsertString);//往志願選擇表(choice)添加資料
Console.WriteLine(TmpID);
}
}
}
private static void TeacherChoice(string TableName)//模拟導師選擇學生 TableName為進行配置設定操作的表名
{
string SelectTeacherString = "SELECT * FROM teacher WHERE StudentCount != ChoiceStudentCount"; //用于查找剩餘的導師
string SelectStudentString = "SELECT * FROM student WHERE IsSelect =" + 0; //用于查找剩餘的學生給你
string SelectChoiceString = "SELECT * FROM "+ TableName; //用于通路TableName表
string UpdateChoiceString; //用于更新TableName表
string SelectStudentByChoiceString; //用于擷取TableName表中的StudentID
string SelectStudentCountByTeacher; //用于擷取teacher表中的StudentCount
//随機選擇
int ChoiceCount = MySqlReadReturnCount(SelectChoiceString);
Random TmpRandom = new Random();
//暫定百分之五十至百分之九十的標明
int RandomNumber = TmpRandom.Next(ChoiceCount/2, ChoiceCount/10*9);
string[] ChoiceID = MySqlReadRandom(SelectChoiceString, "ChoiceID", ChoiceCount, RandomNumber);
//模拟導師選中學生
for (int i = 0; i < RandomNumber; i++)
{
UpdateChoiceString = "UPDATE " + TableName + " SET IsSelect=" + 1 + " WHERE ChoiceID ='" + ChoiceID[i] + "'";//IsSelect用于判斷學生在這輪是否被導師選中
MySqlWrite(UpdateChoiceString);
Console.WriteLine(ChoiceID[i]);
}
//進行配置設定
//根據學生績點排序開始配置設定老師
string SelectStudentOrderGPA = "SELECT * FROM student WHERE IsSelect = 0 ORDER BY GPA DESC";
int StudentCount = MySqlReadReturnCount(SelectStudentOrderGPA);//擷取還未被選中的學生個數
Console.WriteLine(StudentCount);
string[] TmpTeacherID = new string[10];
string[] StudentID = MySqlReadArray(SelectStudentOrderGPA, "StudentID");//擷取還未被選中的學生ID
for (int i = 0; i < StudentCount; i++)
{
//一個學生有多條選中資訊,按志願順序開始配置設定老師
SelectStudentByChoiceString = "SELECT * FROM "+ TableName + " WHERE StudentID = '" + StudentID[i] + "' AND IsSelect = 1 ORDER BY WillNumber ASC";
TmpTeacherID = MySqlReadArray(SelectStudentByChoiceString, "TeacherID");
if (TmpTeacherID != null)
{
for (int j = 0; j < TmpTeacherID.Length; j++)
{
SelectStudentCountByTeacher = "SELECT * FROM teacher WHERE TeacherID = '" + TmpTeacherID[j] + "'";
int TmpStudentCount = int.Parse(MySqlReadReturn(SelectStudentCountByTeacher, "StudentCount"));//擷取老師要選的學生總數
int TmpChoiceStudentCount = int.Parse(MySqlReadReturn(SelectStudentCountByTeacher, "ChoiceStudentCount"));//擷取老師已選的學生總數
if (TmpStudentCount > TmpChoiceStudentCount)//若老師人數未滿
{
//Console.WriteLine(StudentID[i]);
MySqlWrite("INSERT INTO result(StudentID,TeacherID) VALUE('" + StudentID[i] + "','" + TmpTeacherID[j] + "')");//更新結果表
MySqlWrite("UPDATE student SET IsSelect = 1 WHERE StudentID = '" + StudentID[i] + "'");//更新學生資料為已被選中
AllResultCount++;//所有結果條數
TmpChoiceStudentCount++;/老師已選學生數++
MySqlWrite("UPDATE teacher SET ChoiceStudentCount =" + TmpChoiceStudentCount + " WHERE TeacherID ='" + TmpTeacherID[j] + "'");//更新老師資料已選人數
Console.WriteLine(AllResultCount+"學生" + StudentID[i] + "配置設定成功");
break;/選中老師跳出循環,對下個學生進行配置設定
}
}
}
}
}
其他函數
結果分析
生成資料
student表
teacher表
控制台界面
第一輪選擇
模拟學生選擇導師
choice表(志願表)
100個學生 每個學生5個志願 總共有500條記錄
因為初始志願導師還沒有選擇是以IsSelect都為0
模拟導師選擇學生
choice表
IsSelect紀錄該導師是否選擇了該學生
result表:
IsSelect紀錄學生是否中選
重複輪數
小結&感想
王淩傑
本次結對程式設計我學會了git的基本使用,同時也對畢設導師比對系統有了更為深刻的了解和思考。
本來我們也想像其他組那樣用算法全自動比對,然而考慮到很多數學模組化的問題,而且感覺有很
多不符合實際的假設。于是我們決定實作模拟人為選擇,再設計比對方式進行比對。我們比對思
路主要在模拟導師選擇學生之後,即實作按學生績點來作為學生進行比對的順序的依據,而把志
願順序作為單個學生比對不同志願導師的順序依據。
除了比對,本次讓我印象深刻的實作随機不重複的從資料庫中調出資料。原本打算用"select *
from teacher order by rand() limit 5"直接在資料庫中實作,但效率出奇的低,于是便參考了
一些算法,由于時間較趕最後決定用比較Low的list.contain 來判斷。
李烈争
學會Git的基本使用,感謝助教推薦的Git部落格,很詳細。看學長的部落格感歎markdown還可以那樣用。
各種錨點。可以,很強!感謝隊友的大腿,編碼過程中耐心的講解,我代碼的能力有待提高。考慮的
過程中思維不夠嚴謹,遺漏一些重要的點,拖了進度。兩個人交流的時候要組織好後表達,可以提高
效率。