在Matlab中最大化函数(使用fsolve和衍生函数)

时间:2014-03-20 15:27:37

标签: matlab maximize derivative nonlinear-optimization

我想找到矢量p(即p(1),p(2),p(3),...)的值,它最大化函数A(p)

我正在使用MATLAB来做到这一点,我发现fsolve我认为它可以帮助我。所以我创建了函数A

function A = myfun(p)

    R  = 0.1; 
    u1 = 500;
    u2 = 400;
    u3 = 300;

    A = ( (p(1)+p(2)+p(3)) * (1/u1+1/u2+1/u3)) * ...
        (1 + R*(p(1)^2+p(2)^2+p(3)^2) * (1/u1+1/u2+1/u3) );

然后我需要解决一个方程组,它将是:

diff(A,p(1))==0

diff(A,p(2))==0

diff(A,p(3))==0

生成的p向量将成为我问题的解决方案。

fsolve如何解决这个方程组(p0=[1 1 1])?

1 个答案:

答案 0 :(得分:0)

以下是使用符号工具箱进行操作的示例:

%// (there's probably a way to generalize this as well)
dAdp = cellstr(char(...
    [char(diff('C * (p1+p2+p3) * (1 + R*C*(p1^2+p2^2+p3^2))', 'p1')) ';'],...
    [char(diff('C * (p1+p2+p3) * (1 + R*C*(p1^2+p2^2+p3^2))', 'p2')) ';'],...
    [char(diff('C * (p1+p2+p3) * (1 + R*C*(p1^2+p2^2+p3^2))', 'p3')) ';']))

%// convert to proper vector equation
dAdp = regexprep(dAdp, 'p([0-9])', 'p\($1\)');

%// convert to function handle
F = str2func( strcat('@(p) [', dAdp{:}, ']') );

但我不建议这样做(它完全不可读且容易出错)。

您可以编写一个正确的函数并使用符号工具箱评估上面的dAdp,但我也不建议这样做(它只是非常慢)。

我是一个数字人,因为我只相信计算机的构建原因:计算。我在纸上做的衍生,除了过于简单但冗长乏味的(你可以说这是一个例子,我仍然喜欢在纸上做,因为我也想锻炼我的大脑:)。

我建议你这样做,和/或使用符号工具箱不断检查自己。恕我直言,你应该将它用作援助,而不是作为主要引擎。

所以,我们走了。这是你的功能,这次是以不同的形式,应用了更多的大脑:

function A = myfun(p)    
    R = 0.1; 
    u = [500; 400; 300];     
    C = sum(1./u);
    B = C * sum(p) * (1 + R*C*sum(p.^2));

所以,你想要解决∇A( p )= 0 。最好的方法是应用更​​多的大脑。您可以验证矢量导数等于:

function F = Aprime(p)
    R = 0.1;
    u = [500; 400; 300];
    C = sum(1./u);
    F = C*( C*R*sum(p.^2) + 2*C*R*p*sum(p) + 1 );

你可以用更多大脑来解决:

C·( CR·Σp² + 2CR·p·Σp + 1 ) = 0
                Σp² + 2p·Σp = -1/(CR)
     

vector == scalar:这意味着p中的所有元素都相等   替换q = p1 = p2 = p3,然后

 3q² + 2q·3q = -1/(CR)
         9q² = -1/(CR)
     

⇒q=⅓·√(-1 /(CR))

(表示有问题)或fsolve如此:

fsolve(@Aprime, [1 1 1])

将立即导致

  

fsolve完成,因为函数值的向量在初始   通过函数的默认值测量,该点接近零   公差,并且问题看起来是正常的   梯度。

确实表明了麻烦。

既然你已经表明你对最大值感兴趣,并且函数看起来没有静止点,那么唯一的结论就是函数没有最大值而且没有最小值,除非你对 p强加了界限即可。实际上,如果你将维度降低到2,并制作一个情节:

R = 0.1;
u = [500; 400; 300];
C = sum(1./u);
B = @(p) C * sum(p) .* (1 + R*C*sum(p.^2));

[p1,p2] = meshgrid(-10:0.1:10);
surf(p1,p2,reshape(B([p1(:) p2(:)].'), size(p1)), 'edgecolor', 'none')

enter image description here

......没有极端。