2015-02-06 234 views
1

我想解決fmincon的一個簡單問題,但它會返回一條錯誤消息。 我有2個函數f_2和f_1,我想單獨將它們各自最小化。我想在一個matlab函數中編寫f_1和f_2,即我的fun.m.然後我想使用主代碼中的索引來調用它們中的每一個。下面是代碼,你可以看到:使用fmincon matlab的錯誤

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_索引'。

錯誤myfun(線2)如果F_索引== 1

錯誤fmincon(線564) initVals.f = feval(funfcn {3},X,varargin {:});在初始用戶提供 失敗:在主(第6行)

錯誤 [X,FVAL] = fmincon(@ myfun,XO,AA,BB,[],[],VLB,VUB) 引起客觀的 功能評估。 FMINCON無法繼續。

+1

感謝您的編輯!好的,在這種情況下,最簡單的解決方案是定義不同的函數,'myfun1','myfun2'等等。但我更新後的答案中概述的解決方案也應該起作用。請注意,它最好使用'switch'語句而不是一系列'if's。 – 2015-02-06 14:36:32

回答

3

錯誤消息明確指出問題:變量F_index在函數myfun中未定義。 Matlab中的變量有一個範圍侷限於定義它們的函數(或者說「工作空間」)。他們可以成爲「全球」,但這通常不是你想要做的。

一種解決方法是使用嵌套函數,其中包含函數的變量在嵌套函數可用:

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並訪問其變量。

+0

但是我想'如果'我有3個函數實際上並且想要以這種方式對它們進行優化。 @一個。 Donda – 2015-02-06 14:21:55

+0

@Jamaisavenir,我不確定我明白你的意思。請編輯您的問題,並加入一些與您的實際應用程序更接近的代碼,以便我們能夠更好地瞭解如何爲您提供幫助。 – 2015-02-06 14:26:59

+0

@Jamaisavenir,我編輯了我的答案,請看這是否是你需要的。 – 2015-02-06 14:30:09

0

您需要了解變量輸入/輸出函數。

幾乎任何編程語言,當你輸入一個函數,該函數只能訪問創建中,或者被作爲參數,如下面的例子中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_indexglobal,但我會建議你改變函數,所以它不會訪問函數變量。

+0

但是你想使用'if'語句,這樣我就可以單獨優化所有的f1,f2,f3 ...。 @Ander Biguri – 2015-02-06 14:24:25

1

可以使用anonymous functions綁定額外的參數:

fmincon(@(x) myfun(x, F_index), ...) 

這裏,F_索引的價值進行評估,變成匿名函數的一部分。

但是,這些看起來像完全獨立的功能。爲什麼不把它們全部分開,並且爲迭代使用一個單元陣列的句柄?

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