非线性约束
一些优化求解器接受非线性约束,包括 fmincon
、fseminf
、fgoalattain
、fminimax
,以及 Global Optimization Toolbox 求解器 ga
(Global Optimization Toolbox)、gamultiobj
(Global Optimization Toolbox)、patternsearch
(Global Optimization Toolbox)、paretosearch
(Global Optimization Toolbox)、GlobalSearch
(Global Optimization Toolbox) 和 MultiStart
(Global Optimization Toolbox)。非线性约束允许您将解约束在可以用平滑函数描述的任何区域内。
非线性不等式约束的形式为 c(x) ≤ 0,其中 c 是约束组成的向量,每个约束对应一个分量。同样,非线性等式约束的形式为 ceq(x) = 0。
注意
非线性约束函数必须同时返回 c
和 ceq
,即不等式和等式约束函数,即使它们并不都存在也会返回。对于不存在的约束,返回空条目 []
。
例如,假设您有以下不等式作为约束:
请按如下所示在函数文件中编写这些约束:
function [c,ceq] = ellipseparabola(x) c(1) = (x(1)^2)/9 + (x(2)^2)/4 - 1; c(2) = x(1)^2 - x(2) - 1; ceq = []; end
ellipseparabola
为非线性等式约束函数 ceq
返回空条目 []
。同样,需要将第二个不等式重写为 ≤ 0 形式。在 ellipseparabola
约束条件下最小化 exp(x(1) + 2*x(2))
函数。
fun = @(x)exp(x(1) + 2*x(2));
nonlcon = @ellipseparabola;
x0 = [0 0];
A = []; % No other constraints
b = [];
Aeq = [];
beq = [];
lb = [];
ub = [];
x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon)
Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. x = -0.2500 -0.9375
在约束函数中包含梯度
如果您为 c 和 ceq 提供梯度,求解器的运行速度可以更快,提供的结果更可靠。
提供梯度还有另一项优势。求解器可以到达点 x
,这说明 x
是可行点,但 x
附近的有限差分总是导致不可行点。在这种情况下,求解器可能会失败或过早停止。提供梯度可允许求解器继续。
要包含梯度信息,请编写一个条件化函数,如下所示:
function [c,ceq,gradc,gradceq] = ellipseparabola(x) c(1) = x(1)^2/9 + x(2)^2/4 - 1; c(2) = x(1)^2 - x(2) - 1; ceq = []; if nargout > 2 gradc = [2*x(1)/9, 2*x(1); ... x(2)/2, -1]; gradceq = []; end
请参阅编写标量目标函数了解有关条件化函数的信息。梯度矩阵具有以下形式
gradc
i, j = [∂c
(j)/∂xi]。
梯度矩阵的第一列与 c(1)
相关联,第二列与 c(2)
相关联。这种导数形式是雅可比矩阵形式的转置。
要让求解器使用非线性约束的梯度,请使用 optimoptions
指示这些梯度的存在:
options = optimoptions(@fmincon,'SpecifyConstraintGradient',true);
确保将 options 结构体传递给求解器:
[x,fval] = fmincon(@myobj,x0,A,b,Aeq,beq,lb,ub, ... @ellipseparabola,options)
如果您有 Symbolic Math Toolbox™ 许可证,您可以自动计算梯度和黑塞矩阵,如Calculate Gradients and Hessians Using Symbolic Math Toolbox中所述。
匿名非线性约束函数
非线性约束函数必须返回两个输出。第一个输出对应于非线性不等式,第二个输出对应于非线性等式。
匿名函数只返回一个输出。那么该如何将匿名函数写成非线性约束呢?
deal
函数分配多个输出。例如,假设您有非线性不等式
假设您有非线性等式
.
请编写一个如下所示的非线性约束函数。
c = @(x)[x(1)^2/9 + x(2)^2/4 - 1; x(1)^2 - x(2) - 1]; ceq = @(x)tanh(x(1)) - x(2); nonlinfcn = @(x)deal(c(x),ceq(x));
要在满足 nonlinfcn
约束的条件下最小化 函数,请使用 fmincon
。
obj = @(x)cosh(x(1))+sinh(x(2)); opts = optimoptions(@fmincon,'Algorithm','sqp'); z = fmincon(obj,[0;0],[],[],[],[],[],[],nonlinfcn,opts)
Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
z = 2×1
-0.6530
-0.5737
要检查得到的点 z
满足约束的程度,请使用 nonlinfcn
。
[cout,ceqout] = nonlinfcn(z)
cout = 2×1
-0.8704
0
ceqout = 0
z
在约束容差 ConstraintTolerance
默认值 1e-6
范围内满足所有约束。
有关匿名目标函数的信息,请参阅匿名函数目标。
另请参阅
fmincon
| fgoalattain
| ga
(Global Optimization Toolbox) | patternsearch
(Global Optimization Toolbox) | GlobalSearch
(Global Optimization Toolbox) | MultiStart
(Global Optimization Toolbox)