matlab——智能算法之粒子羣優化算法、模擬退火算法、遺傳算法

智能算法之粒子羣優化算法:
%% 初始化種羣  
f= % 函數表達式    % 求這個函數的最大值  
figure(1);ezplot(f,[0,0.01,20]);  
N = 50;                         % 初始種羣個數  
d = 1;                          % 空間維數  
ger = 100;                      % 最大迭代次數       
limit = [0, 20];                % 設置位置參數限制  
vlimit = [-1, 1];               % 設置速度限制  
w = 0.8;                        % 慣性權重  
c1 = 0.5;                       % 自我學習因子  
c2 = 0.5;                       % 羣體學習因子   
for i = 1:d  
    x = limit(i, 1) + (limit(i, 2) - limit(i, 1)) * rand(N, d);%初始種羣的位置  
end  
v = rand(N, d);                  % 初始種羣的速度  
xm = x;                          % 每個個體的歷史最佳位置  
ym = zeros(1, d);                % 種羣的歷史最佳位置  
fxm = zeros(N, 1);               % 每個個體的歷史最佳適應度  
fym = -inf;                      % 種羣歷史最佳適應度  
hold on  
plot(xm, f(xm), 'ro');title('初始狀態圖');  
figure(2)  
%% 羣體更新  
iter = 1;  
record = zeros(ger, 1);          % 記錄器  
while iter <= ger  
     fx = f(x) ; % 個體當前適應度     
     for i = 1:N        
        if fxm(i) < fx(i)  
            fxm(i) = fx(i);     % 更新個體歷史最佳適應度  
            xm(i,:) = x(i,:);   % 更新個體歷史最佳位置  
        end   
     end  
if fym < max(fxm)  
        [fym, nmax] = max(fxm);   % 更新羣體歷史最佳適應度  
        ym = xm(nmax, :);      % 更新羣體歷史最佳位置  
 end  
    v = v * w + c1 * rand * (xm - x) + c2 * rand * (repmat(ym, N, 1) - x);% 速度更新  
    % 邊界速度處理  
    v(v > vlimit(2)) = vlimit(2);  
    v(v < vlimit(1)) = vlimit(1);  
    x = x + v;% 位置更新  
    % 邊界位置處理  
    x(x > limit(2)) = limit(2);  
    x(x < limit(1)) = limit(1);  
    record(iter) = fym;%最大值記錄  
     x0 = 0 : 0.01 : 20;  
     plot(x0, f(x0), 'b-', x, f(x), 'ro');title('狀態位置變化')  
    pause(0.1)  
    iter = iter+1;  
end  
figure(3);plot(record);title('收斂過程')  
x0 = 0 : 0.01 : 20;  
figure(4);plot(x0, f(x0), 'b-', x, f(x), 'ro');title('最終狀態位置')  
disp(['最大值:',num2str(fym)]);  
disp(['變量取值:',num2str(ym)]);  
智能算法之模擬退火算法:

%生成初始解,求目標函數f(x)=x1^2+x2^2+8在x1^2-x2>0;-x1-x2^2+2=0約束下的最小值問題  
sol_new2=1;%1)解空間(初始解)  
sol_new1=2-sol_new2^2;  
sol_current1 = sol_new1;   
sol_best1 = sol_new1;  
sol_current2 = sol_new2;   
sol_best2 = sol_new2;  
E_current = inf;  
E_best = inf;  
  
rand('state',sum(clock)); %初始化隨機數發生器  
t=90; %初始溫度  
tf=89.9; %結束溫度  
a = 0.99; %溫度下降比例  
  
while t>=tf%7)結束條件  
    for r=1:1000 %退火次數  
          
        %產生隨機擾動(3)新解的產生  
        sol_new2=sol_new2+rand*0.2;  
        sol_new1=2-sol_new2^2;  
          
        %檢查是否滿足約束  
        if sol_new1^2-sol_new2>=0 && -sol_new1-sol_new2^2+2==0 && sol_new1>=0 &&sol_new2>=0  
        else  
            sol_new2=rand*2;  
            sol_new1=2-sol_new2^2;  
            continue;  
        end  
          
        %退火過程  
        E_new=sol_new1^2+sol_new2^2+8;%2)目標函數  
        if E_new<E_current%5)接受準則  
                E_current=E_new;  
                sol_current1=sol_new1;  
                sol_current2=sol_new2;  
                if E_new<E_best  
                    %把冷卻過程中最好的解保存下來  
                    E_best=E_new;  
                    sol_best1=sol_new1;  
                    sol_best2=sol_new2;  
                end  
        else  
                if rand<exp(-(E_new-E_current)/t)%4)代價函數差  
                    E_current=E_new;  
                    sol_current1=sol_new1;  
                    sol_current2=sol_new2;  
                else  
                    sol_new1=sol_current1;  
                    sol_new2=sol_current2;  
                end  
        end  
        plot(r,E_best,'*')  
        hold on  
    end  
    t=t*a;%6)降溫  
