排课问题

排课问题
现有课程 40 门,编号为 C01 ~ C40 ;教师共有 25 名,编号为 T01 ~ T25 ;教室 18 间,编号为 R01 ~ R18 。具体属性及要求见表 1 ,表 2 ,表 3 :
课表编排规则:每周以 5 天为单位进行编排;每天最多只能编排 8 节课(上午 4 节,下午 4 节),特殊情况下可以编排 10 节课(晚上 2 节),每门课程以 2 节课为单位进行编排,同类课程尽可能不安排在同一时间。
你所要解决的问题:
1.
请你结合实际情况建立数学模型,通过编程计算,给出较为合理的课表编排方案,分析你所给出的方案的合理性。
2.
如果不准晚上排课,排课结果是否有所变化,如何变化?
3. 对教师聘用,教室配置给出合理化建议。
表 1 :课程属性及要求:

课程编号

课程类别

周课时数

对教室座位最大要求数

对教室

类别要求

时间要求

C01

1

4

50

多媒体教室

上午

C02

1

4

30

普通教室

下午

C03

1

6

40

普通教室

下午

C04

1

4

25

多媒体教室

上午

C05

1

3

60

普通教室

下午

C06

2

4

100

普通教室

下午

C07

2

4

50

多媒体教室

上午

C08

2

2

30

普通教室

上午

C09

2

4

40

普通教室

下午

C10

2

3

25

多媒体教室

上午

C11

3

6

60

普通教室

上午

C12

3

4

80

普通教室

上午

C13

3

6

50

多媒体教室

下午

C14

3

2

30

普通教室

下午

C15

3

3

40

普通教室

下午

C16

4

4

25

多媒体教室

上午

C17

4

4

60

普通教室

下午

C18

4

6

90

普通教室

上午

C19

4

4

50

多媒体教室

上午

C20

4

2

50

普通教室

上午

C21

5

4

30

普通教室

上午

C22

5

4

40

多媒体教室

下午

C23

5

3

25

普通教室

上午

C24

5

6

60

普通教室

下午

C25

5

4

100

多媒体教室

上午

C26

6

3

50

多媒体教室

下午

C27

6

4

30

普通教室

下午

C28

6

4

40

普通教室

下午

C29

6

4

50

多媒体教室

上午

C30

6

4

30

普通教室

下午

C31

7

6

40

普通教室

上午

C32

7

4

25

多媒体教室

下午

C33

7

3

60

普通教室

C34

7

4

80

多媒体教室

上午

C35

7

4

50

普通教室

下午

C36

8

6

30

机房

C37

8

4

40

机房

上午

C38

8

2

25

机房

上午

C39

8

4

60

机房

下午

C40

8

4

50

机房


表 2 :教师属性:

教师编号

能胜任课程类别

周最大

课时数

对教室类别要求

上课时间要求

尽可能不同天上课的教师

T01

1 8

4

多媒体教室或机房

上午

T4

T02

1

4

普通教室

下午

T03

1

6

普通教室

上午

T04

2

4

多媒体教室

上午

T1

T05

2

4

普通教室

下午

T06

2

6

普通教室

T07

3

4

普通教室

上午

T08

3 8

3

普通教室或机房

下午

T09

3

4

普通教室

上午

T11,T18

T10

3

6

多媒体教室

上午

T11

4

8

普通教室

下午

T9,

T12

4

4

普通教室

T13

4

6

多媒体教室

下午

T14

5

2

普通教室

上午

T15

5 8

3

普通教室或机房

下午

T23

T16

5

4

普通教室

上午

T17

6

4

普通教室

下午

T18

6

6

普通教室

T9

T19

6

4

多媒体教室

下午

T20

7

4

普通教室

上午

T21

7

6

普通教室

下午

T22

7

6

多媒体教室

上午

T23

3 8

4

普通教室或机房

T15

T24

4 8

6

普通教室或机房

上午

T25

6 8

