【优化预测】基于matlab差分进化改进灰狼算法优化SVR预测【含Matlab源码 1283期】

561 阅读14分钟

一、差分进化算法简介

1 前言

在遗传、选择和变异的作用下,自然界生物体优胜劣汰,不断由低级向高级进化和发展。人们注意到,适者生存的进化规律可以模式化,从而构成一些优化算法;近年来发展的进化计算类算法受到了广泛的关注。 差分进化算法(Differential Evolution, DE) 是一种新兴的进化计算技术[1] 。它是由S torn等人于1995年提出的, 其最初的设想是用于解决切比雪夫多项式问题,后来发现它也是解决复杂优化问题的有 效技术。 差分进化算法是基于群体智能理论的优化算法,是通过群体内个体间的合作与竞争而产生的智能优化搜索算法。但相比于进化计算,它保留了基于种群的全局搜索策略,采用实数编码、基于差分的简单 变异操作和“一对一”的竞争生存策略,降低了进化计算操作的复杂性。同时,差分进化算法特有的记忆能力使其可以动态跟踪当前的搜索情况,以调整其搜索策略,它具有较强的全局收敛能力和稳健性, 且不需要借助问题的特征信息,适用于求解一些利用常规的数学规划方法很难求解甚至无法求解的复杂优化问题[2-5]。因此,差分进化算法作为一种高效的并行搜索算法,对其进行理论和应用研究具有重要的学术意义和工程价值。 目前,差分进化算法已经在许多领域得到了应用,如人工神经元网络、电力、机械设计、机器人、信号处理、生物信息、经济学、现代农业和运筹学等。然而,尽管差分进化算法获得了广泛研究,但相 对于其他进化算法而言,其研究成果相当分散,缺乏系统性,尤其在理论方面还没有重大突破。

2 差分进化算法理论 2.1差分进化算法原理 差分进化算法是一种随机的启发式搜索算法,简单易用,有较强的鲁棒性和全局寻优能力。它从数学角度看是一种随机搜索算法,从工程角度看是一种自适应的迭代寻优过程。除了具有较好的收敛性外,差分进化算法非常易于理解与执行,它只包含不多的几个控制参数,并且在整个迭代过程中,这些参数的值可以保持不变。差分进化算法是一种自组织最小化方法,用户只需很少的输入。它的关键思想与传统进化方法不同:传统方法是用预先确定的概率分布函数决定向量扰动;而差分进化算法的自组织程序利用种群中两个随机选择的不同向量来干扰一个现有向量,种群中的每一个向量都要进行干扰。差分进化算法利用一个向量种群,其中种群向量的随机扰动可独立进行,因此是并行的。如果新向量对应函数值的代价比它们的前辈代价小,它们将取代前辈向量。 同其他进化算法一样,差分进化算法也是对候选解的种群进行操作,但其种群繁殖方案与其他进化算法不同:它通过把种群中两个成员之间的加权差向量加到第三个成员上来产生新的参数向量,该操作 称为“变异”; 然后将变异向量的参数与另外预先确定的目标向量参数按一定规则混合来产生试验量,该操作称为“交叉”;最后,若试验向量的代价函数比目标向量的代价函数低,试验向量就在下一代中代替目标向量,该操作称为“选择”。种群中所有成员必须当作目标向量进行一次这样的操作,以便在下一代中出现相同个数竞争者。 在进化过程中对每一代的最佳参数向量都进行评价,以记录最小化过程。这样利用随机偏差扰动产生新个体的方式,可以获得一个收敛性非常好的结果,引导搜索过程向全局最优解逼近[6-7]。

2.2差分进化算法的特点 差分进化算法从提出到现在,在短短二十几年内人们对其进行了广泛的研究并取得了成功的应用。该算法主要有如下特点: (1)结构简单,容易使用。差分进化算法主要通过差分变异算子来进行遗传操作,由于该算子只涉及向量的加减运算,因此很容易实现;该算法采用概率转移规则,不需要确定性的规则。此外,差分进化算法的控制参数少,这些参数对算法性能的影响已经得到一定的研究,并得出了一些指导性的建议,因而可以方便使用人员根据问题选择较优的参数设置。 (2)性能优越。差分进化算法具有较好的可靠性、高效性和鲁棒性,对于大空间、非线性和不可求导的连续问题,其求解效率比其他进化方法好,而且很多学者还在对差分进化算法继续改良,以不断提高其性能。 (3)自适应性。差分进化算法的差分变异算子可以是固定常数,也可以具有变异步长和搜索方向自适应的能力,根据不同目标函数进行自动调整,从而提高搜索质量。 (4)差分进化算法具有内在的并行性,可协同搜索,具有利用个体局部信息和群体全局信息指导算法进一步搜索的能力。在同样精度要求下,差分进化算法具有更快的收敛速度。 (5)算法通用,可直接对结构对象进行操作,不依赖于问题信息,不存在对目标函数的限定。差分进化算法操作十分简单,易于编程实现,尤其利于求解高维的函数优化问题。

