Lecture VI - Unit Commitment Problem

Energy System Optimization with Julia

Dr. Tobias Cors

Hamburg University of Applied Science - Summer 2025

Quick Recap from last Week

NamedTuples in Julia

  • NamedTuples are immutable collections of key-value pairs
  • They provide a convenient way to group related data
  • Can be created using a function that returns a tuple with named fields
# Example: Creating a NamedTuple for a student
function Student(name::String, age::Int, grade::Float64)
    return (name = name, age = age, grade = grade)
end

# Create a dictionary of students
students = Dict(
    "Alice" => Student("Alice", 20, 3.7),
    "Bob" => Student("Bob", 21, 3.5)
)

# Access data using dot notation
println(students["Alice"].grade)  # Output: 3.7

Model-Solving Function Pattern

  • Encapsulate optimization models in functions for reusability
  • Return results as NamedTuples for easy access
  • Store results in DataFrames for analysis
# Example data for different scenarios
data = Dict(
    "base" => Dict(
        "cost" => 10.0,
        "limit" => 100.0
    ),
    "high_cost" => Dict(
        "cost" => 15.0,
        "limit" => 100.0
    ),
    "low_limit" => Dict(
        "cost" => 10.0,
        "limit" => 50.0
    )
)

# Example: Function to solve a simple optimization problem
function solve_optimization(data::Dict)
    model = Model(HiGHS.Optimizer)
    set_silent(model)
    
    # Define variables and solve model
    @variable(model, x >= 0)
    @objective(model, Min, data["cost"] * x)
    @constraint(model, x <= data["limit"])
    optimize!(model)
    
    # Return results as NamedTuple
    return (
        solution = value(x),
        objective = objective_value(model)
    )
end

# Store results in DataFrame
results = DataFrame(
    scenario = String[],
    solution = Float64[],
    objective = Float64[]
)

# Solve multiple scenarios
for (name, scenario_data) in data
    solution = solve_optimization(scenario_data)
    push!(results, (name, solution.solution, solution.objective))
end

Economic Dispatch Problem Recap

  • Objective: Minimize total generation cost
  • Decision Variables:
    • Power output of thermal generators (\(p_g\))
    • Power output of wind turbines (\(p_w\))
  • Key Constraints:
    • Power balance: \(\sum_g p_g + \sum_w p_w = d^f\)
    • Generator limits: \(p^{\min}_g \leq p_g \leq p^{\max}_g\)
    • Wind limits: \(0 \leq p_w \leq p^f_w\)

Note

The Economic Dispatch problem optimizes power generation for a single time step, assuming all generators are already committed to operation.

From Economic Dispatch to Unit Commitment

Limitations of Economic Dispatch: - Assumes generators are already running - Ignores start-up and shut-down costs - Doesn’t consider minimum up/down times - Single time step optimization

Unit Commitment Solution: - Adds binary variables for generator on/off status - Considers multiple time steps - Includes start-up/shut-down costs - Enforces minimum up/down time, ramping, etc. constraints - More realistic but computationally more complex

Tip

Unit Commitment extends Economic Dispatch by adding operational constraints and time-dependent decisions.

Solutions from last Week

  • The tutorials from last week will again be available on Friday
  • You can access them in the project folder on Github
  • Click on the little cat icon on the bottom right

Tip

You can ask questions anytime in class or via email!

Introduction

Power System Basic Models: Unit Commitment

Power system with generators and an aggregated demand

  • Generators can be switched on/off to meet the demand
  • Generators have different costs and operational constraints
  • Decisions are made over multiple time steps

Unit Commitment Problem

  • Objective: Minimize the total cost of producing electricity
  • Constraints:
    • Demand must be met
    • Generators have limits on their power output
    • Renewable power injection
    • Generator on/off status
    • Minimum up/down times
    • Ramp rate limits
  • Decision variables:
    • Power output of thermal generators
    • Power output of renewables
    • Binary variables for generator status

How does the mathematical model look like?

Problem Structure

Available Sets

Question: What are the sets we need?

  • \(\mathcal{G}\) - Set of thermal generators indexed by \(g \in \{1,2,...,|\mathcal{G}|\}\)
  • \(\mathcal{W}\) - Set of wind turbines indexed by \(w \in \{1,2,...,|\mathcal{W}|\}\)
  • \(\mathcal{T}\) - Set of time periods indexed by \(t \in \{1,2,...,|\mathcal{T}|\}\)

Available Parameters

