天天看點

第二次結對程式設計作業—畢設導師智能比對

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還可以那樣用。

各種錨點。可以,很強!感謝隊友的大腿,編碼過程中耐心的講解,我代碼的能力有待提高。考慮的

過程中思維不夠嚴謹,遺漏一些重要的點,拖了進度。兩個人交流的時候要組織好後表達,可以提高

效率。