MATLAB数学建模:智能优化算法-免疫算法

免疫算法

免疫算法源于生物免疫系统的基本机制, 是一种具有生成+检测的迭代过程的群智能搜索算法.

生物免疫系统的运行机制和遗传算法的求解有很高的相似度. 在抵御抗原时, 免疫细胞增殖分化, 进而产生大量抗体. 倘若将所求的目标函数和约束条件视为抗原, 将问题的解视作抗体, 那么遗传算法求解的过程就是生物免疫系统抵御抗原的过程.



1. 基本原理

免疫算法的基本思想是在传统遗传算法的基础上加入一个免疫算子, 从而防止出现种群退化的现象. 免疫算子由 接种疫苗免疫选择 组成.

免疫算法解决了遗传算法的早熟收敛问题, 该问题一般出现在实际工程优化计算中. 遗传算法的交叉和变异算子本身是具有一定的盲目性的. 若在遗传算法中引入"免疫"的方法和概念, 对遗传算法全局搜索的过程进行一定强度的干预, 就可以避免很多重复无效的操作, 从而提高算法效率.

在免疫算法中, 合理提取"疫苗"是算法的核心. 免疫算法还可以针对群体进化过程中的一些退化现象进行抑制, 从而更加稳定地提高群体适应度.

一般而言, 免疫算法可分为三种情况:

  1. 模仿免疫系统抗原抗体识别, 结合抗体生成过程抽象而得到的免疫算法
  2. 基于免疫系统中其余特殊机制抽象出的算法, 如 克隆选择算法.
  3. 与遗传算法等其余算法融合产生的新算法, 如 免疫遗传算法.

2. 程序设计

免疫算法和遗传算法的结构基本一致, 最大的差异之处在于, 免疫算法中引入了 “浓度调节机制”:

进行选择操作时, 遗传算法只利用适应度值单一指标对个体进行评价, 在免疫算法中则改为: 适应度越高且浓度越小, 个体被选择的概率越大, 适应度越低且浓度越高的个体被选择的概率越小.


2.1 免疫算法的步骤流程

免疫算法主要步骤如下:

  1. 抗原识别:
    将所求的目标函数和约束条件当作抗原进行"识别",来判断是否曾经解决过类似问题.

  2. 生成初始抗体:
    这一步对应于遗传算法就是得到解的初始值. 经过对抗原的识别这一步骤, 如果算法曾经解决过这类问题, 则直接寻找相应的"记忆细胞", 从而产生初始抗体.

  3. 更新记忆单元:
    选择亲和度更高的抗体进行存储记忆.

  4. 抑制和促进抗体:
    在算法中插入新的策略以避免群体进化单一的现象, 保持群体的多样性.

  5. 遗传操作:
    在考虑抗体亲和度和群体多样性的基础上选择抗体群体, 进行交叉编译, 产生新一代抗体.


2.2 在MATLAB中实现免疫算法

MATLAB是一门基于矩阵的科学计算语言, 具有强大的处理矩阵运算的功能, 因此它很适合用于实现免疫算法.

免疫算法中的标准遗传操作: 选择, 交叉, 变异, 基于生物免疫机制的免疫记忆, 多样性保存, 自我调节功能等均是针对抗体 (即遗传算法中所指的染色体, 个体) 的. 抗体就可以很方便地用行向量表示. 因此, 在MATLAB实现的免疫算法中, 上述操作和功能均是由矩阵运算实现的.

[例] 设计一个免疫算法, 实现对下图所示单阈值图像的分割, 并画图比较分割前后图片的结果.


  1. 主程序:
clc; clear all;
tic
popsize = 15;
lanti = 10;
maxgen  =50;         %最大迭代次数
cross_rate = 0.4;    %交叉概率
mutation_rate = 0.1; %变异概率
a0 = 0.7;
zpopsize = 5;
bestf = 0;
nf = 0;
number = 0;
I = imread('esu.bmp');
q = isrgb(I);        %判断是否为RGB真彩色图像

if q == 1
   I = rgb2gray(I);  %转换为灰度图像
end

