Исследуйте решение оптимизации

Получите числовое решение

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

Для примера решите задачу линейного программирования в двух переменных.

x = optimvar('x');
y = optimvar('y');
prob = optimproblem;
prob.Objective = -x -y/3;
prob.Constraints.cons1 = x + y <= 2;
prob.Constraints.cons2 = x + y/4 <= 1;
prob.Constraints.cons3 = x - y <= 2;
prob.Constraints.cons4 = x/4 + y >= -1;
prob.Constraints.cons5 = x + y >= 1;
prob.Constraints.cons6 = -x + y <= 2;

sol = solve(prob)
Solving problem using linprog.

Optimal solution found.

sol = 

  struct with fields:

    x: 0.6667
    y: 1.3333

Предположим, что вам нужно значение целевой функции в решении. Можно перезапустить задачу, на этот раз запросив значение целевой функции и решение.

[sol,fval] = solve(prob)
Solving problem using linprog.

Optimal solution found.

sol = 

  struct with fields:

    x: 0.6667
    y: 1.3333


fval =

   -1.1111

Кроме того, для трудоемкой задачи экономьте время, вычисляя целевую функцию в решении используя evaluate.

fval = evaluate(prob.Objective,sol)
fval =

   -1.1111

Исследуйте качество решения

Чтобы проверить, является ли представленное решение точным, можно просмотреть выходы solve. Верните все solve выходы

[sol,fval,exitflag,output,lambda] = solve(prob);
  • Проверьте выходной флаг. exitflag = OptimalSolution обычно означает, что solve сходился к решению. Для объяснения другого exitflag значения, см. exitflag.

  • Проверьте выходное сообщение в командной строке или в структуре output. Когда выходное сообщение утверждает, что решатель сходился к решению, то обычно решение надежно. Это сообщение соответствует exitflag = OptimalSolution.

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

Недопустимое решение

Если solve сообщает, что ваша проблема недопустима (выходной флаг NoFeasiblePointFound), исследуйте недопустимость проблемы в различных точках, чтобы увидеть, какие ограничения могут быть чрезмерно ограничительными. Предположим, что у вас есть одна переменная непрерывной оптимизации с именем x который имеет конечные ограничения для всех компонентов, и у вас есть ограничения constr1 через constr20.

N = 100; % check 100 points
infeas = zeros(N,20); % allocate
L = x.LowerBound;
U = x.UpperBound;
S = numel(L);
pthist = cell(N);
for k = 1:N
    pt = L + rand(size(L)).*(U-L);
    pthist{k} = pt;
    for j = 1:20
        infeas(k,j) = infeasibility(['constr',num2str(j)],pt);
    end
end

Результат infeas(a,b) имеет ненулевые значения везде, где связана точка pt{a} недопустимо для ограничения b.

Решение занимает слишком много времени

Если solve занимает много времени, есть несколько возможные причины и исправления.

  • Формулировка задачи медленная. Если вы определили выражения цели или ограничений во вложенных циклах, то solve может занять много времени, чтобы преобразовать задачу внутри в матричную форму. Чтобы ускорить решение, попробуйте сформулировать свои выражения векторизованным способом. См. «Создание эффективных задач оптимизации».

  • Смешано-целочисленное решение задачи линейного программирования медленно. Иногда можно ускорить целочисленную задачу, установив опции. Можно также переформулировать задачу, чтобы она быстрее решалась. См. Раздел «Настройка целочисленного линейного программирования»

  • Решение нелинейного программирования медленно. Для предложений смотрите Решатель Принимает Слишком Долго. Для получения дополнительных предложений см. Раздел «Когда решатель отказывает»

  • Превышен предел решателя. Чтобы решить некоторые проблемы, solve может взять больше, чем количество шагов решения по умолчанию. Для задач с целочисленными ограничениями увеличьте количество разрешенных шагов, увеличив LPMaxIterations, MaxNodes, MaxTime, или RootLPMaxIterations опции для значений выше, чем по умолчанию. Чтобы задать эти опции, используйте optimoptions('intlinprog',...). Для нецелочисленных задач увеличьте MaxIterations опция с использованием optimoptions('linprog','MaxIterations',...). См. options.

См. также

| |

Похожие темы