CSDN编辑器里面没有MATLAB选项,所以我为了注释更清楚,用的是//,大家不要被误解了呀,算法看代码就好了
1 免疫算法的精髓
- 生物免疫系统:动态性免疫、自适应免疫
- 免疫算法-保证信息的无害性、有效、抵御垃圾信息
2 理解免疫算法
生物名词 | 对应计算机 |
---|---|
抗原 | 要解决的问题 |
抗原识别 | 问题识别 |
抗体 | 最优解 |
抗体增加 | 利用遗传算法产生新的最优解 |
记忆细胞产生抗体 | 联想过去的成功 |
淋巴细胞分化 | 优良解或者记忆能力的保持 |
细胞抑制 | 候选解的消除 |
3 免疫算法原理
遗传算法的交叉和变异有一定的盲目性,容易早熟收敛,因此引入免疫算法,对遗传算法全局搜索的过程进行一定强度的干预,提高算法的效率。
4 MatLab代码详解
- 首先要进行初始化种群
%D是维度,NP是种群数目,XMin是取值下限,XMax是取值上限
function pOp = InitialPop(D,NP,XMin,XMax)
pOp = rand(D,NP)*(XMax-XMin)+XMin;
end
- 然后计算一下初始种群的抗原和抗体的亲和度,这里和遗传算法的适应度很像,其实就是函数的值
//计算函数的值
func Eval = EvalFunc(x)
Eval = 5*sin(x(1)*x(2))+x(1)*x(1)+x(2)*x(2);
end
//计算抗体和抗原之间的亲和度
func MSLL = EvalMSLL()
for np = 1:NP
MSLL(np) = EvalFunc(f(:,np));
end
end
- 然后免疫算法比较独特就是引入了个体的浓度,这样可以保证他的全局搜索性,因为浓度高的个体的数目会被抑制,这样不会在一个局部解反复搜索。
//计算个体浓度
for np = 1:NP
for j=1:NP
nd(j) = sqrt(sum((f(:,np)-f(:,j)).^2));
if nd(j)<detas //detas=0.2;相似度阈值
nd(j) = 1;
else
nd(j) = 0;
end
end
ND(j) = sum(nd)/NP;
end
//计算个体的激励度
//alfa和belta都是激励度的系数
//浓度高的个体被抑制,与抗原亲和度高的个体被激励
MSLL = alfa*MSLL — belta*ND;
- 按照激励度对个体进行排序
[SortMSLL,Index] = sort(MSLL);
Sortf = f(:,Index);
-免疫循环
while gen<G
for i=1:NP/2
a = Sortf(:,i);
Na = repmat(a,1,Nc1);//Nc1是复制的个数,本来a是2*1的,复制以后Na变成了2*5
end
deta = deta0/gen;
//变异操作
for j = 1:Nc
for ii = 1:D
if rand<pm
Na(ii,j) = Na(ii,j)+(rand-0.5)*deta;
end
//边界条件处理
if (Na(ii,j)<XMin) | (Na(ii,j)>XMax)
Na(ii,j) = rand*(XMax-XMin)+XMin;
end
end
end
Na(:,1) = Sortf(:,i);
//保留亲和度最高的个体
for j = a:Nc1
NaMSLL(j) = func2(Na(:,j));
end
[NaSortMSLL,Index] = sort(NaMSLL);
aMSLL(i) = NaSortMSLL(1);
NaSortf = Na(:,Index);
af(:,i) = NaSortf(:,1);
end
- 免疫种群激励度
for np = 1:NP/2
for j = 1:NP/2
nda(j) = sqrt(sum((af(:,np)-af(:,j)).^2));
if nda(j) <detas
nda(j) = 1;
else
nda(j) = 0;
end
end
aND(np) = sum(nda)/NP/2;
end
aMSLL = alfa*aMSLL - belta*aND;
-种群刷新
bf = rand(D,NP/2)*(XMax-XMin)+XMin;
for i=1:NP/2
bMSLL(np) = func2(bf(:,np))
end
- 免疫种群与新种群合并
f1 = [af,bf];
MSLL1 = [aMSLL,MSLL];
[SortMSLL,Index] = sort(MSLL);
Sortf = f1(:,Index);
gen = gen + 1;
trace(gen) = func2(Sortf(:,1));
奉上源码
上面是我自己在CDSN上敲的,CSDN代码编辑还不是很舒服,肯定会有一些错误,所以把源码给大家贴在这里,其实算法分步骤去理解也没那么难,奥里给。
%%%%%%%%%%%%%%%%%免疫算法求函数极值%%%%%%%%%%%%%%%%%%%%
%%智能算法专题设计 shiyan42.m
% 蚁群算法求解函数极值问题
% 2020/10/22
%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
D=2; %免疫个体维数
NP=50; %免疫个体数目
Xs=4; %取值上限
Xx=-4; %取值下限
G=200; %最大免疫代数
pm=0.7; %变异概率
alfa=2; %激励度系数
belta=1; %激励度系数
detas=0.2; %相似度阈值
gen=0; %免疫代数
Ncl=5; %克隆个数
deta0=0.5*Xs; %邻域范围初值
%%%%%%%%%%%%%%%%%%%%%%%初始种群%%%%%%%%%%%%%%%%%%%%%%%%
f=rand(D,NP)*(Xs-Xx)+Xx;
for np=1:NP
MSLL(np) = func2(f(:,np));
end
%%%%%%%%%%%%%%%%%计算个体浓度和激励度%%%%%%%%%%%%%%%%%%%
for np=1:NP
for j=1:NP
nd(j) = sum(sqrt((f(:,np)-f(:,j)).^2));
if nd(j)<detas
nd(j)=1;
else
nd(j)=0;
end
end
ND(np)=sum(nd)/NP;
end
MSLL = alfa*MSLL - belta*ND;
%%%%%%%%%%%%%%%%%%%激励度按升序排列%%%%%%%%%%%%%%%%%%%%%%
[SortMSLL,Index] = sort(MSLL);
Sortf = f(:,Index);
%%%%%%%%%%%%%%%%%%%%%%%%免疫循环%%%%%%%%%%%%%%%%%%%%%%%%
while gen<G
for i=1:NP/2
%%%%%%%%选激励度前NP/2个体进行免疫操作%%%%%%%%%%%
a = Sortf(:,i);
Na = repmat(a,1,Ncl);
deta = deta0/gen;
for j = 1:Ncl
for ii = 1:D
%%%%%%%%%%%%%%%%%变异%%%%%%%%%%%%%%%%%%%
if rand<pm
Na(ii,j) = Na(ii,j)+(rand-0.5)*deta;
end
%%%%%%%%%%%%%%边界条件处理%%%%%%%%%%%%%%%
if (Na(ii,j)>Xs) | (Na(ii,j)<Xx)
Na(ii,j) = rand * (Xs-Xx)+Xx;
end
end
end
Na(:,1)=Sortf(:,i); %保留克隆源个体
%%%%%%%%%%克隆抑制,保留亲和度最高的个体%%%%%%%%%%
for j=1:Ncl
NaMSLL(j) = func2(Na(:,j));
end
[NaSortMSLL,Index]=sort(NaMSLL);
aMSLL(i) =NaSortMSLL(1);
NaSortf=Na(:,Index);
af(:,i)=NaSortf(:,1);
end
%%%%%%%%%%%%%%%%%%%%免疫种群激励度%%%%%%%%%%%%%%%%%%%
for np=1:NP/2
for j=1:NP/2
nda(j)=sum(sqrt((af(:,np)-af(:,j)).^2));
if nda(j)<detas
nda(j)=1;
else
nda(j)=0;
end
end
aND(np)=sum(nda)/NP/2;
end
aMSLL = alfa*aMSLL- belta*aND;
%%%%%%%%%%%%%%%%%%%%%%%种群刷新%%%%%%%%%%%%%%%%%%%%%%%
bf=rand(D,NP/2)*(Xs-Xx)+Xx;
for np=1:NP/2
bMSLL(np)=func2(bf(:,np));
end
%%%%%%%%%%%%%%%%%%%新生成种群激励度%%%%%%%%%%%%%%%%%%%%
for np=1:NP/2
for j=1:NP/2
ndc(j)=sum(sqrt((bf(:,np)-bf(:,j)).^2));
if ndc(j)<detas
ndc(j)=1;
else
ndc(j)=0;
end
end
bND(np)=sum(ndc)/NP/2;
end
bMSLL = alfa*bMSLL- belta*bND;
%%%%%%%%%%%%%%免疫种群与新生种群合并%%%%%%%%%%%%%%%%%%%
f1=[af,bf];
MSLL1=[aMSLL,bMSLL];
[SortMSLL,Index]=sort(MSLL1);
Sortf=f1(:,Index);
gen=gen+1;
trace(gen)=func2(Sortf(:,1));
end
%%%%%%%%%%%%%%%%%%%%%%%输出优化结果%%%%%%%%%%%%%%%%%%%%%%%%
Bestf=Sortf(:,1); %最优变量
trace(end); %最优值
figure,plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('亲和度进化曲线')