摘要
- 文章編號:20050803
- 投稿日期:2005/07/25
- 作者:董世尊、徐志祥、施志樹、何建良、吳致中、葉志強
- 備註:
前言
在前幾期當中,已簡略述說到排課之檢查方法,在這邊將自動排課程式中的程式寫法作一個完整的說明。
自動排課的流程
在前一期曾提過自動排課(AutoSchedule)當中,在我們選取資料之時,會先檢查分課表中欄位 WeekDay 的值,觀看是否已排過課,再來決定是否跳過此筆資料。
「檢查流程」包含檢查可否跨中午、檢查「星期」的限制條件、檢查「節次」的限制條件、檢查班級的時間衝突、檢查教室的時間衝突、教師的時間
與距離的衝突。通過檢查之後,更新解決方案,而再次回到檢查迴圈中,如此類推,直到跑完所有可排課之星期、節次後,將顯示共可解決方案次數。
再來分配星期與節次 → 增加教師、班級、場地之排課時數 → 更新解決次數 →更新紀錄。
在ADO.NET之中可分為兩大類,就是Data Providers、DataSet 此兩類型,Data
Providers它負責與實體的資料進行通訊;而DataSet所代表的是真正的資料。兩者皆能與資料進行溝通。在Data
Provider中,有個DataAdapter的物件,它提供Connection與DataSet的溝通橋樑。內部包含了四種物件:查詢、修改、插
入、刪除等Connection物件。我們在載入資料表當中利用了ADO.NET的語法
,稍後將舉實例說明。
資料庫的連接:
string strcon = @"Provider=Microsoft.
Jet.OLEDB.4.0;Data Source=" + dbpath ;
cnMain = new OleDbConnection(strcon);
//建立Connection物件
cnMain.Open( );
上述程式碼Provider提供者的資料庫連結字串,使用New運算子建立名為cnMain的OleDbConnection物件,參數strcon是OLE DB提供者建立的資料來源字串,然後建立與資料來源間的連線。
載入資料項:
private void CreateChildObjects( )
//建立新的子物件
{
mCEvents = new CEvents( ) ;
mWhos = new Whos( ) ;
‧
‧
‧
}
在這設定一個變數mCEvents給它載入new CEvents( ),共用CEvents裡頭的程式,如此類推...... mWhos皆是如此。
載入上課地點:
建立好Connection物件後,使用SQL指令和Connection物件作為參數載入區域變數rstWork之中。呼叫DataSet模組載
入自定的DataSet之中,呼叫DataAdapter的Fill方法,在此一樣使用rstWork,並傳送要被載入的DataSet名稱。從
DataSet中的Tables["locDataSet"]裡面取出資料,然後放至Location裡做處理。
以上皆是使用了物件導向之概念,呼叫模組類別來使用。以下的載入「路程距離」、「時間表」、「教師」、「教室」、「班級」、「科目」、「課程」…等等,均與上式雷同寫法。
檢查流程:
在檢查流程當中,先檢查上課時間是否為空值,如果不是空值則tsCannotFit
放入檢查流程(TestSchedule)之中。接著檢查bPass可否跨中午,檢查地點時間是否為空值和資料的時段長度是否大於1,才可決定可否需要檢
查,如果bPass為true,才執行prdTest(上課的時間)的開始時間、prdBreak(地點時間)的開始時間相減是否小於0,來決定可否跨中
午。
在來檢查檢查上課的時間與地點是否有衝突,首先查看上課時間與上課地點中的屬性LocID查看是否為空值,如果皆不為空值,則進行下一步再
次利用上課時間與上課地點中的LocID編號,來進行印證上課時間及地點的屬性LocID是否相同,相同表示資料所排的上課時間與實際上課地點符合,則通
過;如果不雷同,則反之,將此發生事件回存到檢查流程TestSchedule中,跳出迴圈。
自動排課的流程:
在前面選取的資料列中,若是包含先前已做排課動作的資料列,也就是在evtTest中WeekDay欄位(WeekDay所代表的是否已做排課動
作)不等於0時,則將evtTest中的WhoID、WhomID、WhereID排課時數欄位歸零。如果分課表中的WeekDay欄位資料是0表尚未執
行排課動作,找出未排課的資料列後,使用Do While迴圈將此等資料取出,然後列出所取出之資料。
分課清單中的排課序號丟入到函數evtTest,在evtTest中使用ManualLock(資料鎖定)來鎖定資料,如果值為True,
則跳過這筆資料,繼續往下一筆資料處理。反之,則下去呼叫在我們timetable中我們設定的各類不同制度的學制編號(例:日校一般班、日校實驗班、補
校國技班….等),每週均有40堂課再配合每個「學制」給予一個key值編號,在此使用 i = i
++的方法,對應「地點」進行一個一個下去比對丟值,如果遇到ManualLock(資料鎖定-1:人工排課;0:電腦排課)=
-1表已完成了排課動作,則跳至下一筆資料每完成一筆資料則至TestSchedule檢查,則通過檢查者解決方案數加1,如有產生衝突,則跳過留給日後
手動排課、調課來解決,直到所有課堂時段比對完成、通過檢查為止。
依據排課前所取得的解決方案,分配一個星期、節次的值給正在執行排課的資料列(教師時數、班級時數、場地時數),若解決方案有二個以上的話,則依序分配時數給資料列,再更新解決次數、更新最新的排課資料。