4

普通教室或机房

 

表 3 :教室属性:

教室编号

最大座位数

教室类别

R01

100

多媒体教室

R02

100

普通教室

R03

100

普通教室

R04

50

多媒体教室

R05

50

普通教室

R06

50

普通教室

R07

50

普通教室

R08

60

普通教室

R09

60

普通教室

R10

60

多媒体教室

R11

60

普通教室

R12

60

机房

R13

40

机房

R14

40

机房

R15

40

机房

R16

40

多媒体教室

R17

50

普通教室

R18

40

普通教

----
解:
认为一节课为一课时,两节课为一节大课,每天分为五节大课:上午两节,下午两节,晚上一节。
据题述:“ 每门课程以2 节课为单位进行编排” ,也就是说以“ 大课” 为单位进行编排,所以将表1 中的“ 周课时数” 和表2 中的" 周最大课时数" 均折算成 大课数,即数值需要除以2 ,而那些数值为3 者,除以2 后为1.5 ,作上取整得2 。那么,如果一次课不足一节大课,则上完前半节后就下课了,下半节教室空闲 不再被利用(高校里都是这样安排的)。
很容易发现按题目所给的三个表,是不存在无冲突的排课方案的,这一点从很多角度都可以看出来,例如表1 和表2 的数据就存在如下矛盾:
当只考虑第1,2,3 类课程时,
由表1 可知C01~C15 属于1,2,3 类课程,其总课时数为:4+4+6+4+3+4+4+2+4+3+6+4+6+2+3=59.
再看表2 ,只有T01~T10 及T23 这11 名教师能胜任1,2,3 类课程,其总共能提供的课时数为:4+4+6+4+4+6+4+3+4+6+4=49.
也就是说,1,2,3 类课程需要59 课时,但是教师方面只能提供49 课时,根本满足不了需求。
因此不存在无冲突的排课方案。
但是现在又必须排出课表来,所以只能是追求极小化冲突:
当然,有一些类型冲突是坚决要避免的,例如:
1 ,绝对不能让任何一个教师去教授他不能胜任的课程;
2 ,绝对不能在不合课程要求的教室里上这门课程;
3 ,绝对不能在座位数不合课程要求的教室里上这门课程;
4 ,各门课程的周课时数一定要与规定的相同;
5 ,每天的每节大课的时间段内在一个特定的教室里只能对应一个( 教师, 课程) 。
以上五条约束当成硬约束来处理,必须严格满足。其中第五条是一个常识性约束,但却非常重要,千万不可漏掉。
下面各约束则可作为软约束处理,可以根据轻重缓急来为它们赋予权重:
6 ,教室类别不合教师要求的情况出现的次数尽量少;
7 ,上午老师上下午或晚上的课情况出现次数尽量少;
8 ,下午老师上上午或晚上的课情况出现次数尽量少;
9 ,上午课下午或晚上上情况出现次数尽量少;
10 ,下午课上午或晚上上情况出现次数尽量少;
11 ,教师们的工作时间应与其额定工作时间相去不大,既不能太闲也不能太累;
12 ,尽量少在晚上安排课;
13 ,各类课每天大节数尽量等于1;
下面是依上叙述用lingo 写的01 规划模型:
[ 其中定义的几个重要的基础集为C,T,R,D,J ,而DJRCT 是由它们联合派生出的关系集,有一个属性sel ,为01 变量。
DJRCT 中某个元素(id,ij,ir,ic,it) 的sel=1 表示" 星期id 的第ij 节大课在教室ir 中上ic 这门课, 授课教师为it" ,sel=0 则表示" 星期id 的第ij 节大课没有课" 。

其中1,2,3 三个硬约束作为了DJRCT 的筛选条件,使其成为一个稀疏集以减少内存占用量。
4,5 两个硬约束写在约束段内。
而各软约束加权后作为目标函数的一项被最小化。
其中暂未考虑表2 中“ 尽可能不同天上课的教师” 这一约束]

