Matlab遗传算法工具箱的使用及实例(非线性规划)
  NTGlKyq7MwNU 2023年11月19日 21 0

✅作者简介:热爱科研的算法开发者,Python、Matlab项目可交流、沟通、学习。

🍎个人主页:算法工程师的学习日志

本文将介绍MATLAB遗传算法工具箱求解非线性规划问题。在阅读本文之前,建议读者阅读上一期“MATLAB遗传算法工具箱求解线性规划问题”。文章传送门:

Matlab遗传算法工具箱的使用及实例(线性规划)

一、引例


上一期介绍了遗传算法求解线性规划的问题。我们来看看下面这个例子,能否用上次讲的方法解决。

Matlab遗传算法工具箱的使用及实例(非线性规划)_遗传算法


上述例子,第二个约束条件含有二次项,并不是线性的,用上次的方法好像无法直接解决。下面我们就来介绍一下非线性规划的遗传算法的实现。


二、非线性规划的标准形式


2.1 非线性规划的标准形式


和线性规划一样,在调用遗传算法工具箱之前,也得学习一下非线性规划的标准形式。因为,调用工具箱需要我们将非标准形式的模型转化为标准形式。

Matlab遗传算法工具箱的使用及实例(非线性规划)_遗传算法_02

其中,f(x)是目标函数,线性或者非线性都可以。式[1]、式[2]、式[5]同线性规划,为相应维数的矩阵和向量。式[3]表示非线性的不等式约束,式[4]是非线性等式约束。c(x)和ceq(x)为非线性向量函数(这里可能不好理解,下面结合一个例子解释)


三、非线性规划模型的实例


3.1 还是前面出现的模型

Matlab遗传算法工具箱的使用及实例(非线性规划)_线性规划_03

      

1) 编写适应度函数(即目标函数)

Matlab遗传算法工具箱的使用及实例(非线性规划)_线性规划_04

目标函数的编写就不多说了,和之前线性规划的编写方法相同

function f = fitnessfun(x)
    f = x(1)^2 + x(2)^2 + x(3)^3 + 8;
end


2) 编写非线性约束函数

根据式[1]、[2],非线性不等式约束的函数为:,

Matlab遗传算法工具箱的使用及实例(非线性规划)_遗传算法_05

根据式[3]、[4],等式约束的函数为: 

Matlab遗传算法工具箱的使用及实例(非线性规划)_约束函数_06

非线性约束函数和需要在MATLAB中编写为如下格式(写在一个function里)

function [c, ceq] = 函数名(x)

参数和返回值解释:

x即为自变量的值,为行向量。c即不等式约束的函数值,是列向量(可以存在多个约束)。ceq即等式约束函数的函数值,同样是列向量(可以存在多个约束)

也就是本题返回值要写成这样的形式(这样看的更直观一些):

Matlab遗传算法工具箱的使用及实例(非线性规划)_约束函数_07

因此,这题的function应定义为

function [c,ceq] = nonlconfun(x)
    % 入口参数 x:为自变量的行向量
    % 出口参数 c:非线性不等式约束的函数值。由于本题有两个不等式约束
    %           因此c(1,1)为第一个不等式约束函数值,c(2,1)为第二个不等式约束函数值
    %        ceq:非线性等式约束的函数值,由于本题有两个等式约束,同c一样
    %            ceq(1,1)为第一个等式约束函数值,ceq(2,1)为第二个等式约束函数值
    c(1,1) = -x(1)^2 + x(2) - x(3)^3;
    c(2,1) = x(1) + x(2)^2 + x(3)^3 - 20;
    ceq(1,1) = -x(1) - x(2)^2 + 2;
    ceq(2,1) = x(2) + 2*x(3)^2 - 3;
end


3) 设置遗传算法工具箱的相关参数

这里我们设置种群规模300,迭代次数为800,返回值为options.

options = gaoptimset('PopulationSize', 300, 'Generations', 800);


4) 调用ga工具箱

我们知道,ga工具箱的调用格式为:

[x_best,fval] = ga(fun, nvars, A, b, Aeq, beq, lb, ub, nonlcon, options);

由于本题没有线性约束,因此参数A、b、Aeq、beq都可以设置为空。

对自变量x的约束为:【0,+无穷】,因此,lb = [0,0,0],而ub可以不设置


因此,这部分代码为

options = gaoptimset('PopulationSize', 300, 'Generations', 800); % 遗传算法相关配置
fun = @fitnessfun; % 设置适应度函数句柄
nonlcon = @nonlconfun; % 设置非线性约束函数句柄
nvars = 3; % 自变量个数
A = [];  b = [];
Aeq = [];  beq = [];
lb = [0;0;0];  ub = [];
[x_best, fval] = ga(fun, nvars, A, b, Aeq, beq, lb, ub, nonlcon, options);



完整的代码为:

