Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
personal:blog:2014:0904_pyomo_for_gams_users [2014/09/05 15:27] antonello [Further help] |
personal:blog:2014:0904_pyomo_for_gams_users [2015/01/12 15:40] antonello [A Pyomo tutorial for GAMS users] |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== A Pyomo tutorial for GAMS users ====== | ====== A Pyomo tutorial for GAMS users ====== | ||
- | ===== Introduction ===== | + | **Updates: |
+ | |||
+ | * **2015.01.12: | ||
+ | |||
[[https:// | [[https:// | ||
Line 10: | Line 14: | ||
This mini-tutorial is intended for gams users that want to try Pyomo. There may be two reasons for someone to with to use Pyomo instead of GAMS.\\ | This mini-tutorial is intended for gams users that want to try Pyomo. There may be two reasons for someone to with to use Pyomo instead of GAMS.\\ | ||
The most obvious one, even if often it isn't the key driver, is that GAMS is a commercial software while Pyomo being open-source is free both as freedom and as a free beer.\\ | The most obvious one, even if often it isn't the key driver, is that GAMS is a commercial software while Pyomo being open-source is free both as freedom and as a free beer.\\ | ||
- | While for GAMS a licence for the underlying solver engine is often included with a particular version of GAMS, Pyomo would still require the user to buy a licence to use a specific commercial solvers. However Pyomo interfaces with both GLPK (for linear and mixed-integer programming) and IPOPT (for non-linear optimisation) open-source solvers, both of which are top on their classes, leaving the necessity to acquire a licence for a commercial solver to niche cases.\\ | + | While for GAMS a licence for the underlying solver engine is often included with a particular version of GAMS, Pyomo would still require the user to buy a licence to use a specific commercial solvers. However Pyomo interfaces with both [[https:// |
- | The second reason (and, to me, the most important one) resides in the language features and in the availability of development environments. GAMS uses a VERY ODD syntax, somehow derived from the Cobol language, that is very distant from any programming language in use nowadays, and miss very basic features. For example, in GAMS it is not possible | + | The second reason (and, to me, the most important one) resides in the language features and in the availability of development environments. GAMS uses a VERY ODD syntax, somehow derived from the Cobol language, that is very distant from any programming language in use nowadays. For example |
+ | Its own editor is also very terrible, but as most text editors do not provide a gams syntax highlighting, | ||
Pyomo, at the opposite, is both open source and.. it's python!\\ | Pyomo, at the opposite, is both open source and.. it's python!\\ | ||
Line 18: | Line 23: | ||
- | So let's start. We will see how to code the trasnport.gms problem, the one that ship as default example in GAMS((yes, the default GAMS example | + | So let's start. We will see how to code the trasnport.gms problem, the one that ship as default example in GAMS((yes, the default GAMS example |
GAMS equivalent code is inserted as single-dash comments. The original GAMS code needs slightly different ordering of the commands and it's available at [[http:// | GAMS equivalent code is inserted as single-dash comments. The original GAMS code needs slightly different ordering of the commands and it's available at [[http:// | ||
Line 31: | Line 36: | ||
* '' | * '' | ||
* **Install pyomo:** | * **Install pyomo:** | ||
- | * '' | + | * '' |
- | * '' | + | * '' |
* **Install solvers:** | * **Install solvers:** | ||
* //linear and MIP solver (glpk)//: '' | * //linear and MIP solver (glpk)//: '' | ||
Line 45: | Line 50: | ||
In pyomo everything is an object. The various components of the model (sets, parameters, variables, constrains, objective..) are all attributes of the main model object while being objects themselves.\\ | In pyomo everything is an object. The various components of the model (sets, parameters, variables, constrains, objective..) are all attributes of the main model object while being objects themselves.\\ | ||
There are two type of models in pyomo: A '' | There are two type of models in pyomo: A '' | ||
- | The first thing to do in the script is hence to load the pyomo library and to create a new ConcreteModel (we have little imagination here, and we call our model " | + | The first thing to do in the script is hence to load the pyomo library and to create a new ConcreteModel (we have little imagination here, and we call our model " |
<code python> | <code python> | ||
# Import of the pyomo module | # Import of the pyomo module | ||
- | from coopr.pyomo import * | + | from pyomo.environ |
| | ||
# Creation of a Concrete Model | # Creation of a Concrete Model | ||
Line 66: | Line 71: | ||
==== Parameters ==== | ==== Parameters ==== | ||
- | Parameter objects are created specifying the sets over which they are defined and are initialised with either a python | + | Parameter objects are created specifying the sets over which they are defined and are initialised with either a python |
<code python> | <code python> | ||
## Define parameters ## | ## Define parameters ## | ||
Line 130: | Line 135: | ||
def demand_rule(model, | def demand_rule(model, | ||
return sum(model.x[i, | return sum(model.x[i, | ||
- | model.demand = Constraint(model.j, | + | model.demand = Constraint(model.j, rule=demand_rule, doc=' |
</ | </ | ||
The above code take advantage of [[https:// | The above code take advantage of [[https:// | ||
Line 181: | Line 186: | ||
If you want advanced features and debugging capabilities you can use a dedicated Python IDE, like e.g. [[https:// | If you want advanced features and debugging capabilities you can use a dedicated Python IDE, like e.g. [[https:// | ||
- | You will normally run the script as '' | + | You will normally run the script as '' |
If you want to run the script as '' | If you want to run the script as '' | ||
<code python> | <code python> | ||
Line 188: | Line 193: | ||
if __name__ == ' | if __name__ == ' | ||
#This replicates what the pyomo command-line tools does | #This replicates what the pyomo command-line tools does | ||
- | from coopr.opt import SolverFactory | + | from pyomo.opt import SolverFactory |
- | import | + | import |
opt = SolverFactory(" | opt = SolverFactory(" | ||
instance = model.create() | instance = model.create() | ||
Line 215: | Line 220: | ||
# | # | ||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||
+ | |||
""" | """ | ||
Basic example of transport model from GAMS model library translated to Pyomo | Basic example of transport model from GAMS model library translated to Pyomo | ||
+ | |||
To run this you need pyomo and a linear solver installed. | To run this you need pyomo and a linear solver installed. | ||
When these dependencies are installed you can solve this example in one of | When these dependencies are installed you can solve this example in one of | ||
this ways (glpk is the default solver): | this ways (glpk is the default solver): | ||
- | + | ||
- | ./ | + | ./ |
python transport.py | python transport.py | ||
- | pyomo transport.py | + | pyomo solve transport.py |
- | pyomo --solver=glpk transport.py | + | pyomo solve --solver=glpk transport.py |
+ | |||
To display the results: | To display the results: | ||
+ | |||
cat results.json | cat results.json | ||
- | cat results.yml (if PyYAML is installed on your system | + | cat results.yml (if PyYAML is installed on your system) |
+ | |||
GAMS equivalent code is inserted as single-dash comments. The original GAMS code | GAMS equivalent code is inserted as single-dash comments. The original GAMS code | ||
needs slighly different ordering of the commands and it's available at | needs slighly different ordering of the commands and it's available at | ||
http:// | http:// | ||
+ | |||
Original problem formulation: | Original problem formulation: | ||
Dantzig, G B, Chapter 3.3. In Linear Programming and Extensions. | Dantzig, G B, Chapter 3.3. In Linear Programming and Extensions. | ||
Line 245: | Line 250: | ||
Pyomo translation: | Pyomo translation: | ||
Antonello Lobianco | Antonello Lobianco | ||
+ | |||
This file is in the Public Domain | This file is in the Public Domain | ||
""" | """ | ||
+ | |||
# Import | # Import | ||
- | from coopr.pyomo import * | + | from pyomo.environ |
- | + | ||
# Creation of a Concrete Model | # Creation of a Concrete Model | ||
model = ConcreteModel() | model = ConcreteModel() | ||
- | # Creation of an abstract model would be similar: model = AbstractModel() | + | |
## Define sets ## | ## Define sets ## | ||
# Sets | # Sets | ||
Line 262: | Line 266: | ||
model.i = Set(initialize=[' | model.i = Set(initialize=[' | ||
model.j = Set(initialize=[' | model.j = Set(initialize=[' | ||
+ | |||
## Define parameters ## | ## Define parameters ## | ||
# | # | ||
Line 294: | Line 298: | ||
return model.f * model.d[i, | return model.f * model.d[i, | ||
model.c = Param(model.i, | model.c = Param(model.i, | ||
+ | |||
## Define variables ## | ## Define variables ## | ||
# Variables | # Variables | ||
Line 301: | Line 305: | ||
# Positive Variable x ; | # Positive Variable x ; | ||
model.x = Var(model.i, | model.x = Var(model.i, | ||
+ | |||
## Define contrains ## | ## Define contrains ## | ||
# supply(i) | # supply(i) | ||
Line 312: | Line 316: | ||
def demand_rule(model, | def demand_rule(model, | ||
return sum(model.x[i, | return sum(model.x[i, | ||
- | model.demand = Constraint(model.j, | + | model.demand = Constraint(model.j, rule=demand_rule, doc=' |
## Define Objective and solve ## | ## Define Objective and solve ## | ||
Line 320: | Line 324: | ||
# Solve transport using lp minimizing z ; | # Solve transport using lp minimizing z ; | ||
def objective_rule(model): | def objective_rule(model): | ||
- | # This is equivalent to: | ||
- | # obj = 0.0 | ||
- | # for ki in model.i: | ||
- | # for kj in model.j: | ||
- | # obj += model.c[ki, | ||
- | # return obj | ||
return sum(model.c[i, | return sum(model.c[i, | ||
model.objective = Objective(rule=objective_rule, | model.objective = Objective(rule=objective_rule, | ||
+ | |||
## Display of the output ## | ## Display of the output ## | ||
# Display x.l, x.m ; | # Display x.l, x.m ; | ||
def pyomo_postprocess(options=None, | def pyomo_postprocess(options=None, | ||
model.x.display() | model.x.display() | ||
+ | |||
# This is an optional code path that allows the script to be run outside of | # This is an optional code path that allows the script to be run outside of | ||
# pyomo command-line. | # pyomo command-line. | ||
if __name__ == ' | if __name__ == ' | ||
- | + | ||
#This replicates what the pyomo command-line tools does | #This replicates what the pyomo command-line tools does | ||
- | from coopr.opt import SolverFactory | + | from pyomo.opt import SolverFactory |
- | import | + | import |
opt = SolverFactory(" | opt = SolverFactory(" | ||
instance = model.create() | instance = model.create() | ||
Line 347: | Line 346: | ||
results.write() | results.write() | ||
pyomo_postprocess(None, | pyomo_postprocess(None, | ||
- | + | ||
# Expected result: | # Expected result: | ||
# obj= 153.675 | # obj= 153.675 |