【模拟退火】模拟退火算法在排课中的MATLAB仿真

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时间有BC班上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

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fpga和matlab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值