Question: What are possible parameters?

  • \(C^{var}_g\) - Variable cost of thermal generator \(g\in\mathcal{G}\) in [\(EUR/\text{MWh}\)]
  • \(C^{fix}_g\) - Fixed cost of thermal generator \(g\in\mathcal{G}\) in [\(EUR\)]
  • \(C^{var}_w\) - Cost of wind turbine \(w\in\mathcal{W}\) in [\(EUR/\text{MWh}\)]
  • \(P^{\min}_g\) - Minimum power output of thermal generator \(g\in\mathcal{G}\) in [MW]
  • \(P^{\max}_g\) - Maximum power output of thermal generator \(g\in\mathcal{G}\) in [MW]
  • \(P^{f}_{w,t}\) - Forecasted power output of wind turbine \(w\in\mathcal{W}\) at time \(t\) in [MW]
  • \(D^f_t\) - Forecasted demand at time \(t\) in [MW]
  • \(T^{up}_g\) - Minimum up time of generator \(g\in\mathcal{G}\) in [h]
  • \(T^{down}_g\) - Minimum down time of generator \(g\in\mathcal{G}\) in [h]
  • \(R^{up}_g\) - Maximum ramp-up rate of generator \(g\in\mathcal{G}\) in [MW/h]
  • \(R^{down}_g\) - Maximum ramp-down rate of generator \(g\in\mathcal{G}\) in [MW/h]

Decision Variables

  • \(p_{g,t}\) - Power output of thermal generator \(g\in\mathcal{G}\) at time \(t\)
  • \(p_{w,t}\) - Power injection of wind turbine \(w\in\mathcal{W}\) at time \(t\)
  • \(u_{g,t}\) - Binary variable indicating if generator \(g\in\mathcal{G}\) is on at time \(t\)

Model Formulation

Objective Function

\(\text{Minimize} \quad \sum_{t \in \mathcal{T}} \left( \sum_{g \in \mathcal{G}} (C^{var}_g p_{g,t} + C^{fix}_g u_{g,t}) + \sum_{w \in \mathcal{W}} C^{var}_w p_{w,t} \right)\)

The objective includes:

  • Variable costs for power generation (\(C^{var}_g p_{g,t}\)): Cost per hour of electricity produced
  • Fixed costs for keeping generators on (\(C^{fix}_g u_{g,t}\)): Cost of maintaining a generator in operation
  • Wind power costs (\(C^{var}_w p_{w,t}\)): Variable costs per hour for wind power production

Power Balance Constraints

\(\sum_{g \in \mathcal{G}} p_{g,t} + \sum_{w \in \mathcal{W}} p_{w,t} = D^f_t \quad \forall t \in \mathcal{T}\)

Tip

This constraint ensures that at each time step \(t\): - The sum of all thermal generator outputs (\(\sum_{g \in \mathcal{G}} p_{g,t}\)) - Plus all wind power outputs (\(\sum_{w \in \mathcal{W}} p_{w,t}\)) - Must exactly match the forecasted demand (\(D^f_t\))

Generator Limits Constraints

\(P^{\min}_g u_{g,t} \leq p_{g,t} \leq P^{\max}_g u_{g,t} \quad \forall g \in \mathcal{G}, t \in \mathcal{T}\)

Tip

For each generator \(g\) at time \(t\): - If the generator is on (\(u_{g,t} = 1\)), its output must be between minimum (\(P^{\min}_g\)) and maximum (\(P^{\max}_g\)) power - If the generator is off (\(u_{g,t} = 0\)), its output must be zero - The binary variable \(u_{g,t}\) ensures these limits are enforced

Wind Power Injection Constraints

\(0 \leq p_{w,t} \leq P^f_{w,t} \quad \forall w \in \mathcal{W}, t \in \mathcal{T}\)

Tip

For each wind turbine \(w\) at time \(t\): - Power output must be non-negative - Cannot exceed the forecasted available wind power (\(P^f_{w,t}\)) - Unlike thermal generators, wind turbines don’t have binary variables as the power injection is controllable between 0 and the forecasted available wind power

Minimum Up/Down Time Constraints

\(u_{g,t} - u_{g,t-1} \leq u_{g,\tau} \quad \forall g \in \mathcal{G}, t \in \mathcal{T}, \tau \in [t+1, \min(t+T^{up}_g-1,|\mathcal{T}|)]\)

\(u_{g,t-1} - u_{g,t} \leq 1 - u_{g,\tau} \quad \forall g \in \mathcal{G}, t \in \mathcal{T}, \tau \in [t+1, \min(t+T^{down}_g-1,|\mathcal{T}|)]\)

Tip

