0

グローバル最大化ツールボックスを使用して、次の関数を最大化しています。

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

ここで、 、、およびxの値を変更して最小化しています。これらは、 の値を評価する際に計算される他の関数に割り当てられる重みです。残りのパラメーターは、データを含む定数と構造体です。の値と3 つの重み変数は、構造体を介して関数に供給されるデータに依存します。 w1w2w3xx

重み変数 (つまり、オプティマイザーが最小化するために変更する変数) の 1 つを、最適化さxれている関数内から定数に変更する方法はありますか? 入力データが満たす条件によっては、w変数の 1 つを 0 に設定する必要がある場合があります。関数内からこれを行う方法はありますか?

簡単なステートメントを実行しようとしましたifが、オプティマイザーは問題の重みにゼロ以外の値を割り当てました。

編集:より具体的な例を次に示します。に関連付けられた関数w3が評価されるNaN場合があります (したがって、x の計算から除外する必要があります)。wその場合、最適化実行のその反復の変数に 0 を割り当てたいと思います。

現在、の計算から にif関連付けられている関数を除外する目的関数に単純なステートメントがありますが、オプティマイザーは関係なく に値を割り当てます。 w3xw3

4

1 に答える 1

1

wドロップしたい が見つかったら、すぐに検索を中止できます。この場合、残りの で最適化を再開しwます。

現在無視されているものを追跡するには、ステート マシンを使用できます。次の不完全なコードはw123、すべての変数、変数w12のみw1などの状態を示してw2います。matlab クラスを使用する代わりに、単純な構造体を使用しています。関数呼び出しに必要な this/self 変数を書き出しています。これは、matlab クラスを書きたいかどうかわからないためです。

オプティマイザーを停止および開始する際のオーバーヘッドが重要ではないほど、計算のコストが十分に高いと単純に想定しています。

欠落している状態の実装は、読者の課題として残されています。

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

w123.description='w1, w2, w3';
w123.getStartvalues=@(w) w; % identity
w123.get_w=@(p) p; % identity
w123.getTargetfunction=@(x) NameOfFunction(x, Parameters);
w123.ignore_w1=@(state) state.w23;
w123.ignore_w2=@(state) state.w13;
w123.ignore_w3=@(state) state.w12;

w12.description='w1, w2, 0';
w12.getStartvalues=@(w) [w(1), w(2)];
w12.get_w=@(p) [p(1), p(2), 0];
w12.getTargetfunction=@(x) NameOfFunction([x(1), x(2), 0], Parameters);
w12.ignore_w1=@(state) state.w2;
w12.ignore_w2=@(state) state.w1;
w12.ignore_w3=@(state) state.w12; % w3 is already ignored

w13.description='w1, 0, w3';
w13.getStartvalues=@(w) [w(1), w(3)];
w13.get_w=@(p) [p(1), 0, p(2)];
w13.getTargetfunction=@(x) NameOfFunction([x(1), 0, x(2)], Parameters);
w13.ignore_w1=@(state) state.w3;
w13.ignore_w2=@(state) state.w13; % w2 is already ignored
w13.ignore_w3=@(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
state.ignore_w1=@(s) s.current.ignore_w1(s);
state.ignore_w2=@(s) s.current.ignore_w2(s);
state.ignore_w3=@(s) s.current.ignore_w3(s);
state.getTargetfunction=@(s) s.current.getTargetfunction;
state.getStartvalues=@(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
于 2013-07-15T18:18:43.337 に答える