end  
  
disp('最優解爲:')  
disp(sol_best1)  
disp(sol_best2)  
disp('目標表達式的最小值等於:')  
disp(E_best)  
智能算法之遺傳算法

% 求下列函數的最大值 %
% f(x)=10sin(5x)+7cos(4x) x∈[0,10] %
% 將 x 的值用一個10位的二值形式表示爲二值問題,一個10位的二值數提供的分辨率是每爲 (10-0)/(2^10-1)≈0.01 。 %
% 將變量域 [0,10] 離散化爲二值域 [0,1023], x=0+10*b/1023, 其中 b 是 [0,1023] 中的一個二值數。

% 2.8 主程序
%遺傳算法主程序
%Name:genmain05.m
function genmain()
tic;
clear
clf
popsize=20; %羣體大小
chromlength=10; %字符串長度(個體長度)
pc=0.6; %交叉概率
pm=0.001; %變異概率

pop=initpop(popsize,chromlength); %隨機產生初始羣體
for i=1:20 %20爲迭代次數
[objvalue]=calobjvalue(pop); %計算目標函數
fitvalue=calfitvalue(objvalue); %計算羣體中每個個體的適應度
[newpop]=selection(pop,fitvalue); %複製
[newpop]=crossover(pop,pc); %交叉
[newpop]=mutation(pop,pc); %變異
[bestindividual,bestfit]=best(pop,fitvalue); %求出羣體中適應值最大的個體及其適應值
y(i)=max(bestfit);
n(i)=i;
pop5=bestindividual;
x(i)=decodechrom(pop5,1,chromlength)*10/1023;
pop=newpop;
end

fplot('10*sin(5*x)+7*cos(4*x)',[0 10])
hold on
plot(x,y,'r*')
hold off

[z index]=max(y); %計算最大值及其位置
x5=x(index)%計算最大值對應的x值
y=z
toc

% 2.1初始化(編碼)
% initpop.m函數的功能是實現羣體的初始化,popsize表示羣體的大小,chromlength表示染色體的長度(二值數的長度)% 長度大小取決於變量的二進制編碼的長度(在本例中取10)%遺傳算法子程序
%Name: initpop.m
%初始化

function pop=initpop(popsize,chromlength) 
pop=round(rand(popsize,chromlength)) % rand隨機產生每個單元爲 {0,1} 行數爲popsize,列數爲chromlength的矩陣,
% roud對矩陣的每個單元進行圓整。這樣產生的初始種羣。

% 2.2 計算目標函數值
% 2.2.1 將二進制數轉化爲十進制數(1)
%遺傳算法子程序
%Name: decodebinary.m
%產生 [2^n 2^(n-1) ... 1] 的行向量,然後求和,將二進制轉化爲十進制
function pop2=decodebinary(pop)
[px,py]=size(pop); %求pop行和列數
for i=1:py
pop1(:,i)=2.^(py-i).*pop(:,i);
end
pop2=sum(pop1,2); %求pop1的每行之和

% 2.2.2 將二進制編碼轉化爲十進制數(2)
% decodechrom.m函數的功能是將染色體(或二進制編碼)轉換爲十進制,參數spoint表示待解碼的二進制串的起始位置
% (對於多個變量而言,如有兩個變量,採用20爲表示,每個變量10爲,則第一個變量從1開始,另一個變量從11開始。本例爲1)% 參數1ength表示所截取的長度(本例爲10)。
%遺傳算法子程序
%Name: decodechrom.m
%將二進制編碼轉換成十進制
function pop2=decodechrom(pop,spoint,length)
pop1=pop(:,spoint:spoint+length-1);
pop2=decodebinary(pop1);

% 2.2.3 計算目標函數值
% calobjvalue.m函數的功能是實現目標函數的計算,其公式採用本文示例仿真,可根據不同優化問題予以修改。
%遺傳算法子程序
%Name: calobjvalue.m
%實現目標函數的計算
function [objvalue]=calobjvalue(pop)
temp1=decodechrom(pop,1,10); %將pop每行轉化成十進制數
x=temp1*10/1023; %將二值域 中的數轉化爲變量域 的數
objvalue=10*sin(5*x)+7*cos(4*x); %計算目標函數值

