更好地约束为方程式(硬)还是目标(软)?

时间:2019-12-19 05:00:30

标签: python nonlinear-optimization ipopt gekko

在Gekko中,基于梯度的优化器(APOPT,IPOPT)通常更容易解决将约束作为目标函数(最小化为零)或将其设置为等于零的方程式吗?我以Rosenbrock function为例。最优目标既可以设置为零(等式(硬约束),也可以最小化为零(软约束)。

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)

可能很难对所有问题一概而论,但是我对权衡取舍很感兴趣,尤其是对于一些约束可能是软约束,硬约束或两者兼而有之的大规模问题。对于Rosenbrock问题,结果几乎相同,但软约束方法的迭代次数最少。

Exact:  1 1
Soft:  0.99999999441 0.99999999029 Iterations: 23
Hard:  0.99969681373 0.99942834333 Iterations: 26
Both:  0.99988305657 0.99978643823 Iterations: 27

2 个答案:

答案 0 :(得分:2)

当可以找到可行的解决方案时,我会使用硬约束,而在难以找到可行的解决方案时或者在违反约束但可以阻止的情况下,我会使用软约束。硬约束方程式更适合于大规模应用,因为这些约束条件并未全部集中到一个目标函数值中。优化器使用来自方程式的梯度信息来找到可行解的搜索方向。为了进行比较,这里的scipy.optimize.minimize存在相同的问题。

from scipy.optimize import minimize
def f(z):
    x,y=z
    return (a-x)**2 + b*(y-x**2)**2
sol = minimize(f,[0,0])
print('Soft:',sol.x,'Iterations:',sol.nit)

def f(z):
    return 0
def con(z):
    x,y=z
    return (a-x)**2 + b*(y-x**2)**2
hard = {'type': 'eq', 'fun': con}
sol = minimize(f,[0,0],constraints=hard)
print('Hard:',sol.x,'Iterations:',sol.nit)

def f(z):
    x,y=z
    return (a-x)**2 + b*(y-x**2)**2
def con(z):
    x,y=z
    return (a-x)**2 + b*(y-x**2)**2
hard = {'type': 'eq', 'fun': con}
sol = minimize(f,[0,0],constraints=hard)
print('Both:',sol.x,'Iterations:',sol.nit)

第一种形式(软约束,目标函数)的迭代次数最少。

Exact:  1 1
Soft: [0.99999467 0.99998932] Iterations: 19
Hard: [0.99986205 0.99963916] Iterations: 22
Both: [1.00013127 1.00021689] Iterations: 23

答案 1 :(得分:2)

要回答有关Gekko中特定求解器的问题,您可以使用m.options.SOLVER=0来尝试所有可用的求解器并显示性能摘要。使用SOLVER=0时,没有解决方案返回给Gekko,因此存在try except块可以捕获的错误。

from gekko import GEKKO
from scipy.optimize import minimize

# Rosenbrock function
a=1; b=100
print('Exact: ',a,a**2)

try:
    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=0; m.solve(disp=True,debug=0)
except:
    pass

try:
    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=0; m.solve(disp=True,debug=0)
except:
    pass

try:
    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=0; m.solve(disp=True,debug=0)
except:
    pass

所有求解器(包括BPOPT)都采用硬约束方法成功。不会自动报告IPOPT迭代,因此我从求解器打印输出中提取了它。

 Solver      Variables Equations Res Evals Jac Evals Iter Info   Objective  Solution Time  Status
 ----------- --------- --------- --------- --------- ---- ---- ------------ ------------- ---------
 APOPT (v1.0)           2         1        30        26   26    0  0.00000E+00         0.065 Success
 BPOPT (v1.0)           2         1         0        18   17    0  0.00000E+00         0.004 Success
 IPOPT (v3.12)          2         1        22        17   15    0  0.00000E+00         0.019 Success
 --------------------------------------------------------------------------------------------------