Modeling Nonlinear Problems¶
This section illustrates differences between SimpleModel and regular Pyomo models on a simple nonlinear problem. PuLP is omitted from this comparison because it cannot represent nonlinear problems.
Soda Can Problem¶
Finding the optimal dimensions of a soda can is a simple nonlinear optimization problem. We consider an idealized soda can that is represented as a cylinder with radius r and height h. The problem is to find the radius and height that minimizes the surface area of the cylinder while keeping a fixed volume. Here, the surface area of the cylinder approximates the amount of aluminum needed for a soda can, so this problem can be used to predict the miminum amount of aluminum needed to hold a given volume.
The surface area of a cylinder is
A standard soda can is 12 oz or 355 ml. Thus, we have the constraint
Thus, we have the following optimization representation for this problem:
This is a nonlinear problem, so it cannot be formulated with PuLP. The following sections illustrate how this optimization problem can be formulated and solved with SimpleModel and Pyomo.
SimpleModel Formulation¶
The following script executes the following steps to create and solve the soda can problem:
- Import
pyomo_simplemodel
- Construct a
SimpleModel
class - Declare variables, the objective and the constraint
- Perform optimization
- Summarize the optimal solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # sodacan.py
from pyomo_simplemodel import *
from math import pi
m = SimpleModel()
r = m.var('r', bounds=(0,None))
h = m.var('h', bounds=(0,None))
m += 2*pi*r*(r + h)
m += pi*h*r**2 == 355
status = m.solve("ipopt")
print("Status = %s" % status.solver.termination_condition)
print("%s = %f" % (r, value(r)))
print("%s = %f" % (h, value(h)))
print("Objective = %f" % value(m.objective()))
|
In this example, the model object m
is used to manage the problem
definition. Decision variables are declared with the var()
method, the objective and constraint are added with the +=
operator,
and the solve()
method is used to perform optimization. After
optimization, the solution is stored in the variable objects, and
the objective value can be accessed with using the objective()
method.
Pyomo Formulation¶
The following script executes the same steps as above to create and solve the soda can problem using Pyomo:
# sodacan-pyomo.py
from pyomo.environ import *
from math import pi
m = ConcreteModel()
m.r = Var(bounds=(0,None))
m.h = Var(bounds=(0,None))
m.o = Objective(expr=2*pi*m.r*(m.r + m.h))
m.c = Constraint(expr=pi*m.h*m.r**2 == 355)
solver = SolverFactory('ipopt')
status = solver.solve(m)
print("Status = %s" % status.solver.termination_condition)
print("%s = %f" % (m.r, value(m.r)))
print("%s = %f" % (m.h, value(m.h)))
print("Objective = %f" % value(m.o))
This script is similar to the SimpleModel script, but
Pyomo models are created with an object-oriented design. Thus,
elements of the optimization problem are declared with variable,
objective and constraint components, which are Pyomo objects. As
a consequence, the objective and constraint expressions reference
variable components within the model (e.g. m.x
) instead of
variable objects directly (e.g. x
).