功能目標:實現智能排課系統,根據學校課程進行排課,可以安排課程周數,連課方式,教室以及上課老師,最終打印課表,這里展現本程序核心算法。(本算法根據特定數據庫設計結構設計)
1 /// <summary> 2 /// 取最優的時間片id 3 /// </summary> 4 /// <param name="roomid">教室id</param> 5 /// <param name="wk">星期id</param> 6 /// <param name="tlid">授課id</param> 7 /// <param name="clid">班級id</param> 8 /// <param name="teach">教室id(S)</param> 9 /// <returns></returns> 10 private int GetBestTime(int roomid,int wk,int tlid,int clid) 11 { 12 //定義初始化存放已排的時間片的數組 13 ArrayList uTime = new ArrayList(); 14 //定義初始化存放空時間片的數組 15 ArrayList nTime = new ArrayList(); 16 17 for (int i = 1; i <= 20; i++) 18 { 19 if (i != 7 && i != 8) 20 { 21 //==判斷當前時間片是否為空 22 int timeid = wbgd.GetTimeID(wk, i); 23 int rtlid = wbgd.GetTlIDByRoomATime(roomid, timeid); 24 if (rtlid == 0) 25 { 26 //檢測沖突 27 bool flag = true; 28 DataTable dtteach = wbgd.GetTeachNameByTLID(tlid); 29 for (int t = 0; t < dtteach.Rows.Count; t++) 30 { 31 int teachid = int.Parse(dtteach.Rows[t]["id"].ToString()); 32 if (!wbgd.CheckClash(timeid, teachid, roomid, clid)) 33 { 34 flag = false; 35 } 36 } 37 if (flag) 38 { 39 //加入空時間片數組 40 nTime.Add(timeid); 41 } 42 else 43 { 44 continue; 45 } 46 } 47 else if (rtlid == tlid) 48 { 49 //加入已排時間片數組 50 uTime.Add(timeid); 51 } 52 else 53 { 54 continue; 55 } 56 } 57 } 58 if (nTime.Count == 0) 59 { 60 return 0; 61 } 62 //判斷這門授課已經插入了幾條記錄 63 if (uTime.Count == 0) 64 { 65 //如果沒有則取最近的 66 return (int)nTime[0]; 67 } 68 else if (uTime.Count == 1) 69 { 70 //如果有一條則取最遠的 71 72 return (int)nTime[nTime.Count - 1]; 73 74 } 75 else 76 { 77 //否則進入已下循環,求出權值最大的時間片 78 //max 存放最大的權值,index 存放最大權值空時間片數組的索引 79 int max = 0,index=0; 80 for (int p = 0; p < nTime.Count; p++) 81 { 82 //m存放uTime中略大於nTine[i]的數 83 //l存放uTime中略小於nTine[i]的數 84 int m, l; 85 m = (int)uTime[1]; 86 l = (int)uTime[0]; 87 for (int j = 0; j < uTime.Count; j++) 88 { 89 if ((int)nTime[p] < (int)uTime[j]) 90 { 91 m = (int)uTime[j]; 92 l = (int)uTime[j - 1]; 93 break; 94 } 95 } 96 //如果權值大於max 則記錄新的權值和索引 97 if (Math.Abs(m - (int)nTime[p]) *Math.Abs ((int)nTime[p] - l) > max) 98 { 99 max = Math.Abs(m - (int)nTime[p]) * Math.Abs((int)nTime[p] - l); 100 index = p; 101 } 102 } 103 //返回權值最大的時間片id 104 return (int)nTime[index]; 105 } 106 } 107 108 109 /// <summary> 110 /// 取最優的連課時間片id 111 /// </summary> 112 /// <param name="roomid"></param> 113 /// <param name="wk"></param> 114 /// <param name="tlid"></param> 115 /// <param name="clid"></param> 116 /// <returns></returns> 117 private int GetBestTimeLK(int roomid, int wk, int tlid, int clid) 118 { 119 //定義初始化存放已排的時間片的數組 120 ArrayList uTime = new ArrayList(); 121 //定義初始化存放空時間片的數組 122 ArrayList nTime = new ArrayList(); 123 124 for (int i = 1; i <= 20; i+=2) 125 { 126 if (i != 7) 127 { 128 //==判斷當前時間片是否為空 129 int timeid1 = wbgd.GetTimeID(wk, i); 130 int timeid2 = wbgd.GetTimeID(wk, i + 1); 131 int rtlid1 = wbgd.GetTlIDByRoomATime(roomid, timeid1); 132 int rtlid2 = wbgd.GetTlIDByRoomATime(roomid, timeid2); 133 if (rtlid1 == 0 && rtlid2 == 0) 134 { 135 //檢測沖突 136 bool flag = true; 137 DataTable dtteach = wbgd.GetTeachNameByTLID(tlid); 138 for (int t = 0; t < dtteach.Rows.Count; t++) 139 { 140 int teachid = int.Parse(dtteach.Rows[t]["id"].ToString()); 141 if ((!wbgd.CheckClash(timeid1, teachid, roomid, clid)) && (!wbgd.CheckClash(timeid2, teachid, roomid, clid))) 142 { 143 flag = false; 144 } 145 } 146 if (flag) 147 { 148 //加入空時間片數組 149 nTime.Add(timeid1); 150 } 151 152 } 153 else if (rtlid1 == tlid || rtlid2 == tlid) 154 { 155 //加入已排時間片數組 156 uTime.Add(timeid1); 157 } 158 else 159 { 160 continue; 161 } 162 } 163 } 164 if (nTime.Count == 0) 165 { 166 return 0; 167 } 168 //判斷這門授課已經插入了幾條記錄 169 if (uTime.Count == 0) 170 { 171 //如果沒有則取最近的 172 return (int)nTime[0]; 173 } 174 else if (uTime.Count == 1) 175 { 176 //如果有一條則取最遠的 177 return (int)nTime[nTime.Count - 1]; 178 } 179 else 180 { 181 //否則進入已下循環,求出權值最大的時間片 182 //max 存放最大的權值,index 存放最大權值空時間片數組的索引 183 int max = 0, index = 0; 184 for (int p = 0;p < nTime.Count; p++) 185 { 186 int m = 0, l = 0; 187 m = (int)uTime[1]; 188 l = (int)uTime[0]; 189 for (int j = 0; j < uTime.Count; j++) 190 { 191 if ((int)nTime[p] < (int)uTime[j]) 192 { 193 m = (int)uTime[j]; 194 l = (int)uTime[j - 1]; 195 break; 196 } 197 } 198 //如果權值大於max 則記錄新的權值和索引 199 if (Math.Abs(m - (int)nTime[p]) * Math.Abs((int)nTime[p] - l) > max) 200 { 201 max = Math.Abs(m - (int)nTime[p]) * Math.Abs((int)nTime[p] - l); 202 index = p; 203 } 204 } 205 //返回權值最大的時間片id 206 return (int)nTime[index]; 207 } 208 } 209 210 211 /// <summary> 212 /// 檢測授課id是否有變動 213 /// </summary> 214 /// <param name="dttl">授課表</param> 215 /// <returns>是否有變動</returns>
private bool CheckTLRep(DataTable dttl) { bool flag = true; if (dttl.Rows.Count == tllist.Count) { for (int i = 0; i < dttl.Rows.Count; i++) { if (!tllist.Contains(int.Parse(dttl.Rows[i]["TechlLct_ID"].ToString()))) { flag = false; break; } } } else { flag = false; } if (!flag) { tllist.Clear(); for (int i = 0; i < dttl.Rows.Count; i++) { tllist.Add(int.Parse(dttl.Rows[i]["TechlLct_ID"].ToString())); } } return flag; }