我有一个优化脚本(如下),该脚本给了我错误:
“未定义的函数'cos',用于类型的输入参数 'optim.problemdef.OptimizationExpression'。”
只是为了确保cos
函数没有问题,我将cos
中的confn2
更改为sin
,然后得到:
“未定义函数'sin'用于类型的输入参数 'optim.problemdef.OptimizationExpression'。”
但是,如果我将cos(pi)
放在命令窗口中,则会得到-1。
我之前已经成功运行了该脚本,除了sigma(出现在cos()
中)不是优化变量之外,因此对trig函数进行了评估,使结果线性。对于具有三角函数的约束,这种类型的优化脚本难道难道难道吗? MATLAB中有替代方案吗?
k1 = optimvar('k1', 'LowerBound', -3, 'UpperBound', 3);
k2 = optimvar('k2', 'LowerBound', -3, 'UpperBound', 3);
f = optimvar('f', 'LowerBound', -3, 'UpperBound', 3);
sigma = optimvar('sigma', 'LowerBound', 0, 'UpperBound', 6.28318530718);
obj = fcn2optimexpr(@eq1, k1, k2, f, sigma);
confn1 = obj == 0;
confn2 = -0.9313129901097519*k1 - 1.4693755421886672*k2 - 0.18532000686683578*f*cos((1/2)*(-0.372795 + 2*sigma)) + 0.9826782255931369*f*sin((1/2)*(-0.372795 + 2*sigma)) <= 0;
prob = optimproblem('Objective', obj);
prob.Constraints.confn1 = confn1;
prob.Constraints.confn2 = confn2;
k0.k1 = 0;
k0.k2 = 0;
k0.f = 0;
k0.sigma = 0;
[sol, fval, exitflag, output] = solve(prob, k0)
function f1 = eq1(k1, k2, f, sigma)
f1 = 0.01308996938995749 - 0.3642198710296203*k1 - 0.6784053942919677*k2 + 0.37064001373367156*f*sin((1/2)*(-0.372795 + 2*sigma));
end
答案 0 :(得分:1)
您可以改用fmincon
,也可以在其中指定目标和约束。这样,cos
函数将在每次迭代中进行数值评估,而不会使用optim.problemdef.OptimizationExpression
类型进行调用。
您确实需要将变量指定为向量(初始猜测x0
,下限lb
,上限ub
),请参见代码中的注释。
% x0 = [k1 k2 f sigma];
x0 = [0 0 0 0];
lb = [-3 -3 -3 0];
ub = [3 3 3 2*pi];
% options
options = optimoptions('fmincon','Display','iter', 'ConstraintTolerance', 1e-12);
% optimization
x = fmincon(@objfun,x0,[],[],[],[],lb,ub,@constrfun, options)
% check constraints to check fulfilment of constraints
[c, ceq] = constrfun(x)
您的对象函数必须接受单个向量x
,可以将其“解包”为各个变量。
function f1 = objfun(x)
k1 = x(1);
k2 = x(2);
f = x(3);
sigma = x(4);
f1 = 0.01308996938995749 - 0.3642198710296203*k1 - 0.6784053942919677*k2 + 0.37064001373367156*f*sin((1/2)*(-0.372795 + 2*sigma));
end
必须在约束函数中定义约束,该约束函数返回c
和ceq
,其中c
是不等式约束c(x) <= 0
,而ceq
是不等式约束等式约束ceq(x) = 0
。
function [c,ceq] = constrfun(x)
k1 = x(1);
k2 = x(2);
f = x(3);
sigma = x(4);
c = -0.9313129901097519*k1 - 1.4693755421886672*k2 - 0.18532000686683578*f*cos((1/2)*(-0.372795 + 2*sigma)) + 0.9826782255931369*f*sin((1/2)*(-0.372795 + 2*sigma));
ceq = objfun(x);
end
答案 1 :(得分:0)
由于confn2中的cos(sigma),您需要使用fcn2optimexpr。从R2019a版本开始,仅允许多项式的比率表示优化变量。
k1 = optimvar('k1', 'LowerBound', -3, 'UpperBound', 3);
k2 = optimvar('k2', 'LowerBound', -3, 'UpperBound', 3);
f = optimvar('f', 'LowerBound', -3, 'UpperBound', 3);
sigma = optimvar('sigma', 'LowerBound', 0, 'UpperBound', 6.28318530718);
obj = fcn2optimexpr(@eq1, k1, k2, f, sigma);
c2 = fcn2optimexpr(@conexpr2, k1, k2, f, sigma);
confn1 = obj == 0;
confn2 = c2 <= 0;
prob = optimproblem('Objective', obj);
prob.Constraints.confn1 = confn1;
prob.Constraints.confn2 = confn2;
k0.k1 = 0;
k0.k2 = 0;
k0.f = 0;
k0.sigma = 0;
options = optimoptions(prob,'Display','iter', 'ConstraintTolerance', 1e-12);
[sol, fval, exitflag, output] = solve(prob, k0, 'Options',options)
objval = evaluate(obj,sol)
c2val = evaluate(c2,sol)
function f1 = eq1(k1, k2, f, sigma)
f1 = 0.01308996938995749 - 0.3642198710296203*k1 - 0.6784053942919677*k2 + 0.37064001373367156*f*sin((1/2)*(-0.372795 + 2*sigma));
end
function c2 = conexpr2(k1, k2, f, sigma)
c2 = -0.9313129901097519*k1 - 1.4693755421886672*k2 - 0.18532000686683578*f*cos((1/2)*(-0.372795 + 2*sigma)) + 0.9826782255931369*f*sin((1/2)*(-0.372795 + 2*sigma));
end
正如@rinkert指出的那样,您两次使用物镜。不必具有目标功能。您可能会遇到仅具有约束条件的优化问题。
k1 = optimvar('k1', 'LowerBound', -3, 'UpperBound', 3);
k2 = optimvar('k2', 'LowerBound', -3, 'UpperBound', 3);
f = optimvar('f', 'LowerBound', -3, 'UpperBound', 3);
sigma = optimvar('sigma', 'LowerBound', 0, 'UpperBound', 6.28318530718);
c1 = fcn2optimexpr(@eq1, k1, k2, f, sigma);
c2 = fcn2optimexpr(@conexpr2, k1, k2, f, sigma);
confn1 = c1 == 0;
confn2 = c2 <= 0;
prob = optimproblem();
prob.Constraints.confn1 = confn1;
prob.Constraints.confn2 = confn2;
k0.k1 = 0;
k0.k2 = 0;
k0.f = 0;
k0.sigma = 0;
options = optimoptions(prob,'Display','iter', 'ConstraintTolerance', 1e-12);
[sol, fval, exitflag, output] = solve(prob, k0, 'Options',options)
c1val = evaluate(c1,sol)
c2val = evaluate(c2,sol)
function f1 = eq1(k1, k2, f, sigma)
f1 = 0.01308996938995749 - 0.3642198710296203*k1 - 0.6784053942919677*k2 + 0.37064001373367156*f*sin((1/2)*(-0.372795 + 2*sigma));
end
function c2 = conexpr2(k1, k2, f, sigma)
c2 = -0.9313129901097519*k1 - 1.4693755421886672*k2 - 0.18532000686683578*f*cos((1/2)*(-0.372795 + 2*sigma)) + 0.9826782255931369*f*sin((1/2)*(-0.372795 + 2*sigma));
end