Skip to content

anzapatab/pyomo-unit-commitment-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pyomo Unit Commitment Example -- MILP Generator Scheduling

A production-quality implementation of the unit commitment problem using Pyomo and the open-source HiGHS solver.

What Is Unit Commitment?

Unit commitment (UC) is a fundamental optimization problem in power systems operations. Given a fleet of generators and a forecasted electricity demand over a planning horizon, the goal is to decide which generators to turn on or off (commitment) and how much power each should produce (dispatch) at every time step, while minimizing total operating cost and respecting engineering constraints.

This repository solves a simplified but realistic 24-hour UC problem with 5 thermal generators and 1 wind farm.

Problem Formulation

Decision Variables

  • u[g, t] -- Binary, 1 if generator g is committed (on) at hour t
  • v[g, t] -- Binary, 1 if generator g starts up at hour t
  • w[g, t] -- Binary, 1 if generator g shuts down at hour t
  • p[g, t] -- Continuous, power output of generator g at hour t (MW)

Objective Function

Minimize total cost = fuel cost + startup cost + shutdown cost:

min  SUM over g, t of:
     fuel_cost[g] * p[g,t]  +  startup_cost[g] * v[g,t]  +  shutdown_cost[g] * w[g,t]

Constraints

  1. Power balance -- Total generation must meet demand at every hour:

    SUM_g p[g,t] + wind[t] = demand[t]    for all t
    
  2. Generation limits -- When committed, output must stay within bounds:

    p_min[g] * u[g,t] <= p[g,t] <= p_max[g] * u[g,t]    for all g, t
    
  3. Startup/shutdown logic -- Links commitment, startup, and shutdown variables:

    u[g,t] - u[g,t-1] = v[g,t] - w[g,t]    for all g, t >= 2
    
  4. Ramp-up limit -- Output cannot increase too fast between hours:

    p[g,t] - p[g,t-1] <= ramp_up[g] * u[g,t-1] + p_min[g] * v[g,t]
    
  5. Ramp-down limit -- Output cannot decrease too fast between hours:

    p[g,t-1] - p[g,t] <= ramp_down[g] * u[g,t] + p_min[g] * w[g,t]
    
  6. Minimum up time -- Once started, a generator must stay on for a minimum number of hours:

    SUM_{s=t-min_up[g]+1}^{t} v[g,s] <= u[g,t]    for all g, t
    
  7. Minimum down time -- Once shut down, a generator must stay off for a minimum number of hours:

    SUM_{s=t-min_down[g]+1}^{t} w[g,s] <= 1 - u[g,t]    for all g, t
    
  8. Spinning reserve -- Committed capacity must exceed demand by a reserve margin:

    SUM_g p_max[g] * u[g,t] + wind[t] >= demand[t] + reserve[t]    for all t
    

Installation

Requires Python 3.10 or later.

# Clone the repository
git clone https://github.com/anzapatab/pyomo-unit-commitment-example.git
cd pyomo-unit-commitment-example

# Create a virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate

# Install dependencies
pip install -e ".[dev]"

Usage

python -m src.unit_commitment

Example Output

========================================================================================
  UNIT COMMITMENT RESULTS
========================================================================================

  Solver status   : optimal
  Total cost      : $510,620.00
  Solve time      : 0.22s
  MIP gap         : 0.0000%

----------------------------------------------------------------------------------------
  COMMITMENT SCHEDULE (1 = on, 0 = off)
----------------------------------------------------------------------------------------
Hour |   Coal-1 |   Coal-2 |   Gas-CC | Gas-CT-1 | Gas-CT-2
  01 |        1 |        1 |        0 |        1 |        0
  02 |        1 |        1 |        0 |        1 |        0
  03 |        1 |        1 |        0 |        0 |        0
  ...
  17 |        1 |        1 |        1 |        1 |        0
  18 |        1 |        1 |        1 |        1 |        1
  19 |        1 |        1 |        1 |        0 |        1
  ...

----------------------------------------------------------------------------------------
  DISPATCH SCHEDULE (MW)
----------------------------------------------------------------------------------------
Hour |   Coal-1 |   Coal-2 |   Gas-CC | Gas-CT-1 | Gas-CT-2 |     Wind |   Demand
  01 |    300.0 |    210.0 |      0.0 |     40.0 |      0.0 |    150.0 |    700.0
  ...
  18 |    500.0 |    400.0 |    320.0 |     40.0 |     40.0 |    100.0 |   1400.0
  ...

(Exact values may vary slightly depending on solver version.)

Running Tests

pytest tests/ -v

Project Structure

pyomo-unit-commitment-example/
|-- src/
|   |-- __init__.py
|   |-- data.py               # Generator parameters, demand/wind profiles
|   |-- unit_commitment.py    # Pyomo model construction and solve
|-- tests/
|   |-- __init__.py
|   |-- test_unit_commitment.py
|-- pyproject.toml
|-- LICENSE
|-- README.md

License

MIT License. See LICENSE for details.

About

Simplified 24-hour unit commitment MILP example with Pyomo and HiGHS — thermal generators, wind, ramp constraints, min up/down times

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages