用SQL實現的乙個自動排課機制

2022-05-01 04:12:09 字數 4012 閱讀 7332

同學畢業設計搞的是乙個排課系統,具體功能就給課程安排教室和時間。排課演算法是有一定難度的,很多老師說過,至今也沒有完美的排課演算法,的確,排課,是乙個五維交叉的複雜體系:時間、課程、教室、班級、學生。乙個排好的課表至少要保證以下幾點原則:

乙個教師同一時間只上一門他要教的課

乙個班級同一時間只上一門他要上的課

乙個教室同一時間只上一門課

拿到這個問題,剛開始覺得簡單,後來仔細分析後,發現難度相當大。關鍵是其複雜度太高,對待這種問題,我選擇排除法。也就是先列出可能的各種組合,再依據約束條件進行排除,最後留下的結果即是所求。

利用power designer來資料建模。

首先是建立教師、班級、課程表,因為他們是主體。並建立相關的關係對映表:

這五張表都是要作為輸入資料提交給自動排課系統的。

分配的主體還包括時間和地點,也就是上課時段和教室,由於系統要滿足三點原則,所以,需要將五維關係進行關聯,也就是教室和時間、教師和時間、班級和時間進行關係對映:

上圖中,教室表、教師表、班級表、上課時段表都是系統的輸入資料。而他們之間的關係對映表:room_time_map、class_time_map、teacher_time_map則是系統在執行中使用的表,系統就是靠他們完成前面提到的三個排除原則的,在系統執行之前,它們是空的。執行開始之後,每當系統要為一門課程分配教室時,都要檢查這三個對映表,看是否已經有相關的記錄。舉個例子:當系統要為語文課分配某個時間和某個教室時它首先要看class_time_map,看看上語文課的這個班級是否在同一時間已經有課,如果有則不分配這個時間。同理對教室,和教師。

篩選條件準備好之後,開始構造課程表,準確說是預排課程表,這個課程表包括各種可能:

它是教室表、上課時段、班級課程對應表、教師課程對應表的連線組合,只進行了乙個初步篩選,就是每條記錄中,的班級上的課程與教師上的課程必須是相同的。sql如下:

1

select

2cc.courseid,

3r.roomid,

4cc.classid,

5tc.teacherid,

6t.timeid

7into

8tempplans

9from

10 dbo.class_course_map as

cc,11 dbo.teacher_course_map as

tc,12 dbo.times as

t,13 dbo.rooms asr14

where

15 cc.courseid = tc.courseid

在輸入10個班級、6位教師、5個教室、5門課程、15個上課時段(5 天 × 3 時段/每天)的情況下共有3450條記錄產生。

在構造乙個最終課程表,結構與預排課程表相同,用來放最終結果。所有預排課程表中的記錄只要滿足篩選條件都要插入到此表。

下面就要對3450條記錄進行篩選了,篩選之前還有乙個問題必須考慮,那就是這3450條記錄中有很多記錄可能出現如下情況:乙個班級在不同時間內上同一門課程若干次,而不是一次。系統是假定每門課程每個班級只上一次的(這可能有悖常理,稍後討論)。所以有必要再構造乙個表進行條件篩選,此表稱之為班級課程記錄表:

每當系統為乙個班級分配好一門課程時,都會將班級、課程號記錄再此表內,將來再插入記錄時便可以檢查改表,看是否以為該班分配了該課,避免重複。

下面就可以進行最後的執行了,系統將對預排課程表逐條檢查,看其是否滿足刪除條件:也就是看room_time_map、class_time_map、teacher_time_map、class_course_rec_map中是否已經有此記錄,如果有,略過;如果沒有證明可以排課,則將其新增到最終的課程表;最後將這條記錄從預排表中刪除。

sql如下:

1

/*check the data one by one*/2

34while (select

count(*) from dbo.tempplans) >05

begin67

declare

@course

int,@room

int,@class

int,@teacher

int,@time

int8

select

top1

@course

=courseid, @room

=roomid, @class

=classid, @teacher

=teacherid, @time

=timeid

9from

dbo.tempplans

1011

declare

@classok

int,@teacherok

int,@roomok

int,@classrecok

int12

select

@classok

=count(*) from dbo.class_time_map where classid=

@class

and timeid=

@time

1314

select

@classrecok

=count(*) from dbo.class_course_rec_map where classid=

@class

and courseid=

@course

1516

select

@teacherok

=count(*) from dbo.teacher_time_map where teacherid=

@teacher

and timeid=

@time

1718

select

@roomok

=count(*) from dbo.room_time_map where roomid=

@room

and timeid=

@time

1920

if@classok

+@teacherok

+@roomok

+@classrecok=0

21begin

22insert

into dbo.class_time_map values(@time,@class)23

insert

into dbo.class_course_rec_map values(@class,@course)24

insert

into dbo.teacher_time_map values(@teacher,@time)25

insert

into dbo.room_time_map values(@room,@time)26

insert

into dbo.plans values(@course,@room,@class,@teacher,@time)27

end28

29delete

from

dbo.tempplans

30where courseid=

@course

and roomid=

@room

and classid=

@class

and teacherid=

@teacher

and timeid=

@time

3132

33end

最終的結果條數應該與class_course_map中的條數是一致的,因為我們假設每個課程每個班只上一次。經檢測,實現了預想的效果,只是系統會盡少地完成安排,也就是說,系統會使用盡量少的教室安排課程,5個教室,只使用了3個。當然這些可以通過增加篩選條件加以避免。總的排課策略是對的。

文章最後解決前面提到的乙個問題:系統假設每門課程,每個班只上一次,這完全不滿足現實需要。例如,大學的英語,每週要上三次之多。其實這個很好解決,可以把英語看作三個不同的課程,命名為英語1、英語2、英語3,這樣對於上課多於一次的課程只要修改輸入表:課程、班級課程對應表、教室課程對應表就可以了,並不需要修改系統。

用shell 實現自動ftp的乙個例項

bin bash echo echo cintel ftp test tool echo please input hostip c read hostip echo please input username c read username echo please input password c...

乙個簡單功能的SQL 實現

1.假設有一張表示cj表 name subject result 張三 語文 80張三 數學 90張三 物理 85李四 語文 85李四 數學 92李四 物理 89要求查詢結果 姓名 語文 數學 物理 張三 80 90 85李四 85 92 89 建立cj表sql create table cj id...

乙個簡單功能的SQL 實現

1.假設有一張表示cj表 name subject result 張三 語文 80張三 數學 90張三 物理 85李四 語文 85李四 數學 92李四 物理 89要求查詢結果 姓名 語文 數學 物理 張三 80 90 85李四 85 92 89 建立cj表sql create table cj id...