Main Content

带梯度的非线性约束

此示例说明如何使用导数信息来求解具有非线性约束的非线性问题。

通常,最小化例程使用通过有限差分逼近计算得到的数值梯度。此过程会系统化地扰动每个变量,以便计算函数和约束偏导数。您也可以提供一个函数,以通过解析法计算偏导数。通常,当您提供导数信息时,求解器的工作会更加准确和高效。

目标函数和非线性约束

问题是求解

minxf(x)=ex1(4x12+2x22+4x1x2+2x2+1),

需满足以下约束

x1x2-x1-x2-1.5x1x2-10.

由于 fmincon 求解器要求约束以 c(x) 0 形式编写,请编写约束函数以返回以下值:

c(x)=[x1x2-x1-x2+1.5-10-x1x2].

带梯度的目标函数

目标函数是

f(x)=ex1(4x12+2x22+4x1x2+2x2+1).

计算 f(x) 关于变量 x1x2 的梯度。

f(x)=[f(x)+exp(x1)(8x1+4x2)exp(x1)(4x1+4x2+2)].

此示例末尾objfungrad 辅助函数返回目标函数 f(x) 及其在第二个输出 gradf 中的梯度。将 @objfungrad 设置为目标。

fun = @objfungrad;

带梯度的约束函数

辅助函数 confungrad 是非线性约束函数;它出现在此示例末尾

不等式约束的导数信息使每一列对应于一个约束。换句话说,约束的梯度采用以下格式:

[c1x1c2x1c1x2c2x2]=[x2-1-x2x1-1-x1].

@confungrad 设置为非线性约束函数。

nonlcon = @confungrad;

设置选项以使用导数信息

fmincon 求解器指示目标函数和约束函数提供导数信息。为此,请使用 optimoptionsSpecifyObjectiveGradientSpecifyConstraintGradient 选项值设置为 true

options = optimoptions('fmincon',...
    'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true);

求解问题

将初始点设置为 [-1,1]

x0 = [-1,1];

该问题没有边界或线性约束,因此请将这些参量值设置为 []

A = [];
b = [];
Aeq = [];
beq = [];
lb = [];
ub = [];

调用 fmincon 以求解问题。

[x,fval] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options)
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 = 1×2

   -9.5473    1.0474

fval = 
0.0236

解与示例非线性不等式约束中的解相同,该示例在不使用导数信息的情况下求解问题。使用导数的优点是在获得稳健性的同时求解问题所需的函数计算更少,尽管这一优点在此示例中并不明显。使用更多导数信息(例如在使用解析黑塞函数的 fmincon 内点算法中)会带来更多好处,如更少的求解器迭代次数。

辅助函数

以下代码会创建 objfungrad 辅助函数。

function [f,gradf] = objfungrad(x)
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1);
% Gradient of the objective function:
if nargout  > 1
    gradf = [ f + exp(x(1)) * (8*x(1) + 4*x(2)), 
    exp(x(1))*(4*x(1)+4*x(2)+2)];
end
end

以下代码会创建 confungrad 辅助函数。

function [c,ceq,DC,DCeq] = confungrad(x)
c(1) = 1.5 + x(1) * x(2) - x(1) - x(2); % Inequality constraints
c(2) = -x(1) * x(2)-10; 
% No nonlinear equality constraints
ceq=[];
% Gradient of the constraints:
if nargout > 2
    DC= [x(2)-1, -x(2);
        x(1)-1, -x(1)];
    DCeq = [];
end
end

相关主题