[m,n] = size(I);
p = imhist(I);       %显示图像数据直方图
p = p';              %转置
p = p/(m*n);         %圆整p,将其值变为(0,1)
figure(1)
subplot(1,2,1);
imshow(I);
title('Original Grayscale Image');
hold on

%% 抗原群体初始化
pop = 2*rand(popsize,lanti)-1;   %pop为每个元素值在(-1,1)之间的随机阵
pop = hardlim(pop);              %将图像单阈值化,元素大于等于0转换为1,其余的转为0

%% 进行免疫操作
for gen = 1:maxgen
   [fitness,threshould,number] = fitnessty(pop,lanti,I,popsize,m,n,number);
%计算抗原-抗体亲和度
   if max(fitness) > bestf
      bestf = max(fitness);
      nf = 0;
   for i = 1:popsize
         if fitness(1,i) == bestf
            v = i;
         end
   end
yu = threshould(1,v);
   elseif max(fitness) == bestf
      nf = nf + 1;
   end
      if nf >= 20
        break;
      end

A = shontt(pop);                             %计算抗体-抗体的相似度
f = fit(A,fitness);                          %计算抗体的聚合适应度
pop = select(A,fitness);                     %进行选择操作
pop = cross(pop,cross_rate,popsize,lanti);   %交叉
pop = mutation_compute(pop,mutation_rate,lanti,popsize); %变异
a = shonqt(pop);                             %计算抗体群体相似度
if a > a0
   zpop = 2*rand(zpopsize,lanti)-1;
   zpop = hardlim(zpop);
   pop(popsize+1:popsize+zpopsize,:) = zpop(:,:);
   [fitness,threshould,number] = fitnessty(pop,lanti,I,popsize,m,n,number);
   %计算抗原-抗体亲和度
   A = shontt(pop);                          %计算抗体-抗体相似度
   f = fit(A,fitness);                          %计算抗体的聚合适应度
   pop = select(A,fitness);                     %进行选择操作 
end

if gen == maxgen
   [fitness,threshould,number] = fitnessty(pop,lanti,I,popsize,m,n,number);
   %计算抗原-抗体亲和度
end
end

imshow(I);
subplot(1,2,2);
fresult(I,yu);
title('Splited Image');


  1. 均匀杂交函数
%%均匀杂交函数

function pop = cross(pop,cross_rate,popsize,~)
j = 1;
for i = 1:popsize
    p = rand;
    if p < cross_rate
        parent(j,:) = pop(i,:);
        a(1,j) = i;
        j = j+1;
    end
end

j = j-1;
if rem(j,2)~=0
    j = j-1;
end
for i = 1:2:j
    p = 2*rand(1,lanti)-1;      %随机生成一个模板
    p = hardlim(p);
    for k = 1:lanti
        if p(1,k) == 1
            pop(a(1,j),k) = parent(i+1,k);
            pop(a(1,i+1),k) = parent(i,k);
        end
    end
end

  1. 抗体聚合适应度计算函数
%%抗体的聚合适应度计算函数
function f = fit(A,fitness)
t = 0.8;
[~,m] = size(A);
k = -0.8;
for i = 1:m
    n = 0;
    for j = 1:m
        if A(i,j) > t
            n = n+1;
        end
        C(1,i) = n/m;           %计算抗体浓度
    end
end
    f = fitness.*exp(k.*C);     %抗体的聚合适应度

  1. 适应度计算函数
