使用 fmincon matlab 时出错

Error using fmincon matlab

我想用 fmincon 解决一个简单的问题,但它 returns 出现错误消息。 我有 2 个函数 f_2 和 f_1,我想分别最小化它们中的每一个。我想在一个 matlab 函数中编写 f_1 和 f_2,即我的 fun.m。然后我想使用主代码中的索引调用它们中的每一个。这是您可以看到的代码:

main code: 
 AA=[1 2 -1 -0.5 1];bb=-2;
      xo=[1 1 1 1 1]; 
      VLB=[-1 -1 -1 -1 -1]; 
      VUB=[100 100 100 100 100]; 
  for F_index = 1:2

      [x,fval]=fmincon(@myfun,xo,AA,bb,[],[],VLB,VUB)
      end

%%这里是函数

function f = myfun(x, F_index) 
 if F_index == 1
   f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2  ;
 end 
 if F_index == 2
  f = 100*(x(3) - x(5)) + (3*x(1)+2*x(2) - x(3)/3)^2 + 0.01*(x(4) - x(5))
 end 

未定义函数或变量'F_index'。

Error in myfun (line 2) if F_index == 1

Error in fmincon (line 564) initVals.f = feval(funfcn{3},X,varargin{:});

Error in main (line 6) [x,fval]=fmincon(@myfun,xo,AA,bb,[],[],VLB,VUB) Caused by: Failure in initial user-supplied objective function evaluation. FMINCON cannot continue.

您需要了解变量 in/out 函数。

实际上在任何编程语言中,当您输入一个函数时,该函数只能访问在内部创建的变量,或者作为参数传递的变量,如 xyzpotato 在下一个示例中:myfun(x,y,z, potato).

这意味着在:

function f = myfun(x) 
 if F_index == 1
   f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2  ;
 end 
end 

myfun 不知道 F_index 是什么。

解决它的方法之一是将 F_index 声明为 global,但我建议您以某种方式更改函数,这样它就不会访问函数外的变量。

错误消息清楚地说明了问题:变量F_index 在函数myfun 中未定义。 Matlab 中的变量的范围仅限于定义它们的函数(或者更确切地说 "workspace")。可以制作它们 "global",但这不是您通常想要做的事情。

解决方法是使用嵌套函数,其中封闭函数的变量在嵌套函数中变得可用:

function main_function
    AA=[1 2 -1 -0.5 1];bb=-2;
    xo=[1 1 1 1 1]; 
    VLB=[-1 -1 -1 -1 -1]; 
    VUB=[100 100 100 100 100]; 
    F_index = 1;

    for F_index = 1:2
        [x,fval]=fmincon(@myfun,xo,AA,bb,[],[],VLB,VUB)
    end

    function f = myfun(x) 
       if F_index == 1
           f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2  ;
       end
       if F_index == 2
           f = 100*(x(3) - x(5)) + (3*x(1)+2*x(2) - x(3)/3)^2 + 0.01*(x(4) - x(5))
       end
    end 
end

现在 myfun 嵌套在 main_function 中并且可以访问它的变量。

您可以使用 anonymous functions:

绑定额外参数
fmincon(@(x) myfun(x, F_index), ...)

这里,F_index的值被求值,成为匿名函数的一部分。

但是,这些看起来像是完全独立的函数。为什么不将它们完全分开,并使用句柄元胞数组进行迭代?

fcns = {@fun1, @fun2};
for F_index = 1:2
    [x,fval]=fmincon(fcns{F_index},xo,AA,bb,[],[],VLB,VUB)
end