排课算法
功能目标:实现智能排课系统,根据学校课程进行排课,可以安排课程周数,连课方式,教室以及上课老师,最终打印课表,这里展现本程序核心算法。(本算法根据特定数据库设计结构设计)
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;
}
















