Recent from talks
Nothing was collected or created yet.
Pyomo
View on Wikipedia| Pyomo | |
|---|---|
| Designed by | Gabriel Hackebeil William E. Hart Carl Laird Bethany Nicholson John Siirola Jean-Paul Watson David Woodruff |
| First appeared | 2008 |
| Stable release | 6.8.3
/ November 18, 2024 |
| OS | Cross-platform: Linux, Mac OS X and Windows |
| License | BSD license |
| Filename extensions | .py |
| Website | www |
| Influenced by | |
| Python, AMPL, General Algebraic Modeling System | |
Pyomo is a collection of Python software packages for formulating optimization models.[1][2]
Pyomo was developed by William Hart and Jean-Paul Watson at Sandia National Laboratories and David Woodruff at University of California, Davis. Significant extensions to Pyomo were developed by Bethany Nicholson and John Siirola at Sandia National Laboratories, Carl Laird at Purdue University, and Gabriel Hackebeil. Pyomo is an open-source project that is freely available, and it is licensed with the BSD license. Pyomo is developed as part of the COIN-OR project. Pyomo is a popular open-source software package that is used by a variety of government agencies and academic institutions.
Features
[edit]Pyomo allows users to formulate optimization problems in Python in a manner that is similar to the notation commonly used in mathematical optimization. Pyomo supports an object-oriented style of formulating optimization models, which are defined with a variety of modeling components: sets, scalar and multidimensional parameters, decision variables, objectives, constraints, equations, disjunctions and more. Optimization models can be initialized with python data, and external data sources can be defined using spreadsheets, databases, various formats of text files. Pyomo supports both abstract models, which are defined without data, and concrete models, which are defined with data. In both cases, Pyomo allows for the separation of model and data.
Pyomo supports dozens of solvers, both open source and commercial, including many solvers supported by AMPL, PICO, CBC, CPLEX, IPOPT, and GLPK. Pyomo can either invoke the solver directly or asynchronously with a solver manager. Solver managers support remote, asynchronous execution of solvers, which supports parallel execution of Pyomo scripts. Solver interaction is performed with a variety of solver interfaces, depending on the solver being used. A very generic solver interface is supported with AMPL's nl (format).
Related software
[edit]The following software packages integrate Pyomo as a library to support optimization modeling and analysis:
- SolverStudio lets you use Excel to edit, save and solve optimisation models built using a variety of modeling languages, including Pyomo.[3] Pyomo is bundled with the SolverStudio software.
- TEMOA (Tools for Energy Model Optimization and Assessment) is an open source modeling framework for conducting energy system analysis.[4] The core component of TEMOA is an energy economy optimization model. This model is formulated and optimized using Pyomo.
- MinPower is an open source toolkit for students and researchers in power systems. It is designed to make working with standard power system models simple and intuitive.[5] MinPower uses Pyomo to formulate and optimize these power system models.
- linopy project, offering similar functionality to Pyomo.[6]
See also
[edit]References
[edit]- ^ William E. Hart; Carl D. Laird; Jean-Paul Watson; David L. Woodruff; Gabriel A. Hackebeil; Bethany L. Nicholson; John D. Siirola (2017). Pyomo — Optimization Modeling in Python. Springer. ISBN 978-3-319-58821-6.
- ^ Hart, William; Jean-Paul Watson; David L. Woodruff (2011). "Pyomo: modeling and solving mathematical programs in python". Mathematical Programming Computation. Vol. 3, no. 3. doi:10.1007/s12532-011-0026-8.
- ^ Mason, Andrew (2013). "SolverStudio: A New Tool for Better Optimisation and Simulation Modelling in Excel". INFORMS Transactions on Education. Vol. 14, no. 1. pp. 45–52. doi:10.1287/ited.2013.0112.
- ^ DeCarolis, Joseph; Kevin Hunter; Sarat Sreepathi (2010). The TEMOA Project: Tools for Energy Model Optimization and Analysis (PDF). International Energy Workshop. Stockholm, Sweden.
- ^ Greenhall, Adam; Rich Christie; Jean-Paul Watson (2012). Minpower: A power systems optimization toolkit (PDF). Power and Energy Society General Meeting.
- ^ "linopy: Linear optimization with N-D labeled variables". PyPSA. Retrieved 2022-02-22.
External links
[edit]- Articles from IBM's developerWorks:
- "Pyomo Meets Fantasy Football". 2015-01-27.
- APOPT Solver for LP, QP, MILP, NLP, and MINLP solutions in Pyomo
Pyomo
View on GrokipediaOverview
Definition and Purpose
Pyomo is a Python-based open-source software package that supports a diverse set of optimization capabilities for formulating, solving, and analyzing optimization models.[1] It serves as a collection of Python packages designed to enable users to define symbolic optimization problems directly within Python code, facilitating the modeling of structured optimization applications across various domains such as linear, nonlinear, and mixed-integer programming.[7] This approach allows for the creation of model instances and their subsequent solving using both commercial and open-source solvers, promoting flexibility in handling complex decision-making scenarios.[1] The primary purpose of Pyomo is to empower users with iterative scripting and analysis tools embedded in Python, enabling the development and refinement of optimization models through high-level abstractions and programmatic control. By supporting symbolic problem definition, Pyomo facilitates rapid prototyping and exploration of optimization problems, making it particularly suited for applications requiring repeated model adjustments or sensitivity analyses in fields like operations research, engineering, and data science.[1] A key benefit of Pyomo lies in its seamless integration with the broader Python ecosystem, which provides access to extensive libraries for data manipulation, numerical computation, visualization, and automation, thereby streamlining end-to-end optimization workflows. This embedding in Python enhances productivity by allowing users to combine optimization tasks with other computational tasks without needing to switch languages or tools.[1] Pyomo is released under the BSD license, which imposes minimal restrictions on its use in both academic and commercial contexts, and it is maintained as part of the COIN-OR (Computational Infrastructure for Operations Research) project.[8][1]Development History
Pyomo originated in the late 2000s from research efforts at Sandia National Laboratories' Center for Computing Research, where it was initially developed as the core modeling component of the Coopr software library.[1] The project was spearheaded by primary designers William E. Hart, Jean-Paul Watson, and Carl D. Laird, who aimed to create a flexible, Python-based tool for optimization modeling. Pyomo was first released in 2008, with the first public description appearing in 2009, building on Python's scripting capabilities to enable symbolic problem formulation and integration with existing solvers.[9] Key milestones in Pyomo's evolution include its early integration into the COIN-OR open-source initiative, which provided infrastructure for solver interfaces and community collaboration starting around 2010.[10] A seminal 2011 publication formalized Pyomo's design as an algebraic modeling language, emphasizing its extensibility for complex problems. The project underwent a significant rebranding in 2015 with the release of Pyomo 4.0, shifting the umbrella Coopr name to focus solely on Pyomo as the primary package. Development transitioned to GitHub in mid-2016, enhancing accessibility and version control.[5][4] Subsequent major versions marked further advancements: Pyomo 5.x, released in 2016, improved support for nonlinear programming through better expression handling and solver integrations. Pyomo 6.x followed in 2021, delivering performance optimizations, streamlined architecture, and exclusive compatibility with Python 3 by deprecating Python 2 support.[11] These updates were driven by the need to evolve Pyomo from a standalone library into a deeply embedded Python tool, enabling scripting for advanced applications such as stochastic programming via extensions like PySP.[12] Ongoing development continues under the COIN-OR foundation by a growing community of contributors. As of November 2025, the latest version is 6.9.5, featuring support for newer Python versions (3.10–3.14), enhanced solver interfaces, and ongoing contributions from a community of over 100 developers.[8][13][4]Core Features
Modeling Paradigms
Pyomo provides two primary modeling paradigms for defining optimization problems: abstract models and concrete models. These approaches offer flexibility in how models are constructed and parameterized, allowing users to choose based on the problem's scale, data availability, and reuse requirements.[14] Abstract models enable the symbolic definition of optimization problems without specifying numerical data at the time of model creation. In this paradigm, sets, parameters, variables, objectives, and constraints are declared using symbolic expressions, with data supplied later through mechanisms like data files or portals. This separation facilitates parameterization, where the model structure remains fixed while data varies, making it ideal for generating multiple instances from a single template. For example, an abstract model can represent a transportation problem with generic sets for origins and destinations, loaded with specific values for different scenarios.[14][15] In contrast, concrete models involve direct instantiation of all components with numerical data during the model's definition. Parameters, variables, and other elements are assigned specific values inline, resulting in a fully specified instance ready for immediate solving. This approach suits one-off analyses or data-driven problems where the input is fixed and available upfront, such as prototyping a small linear program with hardcoded coefficients. Concrete models are particularly accessible for users familiar with Python scripting, as they integrate seamlessly with Python data structures like lists or NumPy arrays.[14][12] The choice between abstract and concrete paradigms depends on the application's needs. Abstract models excel in scalability for large-scale optimizations or scenario-based analyses, where reusing a symbolic framework across varied datasets reduces redundancy and supports efficient scripting for parametric studies. Concrete models, however, offer simplicity for rapid prototyping and exploratory work, avoiding the overhead of data management. While both can achieve similar flexibility—such as loading external data into concrete models or hardcoding into abstract ones—the abstract approach aligns more closely with traditional algebraic modeling languages, whereas concrete models leverage Python's dynamic nature.[14][12][16] Pyomo models, particularly concrete instances, support persistence through export to standardized formats like LP (for linear programs) and NL (for nonlinear problems), enhancing compatibility with external solvers. These files are generated automatically via solver interfaces during the solving process, allowing models to be shared, debugged, or warm-started without relying on Python execution. For instance, an LP file captures the matrix representation of a linear model, while an NL file handles nonlinear expressions in AMPL format. This capability ensures interoperability in distributed or legacy solver environments.[17][18]Supported Optimization Types
Pyomo supports linear programming (LP), a class of optimization problems characterized by continuous decision variables, linear objective functions, and linear constraints. The canonical form of an LP problem that Pyomo can model is to minimize subject to and , where is the vector of objective coefficients, is the vector of decision variables, is the constraint matrix, and is the right-hand-side vector.[2] This formulation assumes equality constraints, which can be derived from inequality forms by introducing slack variables; for instance, an inequality becomes with . As an illustrative example, consider minimizing subject to , , and , where the coefficient matrix , , and .[19] Building on LP, Pyomo enables mixed-integer linear programming (MILP), which incorporates discrete decisions through integer or binary variables alongside continuous ones, while maintaining linearity in the objective and constraints. This allows modeling combinatorial aspects, such as scheduling or facility location, where certain variables must take whole-number values. MILP problems retain the linear structure of LP but extend the variable domain to include integers, solvable via branch-and-bound methods interfaced through Pyomo.[2][19] For nonlinear problems, Pyomo supports nonlinear programming (NLP), accommodating quadratic objectives and constraints as well as general nonlinear functions, which arise in applications like process engineering or machine learning. Quadratic programming (QP) is a specific subclass of NLP featuring quadratic terms in the objective or constraints, often convex and solvable efficiently. This capability includes handling nonconvexities, though convergence depends on the interfaced solver. Pyomo's expression system facilitates defining these nonlinear terms symbolically. Pyomo also supports mixed-integer nonlinear programming (MINLP), which combines discrete integer variables with nonlinear functions, enabling the modeling of complex hybrid problems.[19] Pyomo further extends to advanced optimization types via specialized extensions. Stochastic programming, which addresses uncertainty through scenario-based formulations, is supported by the PySP extension for multistage and two-stage problems.[20] Disjunctive programming models logical conditions and disjunctions using the Generalized Disjunctive Programming extension, useful for problems with conditional constraints. Bilevel optimization, involving hierarchical decision-making with an outer problem optimizing over solutions to an inner problem, is handled through dedicated bilevel modeling components. Additionally, differential-algebraic equations (DAEs) are integrated via the Pyomo.DAE extension, enabling dynamic optimization of systems with time-dependent ordinary and algebraic differential equations.[21]Components and Architecture
Key Modeling Objects
Pyomo's key modeling objects form the foundational elements for constructing optimization models, enabling users to define symbolic representations of mathematical programs in Python. These objects include sets for indexing, parameters for fixed data, variables for decision elements, expressions for intermediate computations, constraints for restrictions, and objectives for optimization goals. All such objects inherit from the baseComponent class, which provides a common interface for extensibility and integration within Pyomo's object-oriented framework.[22]
Sets serve as index sets to structure multidimensional arrays of other components, such as variables or parameters, facilitating the modeling of problems with multiple dimensions or categories. They are declared using the Set or RangeSet classes, with options to initialize from iterables like lists or functions. For instance, a simple finite set can be defined as model.S = Set(initialize=[1, 2, 3]), while a range set might be model.R = RangeSet(1, 10). Additional options include specifying dimensionality (dimen=2 for tuple-based members) or restricting membership (within=NonNegativeIntegers). Sets can also be indexed by other sets, creating hierarchical structures like model.E = Set(model.A).[23]
Parameters represent fixed, symbolic data values used throughout the model, such as coefficients or constants, and are declared via the Param class, which supports indexing by sets. Declaration typically involves an initialize option for values, which can be a constant, dictionary, or function; for example, model.p = Param(initialize=5) for a scalar or model.c = Param(model.S, initialize={1: 10, 2: 20, 3: 30}) for an indexed array. Parameters can be made mutable to allow post-instantiation changes (mutable=True), include validation callbacks (validate), or restrict domains (within=NonNegativeReals). If no initialization is provided, a default value can be set.[24]
Variables are the decision elements of the model, representing unknowns to be optimized, and are declared using the Var class, inheriting from Component. They support domains like continuous reals (Reals or NonNegativeReals), integers (Integers or PositiveIntegers), or binary values (Binary or [Boolean](/page/Boolean)), along with bounds specified as a tuple or function. Indices are provided via sets, enabling array-like structures; a basic example is model.x = Var(domain=NonNegativeReals), while an indexed continuous variable is model.x = Var(model.S, domain=NonNegativeReals, bounds=(0, None)). Initial values can be set via initialize, and bounds imply domain restrictions in many cases, such as Binary enforcing 0-1 limits.[25]
Expressions provide a mechanism for defining and storing intermediate symbolic computations that can be reused in objectives or constraints, declared as the Expression component, which behaves similarly to a mutable Param but accepts Pyomo expressions. They are particularly useful for nonlinear or shared terms; for example, model.e = Expression(model.S, rule=lambda m, i: m.x[i] * i) creates an indexed expression. Values can be set or modified directly, such as instance.e[1].value = instance.x**2, and they integrate seamlessly with solvers supporting nonlinear expressions.[26]
Constraints enforce restrictions on variables through equality (==) or inequality (<=, >=) expressions, supporting both linear and nonlinear forms, and are declared using the Constraint class. They can be scalar or indexed by sets, with expressions generated via Python rule functions; a linear inequality example is model.con = Constraint(rule=lambda m: sum(m.x[i] for i in m.S) <= m.b), where m.b is a parameter. For bounds-style declarations, a 3-tuple (lower, expression, upper) is used, such as (2, model.y, None) for model.y >= 2. Indexed constraints iterate over sets or their Cartesian products, ensuring feasibility across model instances.[27]
Objectives define the function to minimize or maximize, declared via the Objective class, which supports single or multiple instances (though only one is active per solve). The expression is provided through a rule function, with a default sense of minimization that can be overridden (sense=maximize); for example, model.obj = Objective(expr=sum(model.c[i] * model.x[i] for i in model.S), sense=minimize). Expressions can incorporate parameters, variables, and even other expressions, enabling complex linear or nonlinear goals like summation(model.p, model.x) + model.y.[28]
Solver Interfaces
Pyomo provides interfaces to a wide range of optimization solvers, enabling users to solve models defined in the framework using both open-source and commercial software. These interfaces allow Pyomo to translate abstract or concrete models into formats compatible with the solvers, execute the optimization, and retrieve results back into the Python environment. The design emphasizes flexibility, supporting direct API calls for performance-critical applications and file-based persistence for broader compatibility, particularly with solvers that use the AMPL Nonlinear (.nl) format or GAMS-style inputs.[18]
Among open-source solvers, Pyomo supports GLPK for linear and mixed-integer linear programming, CBC for mixed-integer programming, IPOPT (via cyipopt) for nonlinear optimization, HiGHS for linear and mixed-integer linear problems, SCIP for mixed-integer nonlinear programming, and others like PyMUMPS for sparse linear systems. Commercial solvers integrated include Gurobi for mixed-integer linear and quadratic programming, CPLEX for linear and mixed-integer linear optimization, KNITRO for nonlinear problems, XPRESS for linear and mixed-integer linear models, and BARON for global optimization of nonlinear problems. Users can list available solvers via the command pyomo help --solvers, and installation typically occurs separately through pip or conda, as Pyomo does not bundle solvers.[29][18]
The solving process begins with model creation, either as a ConcreteModel directly or by instantiating an AbstractModel with data (e.g., instance = model.create_instance(data)). A solver is then instantiated using the SolverFactory class, such as opt = pyo.SolverFactory('glpk'), where the argument specifies the solver name. The solve method is invoked on the solver object, passing the model or instance (e.g., results = opt.solve(model)), which handles model export if needed, solver execution, and solution import. For file-based interfaces, Pyomo optionally persists the model to disk (e.g., as an .nl file) before invoking the solver executable.[18][17]
Solver-specific options can be configured to customize the optimization, such as setting a time limit with opt.options['timelimit'] = 60 or a mixed-integer programming gap tolerance via opt.options['mipgap'] = 0.01. These options are passed either directly to the solver object before calling solve or as a dictionary in the solve method (e.g., opt.solve(model, options={'timelimit': 60})). For parallel or distributed solving, Pyomo's SolverManager class facilitates execution across multiple processes or machines, often leveraging MPI via the mpi4py library; for instance, manager = pyo.SolverManagerFactory('mpi') coordinates jobs like job_id = manager.queue(model, opt=opt).[30][18]
After solving, results are accessible through the returned SolverResults object or directly on the model. The solver status is checked via results.solver.status (e.g., 'ok') and termination condition like results.solver.termination_condition (e.g., pyo.TerminationCondition.optimal or pyo.TerminationCondition.infeasible). Variable values are retrieved using pyo.value(model.var), objective values with pyo.value(model.obj), and dual variables (where supported) by importing suffixes (e.g., model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT) before solving, then pyo.value(model.dual[constraint])). Solutions can be loaded into the model with model.solutions.load_from(results) if not done automatically.[17]
The overall workflow proceeds as: model definition and population → optional persistence to file (e.g., .nl for AMPL-compatible solvers) → solver invocation and execution → results import and analysis. This pipeline supports both scripted Python workflows and command-line usage, such as pyomo solve my_model.py --solver=glpk, ensuring seamless integration with external solvers.[18]
Usage and Examples
Basic Linear Programming Example
To illustrate the core usage of Pyomo for linear programming, consider the classic diet problem, which seeks to minimize the cost of a daily diet while satisfying minimum and maximum nutritional requirements for calories, protein, and vitamin C, as well as a total volume constraint.[31] The problem involves three foods: steak (cost $10 per unit, volume 1 unit, providing 180 calories, 40g protein, 0mg vitamin C), apples (cost $2 per unit, volume 1 unit, 65 calories, 1g protein, 30mg vitamin C), and rice (cost $1 per unit, volume 1 unit, 143 calories, 5g protein, 0mg vitamin C). The decision variables represent the continuous amount (in units) of each food purchased, which must be non-negative. The objective is to minimize total cost, subject to: minimum nutrients (2000 calories, 56g protein, 300mg vitamin C), maximum nutrients (4000 calories, 168g protein, 2000mg vitamin C), and total volume ≤ 400 units. This is a standard toy example used in Pyomo tutorials.[32] Pyomo supports this formulation through an abstract model, where the structure is defined in Python and data is loaded separately (e.g., from a .dat file). The following steps outline the process. First, import Pyomo and create an abstract model instance:import pyomo.environ as pyo
model = pyo.AbstractModel()
import pyomo.environ as pyo
model = pyo.AbstractModel()
# Sets
model.foods = pyo.Set()
model.nutrients = pyo.Set()
# Parameters
model.cost = pyo.Param(model.foods, within=pyo.Reals)
model.volume = pyo.Param(model.foods, within=pyo.PositiveReals)
model.amount = pyo.Param(model.foods, model.nutrients, within=pyo.Reals)
model.min_nutr = pyo.Param(model.nutrients, within=pyo.Reals)
model.max_nutr = pyo.Param(model.nutrients, within=pyo.Reals)
model.max_vol = pyo.Param(within=pyo.Reals)
# Variables
model.x = pyo.Var(model.foods, within=pyo.NonNegativeReals)
# Objective: minimize total cost
def obj_rule(model):
return sum(model.cost[f] * model.x[f] for f in model.foods)
model.obj = pyo.Objective(rule=obj_rule, sense=pyo.minimize)
# Constraints
def vol_rule(model):
return sum(model.volume[f] * model.x[f] for f in model.foods) <= model.max_vol
model.volume_constraint = pyo.Constraint(rule=vol_rule)
def nutr_rule(model, n):
return sum(model.amount[f, n] * model.x[f] for f in model.foods) >= model.min_nutr[n], \
sum(model.amount[f, n] * model.x[f] for f in model.foods) <= model.max_nutr[n]
model.nutr_constraints = pyo.Constraint(model.nutrients, rule=nutr_rule)
# Sets
model.foods = pyo.Set()
model.nutrients = pyo.Set()
# Parameters
model.cost = pyo.Param(model.foods, within=pyo.Reals)
model.volume = pyo.Param(model.foods, within=pyo.PositiveReals)
model.amount = pyo.Param(model.foods, model.nutrients, within=pyo.Reals)
model.min_nutr = pyo.Param(model.nutrients, within=pyo.Reals)
model.max_nutr = pyo.Param(model.nutrients, within=pyo.Reals)
model.max_vol = pyo.Param(within=pyo.Reals)
# Variables
model.x = pyo.Var(model.foods, within=pyo.NonNegativeReals)
# Objective: minimize total cost
def obj_rule(model):
return sum(model.cost[f] * model.x[f] for f in model.foods)
model.obj = pyo.Objective(rule=obj_rule, sense=pyo.minimize)
# Constraints
def vol_rule(model):
return sum(model.volume[f] * model.x[f] for f in model.foods) <= model.max_vol
model.volume_constraint = pyo.Constraint(rule=vol_rule)
def nutr_rule(model, n):
return sum(model.amount[f, n] * model.x[f] for f in model.foods) >= model.min_nutr[n], \
sum(model.amount[f, n] * model.x[f] for f in model.foods) <= model.max_nutr[n]
model.nutr_constraints = pyo.Constraint(model.nutrients, rule=nutr_rule)
data = pyo.DataPortal()
data.load(filename='diet.dat')
instance = model.create_instance(data)
data = pyo.DataPortal()
data.load(filename='diet.dat')
instance = model.create_instance(data)
solver = pyo.SolverFactory('glpk')
results = solver.solve(instance, tee=True)
solver = pyo.SolverFactory('glpk')
results = solver.solve(instance, tee=True)