%%适应度计算函数
function [fitness,b,number] = fitnessty(pop,lanti,I,popsize,m,n,number)
num = m*n;
for i = 1:popsize
    number = number + 1;
        anti = pop(i,:);
        lowsum = 0;             %低于阈值的灰度值之和
        lownum = 0;             %低于阈值的像素点个数
        highsum = 0;            %高于阈值的灰度值之和
        highnum = 0;            %高于阈值的像素点个数
        a = 0;
        for j = 1:lanti
            a = a + anti(i,j) * (2^(j-1));  %加权求和
        end
        b(1,i) = a * 255/(2^lanti - 1);
        for x = 1:m
            for y = 1:n
                if I(x,y) < b(1,i)
                    lowsum = lowsum + double(I(x,y));
                    lownum = lownum + 1;
                else
                    highsum =highsum + double(I(x,y));
                    highnum = highnum + 1;
                end
            end
        end
        
        u = (lowsum + highsum)/num;
        if lownum~ = 0;
            u0 = lowsum/lownum;
        else
            u0 = 0;
        end
        if hoighnum~=0
            u1 = highsum/highnum;
        else
            u1 = 0;
        end
        w0 = lownum/(num);
        w1 = highnum/(num);
        fitness(1,i) = w0*(u0-u)^2 + w1*(u1-u)^2;     
end
end

  1. 图像分割输出函数
%% 根据最佳阈值进行图像分割,输出结果
function fresult(I,f,m,n)
[m,n] = size(I);
for i = 1:m
    for j = 1:n
        if I(i,j) <= f
            I(i,j) = 0;
        else
            I(i,j) = 255;
        end
    end
end
imshow(I);

  1. 图像判断函数
%% 判断图像是否为RGB真彩色
function y = isrgb(x)
wid = sprintf('Images: %s:obsoleteFunction',mfilename);
str1 = sprintf('% s is pbsolete and may be removed in the future',mfilename);
str2 = 'See product release notes for more information.';
warning(wid,'%s\n%s',str1,str2);

y = size(x,3) == 3;
if y
    if isa(x,'logical')
        y = false
    elseif isa(x,'double')
        m = size(x,1);
        n = size(x,2);
        chunk = x(1:min(m,10),1:min(n,10),:);
        y = (min(chunk(:)) >= 0 && max(chunk(:)) <= 1);
        if y
            y = (min(x(:)) >= 0 && max(x(:)) <= 1);
        end
    end
end

  1. 变异算子
%% 变异算子
function pop = mutation_compute(pop,mutation_rate,lanti,popsize)%均匀变异
for i = 1:popsize       
    s = rand(1,lanti);
    for j = 1:lanti
        if s(1,j) < mutation_rate
            if pop(i,j) == 1
                pop(i,j) = 0;
            else
                pop(i,j) = 1;
            end
        end
    end
end

  1. 选择算子
%选择算子
function v = select(v,fit)
[px,~] =size(v);
for i = 1:px
    pfit(i) = fit(i) ./ sum(fit);
end
pfit = cumsum(pfit);
if pfit(px) < 1
    pfit(px) = 1;
end
rs = rand(1,10);
for i = 1:10
    ss = 0;
    for j = 1:px
        if rs(i) <= pfit(j)
            v(i,:) = v(j,:);
            ss = 1;
        end
        if ss == 1
            break;
        end
    end
end

  1. 群体相似度计算函数
%%计算群体相似度
function a = shonqt(pop)
[m,n] = size(pop);
h = 0;
for i = 1:n
    s = sum(pop(:,i));
    if s == 0 || s == m
        h = h;
    else
        h = h - s/m * log2(s/m) - (m-s)/m * log2((m-s)/m);
    end
end
a = 1/(1+h);

  1. 抗体相似度计算函数
%%计算抗体相似度函数
function A = shontt(pop)
[m,n] = size(pop);
for i = 1:m
    for j = 1:m
        if 1 == j
            A(i,j) = 1;
        else
            H(i,j) = 0;
            for k = 1:n
                if pop(i,k) ~= pop(j,k)
                    H(i,j) = H(i,j) + 1;
                end
            end
            H(i,j) = H(i,j)/n;
            A(i,j) = 1/(1 + H(i,j));
        end
    end
end
         

程序模拟输入输出如下:
esu

[注]

阈值分割法适用于目标和背景灰度有较强对比的情况, 尤其是背景或物体的灰度较为单一, 且总可得到封闭且连同区域的边界. 否则, 图片经过阈值分割后的前后对比效果不会非常强烈.

发布了32 篇原创文章 · 获赞 14 · 访问量 6341

猜你喜欢

转载自blog.csdn.net/u010186354/article/details/104215056