定义:
x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options)
含义:从 x0
开始,尝试在满足线性等式 Aeq*x = beq
以及不等式 A*x ≤ b、
c(x) ≤ 0
和 ceq(x) = 0
的情况下寻找 fun
中所述的函数的最小值点 x
。对 x
中的设计变量定义一组下界和上界,使解始终 lb
≤ x
≤ ub
范围内。
fun:目标函数、需要最小化的函数
x0:初值。x0
可以是标量、向量或矩阵。
A,b:线性不等式 A*x ≤ b
的系数矩阵/系数。如果不存在不等式,则设置 A = []
和 b = []
。
Aeq,beq:线性等式Aeq*x = beq
的系数矩阵/系数。如果不存在等式,请设置 Aeq = []
和 beq = []
。
lb,ub:设计变量的下界和上界,使解始终在 lb
≤ x
≤ ub
范围内。如果 x(i)
无下界,请设置 lb(i) = -Inf
,如果 x(i)
无上界,请设置 ub(i) = Inf
。
nonlcon: 执行最小化时,满足 nonlcon
所定义的非线性不等式 c(x)
或等式 ceq(x)
。fmincon
进行优化,以满足 c(x) ≤ 0
和 ceq(x) = 0
。如果不存在边界,请设置 lb = []
和/或 ub = []
。如果没有非线性不等式或等式约束,请设置 nonlcon = []
。
options:使用 options
所指定的优化选项执行最小化。使用 optimoptions 可设置这些选项。
[x,fval,exitflag,output,lambda,grad,hessian] = fmincon(___)
同时返回:
- 描述
fmincon
的退出条件的值exitflag
- 提供优化过程信息的结构体
output
lambda
- 结构体,其字段包含解x
处的拉格朗日乘数。grad
-fun
在解x
处的梯度。hessian
-fun
在解x
处的黑塞矩阵。请参阅fmincon黑塞函数。
示例:
1、线性不等式约束
目标函数:Rosenbrock函数的最小化,无约束解为(1,1),最小目标值为0
从点 [-1,2]
开始求最小值,约束为 x(1)+2x(2)≤1。以 A = [1,2]
和 b = 1
为条件,以 Ax <= b
形式表达此约束。(此约束意味着解不会在无约束解 (1,1) 处,因为在此点 x(1)+2x(2)=3>1)
p=1;
q=100;
%目标函数
fun = @(x)(p-x(1))^2 + q*(x(2)-x(1)^2)^2; %x为2维向量
%求最小值
x0 = [-1,2]; %初始值
A = [1,2]; % Ax <= b
b = 1;
x = fmincon(fun,x0,A,b) %局部最小值
求得:
x =
0.5022 0.2489
2、线性不等式和等式约束
目标函数:Rosenbrock函数的最小化,无约束解为(1,1),最小目标值为0
从点 [0.5,0]
开始求最小值,约束为 x(1)+2x(2)≤1 和 2x(1)+x(2)=1。
-
以
A = [1,2]
和b = 1
为条件,以A*x <= b
形式表达线性不等式约束。 -
以
Aeq = [2,1]
和beq = 1
为条件,以Aeq*x = beq
形式表达线性等式约束。p=1; q=100; %目标函数 fun = @(x)(p-x(1))^2 + q*(x(2)-x(1)^2)^2; %x为2维向量 %求最小值 x0 = [-1,2]; %初始值 A = [1,2]; % Ax <= b b = 1; Aeq=[2,1]; beq=1; x = fmincon(fun,x0,A,b,Aeq,beq) %局部最小值
x =
0.4149 0.1701
3、具有边界约束的最小化
目标函数:f(x)=1+x(1)/(1+x(2)) - 3*x(1)*x(2) + x(2)*(1+x(1))
约束:关注 x 为正值且满足 x(1)≤1 和 x(2)≤2 的区域。
%目标函数
fun = @(x)1+x(1)/(1+x(2)) - 3*x(1)*x(2) + x(2)*(1+x(1));
%约束
lb = [0,0];
ub = [1,2];
A = [];
b = [];
Aeq = [];
beq = [];
%初值
x0 = (lb + ub)/2;
%求解
x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub)
x =
1.0000 2.0000
使用另一个初始点会得到不同的解。
x0 = x0/5;
x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub)
x =
1.0e-06 *
0.4000 0.4000
4、非线性约束(nonlcon)
在边界约束下求罗森布罗克函数在圆内最小的点,
同时在以 [1/3,1/3] 为圆心、半径为 1/3 的圆内寻找。将以下代码复制到您的 MATLAB® 路径上名为 circlecon.m
的文件中。
fun = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2;
lb = [0,0.2];
ub = [0.5,0.8];
A = [];
b = [];
Aeq = [];
beq = [];
x0 = [1/4,1/4];
nonlcon = @circlecon;
x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon)
%满足 nonlcon 所定义的非线性不等式 c(x) 或等式 ceq(x)
function [c,ceq] = circlecon(x)
c = (x(1)-1/3)^2 + (x(2)-1/3)^2 - (1/3)^2;
ceq = [];
5、非默认选项(optimoptions)
在单位圆盘 ∣∣x∣∣^2≤1 上求罗森布罗克函数的最小值
设置选项以在迭代期间查看输出信息并使用不同算法。
%保存为 unitdisk.m
function [c,ceq] = unitdisk(x)
c = x(1)^2 + x(2)^2 - 1;
ceq = [];
求解:要观察 fmincon
求解过程,请将 Display
选项设置为 'iter'
。此外,尝试 'sqp'
算法,该算法有时比默认的 'interior-point'
算法更快或更准确。
options = optimoptions('fmincon','Display','iter','Algorithm','sqp');
fun = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2;
A = [];
b = [];
Aeq = [];
beq = [];
lb = [];
ub = [];
nonlcon = @unitdisk;
x0 = [0,0];
x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options)
x =
0.7864 0.6177
6、使用梯度
将梯度计算加入目标函数中,以实现更快或更可靠的计算。
将梯度计算作为条件化输出包含在目标函数文件中。
目标函数是罗森布罗克函数,
将此代码保存为 MATLAB® 路径上名为 rosenbrockwithgrad.m
的文件。
%建立函数文件
function [f,g] = rosenbrockwithgrad(x)
% Calculate objective f
f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2;
if nargout > 1 % gradient required
g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1));
200*(x(2)-x(1)^2)];
end
求解:
%创建使用目标函数梯度的选项。
options = optimoptions('fmincon','SpecifyObjectiveGradient',true);
%为问题创建其他输入。然后调用 fmincon。
fun = @rosenbrockwithgrad; %将梯度计算加入目标函数中
x0 = [-1,2];
A = [];
b = [];
Aeq = [];
beq = [];
lb = [-2,-2];
ub = [2,2];
nonlcon = [];
x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options)
7、使用问题结构体 (problem)
options = optimoptions('fmincon','Display','iter','Algorithm','sqp');
problem.options = options;
problem.solver = 'fmincon';
problem.objective = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2;
problem.x0 = [0,0];
problem.nonlcon = @unitdisk;
x = fmincon(problem)
%% unitdisk 函数
function [c,ceq] = unitdisk(x)
c = x(1)^2 + x(2)^2 - 1;
ceq = [];
end
8、获得解处的目标函数值
fun = @(x)1+x(1)./(1+x(2)) - 3*x(1).*x(2) + x(2).*(1+x(1));
lb = [0,0];
ub = [1,2];
A = [];
b = [];
Aeq = [];
beq = [];
x0 = (lb + ub)/2;
%获得解处的目标函数值fval
[x,fval] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub)
%获取所有输出
[x,fval,exitflag,output,lambda,grad,hessian] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub)
官方文档:fmincon - 寻找约束非线性多变量函数的最小值 - MATLAB- MathWorks 中国