Как правило, оптимизатору на основе градиента (APOPT, IPOPT) в Gekko проще решить ограничение как целевую функцию (минимизировать до нуля) или как уравнение, в котором оно установлено равным нулю? В качестве примера я установил функцию Rosenbrock. Оптимальная цель может быть установлена равной нулю как уравнение (жесткое ограничение) или минимизировано до нуля (мягкое ограничение).
from gekko import GEKKO
a=1; b=100
print('Exact: ',a,a**2)
m = GEKKO(remote=False)
x = m.Var(0); y=m.Var(0);
m.Minimize((a-x)**2 + b*(y-x**2)**2)
m.options.SOLVER=1; m.solve(disp=False)
print('Soft: ',x.value[0],y.value[0],'Iterations:',m.options.ITERATIONS)
m = GEKKO(remote=False)
x = m.Var(0); y=m.Var(0);
m.Equation((a-x)**2 + b*(y-x**2)**2==0)
m.options.SOLVER=1; m.solve(disp=False)
print('Hard: ',x.value[0],y.value[0],'Iterations:',m.options.ITERATIONS)
m = GEKKO(remote=False)
x = m.Var(0); y=m.Var(0);
m.Minimize((a-x)**2 + b*(y-x**2)**2)
m.Equation((a-x)**2 + b*(y-x**2)**2==0)
m.options.SOLVER=1; m.solve(disp=False)
print('Both: ',x.value[0],y.value[0],'Iterations:',m.options.ITERATIONS)
Это может быть слишком сложно обобщить для всех проблем, но меня интересуют компромиссы, особенно для крупномасштабных задач, где некоторые из ограничений могут быть мягкими, жесткими или и тем, и другим. Для задачи Розенброка результаты почти идентичны, но метод мягких ограничений имеет наименьшее количество итераций.
Exact: 1 1
Soft: 0.99999999441 0.99999999029 Iterations: 23
Hard: 0.99969681373 0.99942834333 Iterations: 26
Both: 0.99988305657 0.99978643823 Iterations: 27