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

[注]

閾值分割法適用於目標和背景灰度有較強對比的情況, 尤其是背景或物體的灰度較爲單一, 且總可得到封閉且連同區域的邊界. 否則, 圖片經過閾值分割後的前後對比效果不會非常強烈.

發佈了37 篇原創文章 · 獲贊 15 · 訪問量 8329
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章