1.算法描述
这里,我们首先介绍一下改进算法的基本原理,按照前面说的,这里我们主要将GA和SA进行合并。
这里,我研究了下,将两种算法做如下方法的结合:
首先,在之前做的改进GA算法和普通SA算法的基础之上,将两个算法进行融合,整体的算法流程图如下所示:
第一、随机化产生N个初始群体P;
第二、代入到优化目标函数,获得N个初始的适应度值;
第三、按照改进GA算法的流程进行选择,变异和交叉等操作;
第四、然后对个体进行模拟退火的操作;
第五、然后对模拟退火后的群体的所有个体进行计算适应度值;
第六、将遗传算法中最优个体(未进行变异交叉的部分个体)和模拟退火后的个体进行融合,构成新的种群,作为新一代的种群;
第七、重复上述的步骤直接优化迭代次数结束。
其算法的流程图如下所示:
具体的理论过程如下所示:
我们按上面的过程,介绍一下具体的理论和原理:
01).种群的初始化
02).定义优化目标函数
当某一个机器生产完毕空闲下来,但由于受到交货期限的限制,需要将其余未生产好的产品放到空闲的机器上进行生产。此时就得到了如下的公式:
这里先说明一下上面公式的含义:
03).保留一部分最优的个体直接复制到新一代,这些群体定义为P1:
这里,采取一种改进后的种群保留机制,具体如下所示:这里,通过对比各个适应度之间的大小关系来判断的方法进行选择。
04).没有被保留的部分进行交叉和变异操作
这里,没有被保留的群体,定义为P2:。然后然后进行交叉和变异操作,具体的步骤见上次发你的关于GA算法的理论说明。
其中,关于这里交叉和变异的几个改进点如下所示:
1).交叉概率变异概率的自适应调整
进行遗传算法的关键点之一是保证种群的多样性。遗传算法的交叉和变异的判断,就是根据每个染色体个体的最大适应度值和平均适应度的差值的大小来判断,即:
当差值较大的时候,说明染色体差异较大,当差值较小的时候,说明染色体差异较小,当差异较小的时候,就会容易出现局部收敛。为了防止这种情况出现,我们需要自适应的调整这种变异概率和交叉概率,分别为:
其中k1和k2为两个常数,取值为1。根据上述的步骤,可以根据染色体的实际情况,自适应的调整交叉概率,变异概率。通过上述三个步骤的改进,可以有效解决传统遗传算法中存在的局部优化的缺陷。
05).模拟退火过程
对上述交叉变异后的个体进行模拟退火处理,获得p2’',关于模拟退火的过程,参考之前的给你写的文档,这里需要注意的是:
在模拟退火算法中,由于允许以一定概率接受差的解,使得当前状态可能比搜索轨迹中的某些中间状态要差,从而实际算法往往最终得到近似最优解,甚至可能比中间经历的最好解差,而且搜索效率较差,为了不遗失当前最优解,并提高搜索效率,在算法搜索过程中增加记忆功能,记住中间最优解,并及时更新。
06).种群的更新:
将种群P1和种群p2’'进行合并,构成新一代的种群。
07).进行下一个循环的迭代
根据上面的改进算法,我们进行编程,获得如下的仿真结果。
2.仿真效果预览
matlab2022a仿真结果如下:
3.MATLAB核心程序
%生产周期
ProduceA = 15*24;
ProduceB = 20*24;
ProduceC = 30*24;
%三种商品的交货期限
Time_OverA = 20;
Time_OverB = 30;
Time_OverC = 40;
%定义初始化时间
Time_iniA = 24;
Time_iniB = 48;
Time_iniC = 72;
%更换机器产生的延迟
Time_delay = 12;
%清洗时间
Time_wash = [2,3,5];
%机器容量
Cap = [20,30,50];
%设置三种产品的随机值得随机数种子
Seek_A = 1;
Seek_B = 2;
Seek_C = 3;
%%%%%%%%%%%%%%此处在Simulink等效替换%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% RandStream.setDefaultStream(RandStream('mt19937ar','seed',Seek_A));
A_source = floor(30*rand(1,Num))+1;
% RandStream.setDefaultStream(RandStream('mt19937ar','seed',Seek_B));
B_source = floor(20*rand(1,Num))+1;
% RandStream.setDefaultStream(RandStream('mt19937ar','seed',Seek_C));
C_source = floor(10*rand(1,Num))+1;
%计算优化前的需要的时间
%计算优化前的需要的时间
TimeA = func_product_time(A_source,Time_iniC,ProduceC,Num,Cap,3)
TimeB = func_product_time(B_source,Time_iniB,ProduceB,Num,Cap,2)
TimeC = func_product_time(C_source,Time_iniA,ProduceA,Num,Cap,1)
MAX_Time = max([TimeA,TimeB,TimeC]);
TASKer = [A_source',B_source',C_source'];
%生产完一批,下一批换产品导致的延迟
A_1 = Time_iniA + Time_wash(1) + Time_delay;
A_2 = Time_iniA + Time_wash(2) + Time_delay;
A_3 = Time_iniA + Time_wash(3) + Time_delay;
A_delays_diff = [A_1,A_2,A_3];
B_1 = Time_iniB + Time_wash(1) + Time_delay;
B_2 = Time_iniB + Time_wash(2) + Time_delay;
B_3 = Time_iniB + Time_wash(3) + Time_delay;
B_delays_diff = [B_1,B_2,B_3];
C_1 = Time_iniC + Time_wash(1) + Time_delay;
C_2 = Time_iniC + Time_wash(2) + Time_delay;
C_3 = Time_iniC + Time_wash(3) + Time_delay;
C_delays_diff = [C_1,C_2,C_3];
%生产完一批,下一批还是生产同样的产品(根据修改后的要求可知,只要是同一批产品,则可以连续生产)
A_1 = 0;
A_2 = 0;
A_3 = 0;
A_delays_same = [A_1,A_2,A_3];
B_1 = 0;
B_2 = 0;
B_3 = 0;
B_delays_same = [B_1,B_2,B_3];
C_1 = 0;
C_2 = 0;
C_3 = 0;
C_delays_same = [C_1,C_2,C_3];
for i = 1:Num
Machine_sel{i,1} = [3,3,3];
Machine_sel{i,2} = [2,2,2];
Machine_sel{i,3} = [1,1,1];
end
%根据每个机器的容量,来等效出每个单个订单的生产时间,但在后面计算过程中,当期满足判决条件的时候,时间则为72,96或者120
for i = 1:Num
Machine_time{i,1} = [C_source(i)/Cap(1)*ProduceC,B_source(i)/Cap(1)*ProduceB,A_source(i)/Cap(1)*ProduceA];
Machine_time{i,2} = [C_source(i)/Cap(2)*ProduceC,B_source(i)/Cap(2)*ProduceB,A_source(i)/Cap(2)*ProduceA];
Machine_time{i,3} = [C_source(i)/Cap(3)*ProduceC,B_source(i)/Cap(3)*ProduceB,A_source(i)/Cap(3)*ProduceA];
end
%一下是遗传算法的一些参数
%个体
Num_gene = 20;
%遗传次数
Iteration = 1000;
%代沟
DG = 0.9;
%交叉率
cross_rate= 0.8;
%变异率
by_rate = 0.2;
%计数器
Cnter = 0;
[Nums_time,Num_ABC] = size(Machine_sel);
Best_save = zeros(2, Iteration);
All_Number = Nums_time*Num_ABC;
Number = zeros(1,Nums_time);
for i=1:Nums_time
Number(i)=Num_ABC;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%01)种群的初始化
Random_save_machine = zeros(Num_gene,2*All_Number);
for j=1:Num_gene
Number2=Number;
for i=1:All_Number
%产品编号ABC - > 123
val = unidrnd(Nums_time);
while Number2(val)==0
val = unidrnd(Nums_time);
end
%产品编号
Random_save_machine(j,i) = val;
Number2(val) = Number2(val)-1;
%机器编号
Temp = Machine_sel{val,Num_ABC-Number2(val)};
SizeTemp = length(Temp);
%随机产品机器
Random_save_machine(j,i+All_Number) = unidrnd(SizeTemp);
end
end
%定义fitness
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%02)定义优化目标函数
[Value_Product,ObjV,Product,Genes] = func_fitness(Random_save_machine,Num_machine,Machine_time,Machine_sel);
s = RandStream('mt19937ar','Seed',0);
RandStream.setGlobalStream(s);
%开始优化迭代
%设置模拟退火算法参数
%初始温度
T = 1000;
%温度降低参数
a = 0.99;
%记录模拟退火次数
kkk = 1;
while Cnter <= Iteration
Cnter
isover = 0;
if Cnter == 0
%交叉率
cross_rate0 = 0.8;
%变异率
by_rate0 = 1 - cross_rate0;
cross_rate = cross_rate0;
by_rate = by_rate0;
else
%交叉率
cross_rate = cross_rate0*(1-exp(1/(1+Cnter))/8);
%变异率
by_rate = 1 - cross_rate;
end
%适应度值
Value_fit = ranking(ObjV);
%选择
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%03)保留一部分最优的个体直接复制到新一代,这些群体定义为:
GA_Oper = select('rws', Random_save_machine, Value_fit, DG);
%04)没有被保留的部分进行交叉和变异操作
%交叉
GA_Oper = func_Gene_cross(GA_Oper,cross_rate,Machine_sel,Machine_time);
%变异
GA_Oper = func_aberrance(GA_Oper,by_rate,Machine_sel,Machine_time);
%适应度值
[Value_Product,Obj_Product,Product,Genes,TYPE] = func_fitness(GA_Oper,Num_machine,Machine_time,Machine_sel);
%新种群
[Random_save_machine,ObjV] = reins(Random_save_machine, GA_Oper,1, 1, ObjV, Obj_Product);
Cnter = Cnter + 1;
%保存最值
Best_save(1,Cnter) = min(ObjV);
Best_save(2,Cnter) = mean(ObjV);
%05)模拟退火过程
[newbestfitness,newbestindex]=min(ObjV);
[worestfitness,worestindex] =max(ObjV);
if Cnter == 1
[bestfitness,bestindex]=min(ObjV);
bestchrom = Random_save_machine(bestindex,:);
else
%代替上一次进化中最好的染色体
if bestfitness>= newbestfitness
bestfitness = newbestfitness;
bestchrom = Random_save_machine(newbestindex,:);
else
bh = bestfitness-newbestfitness;
cc(kkk) = bh/T;
aa(kkk) = exp(bh/T);
if exp(1000*bh/T) > rand/5
kkk = kkk+1;
bestfitness = newbestfitness;
bestchrom = Random_save_machine(newbestindex,:);
end
end
end
T=T*a; %温度降低
Random_save_machine(worestindex,:) = bestchrom;
ObjV(worestindex) = bestfitness;
%延期判决
if isover == 1
Cnter = Cnter-1;%重新开始本次迭代
else
Cnter =Cnter;
end
Best_V(Cnter) = mean(ObjV);
if Cnter <= 64
Best_V2(Cnter) = mean(Best_V(1:Cnter));
else
Best_V2(Cnter) = mean(Best_V(Cnter-64:Cnter));
end
end
%描绘解的变化
figure;
plot(Best_V2,'Linewidth',2);
grid on
xlabel('Iteration Number');
ylabel('GA & SA values');
02_024m