Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
DataScienceUWL
GitHub Repository: DataScienceUWL/DS775
Path: blob/main/Lessons/Lesson 05 - Local Optimization/extras/Lesson_05_Pyomo_Mutable_Parameters.ipynb
871 views
Kernel: Python 3 (system-wide)

Pyomo Mutable Parameters

Sometimes when you are coding a model, you want to be able to run it multiple times with some slight changes. For example, you might want to vary a constraint. Lesson 4 homework has a problem that requires this. There are two ways to do that:

  1. Wrap the model in a function, using the bit you want to change as a parameter to the function, and re-instantiate the entire model for each value you want to test.

  2. Use a mutable parameter.

Mutable just means that it's a paramter value that can change, instead of being a fixed constant. Let's see a quick example of each. We'll use our old standby - the Wyndor model. We'll vary the constant in the constraint, so that instead of just using 18, we'll try the model with 18, 20, and 22.

Wrapping in a function

# unfold to see Pyomo solution with a vector of decision variables from pyomo.environ import * import babel.numbers as numbers # needed to display as currency ############################ # NEW: we're defining a function that takes 1 parameter - the constraint value ############################ def wyndor(c): # Concrete Model - all of this is exactly the same as whatyou did before, except using the parameter in the constraint model = ConcreteModel(name="Wyndor") products = ['drs', 'wdw'] bounds_dict = {'drs': (0, 4), 'wdw': (0, 6)} def bounds_rule(model, product): return (bounds_dict[product]) model.x = Var(products, domain=Reals, bounds=bounds_rule) # Objective model.profit = Objective(expr=3.0 * model.x['drs'] + 5.0 * model.x['wdw'], sense=maximize) # Constraints ###################################### #NEW: Here's where we use the parameter ###################################### model.Constraint3 = Constraint( expr=3.0 * model.x['drs'] + 2.0 * model.x['wdw'] <= c) # Solve solver = SolverFactory('glpk') solver.solve(model) return model ########################################## # NEW: We'll loop over the 3 values we want to model and call our function for each one ########################################## for c in [18,20,22]: model = wyndor(c) # display solution print("Using Constraint", c) print("Profit = ", numbers.format_currency(1000 * model.profit(), 'USD', locale='en_US')) print("Batches of Doors = ", model.x['drs']()) print("Batches of Windows = ", model.x['wdw']()) print("-------------------------------------------------")
Using Constraint 18 Profit = $36,000.00 Batches of Doors = 2.0 Batches of Windows = 6.0 ------------------------------------------------- Using Constraint 20 Profit = $38,000.00 Batches of Doors = 2.66666666666667 Batches of Windows = 6.0 ------------------------------------------------- Using Constraint 22 Profit = $40,000.00 Batches of Doors = 3.33333333333333 Batches of Windows = 6.0 -------------------------------------------------

Mutable Parameter

# Concrete Model - Not wrapped in a function model = ConcreteModel(name="Wyndor") products = ['drs', 'wdw'] ############################################ # NEW: This is our mutable parameter model.c = Param(default=18, mutable=True) ############################################ bounds_dict = {'drs': (0, 4), 'wdw': (0, 6)} def bounds_rule(model, product): return (bounds_dict[product]) model.x = Var(products, domain=Reals, bounds=bounds_rule) # Objective model.profit = Objective(expr=3.0 * model.x['drs'] + 5.0 * model.x['wdw'], sense=maximize) # Constraints ###################################### #NEW: Here's where we use the parameter ###################################### model.Constraint3 = Constraint( expr=3.0 * model.x['drs'] + 2.0 * model.x['wdw'] <= model.c) # Solve solver = SolverFactory('glpk') ################################## #NEW: Loop over our constraints ################################## for c in [18,20,22]: model.c = c solver.solve(model) print("Using Constraint", c) print("Profit = ", numbers.format_currency(1000 * model.profit(), 'USD', locale='en_US')) print("Batches of Doors = ", model.x['drs']()) print("Batches of Windows = ", model.x['wdw']()) print("-------------------------------------------------")
Using Constraint 18 Profit = $36,000.00 Batches of Doors = 2.0 Batches of Windows = 6.0 ------------------------------------------------- Using Constraint 20 Profit = $38,000.00 Batches of Doors = 2.66666666666667 Batches of Windows = 6.0 ------------------------------------------------- Using Constraint 22 Profit = $40,000.00 Batches of Doors = 3.33333333333333 Batches of Windows = 6.0 -------------------------------------------------