1.软件版本
MATLAB2007b
2.本算法理论知识
(1)学生2000人
(2)教师120人
(3)班级40个
(4)教室50个【来源:教室数量应多于班级数,并且要有充足余量,所以取50个教室】
(5)课程15门【来源:因为根据“每位老师只上一门课,而且全校没有合班课的的规则”得出,课程数=教师数】
课程与教师的数据结构
每位老师只上一门课,而且全校没有合班课的的规则
每个星期 40个班级 每班15门课 总共600 节课
120位教师 每周5节课 总共600 节课
15门课 每门8个老师 总共 120位老师
将课程分成15个数组 每个数组存放 8位老师 每个课程数组有一个优先值
课程 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
优先级 | 3 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 3 | 3 | 3 | 4 | 4 | 5 | 5 |
体育 | 主干课 | 选修课 |
例如课程一数组=[教师A ,教师B,教师C,教师D·····] 他们的优先级都为3
| 星期 | 星期一 | 星期二 | 星期三 | 星期四 | 星期五 |
上午 | 1节 | 0.94 | 0.99 | 0.98 | 0.95 | 0.92 |
2节 | 0.85 | 0.89 | 0.87 | 0.84 | 0.82 | |
下午 | 3节 | 0.75 | 0.79 | 0.77 | 0.71 | 0.62 |
4节 | 0.65 | 0.69 | 0.66 | 0.61 | 0.3 | |
晚上 | 5节 | 0.59 | 0.60 | 0.55 | 0.54 | 0.15 |
例如当优先级=1对应权值是0.95 那么他的最佳排课位置是星期四第一节
=2 0.85
=3 0.75
=4 0.63
=5 0.53
如果某课程优先级1 排在 星期二第一节 那么就有一个0.99-0.95=0.04的值 每个课表求此值和 总和可作为目标函数
老师学生上课时间不能冲突 即
A时间有B,C班上D老师课
解决方法 初始解生成后
用递归搜索 是否有课程号相同的科目 重新随机产生新解
教室课时不能冲突 即
A班有B,C门课在D时上
解决方法 在初始解生成后
用递归搜索 是否有课时号相同的科目 重新随机产生新解
或者是产生一个冲突值 累加到目标函数上使之成为不良解
我觉得用递归不太好 解决冲突应该把冲突变成一种常量 列入目标函数运算
3.部分核心代码
function Best_tour_length= tspsiman(EUC_2D)
flops(0) ;
t0= clock ;
xy= EUC_2D ;
n_num= length(xy) ;
rand('state',sum(100*clock));
distance_matrix = zeros(n_num) ;
for n_num_x = 1: n_num,
for n_num_y = 1:n_num_x
x = xy(n_num_x, 1) ;
y = xy(n_num_x, 2) ;
xx = xy(n_num_y, 1) ;
yy = xy(n_num_y, 2) ;
distance_matrix(n_num_x, n_num_y)= ceil(sqrt((x - xx)^2 + (y - yy)^2)) ;
distance_matrix(n_num_y, n_num_x)= distance_matrix(n_num_x, n_num_y) ;
end
end
lenbestNN= inf ;
pbestNN= [] ;
prand= randperm(n_num) ;
f=find(prand==1) ;
prand(f)= prand(1) ;
p= [1 prand(2)] ;
i= prand(3) ;
count= 3 ;
while count <= n_num
NNdist= inf ;
pp= i ;
for j= 1: n_num
if (distance_matrix(i, j) < NNdist) & (j~=i) & ((j~=p) == ones(1,length(p)))%333??????????????????
NNdist= distance_matrix(i, j) ;
pp= j ;
end
end
p= [p pp] ;
i= pp ;
count= count + 1 ;
end
len= tourdist(p, distance_matrix) ;
if len < lenbestNN
lenbestNN= len ;
pbestNN= p ;
end
solnn= [] ;
lenn= [] ; temp= [] ;
soln= 1 ;
% ========================
% A 2-Opt local search
% ========================
lencurr= lenbestNN;
Best_tour_length= lenbestNN
pcurr= pbestNN ;
pbest= pbestNN ;
% ========================
% Temperature control
% ========================
restart= 1 ;
Tstart= 30 ; % Start temperature
Tend= 1 ; % Stop temperature
Tred= 0.97 ;
T= Tstart ;
Nochange= 2 ; % If after Nochange neighborhood searches, no improvements or
% changes in tour search, annealing complete, break search.
% ========================
lenn= [lenn lencurr] ;
temp= [temp T] ;
solnn= [solnn soln] ;
bb= 0 ;
while T >= Tend
big= n_num - 1 ;
while big >= 3
small= big - 2 ;
while small >= 1
curropt= distance_matrix(pcurr(big),pcurr(big+1)) + distance_matrix(pcurr(small),pcurr(small+1)) ;
swap2= distance_matrix(pcurr(small),pcurr(big)) + distance_matrix(pcurr(small+1),pcurr(big+1)) ;
soln= soln + 1 ;
if swap2 < curropt
order2= 1: n_num ;
order2=[1:small big:-1:small+1 big+1:n_num] ;
pcurr= pcurr(order2) ;
lencurr= tourdist(pcurr, distance_matrix) ;
lenn= [lenn lencurr] ;
temp= [temp T] ;
solnn= [solnn soln] ;
if lencurr < Best_tour_length
Best_tour_length= lencurr
pbest= pcurr ;
Temperature_of_best_tour_length= T
Solution_count= soln
T= Tred * T ;
if T <= 3
T= 50 ;
end
end
Tcurr= T ;
bb= 0 ;
big= n_num - 1 ;
small= big - 1 ;
if T <= 3
T= 10 ;
end
if T <= Tend ;
big= 2.9 ;
break
end
elseif swap2 > curropt
%r= abs(randn) ;
r= rand; % where r ranges from 0.0 to 1.0
diff= swap2 - curropt ;
%if r < exp(-(diff) / T)
if r <= exp(-(diff) / T)
order2= 1: n_num ;
order2=[1:small big:-1:small+1 big+1:n_num] ;
pcurr= pcurr(order2) ;
lencurr= tourdist(pcurr, distance_matrix) ;
T= Tred * T ;
bb= 0 ;
end
end
small= small - 1 ;
end
big= big - 1 ;
end
bb= bb + 1 ;
if T <= Tend | bb > Nochange ;
clc
Best_tour_length
besttour= [pbest -pbest(1)]
Temperature_of_best_tour_length
Solution_count
Search_stop_temperature= T
Elapsed_time= etime(clock, t0) % In seconds
Solutions_generated= soln
Floating_point_operations = flops
if bb > Nochange
No_change= bb
end
disp('Press ENTER to display plot')
pause
clc
plot(temp, lenn)
title('Simulated Annealing w/ 2-Opt local search')
xlabel('Temperature (not scaled)')
ylabel('Tour Lengths')
grid
disp('Press ENTER to display plot')
pause
clc
plot(solnn, lenn)
title('Simulated Annealing w/ 2-Opt local search')
xlabel('Number of Solutions')
ylabel('Tour Lengths/Costs')
grid
disp('Press ENTER to restart search (if var restart > 0) or Ctrl^C to end search.')
pause
if restart > 0
clc
T= Tstart ; bb= 0 ;
solnn= []; lenn= []; temp= [] ;
% =======================================================
% This time randomly generate tours and restart annealing
% =======================================================
prand= randperm(n_num) ;
f=find(prand==1) ;
prand(f)= prand(1) ; prand(1)= 1 ;
lencurr= Best_tour_length
pcurr= pbest ;
% =======================================================
end
end
end
% End of local search
4.操作步骤与仿真结论
5.参考文献:
[1]刘继清, 陈传波. 模拟退火算法在排课中的应用[J]. 武汉船舶职业技术学院学报, 2003(3):3. A06-02