clear;
clc
options = gaoptimset('PopulationSize',200, 'Generations', 600); % 遗传算法相关配置
fun = @fitnessfun; % 设置适应度函数句柄
nonlcon = @nonlconfun; % 设置非线性约束函数句柄
nvars = 3; % 自变量个数
A = [];  b = [];
Aeq = [];  beq = [];
lb = [0;0;0];  ub = [];
[x_best, fval] = ga(fun, nvars, A,b,Aeq,beq,lb,ub,nonlcon,options);
 
function [c,ceq] = nonlconfun(x)
    c(1,1) = -x(1)^2 + x(2) - x(3)^3;
    c(2,1) = x(1) + x(2)^2 + x(3)^3 - 20;
    ceq(1,1) = -x(1) - x(2)^2 + 2;
    ceq(2,1) = x(2) + 2*x(3)^2 - 3;
end
 
function f = fitnessfun(x)
    f = x(1)^2 + x(2)^2 + x(3)^3 + 8;
end



运行结果为:

fval的值为10.9886即为所求,此时x_best的值为[0.9917    1.0041    0.9988].

因此当时x1 = 0.9917;x2=1.0041;x3=0.9988,函数取到最小值10.9886

(遗传算法具有一定随机性,每次的运行结果有差别,建议多运行几遍程序,找一个最好的结果)


3.2 求下列问题的解

Matlab遗传算法工具箱的使用及实例(非线性规划)_线性规划_08

1) 编写目标函数

function f = fitnessfun(x)
    f = -2 * x(1) - 3 * x(1)^2 - 3 * x(2) - x(2)^2 - x(3);
end


2)编写非线性约束函数

式[1]、[2]、[3]为非线性不等式约束,式[4]为非线性等式约束,因此

Matlab遗传算法工具箱的使用及实例(非线性规划)_遗传算法_09

使用MATLAB编写为:

function [c,ceq] = nonlconfun(x)
    % 入口参数 x:为自变量的行向量
    % 出口参数 c:非线性不等式约束的函数值。由于本题有多个不等式约束,以列向量的形式返回即可
    %         ceq:非线性等式约束的函数值。
    c(1,1) = x(1) + 2 * x(1)^2 + x(2) + 2 * x(2)^2 + x(3) - 10;
    c(2,1) = x(1) + x(1)^2 + x(2) + x(2)^2 - x(3) - 50;
    c(3,1) = 2 * x(1) + x(1)^2 + 2 * x(2) + x(3) - 40;
    ceq = x(1)^2 + x(3) - 2;
end



3)调用ga函数

(这里就不调用gaoptimset函数配置遗传算法的参数了,直接使用默认参数)

式[5]、[6]为线性不等式约束,标准形式为Ax<=b

Matlab遗传算法工具箱的使用及实例(非线性规划)_遗传算法_10

 可转化为:,因此:

Matlab遗传算法工具箱的使用及实例(非线性规划)_遗传算法_11

本题没有线性等式约束,也没有自变量约束,因此Aeq、beq、lb、ub均设置为空矩阵。写好ga所需的入口参数,即可调用ga函数,调用方式如下:

fun = @fitnessfun; % 设置适应度函数句柄,(在函数名前加@即可)
nonlcon = @nonlconfun; % 设置非线性约束函数句柄
nvars = 3; % 自变量个数
A = [-1,-2,0;-1,0,0];  b = [-1;0];  % 线性不等式约束
Aeq = [];  beq = []; % 线性等式约束
lb = [];  ub = [];   % 自变量定义域
[x_best, fval] = ga(fun, nvars, A, b, Aeq, beq, lb, ub, nonlcon, []);



整体程序为:

clear;
clc
fun = @fitnessfun; % 设置适应度函数句柄,(在函数名前加@即可)
nonlcon = @nonlconfun; % 设置非线性约束函数句柄
nvars = 3; % 自变量个数
A = [-1,-2,0;-1,0,0];  b = [-1;0];  % 线性不等式约束
Aeq = [];  beq = [];   % 线性等式约束
lb = [];  ub = [];     % 自变量定义域
[x_best, fval] = ga(fun, nvars, A,b,Aeq,beq,lb,ub,nonlcon,[]);
 
function [c,ceq] = nonlconfun(x)
    c(1,1) = x(1) + 2 * x(1)^2 + x(2) + 2 * x(2)^2 + x(3) - 10;
    c(2,1) = x(1) + x(1)^2 + x(2) + x(2)^2 - x(3) - 50;
    c(3,1) = 2 * x(1) + x(1)^2 + 2 * x(2) + x(3) - 40;
    ceq = x(1)^2 + x(3) - 2;
end
 
function f = fitnessfun(x)
    f = -2 * x(1) - 3 * x(1)^2 - 3 * x(2) - x(2)^2 - x(3);
end


运行程序后,得到运行结果:fval的值为 -15.2409.由于我们在标准化模型时,将目标函数添加了一个负号,因此原函数的最大值约为15.2409.


(遗传算法具有一定随机性,每次的运行结果有差别,建议多运行几遍程序,找一个最好的结果)


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

上一篇: Paul Graham入门 下一篇: pytorch PairwiseDistance
  1. 分享:
最后一次编辑于 2023年11月19日 0

暂无评论

推荐阅读
NTGlKyq7MwNU