Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
personal:blog:2014:0904_pyomo_for_gams_users [2014/09/05 15:33]
antonello
personal:blog:2014:0904_pyomo_for_gams_users [2018/06/18 15:11] (current)
Line 1: Line 1:
 ====== A Pyomo tutorial for GAMS users ====== ====== A Pyomo tutorial for GAMS users ======
 +
 +**Updates:**
 +
 +  * **2015.01.12: Updated to run under Pyomo 4. See previous revisions if you still use Pyomo 3.**
 +
 +
  
 [[https://software.sandia.gov/trac/coopr|Pyomo]] (Python Optimisation Modeling Object) is an Algebraic Modelling Language (AML) that allows to write optimisation problems using a concise mathematical formulation, acting as interface to the specific solver engine API. For non-linear optimisation problems it allows to keep a high-level approach that doesn't require the modeller to compute the Jacobian or the Hessian.\\ [[https://software.sandia.gov/trac/coopr|Pyomo]] (Python Optimisation Modeling Object) is an Algebraic Modelling Language (AML) that allows to write optimisation problems using a concise mathematical formulation, acting as interface to the specific solver engine API. For non-linear optimisation problems it allows to keep a high-level approach that doesn't require the modeller to compute the Jacobian or the Hessian.\\
Line 8: 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://www.gnu.org/software/glpk/|GLPK]] (for linear and mixed-integer programming) and [[https://projects.coin-or.org/Ipopt|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.\\ 
-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 to make comments that start in the middle of a line, nor even to define a function in order to write a reusable component of the model. Its own editor is also very terrible, but it's the only way one can code in GAMS.\\+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 a macro mechanism to provide an elementary way to structure the code in reusable components has been introduced only in GAMS 22.9. 
 +Its own editor is also very terrible, but as most text editors do not provide a gams syntax highlighting, it'still the most common way to code in GAMS.\\
  
 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 16: 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 in named "tra//sn//port" )), using Pyomo. For a fictions product, there are three canning plants and three markets and the objective of the model is to find the optimal allocation of products between plants and markets that minimises the (transport) costs.\\+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 is named "tra//sn//port" )), using Pyomo. For a fictions product, there are three canning plants and three markets and the objective of the model is to find the optimal allocation of products between plants and markets that minimises the (transport) costs.\\
 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://www.gams.com/mccarl/trnsport.gms]] 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://www.gams.com/mccarl/trnsport.gms]]
  
 ===== Installation ===== ===== Installation =====
  
-**Important: Pyomo requires python 2.x. While python 3.x support is work in progress, at the moment only python 2.x is supported.**+**<del>Important: Pyomo requires python 2.x. While python 3.x support is work in progress, at the moment only python 2.x is supported.</del>** 
 + 
 +//This isn't true any more with Pyomo 4, where support for Python 3.x has been added..//
  
 ==== Ubuntu ==== ==== Ubuntu ====
Line 29: Line 38:
     * ''sudo apt-get install python-yaml, python-pip''      * ''sudo apt-get install python-yaml, python-pip'' 
   * **Install pyomo:**   * **Install pyomo:**
-    * ''sudo pip install Coopr'' +    * ''sudo pip install pyomo'' 
-    * ''sudo pip install coopr.extras''+    * ''sudo pip install pyomo.extras''
   * **Install solvers:**   * **Install solvers:**
     * //linear and MIP solver (glpk)//: ''sudo apt-get install glpk36 glpk-utils''     * //linear and MIP solver (glpk)//: ''sudo apt-get install glpk36 glpk-utils''
Line 43: Line 52:
 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 ''ConcreteModel'' is one where all the data is defined at the model creation. We are going to use this type of model in this tutorial. Pyomo however supports also an ''AbstractModel'', where the model structure is firstly generated and then particular instances of the model are generated with a particular set of data.\\ There are two type of models in pyomo: A ''ConcreteModel'' is one where all the data is defined at the model creation. We are going to use this type of model in this tutorial. Pyomo however supports also an ''AbstractModel'', where the model structure is firstly generated and then particular instances of the model are generated with a particular set of data.\\
-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 "model". You can give it whatever name you want):+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 "model". You can give it whatever name you want((However, if you give your model an other name, you also need to add a ''pyomo_create_model(options=None, model_options=None)'' function that returns your model))):
 <code python> <code python>
 # Import of the pyomo module # Import of the pyomo module
-from coopr.pyomo import *+from pyomo.environ import *
                                  
 # Creation of a Concrete Model # Creation of a Concrete Model
Line 64: Line 73:
  
 ==== Parameters ==== ==== Parameters ====
-Parameter objects are created specifying the sets over which they are defined and are initialised with either a python set or a scalar:+Parameter objects are created specifying the sets over which they are defined and are initialised with either a python dictionary or a scalar:
 <code python> <code python>
 ## Define parameters ## ## Define parameters ##
Line 128: Line 137:
 def demand_rule(model, j): def demand_rule(model, j):
   return sum(model.x[i,j] for i in model.i) >= model.b[j]     return sum(model.x[i,j] for i in model.i) >= model.b[j]  
