This file illustrates the effect of a non-convex feasible region in a variation of the WYNDOR Glass Company example given in Hillier and Lieberman, Section 13.2.

We use the Ipopt solver backend which can handle nonlinear constraints and nonlinear objective functions.

In [1]:
from pyomo.environ import *
from pyomo.opt import *
opt = solvers.SolverFactory("ipopt")
model = ConcreteModel()

For non-convex problems such as this, there may be several local optima and the solver may return a local optimum which is not a global optimum. The solution which gets returned depends on the initial value.

For this problem, the default initialization happens to converge to the global maximum at $x=0$ and $y=7$. However, other initial values result in convergence to the local maximum $x=4$ and $y=3$.

In the code below, we pass an explicit initial value for the search to each of the decision variables.

In [2]:
model.x = Var(within=NonNegativeReals, initialize=3.0)
model.y = Var(within=NonNegativeReals, initialize=2.0)

model.c1 = Constraint(expr = model.x <= 4)
model.c2 = Constraint(expr = 2*model.y <= 14)
model.c3 = Constraint(expr = 8*model.x - model.x**2 + 
                      14*model.y - model.y**2 <= 49)

model.z = Objective(expr = 3*model.x + 5*model.y, sense=maximize)

results = opt.solve(model)
In [3]:
model.x.get_values()
Out[3]:
{None: 4.000000039164761}
In [4]:
model.y.get_values()
Out[4]:
{None: 3.0000000607487776}
In [5]:
model.z.expr()
Out[5]:
27.000000421238173