% 2.3 計算個體的適應值
%遺傳算法子程序
%Name:calfitvalue.m
%計算個體的適應值
function fitvalue=calfitvalue(objvalue)
global Cmin;
Cmin=0;
[px,py]=size(objvalue);
for i=1:px
if objvalue(i)+Cmin>0
temp=Cmin+objvalue(i);
else
temp=0.0;
end
fitvalue(i)=temp;
end
fitvalue=fitvalue';

% 2.4 選擇複製
% 選擇或複製操作是決定哪些個體可以進入下一代。程序中採用賭輪盤選擇法選擇,這種方法較易實現。
% 根據方程 pi=fi/∑fi=fi/fsum ,選擇步驟:
% 1) 在第 t 代,由(1)式計算 fsum 和 pi 
% 2) 產生 {0,1} 的隨機數 rand( .),求 s=rand( .)*fsum
% 3) 求 ∑fi≥s 中最小的 k ,則第 k 個個體被選中
% 4) 進行 N 次2)、3)操作,得到 N 個個體,成爲第 t=t+1 代種羣
%遺傳算法子程序
%Name: selection.m
%選擇複製
function [newpop]=selection(pop,fitvalue)
totalfit=sum(fitvalue); %求適應值之和
fitvalue=fitvalue/totalfit; %單個個體被選擇的概率
fitvalue=cumsum(fitvalue); %如 fitvalue=[1 2 3 4],則 cumsum(fitvalue)=[1 3 6 10] 
[px,py]=size(pop);
ms=sort(rand(px,1)); %從小到大排列
fitin=1;
newin=1;
while newin<=px
if(ms(newin))<fitvalue(fitin)
newpop(newin)=pop(fitin);
newin=newin+1;
else
fitin=fitin+1;
end
end

% 2.5 交叉
% 交叉(crossover),羣體中的每個個體之間都以一定的概率 pc 交叉,即兩個個體從各自字符串的某一位置
% (一般是隨機確定)開始互相交換,這類似生物進化過程中的基因分裂與重組。例如,假設2個父代個體x1,x2爲:
% x1=0100110
% x2=1010001
% 從每個個體的第3位開始交叉,交又後得到2個新的子代個體y1,y2分別爲:
% y1=0100001
% y2=1010110
% 這樣2個子代個體就分別具有了2個父代個體的某些特徵。利用交又我們有可能由父代個體在子代組合成具有更高適合度的個體。
% 事實上交又是遺傳算法區別於其它傳統優化方法的主要特點之一。
%遺傳算法子程序
%Name: crossover.m
%交叉
function [newpop]=crossover(pop,pc)
[px,py]=size(pop);
newpop=ones(size(pop));
for i=1:2:px-1
if(rand<pc)
cpoint=round(rand*py);
newpop(i,:)=[pop(i,1:cpoint),pop(i+1,cpoint+1:py)];
newpop(i+1,:)=[pop(i+1,1:cpoint),pop(i,cpoint+1:py)];
else
newpop(i,:)=pop(i);
newpop(i+1,:)=pop(i+1);
end
end

% 2.6 變異
% 變異(mutation),基因的突變普遍存在於生物的進化過程中。變異是指父代中的每個個體的每一位都以概率 pm 翻轉,即由“1”變爲“0”,
% 或由“0”變爲“1”。遺傳算法的變異特性可以使求解過程隨機地搜索到解可能存在的整個空間,因此可以在一定程度上求得全局最優解。
%遺傳算法子程序
%Name: mutation.m
%變異
function [newpop]=mutation(pop,pm)
[px,py]=size(pop);
newpop=ones(size(pop));
for i=1:px
if(rand<pm)
mpoint=round(rand*py);
if mpoint<=0
mpoint=1;
end
newpop(i)=pop(i);
if any(newpop(i,mpoint))==0
newpop(i,mpoint)=1;
else
newpop(i,mpoint)=0;
end
else
newpop(i)=pop(i);
end
end
% 2.7 求出羣體中最大得適應值及其個體
%遺傳算法子程序
%Name: best.m
%求出羣體中適應值最大的值
function [bestindividual,bestfit]=best(pop,fitvalue)
[px,py]=size(pop);
bestindividual=pop(1,:);
bestfit=fitvalue(1);
for i=2:px
if fitvalue(i)>bestfit
bestindividual=pop(i,:);
bestfit=fitvalue(i);
end
end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章