2013-07-15 78 views
0

我使用的是全球最大化工具箱最大化以下功能:改變優化變量,以恆動態(Matlab的)

function x = NameOfFunction (w1, w2, w3, a, b, c, Structure1, Structure2, Structure3) 

在那裏,我通過改變w1w2值減少xw3,這是分配給在評估x的值時計算的其他函數的權重。其餘參數是包含數據的常量和結構。 x的值以及三個權重變量取決於通過結構輸入函數的數據。

有沒有辦法將權重變量之一(即優化器改變爲最小化x的變量)更改爲正在優化的函數中的常量?有時候,根據輸入數據所符合的條件,w變量之一需要設置爲0.有沒有一種方法可以在函數內部完成此操作?

我試着做一個簡單的if語句,但優化器仍然爲所討論的權重指定了一個非零值。

編輯:這是一個更具體的例子。有時,與w3相關的功能將評估爲NaN(因此應該從x的計算中排除)。發生這種情況時,我想爲優化運行的迭代分配一個0到w變量。

目前,我有目標函數,將排除與w3x計算相關的函數的簡單if說法,但不管優化分配一個值w3

+1

在什麼時間點你知道你是否想排除'w'變量?是在你調用優化器之前,還是在優化器運行一段時間之後? – mars

+0

@mars:給你回覆。我知道我可以控制'w3'是否脫離優化器(然後在運行之前將'w3'的上限和下限設置爲0),但是這種解決方案並不理想。我想知道是否有一種方法可以在優化器開始運行後將'w3'變量設置爲常量。 –

回答

1

只要遇到要刪除的w,就可以立即中止搜索。在這種情況下,請繼續使用剩餘的w進行優化。

要跟蹤目前被忽略的內容,您可以使用state machine。以下不完整代碼顯示所有變量的狀態w123,僅w1w2等的w12。我沒有使用matlab類,而是使用普通結構,寫出函數調用所需的this/self變量,因爲我不知道是否要編寫matlab類。

我只是簡單地假設你的計算是足夠昂貴的,所以停止和啓動優化器的開銷並不重要。

執行缺失的狀態留給讀者練習。

% file so.m (so for stack overflow) 
function so 
Parameters=0; 

w123.description='w1, w2, w3'; 
[email protected](w) w; % identity 
[email protected](p) p; % identity 
[email protected](x) NameOfFunction(x, Parameters); 
[email protected](state) state.w23; 
[email protected](state) state.w13; 
[email protected](state) state.w12; 

w12.description='w1, w2, 0'; 
[email protected](w) [w(1), w(2)]; 
[email protected](p) [p(1), p(2), 0]; 
[email protected](x) NameOfFunction([x(1), x(2), 0], Parameters); 
[email protected](state) state.w2; 
[email protected](state) state.w1; 
[email protected](state) state.w12; % w3 is already ignored 

w13.description='w1, 0, w3'; 
[email protected](w) [w(1), w(3)]; 
[email protected](p) [p(1), 0, p(2)]; 
[email protected](x) NameOfFunction([x(1), 0, x(2)], Parameters); 
[email protected](state) state.w3; 
[email protected](state) state.w13; % w2 is already ignored 
[email protected](state) state.w1; 

% ... and so on for w23, w1, w2, w3 

% ... fill in all the states from above 
state.w123=w123; 
state.w12=w12; 
state.w13=w13; 
state.current=state.w123; % initial state 
[email protected](s) s.current.ignore_w1(s); 
[email protected](s) s.current.ignore_w2(s); 
[email protected](s) s.current.ignore_w3(s); 
[email protected](s) s.current.getTargetfunction; 
[email protected](s, w) s.current.getStartvalues(w); 

% Startvalues for w 
initial_w=[1, 2, 3]; 

% Don't lose the intermediate result 
w_before_abort=initial_w; 

best_w=initial_w; 
while true 
    try 
     fprintf('Starting an optimization run using %s\n', state.current.description); 
     best_fit=fminsearch(state.getTargetfunction(state), state.getStartvalues(state,best_w)); 
     best_w=state.get_w(state, best_fit); 
     break; 
    catch event 
     if strcmp(event.identifier, 'NameOfFunction:ignore_w1') 
      state.current = state.ignore_w1(state); 
     elseif strcmp(event.identifier, 'NameOfFunction:ignore_w2') 
      state.current = state.ignore_w2(state); 
     elseif strcmp(event.identifier, 'NameOfFunction:ignore_w3') 
      state.current = state.ignore_w3(state); 
     else 
      event.stack(1) 
      throw(event); 
     end 
     best_w=w_before_abort; 
    end 
end 
best_w 


% Nested function; watch out for name collisions in the enclosing namespace 
% w_before_abort is intentional, everything else is not. 
function x=NameOfFunction(w, Parameters) 
    % debug output: 
    w1=w(1) 
    w2=w(2) 
    w3=w(3) 

    % run this code if you want to ignore w1: 
    w_before_abort=w; % save the last inspected w 
    throw(MException('NameOfFunction:ignore_w1', 'Set w1 to zero.')); 

    % run this code if you want to ignore w2: 
    w_before_abort=w; % save the last inspected w 
    throw(MException('NameOfFunction:ignore_w2', 'Set w2 to zero.'));  
end 

end