文章目录
安装
- 环境: ubuntu 21.04 + python 3.9.5(其实对于这个而言的话ubuntu / windows 以及 python的版本应该是不会对结果造成任何影响的)
整个求解是基于Python的pyomo建模平台的,因此首先先安装pyomo,然后在基于pyomo使用开源的ipopt进行求解
安装 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