整个求解是基于Python的pyomo建模平台的,因此首先先安装pyomo,然后在基于pyomo使用开源的ipopt进行求解
!pip install pyomo # 安装 pyomo # Download ipopt-linux64 !wget "https://ampl.com/dl/open/ipopt/ipopt-linux64.zip" !unzip ipopt-linux64.zip # 解压后得到 ipopt 文件夹,里面有 ipopt 执行文件
以最基础的一个非线性求解问题来看
m i n f ( x ) = x 1 2 + x 2 2 s . t . − x 1 2 + x 2 < = 0 x 1 + x 2 = 2 \begin{aligned} min \quad &f(x) = x_1^2 + x_2^2 \\ s.t. \quad &-x_1^2 + x_2 <=0 \\ & x_1 + x_2 = 2 \end{aligned} mins.t.f(x)=x12+x22−x12+x2<=0x1+x2=2
from pyomo.environ import * path = '~/Documents/ipopt/ipopt' # 这里的 path 指的就是刚刚 ipopt 执行文件的路径 model = ConcreteModel() # 创建模型对象 # define model variables # domain = Reals(Default) / NonNegativeReals Binary model.x1 = Var(domain=Reals) model.x2 = Var(domain=Reals) # define objective function # sense = minimize(Default) / maximize model.f = Objective(expr = model.x1**2 + model.x2**2, sense=minimize) # define constraints, equations or inequations model.c1 = Constraint(expr = -model.x1**2 + model.x2 <= 0) model.ceq1 = Constraint(expr = model.x1 + model.x2**2 == 2) # use 'pprint' to print the model information model.pprint()
得到输出如下:
2 Var Declarations x1 : Size=1, Index=None Key : Lower : Value : Upper : Fixed : Stale : Domain None : None : None : None : False : True : Reals x2 : Size=1, Index=None Key : Lower : Value : Upper : Fixed : Stale : Domain None : None : None : None : False : True : Reals 1 Objective Declarations f : Size=1, Index=None, Active=True Key : Active : Sense : Expression None : True : minimize : x1\**2 + x2**2 2 Constraint Declarations c1 : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : - x1\**2 + x2 : 0.0 : True ceq1 : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : 2.0 : x1 + x2**2 : 2.0 : True 5 Declarations: x1 x2 f c1 ceq1
然后使用 SolverFactory
函数进行求解:
SolverFactory('ipopt', executable=path).solve(model).write()
此处 ipopt
还可以换成别的求解器,例如cbc
等等,可以对不同求解器的性能进行横向的比较,在此我就不展开了
求解后得到结果如下:
# ========================================================== # = Solver Results = # ========================================================== # ---------------------------------------------------------- # Problem Information # ---------------------------------------------------------- Problem: - Lower bound: -inf Upper bound: inf Number of objectives: 1 Number of constraints: 2 Number of variables: 2 Sense: unknown # ---------------------------------------------------------- # Solver Information # ---------------------------------------------------------- Solver: - Status: ok Message: Ipopt 3.12.13\x3a Optimal Solution Found Termination condition: optimal Id: 0 Error rc: 0 Time: 0.011124610900878906 # ---------------------------------------------------------- # Solution Information # ---------------------------------------------------------- Solution: - number of solutions: 0 number of solutions displayed: 0
除此之外,我们还能对模型中的内容进行查看和打印:
print('optimal f: {:.4f}'.format(model.f())) print('optimal x: [{:.4f}, {:.4f}]'.format(model.x1(), model.x2()))
得到
optimal f: 2.0000 optimal x: [1.0000, 1.0000]
上述内容参考了 Jeffrey Kantor 的 Github 内容:
ND Pyomo Cookbook