2

我在优化练习期间遇到问题。我正在尝试在 matlab 中使用 fminsearch() 来解决它。运行代码时会产生以下错误:

从 sym 转换为 double 时发生以下错误:使用 symengine 时出错(第 59 行) DOUBLE 无法将输入表达式转换为双精度数组。如果输入表达式包含符号变量,请使用 VPA。

fminsearch 中的错误(第 190 行) fv(:,1) = funfcn(x,varargin{:});

优化错误(第 22 行) sol2 = fminsearch(J, x0);

我使用的脚本如下所示。f 是最小化问题,其中 g1 和 g2 是约束。p 在那里,以便我以后可以将其转换为 for 循环。

syms x1 x2 x3 x4;
syms p;

f = x1.^4 - x3.^2 + x1*x3 + x2*x4 - 5*x2 + 3;
g1 = x1.^2 + x2.^2 + x3.^2 + x4.^2 - 1;
g2 = x1 + x3 - 1;

x0 = [2 2 2 2];
p = 3;

J = @(x1,x2,x3,x4) sym(f + p * g1.^2 + g2.^2);
sol2 = fminsearch(J, x0);

这个 Stackoverflowpost 有同样的问题,但从另一个角度来看。根据这篇文章,以有效方式分配可能是一个问题。我尝试了几种不同的方法来解决我的问题。我试过 matlabFunction() 并将函数放在一个单独的文件中。

如果输入表达式包含符号变量,请改用 VPA 函数?

在此先感谢您的帮助。

4

1 回答 1

1

fminsearch专为数值最小化而设计。在这种情况下使用符号数学没有什么意义(它可以使用,但它会更慢,使你的代码复杂化,并且结果仍然是双精度的)。其次,如果您阅读文档并查看 的示例fminsearch,您会发现它需要一个接受单个向量输入的函数(与您的案例中的四个标量相反)。以下是使用匿名函数重写方程的方法:

f = @(x)x(1).^4 - x(3).^2 + x(1).*x(3) + x(2).*x(4) - 5*x(2) + 3;
g1 = @(x)x(1).^2 + x(2).^2 + x(3).^2 + x(4).^2 - 1;
g2 = @(x)x(1) + x(3) - 1;

x0 = [2 2 2 2];
p = 3;

J = @(x)f(x) + p*g1(x).^2 + g2(x).^2;
sol2 = fminsearch(J, x0)

这返回

sol2 =

  0.149070165097281   1.101372214292880   0.326920462283209  -0.231885482601008

使用符号数学和subs

syms x1 x2 x3 x4;

f = x1^4 - x3^2 + x1*x3 + x2*x4 - 5*x2 + 3;
g1 = x1^2 + x2^2 + x3^2 + x4^2 - 1;
g2 = x1 + x3 - 1;

x0 = [2 2 2 2];
p = sym(3);

J = @(X)subs(f + p*g1^2 + g2^2,[x1 x2 x3 x4],X);
sol2 = fminsearch(J, x0)

它返回相同的结果。

于 2015-09-22T14:15:51.567 回答