本篇遗传算法根据下述文章进行编写,框架一致
https://blog.csdn.net/qq_38757869/article/details/107598731
1 导入调度数据集
数据集需要符合下述格式(数据集描述见代码所述),否则需要自己修改代码。
2 主程序
%%%%%%%%%%%%遗传算法解决single-machine job-shop问题%%%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
maxrun=10; %最大运行次数
maxgen=10; %最大迭代次数
NP=200; %种群规模
OW=0.5; %目标1权重
T=importdata('task.txt'); %导入任务数据
%%%%%%%%%%%task.txt数据格式%%%%%%%%%%%%
%工件 ……………………
%加工时间……………………
%到达时间……………………
%交货期 ……………………
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
N=size(T,2); %染色体长度
NJ=N; %工件数量
mbest=zeros(maxrun,N+3); %每次运行的最佳个体,及其三个目标值
CL=zeros(1,NJ);
for li=1:NJ %工件工序数,为1
CL(1,li)= 1;
end
for run=1:maxrun %运行maxrun次
Bestg=zeros(1,maxgen);
[f1]=initial(T,NP,NJ); %种群初始化
OP=0;
[fitness]=fit(f1,NP,N,T,NJ,OP,OW); %适应度计算
OP=min(fitness(:,1))/min(fitness(:,2)); %双目标折衷值
fitness(:,3)=OW*fitness(:,1)+OP*(1-OW)*fitness(:,2);
[f1,f2]=select(f1,fitness,N); %选择
Bestgen=f2;
for gen=1:maxgen %迭代maxgen代
[f1]=cross(f1,T,N,NP,NJ,CL); %交叉(里面有变异)
[fitness]=fit(f1,NP,N,T,NJ,OP,OW); %适应度计算
[f1,f2]=select(f1,fitness,N); %选择
if(f2(1,N+3)<Bestgen(1,N+3))
Bestgen=f2;
end
Bestg(1,gen)=min(Bestgen(1,N+3),f2(1,N+3));
end
figure(run);
plot(Bestg);
mbest(run,:)=Bestgen;
end
dlmwrite('best_result.txt',mbest); %将最优结果存入文件
3 初始化函数
function [fi1] = initial(T,NP,NJ)
%随机初始化任务调度和AGV分配种群%
fi1=zeros(NP,NJ); %用于存储任务调度种群
for ii=1:NP %种群初始化
fi1(ii,:)=T(1,randperm(NJ)); %随机生成初始种群
end
end
4 适应度计算函数
function [fitf] = fit(f1,NP,N,T,NJ,OP,OW)
%目标1:最大完工时间;
%目标2:总延迟;
fitf=zeros(NP,3); %个体适应值:最大完工时间;最大功耗;双目标
for i1=1:NP
Mi=0; % 存储机器最早开始时间
Ci=zeros(1,NJ); % 存储工件完工时刻
Et=T(3,:); % 工件最早开始时间
for i2=1:N
Ci(1,f1(i1,i2))=max(Mi,Et(1,f1(i1,i2)))+T(2,f1(i1,i2)); %机器和工件的最迟开始时间+加工时间
Mi=Ci(1,f1(i1,i2));
end
Dt=max(0,Ci-T(4,:));
fitf(i1,1)=Mi; %完工时间
fitf(i1,2)=sum(Dt); %总延迟
fitf(i1,3)=OW*fitf(i1,1)+OP*(1-OW)*fitf(i1,2);
end
end
5 选择函数
function [fs1,fs2] = select(f1,fitness,N)
% 优先权选择:选择最优个体,适应度1:20;适应度2:20;适应度3:60;
Ns1=20;
Ns2=20;
Ns3=60;
CH=[f1,fitness];
CHa=sortrows(CH,N+3);
Best=CHa(1:Ns3,:);
CHa=sortrows(CH,N+2);
Best=[Best;CHa(1:Ns2,:)];
CHa=sortrows(CH,N+1);
Best=[Best;CHa(1:Ns1,:)];
fs1=Best(:,1:N);
fs2=Best(1,:);
end
6 子代生成函数
function [fc1] = cross(f1,T,N,NP,NJ,CL)
%从最优的100个体生成100个后代
%随机生成100个后代
%概率交叉完成后概率变异
Pc=0.8; %交叉概率
Pm=0.2; %变异概率
Nr=NP/2; %随机子代数量
Rc=NP/4; %交叉数范围
fc1=[];
for ic=1:Rc % 产生NP/2个后代
pcp=unidrnd(Rc); %选择交叉父代
p1f1=f1(pcp,:);
p2f1=f1(pcp+Rc,:);
if(rand()<Pc)
cr=unidrnd(N-2)+1; %产生交叉点
temp1=p1f1(1,cr:N); %父代染色体互换
p1f1=p1f1(1,1:cr-1);
temp2=p2f1(1,cr:N);
p2f1=p2f1(1,1:cr-1);
p1f1=[p1f1,temp2];
p2f1=[p2f1,temp1];
CLt=CL;
for le=1:N %父代1染色体合法化
for lei=1:NJ
if(p1f1(1,le)==lei)
if(CLt(1,lei)>0)
CLt(1,lei)= CLt(1,lei)-1;
break;
else
p1f1(1,le)=0;
break;
end
end
end
end
for le=1:N
if(p1f1(1,le)==0)
for lei=1:NJ
if(CLt(1,lei)>0)
p1f1(1,le)=lei;
CLt(1,lei)= CLt(1,lei)-1;
break;
end
end
end
end
CLt=CL;
for le=1:N %父代2染色体合法化
for lei=1:NJ
if(p2f1(1,le)==lei)
if(CLt(1,lei)>0)
CLt(1,lei)= CLt(1,lei)-1;
break;
else
p2f1(1,le)=0;
break;
end
end
end
end
for le=1:N
if(p2f1(1,le)==0)
for lei=1:NJ
if(CLt(1,lei)>0)
p2f1(1,le)=lei;
CLt(1,lei)= CLt(1,lei)-1;
break;
end
end
end
end
if(rand()<Pm) %概率变异
cm=unidrnd(N-2)+1; %产生变异点
jm=unidrnd(NJ); %产生变异 工件
mg=p1f1(1,cm);
p1f1(1,cm)=jm;
for mi=1:N %p1f1合法化
if(p1f1(1,mi)==jm)
p1f1(1,mi)=mg;
break;
end
end
cm=unidrnd(N-2)+1; %产生变异点
jm=unidrnd(NJ); %产生变异 工件
mg=p2f1(1,cm);
p2f1(1,cm)=jm;
for mi=1:N %p2f1合法化
if(p2f1(1,mi)==jm)
p2f1(1,mi)=mg;
break;
end
end
end
end
fc1=[fc1;p1f1;p2f1];
end
for ri=1:Nr %生成随机个体
fr1(ri,:)=T(1,randperm(NJ)); %随机生成初始种群
end
fc1=[fc1;fr1];
end
备注:此算法仅为最基本的遗传算法对单机调度问题的多目标求解应用,仅供初学者参考,用于对遗传算法和单机调度问题的了解,算法的性能不能保证最好。