如何解决关于使用 fmincon 最小化具有复杂非线性约束的函数的一般问题
让乐趣 = X(1)*X(2)*X(3) - X(4)*X(5) + X(1)^(2)
参数向量 X = [X(1),X(2),X(3),X(4),X(5)]
约束:
- X(1) > 0;
- X(1)-(X(4)*X(3))
- X(4)X(3)(X(2)-((1-X(3))/2))
当约束更简单时,我可以根据情况制作适当的 A,b,Aeq,beq,lb,ub,nonlcon 向量或矩阵。但是当约束很复杂时如何处理。
解决方法
您可以使用惩罚法作为解决任何约束问题的一般方法。网络上有很多关于 this 等惩罚方法的信息。
,您可以修改您的函数,以便在每次违反约束时添加一个大值。这并不优雅,但会很容易。每个约束都被反转,如果约束的逆为真,则将 10^6 添加到函数返回值。我试过这个方法。它不能很好地工作,可能是因为函数中的不连续性导致内置例程 fmincon() 出现问题。以下是不该做的事情:
function Z = frbeginner2(x)
%FRBEGINNER2 Function to minimize
% x(1:5) = model parameters
% Function frbeginner2() is to be minimized subject to constraints
Z=x(1)*x(2)*x(3)-x(4)*x(5)+x(1)^2 ...
+1e6*(x(1)<=0) ...
+1e6*(x(1)-(x(4)*x(3))>x(2)) ...
+1e6*(x(2)>(2-x(3))/3) ...
+1e6*(x(4)*x(3)*(x(2)-((1-x(3))/2))>x(1)*(x(2)-x(1)+(x(4)*x(3))));
end
一个更好的解决方案是阅读关于 fmincon() 的 Matlab 帮助。它有一个可选参数 nonlcon,它是一个函数的名称,该函数返回 2 个数组,c 和 ceq:不等式约束(如果有),以及等式约束的方程值(如果有)。第一个约束 x(1)>0 是通过将 x(1) 的下限设置为 0 来实现的,函数 frbeginCon() 负责处理其他约束。没有等式约束,所以 ceq 返回 0 的值。我尝试使用下面的函数为 nonlcon 调用 fmincon(),并且对于许多随机起点都取得了不错的结果。
function [c,ceq] = frbeginCon(x)
%FRBEGINCON Constraints specified by rbeginner on stack overflow,2021-01-15
% x1..x5 = model parameters
% These are the constarints on function frbegin0().
% Constraints:
% 1. X(1) > 0; %handle this constraint by set lb(1)=0
% 2. X(1)-(X(4)*X(3)) <= X(2) <= (2-X(3))/3;
% 3. X(4)X(3)(X(2)-((1-X(3))/2)) <= X(1)(X(2)-X(1)+(X(4)*X(3)));
% Convert each constraint to equation that is <=0 when constraint is met.
% 2a. X(1)-X(4)*X(3)- X(2) <= 0
% 2b. X(2) - (2-X(3))/3 <=0
% 3. X(4)*X(3)*(X(2)-((1-X(3))/2)) - X(1)*(X(2)-X(1)+X(4)*X(3)) <= 0
x1=x(1); x2=x(2); x3=x(3); x4=x(4); x5=x(5);
c=[x1-x2-x4*x3,x2-(2-x3)/3,x4*x3*(x2-((1-x3)/2))-x1*(x2-x1+x4*x3)];
ceq=0;
end
最小化函数就是
function z = frbegin(x)
%FRBEGIN Function specified by rbeginner on stack overflow,2021-01-15
% x1..x5 = model parameters
% Minimize function frbegin() subject to constraints.
z=x(1)*x(2)*x(3)-x(4)*x(5)+x(1)^2;
end
,
谢谢大家的帮助。我走上了@Erwin Kalvelagen 建议的道路。对于其他人来说,这也是一个非常好的方法。我就是这样做的
创建一个空问题
prob1 = optimproblem
定义有边界的优化变量
x1 = optimvar("x1","LowerBound",0);
x2 = optimvar("x2","UpperBound",1);
x3 = optimvar("x3",0);
x4 = optimvar("x4",1);
x5 = optimvar("x5",1);
创建目标函数
edit function
创建优化表达式
obj = fcn2optimexpr(@function,x1,x2,x3,x4,x5)
分配目标函数
prob1.Objective = obj
设置约束
constr1 = x1 - (x4*x3) - x2 <=0;
prob1.Constraints.optim1 = constr1;
constr2 = x2 - ((2-x3)/3) <=0;
prob1.Constraints.optim2 = constr2;
constr3 = (x4*(x3))*(x2-((1-x3)/2))-(x1*(x2-x1+(x4*x3)))<=0;
prob1.Constraints.optim3 = constr3;
再看问题检查
showproblem(prob1)
设置初始条件
x0.x1 = 0.01;
x0.x2 = 0.15;
x0.x3 = 0.20;
x0.x4 = 0.20;
x0.x5 = 0.5;
解决问题
[sol,fval,exitflag] = solve(prob1,x0)
希望这会有所帮助。谢谢@Mansour Torabi,尤其是@rosewc 的帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。