matlab新手快速上手3(差分进化算法)

        本文用经典差分进化框架模板,对matlab新手友好,快速上手看懂matlab代码,快速应用实践,源代码在文末给出。 

差分进化算法定义:

差分进化算法(Differential Evolution,简称DE算法)是一种优化算法,由Storn和Price于1997年提出。这个算法主要用于解决连续优化问题。

DE算法的基本思想是模拟生物进化中的个体竞争和适者生存的原理。它通过维护一个种群,每个个体都代表问题的一个解,并通过不断的迭代和交叉变异来寻找最优解。

DE算法的核心操作包括选择、交叉和变异:

  1. 选择:通过比较个体的适应度来选择优秀的个体进入下一代。
  2. 变异:随机选择种群中的个体,并基于差分向量进行变异操作,产生新的个体。
  3. 交叉:将变异后的个体与原始个体进行交叉操作,产生新的解。

DE算法具有较好的全局搜索能力和较快的收敛速度,在许多优化问题中表现良好。它已经被广泛应用于工程优化、信号处理、机器学习等领域。

开始编程:

参数与子函数定义:

function DE
%---------------------------------- 参数设置 -------------------------------
NP=100;                            %种群规模
D=10;                              %变量个数
MinX=-30;                          %范围下限
MaxX=30;                           %范围上限
alpha=0.6;                         %缩放因子
beta=0.6;                          %缩放因子
CR=0.8;                            %交叉概率
Error=0.001;                         %限定精度
Max_N=1000;                        %限定代数
flagc=[0,Max_N];                   %收敛标志
%---------------------- 粒子位置初始化 ----------------------
for i=1:1:D
    X(:,i)=MinX+(MaxX-MinX)*rand(NP,1);
    selfX(:,i)=X(:,i);
end
%----------------------- 计算函数值 -------------------------
F=fun(X);
selfF=F;
%---------------------------- 子函数1:目标函数 ----------------------------
function F=fun(X)
for i=1:1:size(X,1)
    for j=1:1:size(X,2)
        x(j)=X(i,j);
    end
    for j=1:1:size(X,2)-1
        temp(j)=100*(x(j+1)-x(j)^2)^2+(x(j)-1)^2;
    end
    F(i)=sum(temp);
end
%--------------------- 求最优解 ---------------------------
[Bestf,Indexf]=sort(F,2);        %对NP个函数值排序

Bestfi=Bestf(1);                 %第1个函数值最小
Bestp=Indexf(1);                 %最优粒子序号

粒子位置初始化:

此函数生成一个X矩阵,为NP行,D列的矩阵,矩阵元素为0~1的随机值,每一行代表一个个体列的元素代表每个自变量,selfX矩阵与它相等。

子函数定义:

根据fun(X)得知,子函数为经典的罗森布鲁克函数f(x) = \sum_{i=1}^{D-1} \left[ 100 \times (x_{i+1} - x_i^2)^2 + (x_i - 1)^2 \right],此函数在x = 1处时,函数最小为0。差分进化算法就是寻找此函数找到最小值的点,最终输出的X中最优个体中的元素应该都接近于1。

附:罗森布鲁克函数(百度百科)

程序主体:

%--------------------- 程序主循环开始 ----------------------
for gen=1:1:Max_N
    time(gen)=gen;
    %----------------- 变异操作 ---------------------------
    for i=1:1:NP
        flag1=ceil(rand*NP);
        while(flag1==i)
            flag1=ceil(rand*NP);
        end
        flag2=ceil(rand*NP);
        while((flag2==i)|(flag2==flag1))
            flag2=ceil(rand*NP);
        end
        X(i,:)=X(i,:)+alpha*(X(Bestp,:)-X(i,:))+beta*(X(flag1,:)-X(flag2,:));
    end
    %----------------- 交叉操作 ---------------------------
    for i=1:1:NP
        temp=rand(1,D);
        for j=1:1:D
            if temp(j)>CR
                X(i,j)=selfX(i,j);
            end                
        end
    end
    %----------------- 计算函数值 ---------------------------
    F=fun(X);
    %----------------- 选择操作 ---------------------------
    for i=1:1:NP
        if F(i)>=selfF(i)
            F(i)=selfF(i);
            X(i,:)=selfX(i,:);            
        end
    end
    %----------------- 迭代更新 ---------------------------
    for i=1:1:NP
        selfF(i)=F(i); selfX(i,:)=X(i,:);            
    end
    %----------------- 求最优解 ---------------------------
    [Bestf,Indexf]=sort(F,2);        %对NP个函数值排序
    Bestfi=Bestf(1);                 %第1个函数值最小
    Bestp=Indexf(1);                 %最优粒子序号
    %----------------------------- 记录结果 --------------------------------
    result(gen)=Bestfi;
    if mod(gen,10)==0
        disp(sprintf('代数:%d -------- 结果:%f',gen,Bestfi));
        plot(time,result,'r');axis([1,Max_N,0,100]);
        xlabel('迭代步数');ylabel('优化结果');drawnow;pause(0.1);
    end
    if Bestfi<Error break;end
end
disp(' ');
disp(sprintf('迭代步数:%d -------- 优化结果:%f',gen,Bestfi));
disp(X);

最外层循环:

大循环表示迭代Max_N次,time存储每次循环的迭代次数。

变异操作:

for循环遍历NP次,表示对每个个体都进行变异,flag1表示一个[1,NP]之间的随机整数,while控制这个整数不能与当前个体序号相等,flag1与flag2也不能相同,也就是防止选择相同的两个个体导致变异不明显。后续的X(i,:)的操作就是让当前个体加上0.6倍的与种群最优个体的差值向量(这个就是差分变异),再加上0.6倍的两个随机个体的差值向量。这样就实现了一个个体的变异操作。

交叉操作:

交叉操作很明显,就是根据交叉概率,将当前的个体的某些参数变为没变异之前的参数

选择操作:

选择操作就是根据适应度进行选择,将适应度低的个体变为上一代的个体。

迭代更新:

将这一代的个体更新到self中,为下一次迭代做准备,也就是在下一代更新后,将下一代与这个self做对比。

后续就是排序,绘图,输出,等操作,就是将个体按照适应度排序,将最优个体进行输出

源代码:

%---------------------------------- 程序说明 -------------------------------

%                          该程序实现了基本差分变异算法

%---------------------------------- 程序正文 -------------------------------
function DE
%---------------------------------- 参数设置 -------------------------------
NP=100;                            %种群规模
D=10;                              %变量个数
MinX=-30;                          %范围下限
MaxX=30;                           %范围上限
alpha=0.6;                         %缩放因子
beta=0.6;                          %缩放因子
CR=0.8;                            %交叉概率
Error=0.001;                         %限定精度
Max_N=1000;                        %限定代数
flagc=[0,Max_N];                   %收敛标志
%---------------------- 粒子位置初始化 ----------------------
for i=1:1:D
    X(:,i)=MinX+(MaxX-MinX)*rand(NP,1);
    selfX(:,i)=X(:,i);
end
%X=MinX+(MaxX-MinX)*rand(NP,D);
%selfX = X;
%----------------------- 计算函数值 -------------------------
F=fun(X);
selfF=F;
%--------------------- 求最优解 ---------------------------
[Bestf,Indexf]=sort(F,2);        %对NP个函数值排序

Bestfi=Bestf(1);                 %第1个函数值最小
Bestp=Indexf(1);                 %最优粒子序号
%--------------------- 程序主循环开始 ----------------------
for gen=1:1:Max_N
    time(gen)=gen;
    %----------------- 变异操作 ---------------------------
    for i=1:1:NP
        flag1=ceil(rand*NP);
        while(flag1==i)
            flag1=ceil(rand*NP);
        end
        flag2=ceil(rand*NP);
        while((flag2==i)|(flag2==flag1))
            flag2=ceil(rand*NP);
        end
        X(i,:)=X(i,:)+alpha*(X(Bestp,:)-X(i,:))+beta*(X(flag1,:)-X(flag2,:));
    end
    %----------------- 交叉操作 ---------------------------
    for i=1:1:NP
        temp=rand(1,D);
        for j=1:1:D
            if temp(j)>CR
                X(i,j)=selfX(i,j);
            end                
        end
    end
    %----------------- 计算函数值 ---------------------------
    F=fun(X);
    %----------------- 选择操作 ---------------------------
    for i=1:1:NP
        if F(i)>=selfF(i)
            F(i)=selfF(i);
            X(i,:)=selfX(i,:);            
        end
    end
    %----------------- 迭代更新 ---------------------------
    for i=1:1:NP
        selfF(i)=F(i); selfX(i,:)=X(i,:);            
    end
    %----------------- 求最优解 ---------------------------
    [Bestf,Indexf]=sort(F,2);        %对NP个函数值排序
    Bestfi=Bestf(1);                 %第1个函数值最小
    Bestp=Indexf(1);                 %最优粒子序号
    %----------------------------- 记录结果 --------------------------------
    result(gen)=Bestfi;
    if mod(gen,10)==0
        disp(sprintf('代数:%d -------- 结果:%f',gen,Bestfi));
        plot(time,result,'r');axis([1,Max_N,0,100]);
        xlabel('迭代步数');ylabel('优化结果');drawnow;pause(0.1);
    end
    if Bestfi<Error break;end
end
disp(' ');
disp(sprintf('迭代步数:%d -------- 优化结果:%f',gen,Bestfi));
disp(X);
%---------------------------- 子函数1:目标函数 ----------------------------
function F=fun(X)
for i=1:1:size(X,1)
    for j=1:1:size(X,2)
        x(j)=X(i,j);
    end
    for j=1:1:size(X,2)-1
        temp(j)=100*(x(j+1)-x(j)^2)^2+(x(j)-1)^2;
    end
    F(i)=sum(temp);
end

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-27 22:22:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-27 22:22:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-27 22:22:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-27 22:22:02       20 阅读

热门阅读

  1. 安装docker后部署一个redis服务

    2024-04-27 22:22:02       14 阅读
  2. 递推入门,LeetCode 377. 组合总和 Ⅳ

    2024-04-27 22:22:02       9 阅读
  3. 自行车相关

    2024-04-27 22:22:02       7 阅读
  4. PS 2018

    2024-04-27 22:22:02       9 阅读
  5. python实现的循环双向链表

    2024-04-27 22:22:02       12 阅读
  6. React 之 组件模块依赖

    2024-04-27 22:22:02       11 阅读
  7. QT案例 使用QProcess调用Aria2.exe下载网络资源文件

    2024-04-27 22:22:02       9 阅读
  8. js实现字符串转json对象的四种方法

    2024-04-27 22:22:02       12 阅读