-model.demand = Constraint(model.j, doc='Satisfy demand at market j')+model.demand = Constraint(model.j, rule=demand_rule, doc='Satisfy demand at market j')
 </code> </code>
 The above code take advantage of [[https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions|List Comprehensions]], a powerful feature of the python language that provides a concise way to loop over a list. The above code take advantage of [[https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions|List Comprehensions]], a powerful feature of the python language that provides a concise way to loop over a list.
Line 179: Line 188:
 If you want advanced features and debugging capabilities you can use a dedicated Python IDE, like e.g. [[https://code.google.com/p/spyderlib/|Spyder]]. If you want advanced features and debugging capabilities you can use a dedicated Python IDE, like e.g. [[https://code.google.com/p/spyderlib/|Spyder]].
  
-You will normally run the script as ''pyomo --solver=glpk transport.py''. You can output solver specific output adding the option ''--stream-output''.\\+You will normally run the script as ''pyomo solve --solver=glpk transport.py''. You can output solver specific output adding the option ''--stream-output''.\\
 If you want to run the script as ''python transport.py'' add the following lines at the end:\\ If you want to run the script as ''python transport.py'' add the following lines at the end:\\
 <code python> <code python>
Line 186: Line 195:
 if __name__ == '__main__': if __name__ == '__main__':
     #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 coopr.environ+    import pyomo.environ
     opt = SolverFactory("glpk")     opt = SolverFactory("glpk")
     instance = model.create()     instance = model.create()
Line 213: Line 222:
 #!/usr/bin/env python #!/usr/bin/env python
 # -*- 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):
 + 
     ./transport.py (Linux only)     ./transport.py (Linux only)
     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://www.gams.com/mccarl/trnsport.gms http://www.gams.com/mccarl/trnsport.gms
 + 
 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 243: Line 252:
 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 import * 
-                + 
 # Creation of a Concrete Model # Creation of a Concrete Model
 model = ConcreteModel() model = ConcreteModel()
 + 
 ## Define sets ## ## Define sets ##
 #  Sets #  Sets
Line 259: Line 268:
 model.i = Set(initialize=['seattle','san-diego'], doc='Canning plans') model.i = Set(initialize=['seattle','san-diego'], doc='Canning plans')
 model.j = Set(initialize=['new-york','chicago', 'topeka'], doc='Markets') model.j = Set(initialize=['new-york','chicago', 'topeka'], doc='Markets')
 + 
 ## Define parameters ## ## Define parameters ##
 #   Parameters #   Parameters
Line 291: Line 300:
   return model.f * model.d[i,j] / 1000   return model.f * model.d[i,j] / 1000
 model.c = Param(model.i, model.j, initialize=c_init, doc='Transport cost in thousands of dollar per case') model.c = Param(model.i, model.j, initialize=c_init, doc='Transport cost in thousands of dollar per case')
 + 
 ## Define variables ## ## Define variables ##
 #  Variables #  Variables
Line 298: Line 307:
 #  Positive Variable x ; #  Positive Variable x ;
 model.x = Var(model.i, model.j, bounds=(0.0,None), doc='Shipment quantities in case') model.x = Var(model.i, model.j, bounds=(0.0,None), doc='Shipment quantities in case')
 + 
 ## Define contrains ## ## Define contrains ##
 # supply(i)   observe supply limit at plant i # supply(i)   observe supply limit at plant i
Line 309: Line 318:
 def demand_rule(model, j): def demand_rule(model, j):
   return sum(model.x[i,j] for i in model.i) >= model.b[j]     return sum(model.x[i,j] for i in model.i) >= model.b[j]  
-model.demand = Constraint(model.j, doc='Satisfy demand at market j')+model.demand = Constraint(model.j, rule=demand_rule, doc='Satisfy demand at market j')
  
 ## Define Objective and solve ## ## Define Objective and solve ##
Line 320: Line 329:
 model.objective = Objective(rule=objective_rule, sense=minimize, doc='Define objective function') model.objective = Objective(rule=objective_rule, sense=minimize, doc='Define objective function')
  
 + 
 ## Display of the output ## ## Display of the output ##
 # Display x.l, x.m ; # Display x.l, x.m ;
 def pyomo_postprocess(options=None, instance=None, results=None): def pyomo_postprocess(options=None, instance=None, results=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.  For example:  python transport.py # pyomo command-line.  For example:  python transport.py
 if __name__ == '__main__': if __name__ == '__main__':
-   + 
     #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 coopr.environ+    import pyomo.environ
     opt = SolverFactory("glpk")     opt = SolverFactory("glpk")
     instance = model.create()     instance = model.create()
Line 338: Line 348:
     results.write()     results.write()
     pyomo_postprocess(None, instance, results)     pyomo_postprocess(None, instance, results)
-   + 
 # Expected result: # Expected result:
 # obj= 153.675 # obj= 153.675
personal/blog/2014/0904_pyomo_for_gams_users.1409924017.txt.gz · Last modified: 2018/06/18 15:10 (external edit)
CC Attribution-Noncommercial-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0