pyomo
npx skills add https://github.com/tondevrel/scientific-agent-skills --skill pyomo
Agent 安装分布
Skill 文档
Pyomo – Mathematical Optimization Modeling
Pyomo allows you to define optimization problems using a natural mathematical syntax (Sets, Parameters, Variables, Constraints). It decouples the model from the solver, allowing the same model to be solved by different engines without code changes.
FIRST: Verify Prerequisites
pip install pyomo
# Also install a solver (e.g., GLPK for linear/integer problems)
# Conda: conda install -c conda-forge glpk ipopt
When to Use
- Strategic Planning: Long-term resource allocation or investment planning.
- Process Engineering: Optimizing chemical plants or refinery operations (Non-linear).
- Energy Systems: Power grid dispatch and unit commitment problems.
- Supply Chain Optimization: Multi-period, multi-commodity flow problems.
- Non-Linear Programming (NLP): When your constraints or objectives involve smooth curves (e.g., x², log(x)).
- Stochastic Programming: Modeling uncertainty in optimization.
- Custom Solver Integration: When you need to use specific solvers like IPOPT, SCIP, or Baron.
Reference Documentation
Official docs: http://www.pyomo.org/
GitHub: https://github.com/Pyomo/pyomo
Search patterns: pyo.ConcreteModel, pyo.Constraint, pyo.Objective, pyo.SolverFactory
Core Principles
Concrete vs. Abstract Models
- ConcreteModel: Data is defined at the time the model is built (most common in Python/Data Science).
- AbstractModel: The structure is defined first, and data is loaded later (standard for large-scale industrial models).
Components
- Var: Unknowns the solver needs to find.
- Set/Param: Data that defines the problem instance.
- Objective: The function to minimize or maximize.
- Constraint: Rules the variables must follow.
Solvers
Pyomo does not have its own solver. It requires external solvers (like glpk for LP/MIP or ipopt for NLP) installed on the system.
Quick Reference
Installation
pip install pyomo
# Also install a solver (e.g., GLPK for linear/integer problems)
# Conda: conda install -c conda-forge glpk ipopt
Standard Imports
import pyomo.environ as pyo
from pyomo.opt import SolverFactory
Basic Pattern – Simple Linear Model (Concrete)
import pyomo.environ as pyo
# 1. Create Model
model = pyo.ConcreteModel()
# 2. Define Variables
model.x = pyo.Var(within=pyo.NonNegativeReals)
model.y = pyo.Var(within=pyo.NonNegativeReals)
# 3. Define Objective (Minimize x + 2*y)
model.obj = pyo.Objective(expr=model.x + 2*model.y, sense=pyo.minimize)
# 4. Define Constraints
model.con1 = pyo.Constraint(expr=3*model.x + 4*model.y >= 12)
model.con2 = pyo.Constraint(expr=2*model.x + 5*model.y >= 10)
# 5. Solve
solver = pyo.SolverFactory('glpk')
results = solver.solve(model)
# 6. Access Results
print(f"x = {pyo.value(model.x)}, y = {pyo.value(model.y)}")
Critical Rules
â DO
- Scale your problem – Like all optimization, Pyomo works best if variables and constraints are within a similar order of magnitude (e.g., 0.1 to 100).
- Use pyo.value() – Always wrap variables in
pyo.value(model.x)to get their numerical result after solving. - Check Solver Status – Verify the solver reached an optimal solution using
results.solver.termination_condition. - Use pyo.Set and pyo.Param – For complex models, organize data using these components rather than raw Python lists/dicts.
- Specify Solver Options – Use
solver.options['tm_limit'] = 60(or similar depending on the solver) to manage execution time. - Use model.dual – If the solver supports it, enable dual suffix to get shadow prices (important for economic analysis).
â DON’T
- Don’t use Python math functions – Use
pyo.log(),pyo.exp(),pyo.sqrt()instead ofmath.log()ornp.log()inside expressions. - Don’t use if statements in constraints – Constraints must be algebraic. Use “Big-M” notation or logical reformulations for conditional logic.
- Avoid “Hard” non-linearities – Functions like
abs(x)ormax(x, y)are non-smooth and can break many solvers. Use reformulations. - Don’t forget the Intercept/Constant – Constraints like
x + y = 10are fine, but ensure your units are consistent.
Anti-Patterns (NEVER)
import pyomo.environ as pyo
import numpy as np
# â BAD: Using NumPy/Math functions in constraints
# model.con = pyo.Constraint(expr=np.sin(model.x) <= 0.5)
# â
GOOD: Use Pyomo-compatible functions
model.con = pyo.Constraint(expr=pyo.sin(model.x) <= 0.5)
# â BAD: Using Python IF for conditional constraints
# if model.x > 10:
# model.con = pyo.Constraint(expr=model.y <= 5)
# â
GOOD: Using Big-M notation (for binary variable z)
# y <= 5 + M * (1 - z)
# x >= 10 - M * (1 - z)
# â BAD: Printing a variable directly
# print(model.x) # Returns a reference object, not a number!
# â
GOOD: Use value()
print(pyo.value(model.x))
Modeling with Sets and Indices
Large-Scale Model Construction
model = pyo.ConcreteModel()
# Data
products = ['A', 'B', 'C']
profit = {'A': 10, 'B': 20, 'C': 15}
limit = 100
# Components
model.P = pyo.Set(initialize=products)
model.x = pyo.Var(model.P, within=pyo.NonNegativeReals)
# Indexed Objective
def obj_rule(model):
return sum(profit[p] * model.x[p] for p in model.P)
model.obj = pyo.Objective(rule=obj_rule, sense=pyo.maximize)
# Indexed Constraint
def limit_rule(model):
return sum(model.x[p] for p in model.P) <= limit
model.con = pyo.Constraint(rule=limit_rule)
Non-Linear Programming (NLP)
Using the IPOPT Solver
# Solving: Minimize (x-2)^2 + (y-2)^2
model = pyo.ConcreteModel()
model.x = pyo.Var(initialize=0) # Initialization is CRUCIAL for NLP
model.y = pyo.Var(initialize=0)
model.obj = pyo.Objective(expr=(model.x - 2)**2 + (model.y - 2)**2)
# Constraint: x^2 + y <= 1
model.con = pyo.Constraint(expr=model.x**2 + model.y <= 1)
# Solve with IPOPT
solver = pyo.SolverFactory('ipopt')
solver.solve(model)
Mixed-Integer Linear Programming (MILP)
Discrete Decisions
# Binary variable: 1 if we open a warehouse, 0 otherwise
model.use_warehouse = pyo.Var(within=pyo.Binary)
# Integer variable: Number of trucks to buy
model.num_trucks = pyo.Var(within=pyo.NonNegativeIntegers)
# Conditional logic: If warehouse is not used, trucks must be 0
# trucks <= Capacity * use_warehouse
model.cap_con = pyo.Constraint(expr=model.num_trucks <= 100 * model.use_warehouse)
Practical Workflows
1. Diet Problem (Classic Linear Programming)
def solve_diet(foods, nutrients, costs, requirements):
model = pyo.ConcreteModel()
model.F = pyo.Set(initialize=foods)
model.N = pyo.Set(initialize=nutrients)
model.x = pyo.Var(model.F, within=pyo.NonNegativeReals)
# Minimize cost
model.obj = pyo.Objective(expr=sum(costs[f] * model.x[f] for f in model.F))
# Meet nutrient requirements
def nutrient_rule(model, n):
return sum(nutrients[f][n] * model.x[f] for f in model.F) >= requirements[n]
model.con = pyo.Constraint(model.N, rule=nutrient_rule)
pyo.SolverFactory('glpk').solve(model)
return {f: pyo.value(model.x[f]) for f in model.F}
2. Blending Problem (Chemical/Process Engineering)
# Balancing component fractions in a mixture
# Note: Often becomes non-linear (NLP) if both flow and fraction are variables
def blend_optimization(inputs, target_purity):
model = pyo.ConcreteModel()
# ... model setup ...
# con: sum(flow[i] * purity[i]) / sum(flow[i]) == target_purity
# becomes: sum(flow[i] * purity[i]) == target_purity * sum(flow[i]) (Linearized)
Performance Optimization
Solver Choice
- GLPK/CBC: Good for free/open-source LP/MIP.
- Gurobi/CPLEX: Industrial standards (extremely fast for large MIP).
- IPOPT: Best for smooth Non-linear (NLP).
Warm Starts
For iterative optimizations, use the previous solution as a starting point.
# For NLP solvers like IPOPT
model.x.set_value(prev_x_value)
solver.solve(model)
Common Pitfalls and Solutions
Termination Condition
Always check why the solver stopped.
from pyomo.opt import TerminationCondition
results = solver.solve(model)
if results.solver.termination_condition == TerminationCondition.optimal:
print("Success")
elif results.solver.termination_condition == TerminationCondition.infeasible:
print("Check your constraints!")
Non-Convexity in NLP
If your NLP model has multiple local minima, IPOPT might get stuck.
# â
Solution:
# 1. Provide multiple different initial guesses (multistart).
# 2. Use a global solver like BARON or SCIP.
Indexing with Variables
model.x[model.y] where y is a Var is illegal.
# â
Solution: Use model.AddElement or binary variable reformulations.
Best Practices
- Always scale your problem – variables and constraints should be within similar orders of magnitude
- Use
pyo.value()to extract numerical results from variables after solving - Check solver termination conditions to verify optimality or diagnose issues
- Use
pyo.Setandpyo.Paramfor organizing data in complex models - Initialize variables for NLP problems – good starting points are crucial
- Use Pyomo-compatible functions (
pyo.log(),pyo.exp(), etc.) instead of NumPy/math functions in expressions - Reformulate conditional logic using Big-M notation or binary variables
- Avoid non-smooth functions like
abs()ormax()– use reformulations - Enable dual suffix for shadow prices when economic analysis is needed
- Set solver time limits and options appropriately for your problem size
Pyomo is the ultimate tool for turning high-level mathematical abstractions into solved business and scientific problems. Its ability to bridge the gap between algebraic modeling and high-performance solvers makes it the foundation of modern prescriptive analytics.