These constraints enforce minimum operating times: - First equation: If a generator starts up at time \(t\), it must stay on for at least \(T^{up}_g\) time periods - Second equation: If a generator shuts down at time \(t\), it must stay off for at least \(T^{down}_g\) time periods - \(\tau\) represents the time periods during which these constraints must be enforced

Ramp Rate Constraints

\(p_{g,t} - p_{g,t-1} \leq R^{up}_g \quad \forall g \in \mathcal{G}, t \in \mathcal{T}\)

\(p_{g,t-1} - p_{g,t} \leq R^{down}_g \quad \forall g \in \mathcal{G}, t \in \mathcal{T}\)

Tip

These constraints limit how quickly generators can change their output: - First equation: Power increase between consecutive time steps cannot exceed ramp-up rate \(R^{up}_g\) - Second equation: Power decrease between consecutive time steps cannot exceed ramp-down rate \(R^{down}_g\) - Prevents sudden changes in generator output that could damage equipment

Complete Unit Commitment Model

\(\text{Minimize} \quad \sum_{t \in \mathcal{T}} \left( \sum_{g \in \mathcal{G}} (C^{var}_g p_{g,t} + C^{fix}_g u_{g,t}) + \sum_{w \in \mathcal{W}} C^{var}_w p_{w,t} \right)\)

subject to

\(\sum_{g \in \mathcal{G}} p_{g,t} + \sum_{w \in \mathcal{W}} p_{w,t} = D^f_t \quad \forall t \in \mathcal{T}\)

\(P^{\min}_g u_{g,t} \leq p_{g,t} \leq P^{\max}_g u_{g,t} \quad \forall g \in \mathcal{G}, t \in \mathcal{T}\)

\(0 \leq p_{w,t} \leq P^f_{w,t} \quad \forall w \in \mathcal{W}, t \in \mathcal{T}\)

\(u_{g,t} - u_{g,t-1} \leq u_{g,\tau} \quad \forall g \in \mathcal{G}, t \in \mathcal{T}, \tau \in [t+1, \min(t+T^{up}_g-1,|\mathcal{T}|)]\)

\(u_{g,t-1} - u_{g,t} \leq 1 - u_{g,\tau} \quad \forall g \in \mathcal{G}, t \in \mathcal{T}, \tau \in [t+1, \min(t+T^{down}_g-1,|\mathcal{T}|)]\)

\(p_{g,t} - p_{g,t-1} \leq R^{up}_g \quad \forall g \in \mathcal{G}, t \in \mathcal{T}\)

\(p_{g,t-1} - p_{g,t} \leq R^{down}_g \quad \forall g \in \mathcal{G}, t \in \mathcal{T}\)

\(u_{g,t} \in \{0,1\} \quad \forall g \in \mathcal{G}, t \in \mathcal{T}\)

Model Characteristics

Model Type

Question: What type of optimization problem is this?

  • Mixed-Integer Linear Programming (MILP)
  • Binary variables for generator status
  • Linear constraints and objective
  • Time-dependent decisions

Solution Methods

Question: How can we solve this problem?

  • Branch and Bound algorithm
  • Commercial solvers (Gurobi, CPLEX)
  • Open-source solvers (HiGHS)
  • Decomposition methods for large problems

Computational Challenges

Question: What makes this problem challenging?

  • Large number of binary variables
  • Time-dependent inter-temporal constraints
  • Minimum up/down time constraints
  • Ramp rate constraints
  • Multiple time periods

Impact

Real-World Applications

  • Generation scheduling
  • Day-ahead market clearing
  • Ancillary services
  • Reserve capacity planning

Further Extensions

  • Battery storage
  • Demand response
  • Network constraints
  • Reserve requirements
  • Multiple fuel types
  • Emission constraints
  • Uncertainty in forecasts

And that’s it for today’s lecture!

We have covered the Unit Commitment problem and its mathematical formulation. The tutorial will help you implement and solve this problem using Julia and JuMP.

Questions?

Literature

Literature I

For more interesting literature to learn more about Julia, take a look at the literature list of this course.

Literature II

For a detailed mathematical formulation of the Unit Commitment problem, see Morales-Espana, Latorre, and Ramos (2013) and Zimmermann and Kather (2019).

Morales-Espana, G., J. M. Latorre, and A. Ramos. 2013. “Tight and Compact MILP Formulation for the Thermal Unit Commitment Problem.” IEEE Transactions on Power Systems 28 (4): 4897–4908.
Zimmermann, Cors, T., and A. Kather. 2019. “Increasing Tightness by Introduction of Intertemporal Constraints in MILP Unit Commitment.” In NEIS 2019; Conference on Sustainable Energy Supply and Energy Storage Systems, edited by Detlef Schulz, 209–14. VDE Verl.