摘要
- 文章編號:20050703
- 投稿日期:2005/06/25
- 作者:董世尊、徐志祥、施志樹、何建良、吳致中、葉志強
- 備註:
前言
在之前我們已經先介紹過了排課所需的資料、排課流程、檢查流程…等,接下來就開始進行排課的動作。現在我們將說明將排課的動作如何使用程式來實作。
準備排課事件清單
當我們執行程式後,載入資料庫,會出現教師名單、場地名單、班級名單等資料,而我們就可以針對需要排課的資料作選取的動作。而選取後的資料,先定義
選取資料的開頭及結尾,這樣就可以知道所選取的資料有多少筆,而接下來就可以利用FOR迴圈來取得選取的資料內容,並且準備排課的事件清單。
而我們利用以下的程式範例來做解釋:
Set evtsAuto = New CEvents
For nRow = nStartRow To nEndRow
Set evtNew = schLocal.CEvents(CStr(fgEvents.RowData(nRow)))
If Not evtNew.ManualLock Then
evtsAuto.Add evtNew
End If
Next nRow
CEvents是一個模組,主要的功能是將傳入的值經過另一個模組CEvent重新宣告型態後,將分課編號當成數字索引,再重
新將資料及數字索引建立陣列,陣列的資料會依照數字索引的順序重新將資料排序。
nStartRow為選取資料的起始點。
nEndRow為選取資料的結束點。
接下來利用FOR迴圈將資料陣列裡面的資料一筆一筆的取出,存成nRow變數,再利用CEvents來整理成一個排序過的陣列,,其中會檢
查取出的資料,也就是檢查資料中的ManualLock值,如果值為TRUE,則跳過這筆資料,繼續往下一筆資料處理。等所有資料處理完後,排課事件的清
單就已經準備完成了。
取得解決方案
當排課事件清單準備完成後,接下來就是取得是否有解決次數,第一步會先檢查取得資料中的WeekDay是否為0(0:代表未排課),接下來再檢查取
得資料中的SolutionCount值是否為-1(-1:表示沒有解決方案、已排課完畢的資料、無法排課的資料;如有其他的數字代表其解決方案數),如
果是的話,就可以開始取得排課解決方案。
解決方案的取得方法是會依據取得資料,來取得可排課的所有時間,例如:日校的上課時間是星期一早上第一節開始至星期五下午第七節。取得星期
及節次後,再將資料傳至TestSchedule作檢查,如果通過檢查,則解決方案數加1,然後再換下一個星期及節次的值,再做重新檢查。如此,再檢查過
所有的可排課時間後,將資料更新,顯示解決方案數。
自動排課的流程
我們將剛才取得的每一筆資料列做自動排課(AutoSchedule)的動作,自動排課的詳細過程如下:
在我們選取的資料列中,若是包含先前已做排課動作的資料列時,則將其排課時數歸零。分課表中的欄位值WeekDay =
0的資料列是尚未做排課動作,找出最先未排課的資料列後,利用迴圈將它一筆一筆的取出,若是遇到
ManualLock =
-1(ManualLock為資料鎖定,-1:人工排課;0:電腦排課)時,則跳到下一筆資料列,並且執行TestSchedule(見前期刊)檢查其資
料的完整性、及是否與TestSchedule的檢查條件有衝突。通過檢查後,依據排課前所取得的解決方案,分配一個WeekDay、PeriodNo的
值給正在執行自動排課的資料列,若是排課的解決方案有二個以上的話,則依序分配,例如可排課的時間為星期一的第一節及第五節,則以星期一第一節為優先分
配。
檢查排課是否完成
當nCurIndex > nTotItem時AutoSchedule = 0; nCurIndex <
nTotItem時,則AutoSchedule
=EventList(nMostNear).EventID(目前正執行自動排課的分課ID)。如果自動排課的回傳值AutoSchedule&
lt;>0時,則表示無法將分課安排至任何一個時段裡,也就是發生排課衝突。
當資料處理完後,就執行重新整理的副程式,將資料更新。
|