资料来源《Matlab智能算法30个案例分析》
郁磊 史峰 等 著
问题描述:共有6个工件,在10台机器上加工,每个工件序经过6道工序,安排最零件加工方案。
列号,表示零件的标号;行号表示加工工序;矩阵中的元素表示该零件的该道工序的加工机器
列号,表示零件的标号;行号表示加工工序;矩阵中的元素表示该零件的该道工序加工时所需的时间
unidrnd
Random arrays from the discrete uniform distribution.
R =
unidrnd(N) returns an array of random numbers chosen
uniformly
from
the set {1, 2, 3, ... ,N}. The size of R is the
size of N.
> r=unidrnd(10,2,5)
r
=
2 9 3 2 9
7 9 3 9 8
题目中需要的数据保存在scheduleData.mat中
其中Jm是工序和可选机器表
行数表示工序1-6
列数表示工件1-6
矩阵中的元素表示机器的标号,例如3行5列[4,10]表示第五个零件的第三道工序可以在4号或10号机器上加工
每个零件的工序必须依次完成
T表示每个零件每道工序的加工时间表
JmNumber是机器数
程序
%%
清空环境
clc;clear
%%
下载数据
load
scheduleData Jm T JmNumber%注意,Jm T JmNumber之间有空格
%工序
时间
%%
基本参数
NIND=40; %个体数目
MAXGEN=50; %最大遗传代数
GGAP=0.9; %代沟
XOVR=0.8; %交叉率
MUTR=0.6; %变异率
gen=0; %代计数器
%PNumber 工件个数 MNumber 工序个数
[PNumber
MNumber]=size(Jm);
trace=zeros(2,
MAXGEN); %寻优结果的初始值
WNumber=PNumber*MNumber; %工序总个数
%%
初始化
Number=zeros(1,PNumber); % PNumber 工件个数
for
i=1:PNumber
Number(i)=MNumber; %MNumber工序个数
end
%
代码2层,第一层工序,第二层机器
Chrom=zeros(NIND,2*WNumber);
for
j=1:NIND
WPNumberTemp=Number;
for
i=1:WNumber %工序总个数
%随机产成工序
val=unidrnd(PNumber);%工件的个数,生成一个随机数
while WPNumberTemp(val)==0
val=unidrnd(PNumber);
end
%第一层代码表示工序
Chrom(j,i)= val;
WPNumberTemp(val)=WPNumberTemp(val)-1;
%第2层代码表示机器
Temp=Jm{val,MNumber-WPNumberTemp(val)};
SizeTemp=length(Temp);
%随机产成工序机器
Chrom(j,i+WNumber)= unidrnd(SizeTemp);
end
end
%计算目标函数值
[PVal ObjV
P S]=cal(Chrom,JmNumber,T,Jm);
%%
循环寻找
while
gen
%分配适应度值
FitnV=ranking(ObjV);
%选择操作
SelCh=select('rws', Chrom, FitnV,
GGAP);
%交叉操作
SelCh=across(SelCh,XOVR,Jm,T);
%变异操作
SelCh=aberranceJm(SelCh,MUTR,Jm,T);
%计算目标适应度值
[PVal ObjVSel P
S]=cal(SelCh,JmNumber,T,Jm);
%重新插入新种群
[Chrom ObjV] =reins(Chrom, SelCh,1, 1, ObjV,
ObjVSel);
%代计数器增加
gen=gen+1;
%保存最优值
trace(1,
gen)=min(ObjV);
trace(2, gen)=mean(ObjV);
% 记录最佳值
if
gen==1
Val1=PVal;
Val2=P;
MinVal=min(ObjV);%最小时间
STemp=S;
end
%记录
最小的工序
if
MinVal> trace(1,gen)
Val1=PVal;
Val2=P;
MinVal=trace(1,gen);
STemp=S;
end
end
%
当前最佳值
PVal=Val1;
%工序时间
P=Val2; %工序
S=STemp;
%调度基因含机器基因
%%
描绘解的变化
figure(1)
plot(trace(1,:));
hold
on;
plot(trace(2,:),'-.');grid;
legend('解的变化','种群均值的变化');
%%
显示最优解
figure(2);
MP=S(1,PNumber*MNumber+1:PNumber*MNumber*2);
for
i=1:WNumber
val=
P(1,i);
a=(mod(val,100)); %工序
b=((val-a)/100); %工件
Temp=Jm{b,a};
mText=Temp(MP(1,i));
x1=PVal(1,i);
x2=PVal(2,i);
y1=mText-1;
y2=mText;
plotRec(x1,x2,mText);
plotRec(PVal(1,i),PVal(2,i),mText);
hold
on;
fill([x1,x2,x2,x1],[y1,y1,y2,y2],[1-1/b,1/b,b/PNumber]);
text((x1+x2)/2,mText-0.25,num2str(P(i)));
end
function
[PVal ObjV P S]=cal(Chrom,JmNumber,T,Jm)
%
功能说明:
根据基因群,计算出个群中每个个体的调度工序时间,
%
保存最小时间的调度工序和调度工序时间
%
输入参数:
% Chrom
为基因种群
% T
为各工件各工序使用的时间
% Jm
为各工件各工序使用的机器
%
输出参数:
% PVal
为最佳调度工序时间
% P
为最佳输出的调度工序
% ObjV
为群中每个个体的调度工序时间
% S
为最佳输出的调度基因
%初始化
NIND=size(Chrom,1);
ObjV=zeros(NIND,1);
% 工件个数 工序个数
[PNumber
MNumber]=size(Jm);
for
i=1:NIND
%取一个个体
S=Chrom(i,:);%S为一个基因
%根据基因,计算调度工序
P= calp(S,PNumber);
function
P=calp(S,PNumber)
% 功能说明:
根据基因S,计算调度工序P
% 输入参数:
% S
为基因
% PNumber
为工件个数
% 输出参数:
% P
为输出的调度工序 所有工件的工序
%
比如数字1002表示工件10的工序03
WNumber=length(S);%工序总个数
即S的长度
WNumber=WNumber/2;
%取工序基因,取基因的一半
S=S(1,1:WNumber);
%初始化
temp=zeros(1,PNumber);
P=zeros(1,WNumber);
%解码生成调度工序
基因S的前36个编码表示工件
for i=1: WNumber
%工序加+1
temp(S(i))=temp(S(i))+1;
%当连续两个编码是同一个工件时,工序要加1
%例如S(i)=6,temp(6)=temp(6)+1=1
%s(i+1)=6,temp(6)=temp(6)+1=2
%S(i+2)=6,temp(6)=temp(6)+1=3;
%于是有P(i)=601,602,603 即第6个工件的第1,2,3道工序
P(i)=S(i)*100+temp(S(i));
end
%根据调度工序,计算出调度工序时间
PVal=caltime(S,P,JmNumber,T,Jm);
function
PVal=caltime(S,P,JmNumber,T,Jm)
% 功能说明:
根据调度工序,计算出调度工序时间
% 输入参数:
% P
为调度工序
% JmNumber
为机器个数
% T
为各工件各工序的加工时间
% Jm
为各工件各工序使用的机器
% 输出参数:
% PVal 为调度工序开始加工时间及完成时间
% 工件个数 工序个数
[PNumber MNumber]=size(Jm);
%取机器基因,取基因的一半
取S的后半部分
M=S(1,PNumber*MNumber+1:PNumber*MNumber*2);
%工序总个数
WNumber=length(P);
%初始化
TM=zeros(1,JmNumber);%机器个数
TP=zeros(1,PNumber);%工件个数
PVal=zeros(2,WNumber);%工序总个数
%计算调度工序时间
for i=1: WNumber %1-36,所有工件的工序
%
取机器号
val=
P(1,i);
a=(mod(val,100)); %工序
val除100取余,得到工序号a
b=((val-a)/100); %工件
val-a,除100,得到工件标号b
Temp=Jm{b,a};%在Jm中获取机器标号
m=Temp(M(1,i));%m为机器编号
Temp=T{b,a}; %在数据表T中取加工时间
t=Temp(M(1,i));%t为加工时间
%取机器加工本工序的开始时间和前面一道工序的完成时间
TMval=TM(1,m);%机器加工本工序开始的时间
%TM中存储的为机器时间,取标号为m的机器的时间。
TPval=TP(1,b); %前一道工序的完成时间
%机器加工本工序的开始时间
大于前面一道工序的完成时 ,取机器加工本工序的开始时间
if
TMval>TPval
val=TMval;
else
val=TPval;
end
%计算时间
PVal(1,i)=val;
PVal(2,i)=val+t;
%记录本次工序的机器时间和工序时间
TM(1,m)=PVal(2,i);%记录机器使用的时间,即编号为m的机器在本道工序中使用的时间
TP(1,b)=PVal(2,i); %本次工序的时间
End
%在零件加工的工程中,有可能机器正在被使用,所以零件需要等待机器使用完毕之后才能继续加工
或者机器没有使用时,零件可以直接使用,TM中就是记录的机器使用的时间,TP中记录的是零件加工工序的时间,即当TM3即第3台机器的时间大于TP3,表明第三台机器可以使用,所以时间取TM3,当TM3小于TP3时,说明第3台机器正在使用,只有等使用完成后才能进入下一道工序,所以时间取TP3
%取完成时间
MT=max(PVal);
TVal=max(MT);
%保存时间
ObjV(i,1)=TVal;
%初始化
if
i==1
Val1=PVal;
Val2=P;
MinVal=ObjV(i,1);
STemp=S;
end
%记录
最小的调度工序时间、最佳调度工序时间 最佳输出的调度工序
if
MinVal> ObjV(i,1)
Val1=PVal;
Val2=P;
MinVal=ObjV(i,1);
STemp=S;
end
end
%最佳调度工序时间
最佳输出的调度工序
PVal=Val1;
P=Val2;
S=STemp;
实验结果
其中301表示第3个零件的第一道工序,以此类推。