3 差分进化算法种类 3.1基本差分进化算法 基本差分进化算法的操作程序如下[8]: (1)初始化; (2)变异; (3)交叉; (4)选择; (5)边界条件处理。 初始化 差分进化算法利用NP个维数为D的实数值参数向量,将它们作为每 一代的种群,每个个体表示为: 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 另外一个方法是进行边界吸收处理,即将超过边界约束的个体值设置为临近的边界值。

3.2差分进化算法的其他形式 上面阐述的是最基本的差分进化算法操作程序,实际应用中还发展了差分进化算法的几个变形形式,用符号DE/x/y/z加以区分,其中:x限定当前被变异的向量是“随机的”或“最佳的”;y是所利用的差向量的个数;z指示交叉程序的操作方法。前面叙述的交叉操作表示为“bin”。利用这个表示方法, 基本差分进化算法策略可描述为DE/rand/1/bin。 还有其他形式[5,如: 在这里插入图片描述 3.3改进的差分进化算法 自适应差分进化算法 作为一种高效的并行优化算法,差分进化算法发展很快,出现了很多改进的差分进化算法。下面介绍一种具有自适应算子的差分进化算法[9]. 在这里插入图片描述 在这里插入图片描述

4差分进化算法流程 差分进化算法采用实数编码、基于差分的简单变异操作和“一对一”的竞争生存策略,其具体步骤如下: (1)确定差分进化算法的控制参数和所要采用的具体策略。差分进化算法的控制参数包括:种群数量、变异算子、交叉算子、最大进化代数、终止条件等。 (2)随机产生初始种群,进化代数k=1。 (3)对初始种群进行评价,即计算初始种群中每个个体的目标函数值。 (4)判断是否达到终止条件或达到最大进化代数:若是,则进化终止,将此时的最佳个体作为解输出;否则,继续下一步操作。 (5)进行变异操作和交叉操作,对边界条件进行处理,得到临时种群。 (6)对临时种群进行评价,计算临时种群中每个个体的目标函数值。 (7)对临时种群中的个体和原种群中对应的个体,进行“一对-”的选择操作,得到新种群。 (8)进化代数k=k+1,转步骤(4)。 差分进化算法运算流程如图3.1所示。 在这里插入图片描述

5关键参数的说明 控制参数对一个全局优化算法的影响是很大的,差分进化算法的控制变量选择也有一些经验规则。

种群数量NP 一般情况下,种群的规模AP越大,其中的个体就越多,种群的多样性也就越好,寻优的能力也就越强,但也因此增加了计算的难度。所以,NP不能无限取大。根据经验,种群数量NP的合理选择在5D~ 10D之间,必须满足NP≥4,以确保差分进化算法具有足够的不同的变异向量。

变异算子F 变异算子FE[0,2]是一个实常数因数,它决定偏差向量的放大比例。变异算子熨小,则可能造成算法“早熟”。随着/值的增大,防止算法陷入局部最优的能力增强,但当F>1时,想要算法快速收敛到最优值会变得十分不易;这是由于当差分向量的扰动大于两个个体之间的距离时,种群的收敛性会变得很差。目前的研究表明,F小于0.4和大于1的值仅偶尔有效,/=0.5通常是一个较好的初始选择。若种 群过早收敛,那么F或NP应该增大。

交叉算子CR 交叉算子CR是一个范围在[0,1]内的实数,它控制着一个试验向量参数来自于随机选择的变异向量而不是原来向量的概率。交叉算子CK越大,发生交叉的可能性就越大。CR的一个较好的选择是0.1,但 较大的CK通常会加速收敛,为了看看是否可能获得一个快速解,可以先尝试CR=0.9或CF=1.0.

最大进化代数G 最大进化代数6是表示差分进化算法运行结束条件的一个参数,表示差分进化算法运行到指定的进化代数之后就停止运行,并将当前群体中的最佳个体作为所求问题的最优解输出。一般,6取100~500。

终止条件 除最大进化代数可作为差分进化算法的终止条件外,还可以增加其他判定准则。一般当目标函数值小于阈值时程序终止,阈值常选为10-6。上述参数中,F、CR与NP一样,在搜索过程中是常数,一般F和CR影响搜索过程的收敛速度和稳健性,它们的优化值不仅依赖于目标函数的特性,还与NP有关。通常可通过对不同值做一些试验之后,利用试验和结果误差找到F、CR和NP的合适值。

二、完整源代码

function [bestc,bestg,test_pre]=my_HGWO_SVR(para,input_train,output_train,input_test,output_test)
% 参数向量 parameters [n,N_iteration,beta_min,beta_max,pCR]
% n为种群规模,N_iteration为迭代次数
% beta_min 缩放因子下界 Lower Bound of Scaling Factor
% beta_max=0.8; % 缩放因子上界 Upper Bound of Scaling Factor
% pCR 交叉概率 Crossover Probability
% 要求输入数据为列向量(矩阵)

%% 数据归一化
[input_train,rule1]=mapminmax(input_train');
[output_train,rule2]=mapminmax(output_train');
input_test=mapminmax('apply',input_test',rule1);
output_test=mapminmax('apply',output_test',rule2);
input_train=input_train';
output_train=output_train';
input_test=input_test';
output_test=output_test';
%% 利用差分进化-灰狼优化混合算法(DE_GWO)选择最佳的SVR参数
nPop=para(1); % 种群规模 Population Size
MaxIt=para(2); % 最大迭代次数Maximum Number of Iterations
nVar=2; % 自变量维数,此例需要优化两个参数c和g Number of Decision Variables
VarSize=[1,nVar]; % 决策变量矩阵大小 Decision Variables Matrix Size
beta_min=para(3); % 缩放因子下界 Lower Bound of Scaling Factor
beta_max=para(4); % 缩放因子上界 Upper Bound of Scaling Factor
pCR=para(5); %  交叉概率 Crossover Probability
lb=[0.01,0.01]; % 参数取值下界
ub=[100,100]; % 参数取值上界
%% 初始化
% 父代种群初始化
parent_Position=init_individual(lb,ub,nVar,nPop); % 随机初始化位置
parent_Val=zeros(nPop,1); % 目标函数值
for i=1:nPop % 遍历每个个体
    parent_Val(i)=fobj(parent_Position(i,:),input_train,output_train,input_test,output_test); % 计算个体目标函数值
end
% 突变种群初始化
mutant_Position=init_individual(lb,ub,nVar,nPop); % 随机初始化位置
mutant_Val=zeros(nPop,1); % 目标函数值
for i=1:nPop % 遍历每个个体
    mutant_Val(i)=fobj(mutant_Position(i,:),input_train,output_train,input_test,output_test); % 计算个体目标函数值
end
% 子代种群初始化
child_Position=init_individual(lb,ub,nVar,nPop); % 随机初始化位置
child_Val=zeros(nPop,1); % 目标函数值
for i=1:nPop % 遍历每个个体
    child_Val(i)=fobj(child_Position(i,:),input_train,output_train,input_test,output_test); % 计算个体目标函数值
end
%% 确定父代种群中的Alpha,Beta,Delta狼
[~,sort_index]=sort(parent_Val); % 父代种群目标函数值排序
parent_Alpha_Position=parent_Position(sort_index(1),:); % 确定父代Alpha狼
parent_Alpha_Val=parent_Val(sort_index(1)); % 父代Alpha狼目标函数值
parent_Beta_Position=parent_Position(sort_index(2),:); % 确定父代Beta狼
parent_Delta_Position=parent_Position(sort_index(3),:); % 确定父代Delta狼
%% 迭代开始
BestCost=zeros(1,MaxIt);
BestCost(1)=parent_Alpha_Val;
for it=1:MaxIt
    a=2-it*((2)/MaxIt); % 对每一次迭代,计算相应的a值,a decreases linearly fron 2 to 0
    % 更新父代个体位置
    for par=1:nPop % 遍历父代个体
        for var=1:nVar % 遍历每个维度            
            % Alpha狼Hunting
            r1=rand(); % r1 is a random number in [0,1]
            r2=rand(); % r2 is a random number in [0,1]            
            A1=2*a*r1-a; % 计算系数A
            C1=2*r2; % 计算系数C
            D_alpha=abs(C1*parent_Alpha_Position(var)-parent_Position(par,var));
            X1=parent_Alpha_Position(var)-A1*D_alpha;
            % Beta狼Hunting
            r1=rand();
            r2=rand();            
            A2=2*a*r1-a; % 计算系数A
            C2=2*r2; % 计算系数C
            D_beta=abs(C2*parent_Beta_Position(var)-parent_Position(par,var));
            X2=parent_Beta_Position(var)-A2*D_beta;
            % Delta狼Hunting
            r1=rand();
            r2=rand();
            A3=2*a*r1-a; % 计算系数A
            C3=2*r2; % 计算系数C
            D_delta=abs(C3*parent_Delta_Position(var)-parent_Position(par,var));
            X3=parent_Delta_Position(var)-A3*D_delta;
            % 位置更新,防止越界
            X=(X1+X2+X3)/3;
            X=max(X,lb(var));
            X=min(X,ub(var));
            parent_Position(par,var)=X;
        end
        parent_Val(par)=fobj(parent_Position(par,:),input_train,output_train,input_test,output_test); % 计算个体目标函数值
    end
    % 产生变异(中间体)种群
    for mut=1:nPop
        A=randperm(nPop); % 个体顺序重新随机排列
        A(A==i)=[]; % 当前个体所排位置腾空(产生变异中间体时当前个体不参与)
        a=A(1);
        b=A(2);
        c=A(3);
        beta=unifrnd(beta_min,beta_max,VarSize); % 随机产生缩放因子
        y=parent_Position(a)+beta.*(parent_Position(b)-parent_Position(c)); % 产生中间体
        % 防止中间体越界
        y=max(y,lb);
		
    end
    % 产生子代种群,交叉操作 Crossover
    for child=1:nPop
        x=parent_Position(child,:);
        y=mutant_Position(child,:);
        z=zeros(size(x)); % 初始化一个新个体
        j0=randi([1,numel(x)]); % 产生一个伪随机数,即选取待交换维度编号???
        for var=1:numel(x) % 遍历每个维度
            if var==j0 || rand<=pCR % 如果当前维度是待交换维度或者随机概率小于交叉概率
                z(var)=y(var); % 新个体当前维度值等于中间体对应维度值
            else
                z(var)=x(var); % 新个体当前维度值等于当前个体对应维度值
            end
        end
        child_Position(child,:)=z; % 交叉操作之后得到新个体
        child_Val(child)=fobj(z,input_train,output_train,input_test,output_test); % 新个体目标函数值
    end
    % 父代种群更新
    for par=1:nPop
        if child_Val(par)<parent_Val(par) % 如果子代个体优于父代个体
            parent_Val(par)=child_Val(par); % 更新父代个体
        end
    end
    % 确定父代种群中的Alpha,Beta,Delta狼
    [~,sort_index]=sort(parent_Val); % 父代种群目标函数值排序
    parent_Alpha_Position=parent_Position(sort_index(1),:); % 确定父代Alpha狼
    parent_Alpha_Val=parent_Val(sort_index(1)); % 父代Alpha狼目标函数值
    parent_Beta_Position=parent_Position(sort_index(2),:); % 确定父代Beta狼
    parent_Delta_Position=parent_Position(sort_index(3),:); % 确定父代Delta狼
    BestCost(it)=parent_Alpha_Val;
end
bestc=parent_Alpha_Position(1,1);
bestg=parent_Alpha_Position(1,2);
%% 图示寻优过程
plot(BestCost);
xlabel('Iteration');
ylabel('Best Val');
grid on;
%% 利用回归预测分析最佳的参数进行SVM网络训练

%% SVM网络回归预测
[output_test_pre,~]=svmpredict(output_test,input_test,model_cs_svr); % SVM模型预测及其精度
test_pre=mapminmax('reverse',output_test_pre',rule2);
test_pre = test_pre';
%% SVR_fitness -- objective function
function fitness=fobj(cv,input_train,output_train,input_test,output_test)
% cv为长度为2的横向量,即SVR中参数c和v的值

cmd = ['-s 3 -t 2',' -c ',num2str(cv(1)),' -g ',num2str(cv(2))];
model=svmtrain(output_train,input_train,cmd); % SVM模型训练
[~,fitness]=svmpredict(output_test,input_test,model); % SVM模型预测及其精度
fitness=fitness(2); % 以平均均方误差MSE作为优化的目标函数值
function x=init_individual(xlb,xub,dim,sizepop)
% 参数初始化函数
% lb:参数下界,行向量
% ub:参数上界,行向量
% dim:参数维度
% sizepop 种群规模
% x:返回sizepop*size(lb,2)的参数矩阵

三、运行结果

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

四、matlab版本及参考文献

1 matlab版本 2014a

2 参考文献 《智能优化算法及其MATLAB实例(第2版)》包子阳 余继周 杨杉著 电子工业出版社