This model formulation and associated Python file hard-codes data values directly into the optimization model. If you want to see how to formulate this same model using more advanced data input methods and take advantage of more of Pyomo's model building functions, see this other article, Bubbles Brewery Advanced Formulation.
Download Optimization Models
Model Description
You are the brewmaster in charge of planning your brewery's next production run. Your task is to decide how many barrels of light beer and dark beer to produce. Each barrel sold will earn your company a profit, as shown below.
- Light beer: $13 per barrel
- Dark beer: $23 per barrel
However, your production is limited by the amount of corn, hops, and malt available. The table below shows the amount of each ingredient required for each type of beer, as well as the total available for this production run.
Corn |
Hops |
Malt |
|
Light beer (per barrel) | 5 | 4 | 35 |
Dark beer (per barrel) | 15 | 4 | 20 |
Amount available | 480 | 160 | 1,190 |
Mathematical Formulation
Decision Variables
\(x\): Number of barrels of light beer to produce
\(y\): Number of barrels of dark beer to produce
Objective
\( \max 13x + 23y \)
Constraints
Cannot use more ingredients than what is already available at the brewery
corn: \( 5x + 15y \le 480 \)
hops: \( 4x + 4y \le 160 \)
malt: \( 35x + 20y \le 1,190 \)
The amount of barrels of beer produced needs to be non-negative
\(x \ge 0\)
\(y \ge 0\)
Solution
When you solve this model using the Rose solver, the optimal solution should yield a profit of $800, achieved by producing 12 barrels of light beer and 28 barrels of dark beer.
Python Pyomo File
Below is the Python code that uses Pyomo to formulate this optimization model.
import pyomo.environ as pyo
model = pyo.ConcreteModel(name='Bubbles Brewery')
# Decision variables
model.light_beer = pyo.Var(within=pyo.NonNegativeReals)
model.dark_beer = pyo.Var(within=pyo.NonNegativeReals)
# Objective function
model.objective = pyo.Objective(expr=13*model.light_beer + 23*model.dark_beer,
sense=pyo.maximize)
# Constraints
model.corn = pyo.Constraint(expr=5*model.light_beer + 15*model.dark_beer <= 480)
model.malt = pyo.Constraint(expr=4*model.light_beer + 4*model.dark_beer <= 160)
model.hops = pyo.Constraint(expr=35*model.light_beer + 20*model.dark_beer <= 1190)
# Export the model
model.write('bubbles_brewery.mps', io_options={'symbolic_solver_labels': True})
# Optionally print the model to verify
model.pprint()
Optimization Model (.mps) File
Below is the resulting .mps file, which can be solved using the Rose solver. Note that the .mps file generated directly from Pyomo may appear slightly different. This version has been cleaned up for readability, though it performs the same.
NAME Bubbles Brewery
OBJSENSE MAX
ROWS
N profit
L corn
L hops
L malt
COLUMNS
light_beer profit 13
light_beer corn 5
light_beer hops 4
light_beer malt 35
dark_beer profit 23
dark_beer corn 15
dark_beer hops 4
dark_beer malt 20
RHS
RHS1 corn 480
RHS1 hops 160
RHS1 malt 1190
BOUNDS
ENDATA
Solution File
The full solution returned from Rose is shown in the .json file below. For understanding how to interpret these results, see this article about the Output JSON.
{ "dual": { "constraint_dual": { "corn": 1, "hops": 2, "malt": 0 }, "variable_dual": { "dark_beer": 0, "light_beer": 0 } }, "objective": { "profit": 800 }, "primal": { "constraint_value": { "corn": 480, "hops": 160, "malt": 980 }, "variable_value": { "dark_beer": 28, "light_beer": 12 } } }
Comments
0 comments
Please sign in to leave a comment.