首頁‎ > ‎電子期刊‎ > ‎2005 年 第 10 期‎ > ‎

排課系統解析-物件導向程式設計案例研究(五)


摘要

  • 文章編號: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的 值給正在執行自動排課的資料列,若是排課的解決方案有二個以上的話,則依序分配,例如可排課的時間為星期一的第一節及第五節,則以星期一第一節為優先分 配。

檢查排課是否完成

  • 設nTotItem為選取的分課總數目。
  • 設nCurIndex為排課序號。

當nCurIndex > nTotItem時AutoSchedule = 0; nCurIndex < nTotItem時,則AutoSchedule =EventList(nMostNear).EventID(目前正執行自動排課的分課ID)。如果自動排課的回傳值AutoSchedule& lt;>0時,則表示無法將分課安排至任何一個時段裡,也就是發生排課衝突。

當資料處理完後,就執行重新整理的副程式,將資料更新。

Comments