一、简介
1 免疫算法
1.1免疫算法的基本步骤:
(1)抗原识别。输入目标函数和各种约束作为免疫算法的抗原。
(2)初始抗体生成。随机生成初始抗体种群。
(3)亲和力计算。计算抗体的适应值。对解群体中的各个解个体进行综合评价,包括解(抗体)与问题(抗原)的适应值(亲和力)以及解与解之间的相似度(亲和力)
(4)免疫处理。免疫处理包括免疫选择、克隆、变异和抑制。
(5)免疫选择:根据抗体的亲和力选出亲和度较高的抗体。
(6)克隆:对选出的亲和力较高的抗体进行复制。
(7)变异:对克隆得到的个体进行交叉、变异操作,使其亲和力发生改变。
(8)抑制:对变异的抗体进行选择,保留亲和度较高的抗体。
(9)群体刷新。将免疫选择的抗体和免疫抑制后的抗体组成一个集合,保留其中亲和度较高的抗体,使这些抗体进入新的种群。新的种群中不足的部分随机生成,以增加多样性。
2 免疫算法与遗传算法的区别
免疫算法是模拟免疫系统对病菌的多样性识别能力(即免疫系统几乎可以识别无穷多种类的病菌)而设计出来的多峰值搜索算法,其具体步骤如下
二、源代码
%% 清空环境
clc;clear
%% 下载数据
load scheduleData Jm T JmNumber Q
%工序 时间
%% 基本参数
NIND=40; %个体数目
MAXGEN=80; %最大遗传代数
GGAP=0.9; %代沟
XOVR=0.8; %交叉率
MUTR=0.1; %变异率
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<MAXGEN
%分配适应度值
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;
function NewChrom=across(Chrom,XOVR,Jm,T)
% Chrom=[1 3 2 3 1 2 1 3 2;
% 1 1 2 3 3 1 2 3 2;
% 1 3 2 3 2 2 1 3 1;
% 1 3 3 3 1 2 1 2 2;
% ];
% XOVR=0.7;
[NIND,WNumber]=size(Chrom);
WNumber=WNumber/2;
NewChrom=Chrom;%初始化新种群
[PNumber MNumber]=size(Jm);
Number=zeros(1,PNumber);
for i=1:PNumber
Number(i)=1;
end
%随机选择交叉个体(洗牌交叉)
SelNum=randperm(NIND);
Num=floor(NIND/2);%交叉个体配对数
for i=1:2:Num
if XOVR>rand;
Pos=unidrnd(WNumber);%交叉位置
while Pos==1
Pos=unidrnd(WNumber);
end
%取两交叉的个体
S1=Chrom(SelNum(i),1:WNumber);
S2=Chrom(SelNum(i+1),1:WNumber);
S11=S2;S22=S1; %初始化新的个体
%新个体中间片断的COPY
S11(1:Pos)=S1(1:Pos);
S22(1:Pos)=S2(1:Pos);
%比较S11相对S1,S22相对S2多余和缺失的基因
S3=S11;S4=S1;
S5=S22;S6=S2;
for j=1:WNumber
Pos1=find(S4==S3(j),1);
Pos2=find(S6==S5(j),1);
if Pos1>0
S3(j)=0;
S4(Pos1)=0;
end
if Pos2>0
S5(j)=0;
S6(Pos2)=0;
end
end
for j=1:WNumber
if S3(j)~=0 %多余的基因
Pos1=find(S11==S3(j),1);
Pos2=find(S4,1);%查找缺失的基因
S11(Pos1)=S4(Pos2);%用缺失的基因修补多余的基因
S4(Pos2)=0;
end
if S5(j)~=0
Pos1=find(S22==S5(j),1);
Pos2=find(S6,1);
S22(Pos1)=S6(Pos2);
S6(Pos2)=0;
end
end
% 保存交叉前的机器 基因
S1=Chrom(SelNum(i),:);
S2=Chrom(SelNum(i+1),:);
for k=1:WNumber
Pos1=Find(S11(k),S1);
S11(WNumber+k)=S1(WNumber+Pos1);
S1(Pos1)=0;
Pos1=Find(S22(k),S2);
S22(WNumber+k)=S2(WNumber+Pos1);
S2(Pos1)=0;
end
三、运行结果
四、备注
版本:2014a