2013-07-15 2 views
0

Я использую глобальную максимизацию инструментов для максимизации следующей функции:Изменение переменной оптимизации для постоянной Динамически (Matlab)

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

где я минимизируя x путем изменения значения w1, w2 и w3, который являются весами, которые назначаются другим функциям, рассчитанным при оценке значения x. Остальные параметры - это константы и структуры, содержащие данные. Значение x, а также три весовые переменные зависят от данных, которые передаются в функцию через структуры.

Есть ли способ изменить одну из весовых переменных (т. Е. Переменные, которые оптимизатор изменяет, чтобы свести к минимуму x) константе изнутри оптимизируемой функции? Иногда, в зависимости от условий, удовлетворяемых входными данными, одна из переменных w должна быть установлена ​​равной 0. Есть ли способ сделать это изнутри функции?

Я пробовал сделать простой оператор if, но оптимизатор все еще присвоил ненулевое значение рассматриваемому весу.

EDIT: Вот более конкретный пример. Иногда функция, связанная с w3, будет оцениваться до NaN (и поэтому ее следует исключить из расчета x). Когда это произойдет, я хотел бы присвоить 0 переменной w для этой итерации цикла оптимизации.

В настоящее время у меня есть простой if заявления в целевой функции, которая исключает функцию, связанную с w3 из расчета x, но оптимизатор присваивает значение w3 независимо.

+1

В какой момент времени вы знаете, хотите ли вы исключить переменную 'w'? Это до того, как вы назовите оптимизатор или только после того, как оптимизатор работает некоторое время? – mars

+0

@mars: Это ты для своего ответа. Я знаю, что могу контролировать, выходит ли «w3' за пределы оптимизатора (а затем установите верхнюю и нижнюю границы« w3 »в 0 перед запуском), но это решение не идеально. Мне интересно, есть ли способ установить переменную 'w3' в константу после запуска оптимизатора. –

ответ

1

Вы можете прервать поиск, как только вы столкнулись с w, который вы хотите удалить. В этом случае возобновите оптимизацию с остальными w.

Чтобы отслеживать то, что в настоящее время игнорируется, вы можете использовать state machine. Следующий неполный код показывает состояния w123 для всех переменных, w12 только для w1 и w2 и так далее. Вместо использования классов matlab я использую простые структуры, выписывая эту переменную/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 
Смежные вопросы