6

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

 1 year ago
source link: https://blog.51cto.com/domi/5936344
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

推荐 原创

domi+1 2022-12-14 12:05:48 博主文章分类:matlab ©著作权

文章标签 线性规划 遗传算法 约束函数 文章分类 其它 编程语言 yyds干货盘点 阅读数171

✅作者简介:热爱科研的算法开发者,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],非线性不等式约束的函数为:,

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

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

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

参数和返回值解释:

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

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

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

因此,这题的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遗传算法工具箱的使用及实例(非线性规划)_线性规划_06

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遗传算法工具箱的使用及实例(非线性规划)_约束函数_07

使用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遗传算法工具箱的使用及实例(非线性规划)_遗传算法_08

 可转化为:,因此:

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

本题没有线性等式约束,也没有自变量约束,因此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.

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK