Сделайте определенное изменение шага с помощью функции fmincon MATLAB

Я использую набор инструментов оптимизации "fmincon" MATLAB, но у меня возникла следующая проблема:

У меня есть 6 параметров для изменения, пара из них чаще всего варьируется в четных числах, от 4 до 16 (эти значения могут варьироваться, но всегда будут варьироваться в четных числах). Итак, давайте определим их так:

x1=[4:2:16];
x2=[4:2:16];

Еще пара переменных должна изменяться между 300 и 1500 с шагом 100, я имею в виду:

x3=[300:100:1500];
x4=[300:100:1500];

Последняя пара просто варьируется от 4 до 6, например:

x5=4:6;
x6=4:6;

Ограничение параметров таково:

x1<=x2
x3<=x4
x5<=x6

Здесь очень важно то, что вариация, которая создает fmincon, не может вносить небольшие изменения, я имею в виду, что первое значение x1, равное 4, не может быть 4.0000000001, потому что в моей целевой функции эти изменения не будут иметь никакого значения; и в этом моя проблема, потому что шагов слишком мало, поэтому вариация ничего не даст, и алгоритм останавливается, говоря, что вариации целевой функции нет.

Я установил fmincon, DiffMinChange=1, и это работает для первой итерации, и они начинают делать слишком маленькие шаги. Это начальная конфигурация для fmincon:

options1 = optimset('Display','iter',...
    'Algorithm','sqp','PlotFcns',@optimplotfval,...
    'MaxIter',400,'MaxFunEvals',2000,'DiffMinChange',1);

Первоначальные ограничения:

A=[1 -1 0 0 0 0;0 0 1 -1 0 0;0 0 0 0 1 -1];
b=[0;0;0];

Чтобы быть более ясным, я ищу создание 3 диапазонов, позволяющих определить их следующим образом:

R1=[x1:2:x2];
R2=[x3:100:x4];
R3=[x5:x6];

РЕДАКТИРОВАТЬ 1: Вы можете знать, что каждая оценка целевой функции займет около 2-3 часов.

Как видите, наконец то, что я ищу, это вариация интервала, по этой причине лимит в начале не может быть больше лимита в топе, иначе ранг будет пустым.


person lisandrojim    schedule 02.10.2014    source источник


Ответы (3)


Ну, это не касается того, как заставить fmincon уважать эти ограничения, а просто потенциальная мысль...

Учитывая диапазоны, которые вы хотите, у вас есть пространство 7x7x13x13x3x3 возможных комбинаций переменных, что составляет в общей сложности ~ 75000 комбинаций, прежде чем вы ограничитесь до x1‹=x2, x3‹=x4, x5‹=x6. Это небольшое пространство — почему бы просто не оценить целевую функцию при каждой комбинации параметров, а затем использовать min, чтобы найти минимум вашей целевой функции?

person KevinMc    schedule 03.10.2014
comment
Примечание - я могу неправильно понять, и может быть полезно опубликовать ваш фактический вызов fmincon и вашу фактическую целевую функцию, чтобы мы могли видеть, что происходит. - person KevinMc; 03.10.2014
comment
Спасибо за ваш ответ, но я не могу дать целевую функцию, кроме того, это не очень хорошее решение, потому что для каждой итерации целевая функция займет около 2-3 часов, чтобы сделать только одну (1) итерацию, так что это решение займет около 17 лет, чтобы сделать все возможные комбинации. - person lisandrojim; 03.10.2014

Поскольку fmincon является оптимизатором непрерывных задач, а ваша проблема является дискретной, существует несоответствие между подходом к проблеме и решению, см., например, вики.

Вы можете попробовать дискретный решатель оптимизации, такой как branch andbound. Поскольку количество точек в вашей возможной области весьма ограничено, подход грубой силы также может работать (зависит от времени, необходимого вашей целевой функции). Что-то вроде этого должно работать для вашей целевой функции fun:

lb = [4 4 300 300 4 4]; % lower bound
st = [2 2 100 100 1 1]; % step size
ub = [16 16 1500 1500 6 6]; % upoper bound

% init the best solution as infinity
bestF = inf;
bestX = nan(6,1);

% construct all permutations
for idx = 1:numel(lb)
    % construct range
    nextRange = (lb(idx):st(idx):ub(idx))';
    if (idx==1)
        permutations = nextRange;
    else
        a = repmat(permutations,numel(nextRange),1);
        b = repmat(nextRange,1,size(permutations,1))';
        permutations = [a,b(:)];
    end
    % remove permutations that do not satisfy constraints
    if (idx==2)
        permutations(permutations(:,1) > permutations(:,2),:) = [];
    end
    if (idx==4)
        permutations(permutations(:,3) > permutations(:,4),:) = [];
    end
    if (idx==6)
        permutations(permutations(:,5) > permutations(:,6),:) = [];
    end
end

N = size(permutations,1);

assert(N == 7*4 * 13*7 * 6)

for idx = 1:N
    candX = permutations(idx,:)';
    % evaluate ...
    candF = fun(candX);
    % ... and if improvement, update best
    if (candF < bestF)
        bestF = candF;
        bestX = candX;
    end
end

% results
bestF
bestX

Количество перестановок равно 15288, поэтому, если вашей целевой функции fun требуется 0,1 секунды (что довольно много ;)), вам придется ждать ответа 25 минут.

person MeMyselfAndI    schedule 03.10.2014
comment
Я вижу, что у KevinMc была такая же идея, почти одновременно;) - person MeMyselfAndI; 03.10.2014

Я читал много форумов, и нашел очень интересное решение, я попробовал, и на самом деле оно работает довольно хорошо. Я обнаружил, что между целевыми функциями есть некоторые различия. Здесь я пытался использовать fmincon, но эта функция работает только для целевых функций, которые изменяются во всем диапазоне, другими словами, дифференцируемы во всем диапазоне. Но здесь есть разница, потому что эта функция работает только с некоторыми конкретными значениями, и целевая функция будет той же, если вариация незначительна; другими словами, не является дифференцируемым во всем диапазоне. Что я обнаружил, так это то, что в MATLAB есть функция, называемая «поиск по шаблону», и я попробовал и получил замечательные результаты. Она очень похожа на fmincon, но работает по-другому. Я рекомендую это для такого рода проблем.

person lisandrojim    schedule 12.10.2014