使用fmincon matlab时出错

时间:2015-02-06 14:05:03

标签: matlab optimization

我想用fmincon解决一个简单的问题,但它返回一条错误信息。 我有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'。

  

如果F_index == 1

,myfun(第2行)出错      

fmincon出错(第564行)         initVals.f =         feval(funfcn {3},X,varargin {:});

     

主要错误(第6行)         [X,FVAL] = fmincon(@ myfun,XO,AA,BB,[],[],VLB,VUB)          引起:       初始用户提供的目标失败       功能评估。 FMINCON无法继续。

3 个答案:

答案 0 :(得分:3)

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

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

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中,可以访问其变量。

答案 1 :(得分:1)

您可以使用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

答案 2 :(得分:0)

您需要了解变量输入/输出功能。

实际上,在任何编程语言中,当您输入函数时,该函数只能访问在内部创建的变量,或者作为参数传递的变量xy,{{1在下一个示例中{}}和zpotato

这意味着:

myfun(x,y,z, potato)

myfun不知道function f = myfun(x) if F_index == 1 f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2 ; end end 是什么。

解决问题的方法之一就是将F_index声明为F_index,但我建议您不要以某种方式更改函数,因此它无法访问函数变量。