排课软件
2.1. 自動排課算法
1 .問題的描述
我們討論的自動排課問題的簡化描述如下:
設要安排的課程為{ C1 , C2 , ., Cn} ,課程總數為n , 而各門課程每周安排次數(每次為連續的2 學時) 為{ N1 , N2 , ., Nn} ;每周教學日共5 天,即星期一~ 星期五;每個教學日最多安排4 次課程教學,即1 ~ 2 節、3 ~ 4 節、5 ~ 6 節和7 ~ 8 節(以下分別稱第1 、2 、3 、4 時間段) . 在這種假設下,顯然每周的教學總時間段數為5 ×4 = 20 ,并存在以下約束關系:
n ≤20 , (1)
N = 6n, i =1, Ni ≤20. (2)
自動排課問題是:設計適當的數據結構和算法, 以確定{ C1 , C2 , ., Cn } 中每個課程的教學應占據的時間段,并且保證任何一個時間段僅由一門課程占據.
2 .主要數據結構
對于每一門課程,分配2 個字節的“時間段分配字”(無符號整數) :{ T1 , T2 , ., Tn} . 其中任何一個時間段分配字(假設為Ti ) 都具有如下格式:
Ti 的數據類型C 語言格式定義為:unsigned int . Ti 的最高位是該課程目前是否是有效的標志,0 表示有效,1 表示無效(如停課等) ;其它各位稱為課程分配位, 每個課程分配位占連續的3 個位(bit) ,表示某教學日(星期一~ 星期五) 安排該課程的時間段的值,0 表示當日未安排,1 ~ 4 表示所安排的相應的時間段(超過4 的值無效) .
在這種設計下, 有效的時間段分配字的值應小于32 768 (十六進制8000) , 而大于等于32 768 的時間段分配字對應于那些當前無效的課程(既使課程分配位已設置好也如此) , 因此很容易實現停課/ 開課處理.
3 .排課算法
在上述假設下,自動排課算法的目標就是確定{ C1 , C2 , ., Cn} 所對應的{ T1 , T2 , ., Tn} .
從安排的可能性上看,共有20 !/ (20 - N) !種排法( N 的含義見(2) 式) . 如果有4 門課,每門課一周上2 次,則N = 8 ,這8 次課可能的安排方法就會有20 !/ (20 - 8) ! = 5 079 110 400 ,即50 多億種. 如果毫無原則地在其中選擇一種方案,將會耗費巨大量的時間. 所以排課的前提是必須有一個確定的排課原則. 我們采用輪轉分配法作為排課原則:從星期一第1 時間段開始按{ C1 , C2 , ., Cn} 中所列順序安排完各門課程之后(每門課安排1 次) ,再按該順序繼續向后面的時間段進行安排,直到所有課程的開課次數符合{ N1 , N2 , ., Nn} 中給定的值為止. 在算法描述中將用{ C[1 ] , C[2 ] , ., C[ n ]} 表示{ C1 , C2 , ., Cn} , 對{ N1 , N2 , ., Nn}
和{ T1 , T2 , ., Tn} 也采用同樣的表示法.
算法1 排課算法
輸入 { C1 , C2 , ., Cn} 、{ N1 , N2 , ., Nn} .
輸出 { T1 , T2 , ., Tn} .
① 初始化:
星期值week = 1
時間段值segment = 1
{ T [1 ] , T [2 ] , ., T [ n ]} 中各時間段分配字清零
② 新一輪掃描課程:
置繼續處理標志flag = 0
對課程索引值c-index = 1 ,2 , ., n 進行以下操作:
如果N[c-index ] > 0 ,則做以下操作:
把segment 的值寫入T[c-index ]的第(week - 1) 3 3~week 3 3 - 1 位中 N[c-index ]的值減1
如果N[c-index ] > 0 ,則置flag = 1
如果week = 5 并且segment = 4
??? 則:置flag = 1 并轉③
否則:如果segment = 4
則:置segment = 1 且week 增1
否則:segment 增1
檢測是否已全部安排完畢:
如果flag = 1
則:轉②
否則:轉③
③ 檢測是否成功:
如果flag = 1
則:開課次數過多
否則:課程安排成功
④ 算法結束
顯然,本算法的時間復雜度為O ( N) ( N 為每周總開課次數, 見(2) 式) , 而存儲時間段分配字所用空間為2 n 個字節( n 為課程門數) .
4 .沖突檢測算法
有時在自動排課完畢后,需要人工調整某些課程的安排時間,如把第i 門課程在人工干預下改成星期數為week 、時間段為segment 的位置,則根據上述數據結構需做如下運算:
T [ i ] = T [ i ] &(~ (7 << (week - 1) * 3) ) + (segment << (week - 1)*3) ,
其中&、~ 和n 分別為按位與、按位取反和按位左移運算符(下同) .
問題是如何判斷是否已有其它課程安排在同一個時間段上. 設人工調整的時間段分配
字為T[1 ] ,則該問題描述為:判斷時間段分配字T [1 ] 與{ T[2 ] , T [3 ] , ., T [ n ]} 中的某個分配字是否存在相同課程分配位上的相等的非零時間段值, 或者說{ T [2 ] , T [3 ] , .,T[ n ]} 中是否存在與T [1 ] 沖突的時間段分配字. 為簡化起見,在以下算法描述中假設所有時間段分配字的最高位為0.
算法2 沖突檢測算法
輸入 T1 和{ T2 , ., Tn} .
輸出 與T1 沖突的{ T2 , ., Tn} 中的時間段分配字.
① 對c-index = 2 ,3 , ., n 做以下操作:
初始化屏蔽字mask = 7
對星期值week = 1 ,2 ,3 ,4 ,5 做以下操作:
如果T[1] & mask 等于T[c-index] & mask ,而且二者不等于0
則: T[ 1 ]與T[c-index ]相沖突,轉①
mask 左移3 位(或乘8)
② 算法結束
本算法時間復雜度為O ( n) ( n 為課程門數)
5.算法分析
?? 此算法以課程為中心,進行搜索匹配,取最先匹配的值;具有占有空間少,運算速度快的特點。但其未對數據進行擇優選取,所以不能對教學資源(教師、教室)合理分配,也不能滿足一些特殊要求(比如有些老師喜歡上午上課,有些老師偏向于集中式上課;有些課程安排到上午會更合適些,有些課程不能安排到上午等)。
總結
- 上一篇: linux背光子系统(backlight
- 下一篇: 听乌森聊强化学习的那些事