根据学生的成绩将他们分配到大学

时间:2018-07-22 08:17:41

标签: sql algorithm

我知道我可能会为这个问题而烦恼,可能会被贴上题外话,但我迫切希望获得帮助。

我需要创建一个系统,根据学生的成绩将他们分配到大学。而且我需要知道使用哪种算法。我对算法不好。

我有下表:

学院:

id | name | capacity
--------------------
1  | C1   | 50
2  | C2   | 30

学生:

id | name | degree | status
----------------------------
1  | S1   | 90     | 0
2  | S2   | 77     | 0

学生选择:

student_id | college_id | choice_order
---------------------------------------
1          | 10         | 1
1          | 3          | 2

因此,基本上,我需要的是根据学生的选择顺序和分数,当然还要根据大学的能力,将学生分配到正确的大学。因此,我们首先从前50名学生中选择了Choice_order 1分配给第一所大学。那些没有做到的人应该分配给他们的第二选择,等等。

我对大学1的基本查询如下:

SELECT * FROM student 
INNER JOIN student_selection ON student.id = student_selection.student_id
WHERE college_id = 1 AND choice_order = 1 AND status = 0 
Limit 50;

这些选定的学生将被分配到大学1,并从算法中删除: UPDATE student SET status = 1 WHERE ...

但是我知道这行不通,因为我需要某种递归算法,当学生由于低分而未能按顺序升读大学时,我们需要检查他的第二选择,依此类推。 / p>

任何线索或技巧将不胜感激。

2 个答案:

答案 0 :(得分:1)

  

我需要某种递归算法

不递归,您需要简单的循环。当您谈论算法而不是谈论编程语言时,我会显示一些“伪代码”(可以是Delphi,C ++,C#..以及PSQL,T-SQL ..) 但为简化起见,我更改了表定义

这也不是完整的答案(一些伪代码指向)-因为stackoverflow并不是为您编写代码,只能解决问题。

学院:

id | name | capacity | remained |
---------------------------------
1  | C1   | 50       | 50       | 
2  | C2   | 30       | 30       | 

学生:

id | name | degree | college_id
-------------------------------
1  | S1   | 90     | null
2  | S2   | 77     | null

学生选择:

student_id | college_id | choice_order
---------------------------------------
1          | 10         | 1
1          | 3          | 2

_

Var choice: Integer;
Var WasSelection: Boolean;

WasSelection:= true;
while WasSelection do
    begin
        WasSelection:= false;
        while not College.Eof do
            begin
                choice:= 0;
                while true do
                    begin
                        choice:= choice + 1;

                        SELECT * FROM student 
                        INNER JOIN student_selection ON student.id = student_selection.student_id
                        WHERE college_id = :College.id AND choice_order = :choice AND college_id is null 
                        Limit :College.remained;

                        if ABOVE_SELECT_RECORD_COUNT=0 then
                          break; //!!! end loop 

                        WasSelection:= true;
                        UPDATE student SET college_id = :College.id WHERE ...  
                        UPDATE College SET remained = remained - :ABOVE_SELECT_RECORD_COUNT  WHERE college_id = :College.id  
                    end
                College.Next;
            end
    end

评论后更新 您的评论会改变事情,因为优先级是等级和选择。

SELECT * FROM student ORDER BY GRADE

while not student.eof do
    begin
        select TOP 1 * from student_selection S INNER JOIN College C on S.college_id = C.ID WHERE student_selection.student_id= :student.id AND C.remained>0 ORDER BY choice_order

        if ABOVE_SELECT_RECORD_COUNT>0 then
            begin
                UPDATE student SET college_id = :College.id WHERE student.id= :student.id;  
                UPDATE College SET remained = remained - 1 WHERE college_id = :student_selection.college_id; 
            end

        student.next;
    end

如我的评论 您还需要考虑如果有2个同等成绩的学生该怎么办,以及如果学生没有获得任何大学但其他学院仍然有名额但不在学生选择列表中怎么办

答案 1 :(得分:0)

来自您的问题(重点是我的问题):

  

因此,我们首先选择Choice_order为1的前50名学生分配给第一所大学

从您对Livius答案的评论(再次强调我的观点):

  

如果学生1最终没有被选择1接受,他需要竞争选择2,如果学生1的成绩优于学生,则可能会拒绝已被接受的学生3 3。

我认为您正在使事情变得不必要地复杂。如果一个学生的成绩胜过另一个学生的偏好,请在您的算法中跟进。与其从第一所大学开始,不如从最高评价的学生开始。通过确定学生的作业 ,然后再分配任何低等学生,您以后再也不必取消分配学生了。

我提出了以下算法:

  1. 获取尚未分配的前1名学生(即最高分)。
  2. 获得前1所大学(按该学生的偏好排序),其剩余容量> 0。
  3. 将学生分配到大学。
  4. 减少大学的剩余容量。
  5. 从第1步开始重复,直到分配了每个人或所有容量都用完为止。

我希望这会有所帮助。如果我错过任何需要采用更复杂方法的重要要求,请告诉我。