model:
sets:
C/1..40/:!课程集合;
c_type,
c_N,
c_Nseat,
c_roomtype,
c_AP;

T/1..25/:!教师集合;
t_ctype1,
t_ctype2,
t_N,
t_roomtype,
t_roomtype2,
t_AP;

R/1..18/:!教室集合;
r_Nseat,
r_roomtype;

D/1..5/:;!一周五天集合;

J/1..5/:;!一天五节课集合;

Ctype/1..8/:;!课程类别集合;

DJRCT(D,J,R,C,T)!星期几_第几节_教室_课程_教师 关系集合;
|#not#(!将如下情况剔除;
(c_roomtype(&4)#ne#r_roomtype(&3))!教室类型不合课程要求;
#or#
(r_Nseat(&3)#lt#c_Nseat(&4))!教室座位数不合课程要求;
#or#
(c_type(&4)#ne#t_ctype1(&5)#and#c_type(&4)#ne#t_ctype2(&5))!教师不能胜任课程;
):
sel;
endsets
data:
c_type     =1    1    1    1    1    2    2    2    2    2    3    3    3    3    3    4    4    4    4    4    5    5    5    5    5    6    6    6    6    6    7    7    7    7    7    8    8    8    8    8;
c_N        =2    2    3    2    2    2    2    1    2    2    3    2    3    1    2    2    2    3    2    1    2    2    2    3    2    2    2    2    2    2    3    2    2    2    2    3    2    1    2    2;
c_Nseat    =50    30    40    25    60    100    50    30    40    25    60    80    50    30    40    25    60    90    50    50    30    40    25    60    100    50    30    40    50    30    40    25    60    80    50    30    40    25    60    50;
c_roomtype =2    1    1    2    1    1    2    1    1    2    1    1    2    1    1    2    1    1    2    1    1    2    1    1    2    2    1    1    2    1    1    2    1    2    1    3    3    3    3    3;
c_AP       =1    2    2    1    2    2    1    1    2    1    1    1    2    2    2    1    2    1    1    1    1    2    1    2    1    2    2    2    1    2    1    2    0    1    2    0    1    1    2    0;
t_ctype1   =1    1    1    2    2    2    3    3    3    3    4    4    4    5    5    5    6    6    6    7    7    7    3    4    6;
t_ctype2   =8    0    0    0    0    0    0    8    0    0    0    0    0    0    8    0    0    0    0    0    0    0    8    8    8;
t_N        =2    2    3    2    2    3    2    2    2    3    4    2    3    1    2    2    2    3    2    2    3    3    2    3    2;
t_roomtype =2    1    1    2    1    1    1    1    1    2    1    1    2    1    1    1    1    1    2    1    1    2    1    1    1;
t_roomtype2=3    0    0    0    0    0    0    3    0    0    0    0    0    0    3    0    0    0    0    0    0    0    3    3    3;
t_AP       =1    2    1    1    2    0    1    2    1    1    2    0    2    1    2    1    2    0    2    1    2    1    0    1    2;
r_Nseat    =100   100   100   50    50    50    50    60    60    60    60    60    40    40    40    40    50    40;
r_roomtype =2     1     1     2     1     1     1     1     1     2     1     3     3     3     3     2     1     1;
enddata
@for(DJRCT(id,ij,ir,ic,it):
@bin(sel);
);
!目标函数;
min=10*@sum(DJRCT(id,ij,ir,ic,it)|t_roomtype(it)#ne#r_roomtype(ir)#and#t_roomtype2(it)#ne#r_roomtype(ir):sel)!教室类别不合教师要求的情况出现的次数;
   +10*@sum(DJRCT(id,ij,ir,ic,it)|t_AP(it)#eq#1#and#(ij#eq#3#or#ij#eq#4#or#ij#eq#5):sel)!上午老师上下午或晚上的课情况出现次数;
   +10*@sum(DJRCT(id,ij,ir,ic,it)|t_AP(it)#eq#2#and#(ij#eq#1#or#ij#eq#2#or#ij#eq#5):sel)!下午老师上上午或晚上的课情况出现次数;
   +@sum(DJRCT(id,ij,ir,ic,it)|c_AP(ic)#eq#1#and#(ij#eq#3#or#ij#eq#4#or#ij#eq#5):sel)!上午课下午或晚上上情况出现次数;
   +@sum(DJRCT(id,ij,ir,ic,it)|c_AP(ic)#eq#2#and#(ij#eq#1#or#ij#eq#2#or#ij#eq#5):sel)!下午课上午或晚上上情况出现次数;
   +100*@sum(T(it):(@sum(DJRCT(id,ij,ir,ic,it):sel)-t_N(it))^2)!教师们的工作时间应与其额定工作时间相去不大,既不能太闲也不能太累;
   +10*@sum(DJRCT(id,ij,ir,ic,it)|ij#eq#5:sel)!尽量少在晚上安排课;
   +100*@sum(Ctype(ict):@sum(D(id):(@sum(DJRCT(id,ij,ir,ic,it)|c_type(ic)#eq#ict:sel)-1)^2))!各类课每天大节数尽量等于1;
;
!约束;
!某一时间某一地点上的(教师,课程)是唯一的;
@for(D(id):
   @for(J(ij):
       @for(R(ir):
       @sum(DJRCT(id,ij,ir,ic,it):sel)<=1;
         );
   );
);
!课程课时数限制;
@for(C(ic):
@sum(DJRCT(id,ij,ir,ic,it):sel)=c_N(ic);
);
end

 

运行结果:
 Feasible solution found.
   Objective value:                              8508.000

                                           Variable           Value
                                SEL( 1, 1, 1, 1, 1)        0.000000
                                SEL( 1, 1, 1, 1, 2)        0.000000
                                SEL( 1, 1, 1, 1, 3)        0.000000
                                SEL( 1, 1, 1, 4, 1)        0.000000
                                SEL( 1, 1, 1, 4, 2)        0.000000
                                ... ...


                                (由于列表过长,无法完全贴出)

将灰色部分保存为lingors.txt,拷贝到matlab中,运行下面程序:

clear;
lingors=textread('lingors.txt','%s','delimiter','/n');
rs=[];
for i=1:length(lingors)
    rs=[rs;getvalu(lingors{i})];
end
index=find(rs(:,end)==1);
rs=rs(index,1:end-1);
disp(rs);

得到结果:
     1     1     1    34    22
     1     1     2    24    16
     1     1     3    11     9
     1     1     4     1     3
     1     1     7    20    12
     1     1     8    21    16
     1     1    10    29    18
     1     1    12    40    24
     1     1    13    36    24
     1     2     1    13    10
     1     2    10     4     1
     1     2    18    31    20
     1     3     2    27    18
     1     3     6     9     5
     1     4     2     6     5
     1     4     3    18    11
     2     1     1    13    10
     2     1     2    23    16
     2     1     4     7     4
     2     1     9     5     1
     2     1    10    32    22
     2     1    12    36    24
     2     1    13    37    24
     2     2     2    14     7
     2     2     9    31    20
     2     2    18     2     3
     2     3     1    16    13
     2     3     2    28    17
     2     3     3     2     2
     2     3     4    19    13
     2     3     5    35    21
     2     3    10    22    15
     2     4     4    29    17
     3     1     1     4     3
     3     1     2     3     1
     3     1     3    23    16
     3     1     5    31    20
     3     1     8    11     7
     3     1    11    11     9
     3     1    16    10     6
     3     2     1    25    14
     3     2     4    10     6
     3     2    13    37    23
     3     3     2    27    19
     3     3     3    18    11
     3     3     6    35    21
     3     4     7    30    25
     3     4     9    24    15
     3     4    11    17    11
     3     4    12    39     8
     4     1     1    25    14
     4     1     4     7     6
     4     1    10    19    13
     4     2     1    34    22
     4     2     2    12     7
     4     2     3    12     9
     4     2    16    32    22
     4     2    18    21    14
     4     3     1    16    13
     4     3     2    15     8
     4     3     3     3     2
     4     3    12    39    25
     4     4     1    26    19
     4     4     3     9     5
     4     4     8    28    18
     4     4    11     5     2
     4     4    12    40     8
     5     1     2     6     4
     5     1     4     1     3
     5     1     5     3     1
     5     1    12    38    23
     5     2     1    13    10
     5     2     3    18    12
     5     2    18     8     6
     5     3     9    15    23
     5     3    11    17    11
     5     4     1    26    17
     5     4     3    33    21
     5     4     8    24    15
     5     4     9    30    18
     5     4    11    33    21
     5     4    15    36    25
     5     4    16    22    15
例如,最后一行的意思是:
星期5第4节大课在教室R16上课程C22,授课教师为T15。
----
待改进处:
1,考虑加入"尽可能不同天上课的教师"这个(软)约束。
2,数据由数据库或excel读取。
3,数据与程序分离。
4,对结果的检验和评价。

----------------------------------------------------------------------------------------------------------

续:

刚才将“尽可能不同天上课的教师”这个约束也可上了,代码通过了语法检查,但是由于所需运行时间较长,影响看电影,所以今天就不运行了,等电脑空闲的时候再跑吧,代码如下:

(其中红色部分为本次新加的代码)

model:
sets:
C/1..40/:!课程集合;
c_type,
c_N,
c_Nseat,
c_roomtype,
c_AP;

T/1..25/:!教师集合;
t_ctype1,
t_ctype2,
t_N,
t_roomtype,
t_roomtype2,
t_AP,
t_avoid1,
t_avoid2;

R/1..18/:!教室集合;
r_Nseat,
r_roomtype;

D/1..5/:;!一周五天集合;

J/1..5/:;!一天五节课集合;

Ctype/1..8/:;!课程类别集合;


DJRCT(D,J,R,C,T)!星期几_第几节_教室_课程_教师 关系集合;
|#not#(!将如下情况剔除;
(c_roomtype(&4)#ne#r_roomtype(&3))!教室类型不合课程要求;
#or#
(r_Nseat(&3)#lt#c_Nseat(&4))!教室座位数不合课程要求;
#or#
(c_type(&4)#ne#t_ctype1(&5)#and#c_type(&4)#ne#t_ctype2(&5))!教师不能胜任课程;
):
sel;
endsets
data:
c_type     =1    1    1    1    1    2    2    2    2    2    3    3    3    3    3    4    4    4    4    4    5    5    5    5    5    6    6    6    6    6    7    7    7    7    7    8    8    8    8    8;
c_N        =2    2    3    2    2    2    2    1    2    2    3    2    3    1    2    2    2    3    2    1    2    2    2    3    2    2    2    2    2    2    3    2    2    2    2    3    2    1    2    2;
c_Nseat    =50    30    40    25    60    100    50    30    40    25    60    80    50    30    40    25    60    90    50    50    30    40    25    60    100    50    30    40    50    30    40    25    60    80    50    30    40    25    60    50;
c_roomtype =2    1    1    2    1    1    2    1    1    2    1    1    2    1    1    2    1    1    2    1    1    2    1    1    2    2    1    1    2    1    1    2    1    2    1    3    3    3    3    3;
c_AP       =1    2    2    1    2    2    1    1    2    1    1    1    2    2    2    1    2    1    1    1    1    2    1    2    1    2    2    2    1    2    1    2    0    1    2    0    1    1    2    0;
t_ctype1   =1    1    1    2    2    2    3    3    3    3    4    4    4    5    5    5    6    6    6    7    7    7    3    4    6;
t_ctype2   =8    0    0    0    0    0    0    8    0    0    0    0    0    0    8    0    0    0    0    0    0    0    8    8    8;
t_N        =2    2    3    2    2    3    2    2    2    3    4    2    3    1    2    2    2    3    2    2    3    3    2    3    2;
t_roomtype =2    1    1    2    1    1    1    1    1    2    1    1    2    1    1    1    1    1    2    1    1    2    1    1    1;
t_roomtype2=3    0    0    0    0    0    0    3    0    0    0    0    0    0    3    0    0    0    0    0    0    0    3    3    3;
t_AP       =1    2    1    1    2    0    1    2    1    1    2    0    2    1    2    1    2    0    2    1    2    1    0    1    2;
t_avoid1   =4    0    0    1    0    0    0    0    11    0    9    0    0    0    23    0    0    9    0    0    0    0    15    0    0;
t_avoid2   =0    0    0    0    0    0    0    0    18    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0;
r_Nseat    =100   100   100   50    50    50    50    60    60    60    60    60    40    40    40    40    50    40;
r_roomtype =2     1     1     2     1     1     1     1     1     2     1     3     3     3     3     2     1     1;
enddata
@for(DJRCT(id,ij,ir,ic,it):
@bin(sel);
);
!目标函数;
min=10*@sum(DJRCT(id,ij,ir,ic,it)|t_roomtype(it)#ne#r_roomtype(ir)#and#t_roomtype2(it)#ne#r_roomtype(ir):sel)!教室类别不合教师要求的情况出现的次数;
   +10*@sum(DJRCT(id,ij,ir,ic,it)|t_AP(it)#eq#1#and#(ij#eq#3#or#ij#eq#4#or#ij#eq#5):sel)!上午老师上下午或晚上的课情况出现次数;
   +10*@sum(DJRCT(id,ij,ir,ic,it)|t_AP(it)#eq#2#and#(ij#eq#1#or#ij#eq#2#or#ij#eq#5):sel)!下午老师上上午或晚上的课情况出现次数;
   +@sum(DJRCT(id,ij,ir,ic,it)|c_AP(ic)#eq#1#and#(ij#eq#3#or#ij#eq#4#or#ij#eq#5):sel)!上午课下午或晚上上情况出现次数;
   +@sum(DJRCT(id,ij,ir,ic,it)|c_AP(ic)#eq#2#and#(ij#eq#1#or#ij#eq#2#or#ij#eq#5):sel)!下午课上午或晚上上情况出现次数;
   +100*@sum(T(it):(@sum(DJRCT(id,ij,ir,ic,it):sel)-t_N(it))^2)!教师们的工作时间应与其额定工作时间相去不大,既不能太闲也不能太累;
   +10*@sum(DJRCT(id,ij,ir,ic,it)|ij#eq#5:sel)!尽量少在晚上安排课;
   +100*@sum(Ctype(ict):@sum(D(id):(@sum(DJRCT(id,ij,ir,ic,it)|c_type(ic)#eq#ict:sel)-1)^2))!各类课每天大节数尽量等于1;
   +10*@sum(D(id):@sum(T(it1):@sum(T(it2)|t_avoid1(it2)#eq#it1#or#t_avoid2(it2)#eq#it1:@if(@sum(DJRCT(id,ij,ir,ic,it1):sel)#ge#1,1,0)*@if(@sum(DJRCT(id,ij,ir,ic,it2):sel)#ge#1,1,0))))!不宜同天上课的老师同天上课的次数;
;
!约束;
!某一时间某一地点上的(教师,课程)是唯一的;
@for(D(id):
   @for(J(ij):
       @for(R(ir):
       @sum(DJRCT(id,ij,ir,ic,it):sel)<=1;
         );
   );
);
!课程课时数限制;
@for(C(ic):
@sum(DJRCT(id,ij,ir,ic,it):sel)=c_N(ic);
);
end

 

展开阅读全文

没有更多推荐了,返回首页