Improve docs

pull/24/head
Alinson S. Xavier 3 years ago
parent 18daaf5358
commit 5fef01cd99

@ -1,3 +1,4 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
UnitCommitment = "64606440-39ea-11e9-0f29-3303a1d3d877"

@ -16,13 +16,15 @@ UnitCommitment.write
```@docs
UnitCommitment.slice
UnitCommitment.randomize!
generate_initial_conditions!
UnitCommitment.randomize!(::UnitCommitment.UnitCommitmentInstance)
UnitCommitment.generate_initial_conditions!
```
## Formulations
```@docs
UnitCommitment.Formulation
UnitCommitment.ShiftFactorsFormulation
UnitCommitment.ArrCon2000
UnitCommitment.CarArr2006
UnitCommitment.DamKucRajAta2016
@ -36,13 +38,11 @@ UnitCommitment.WanHob2016
## Solution Methods
```@docs
UnitCommitment.XavQiuWanThi2019
UnitCommitment.XavQiuWanThi2019.Method
```
## Randomization Methods
```@docs
UnitCommitment.XavQiuAhm2021
UnitCommitment.XavQiuAhm2021.Randomization
```
```

@ -13,15 +13,13 @@ const INSTANCES_URL = "https://axavier.org/UnitCommitment.jl/0.3/instances"
"""
read_benchmark(name::AbstractString)::UnitCommitmentInstance
Read one of the benchmark unit commitment instances included in the package.
See "Instances" section of the documentation for the entire list of benchmark
instances available.
Read one of the benchmark instances included in the package. See
[Instances](instances.md) for the entire list of benchmark instances available.
Example
-------
import UnitCommitment
instance = UnitCommitment.read_benchmark("matpower/case3375wp/2017-02-01")
# Example
```julia
instance = UnitCommitment.read_benchmark("matpower/case3375wp/2017-02-01")
```
"""
function read_benchmark(
name::AbstractString;
@ -48,13 +46,13 @@ end
"""
read(path::AbstractString)::UnitCommitmentInstance
Read a unit commitment instance from a file. The file may be gzipped.
Read instance from a file. The file may be gzipped.
Example
-------
# Example
import UnitCommitment
instance = UnitCommitment.read("/path/to/input.json.gz")
```julia
instance = UnitCommitment.read("/path/to/input.json.gz")
```
"""
function read(path::AbstractString)::UnitCommitmentInstance
if endswith(path, ".gz")

@ -9,22 +9,59 @@ import JuMP: value, fix, set_name
function build_model(;
instance::UnitCommitmentInstance,
optimizer = nothing,
formulation = Formulation(),
variable_names::Bool = false,
)::JuMP.Model
Build the JuMP model corresponding to the given unit commitment instance.
Arguments
=========
---------
- `instance`:
the instance.
- `optimizer`:
the optimizer factory that should be attached to this model (e.g. Cbc.Optimizer).
If not provided, no optimizer will be attached.
- `formulation`:
the MIP formulation to use. By default, uses a formulation that combines
modeling components from different publications that provides good
performance across a wide variety of instances. An alternative formulation
may also be provided.
- `variable_names`:
If true, set variable and constraint names. Important if the model is going
if true, set variable and constraint names. Important if the model is going
to be exported to an MPS file. For large models, this can take significant
time, so it's disabled by default.
Examples
--------
```julia
# Read benchmark instance
instance = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
# Construct model (using state-of-the-art defaults)
model = UnitCommitment.build_model(
instance = instance,
optimizer = Cbc.Optimizer,
)
# Construct model (using customized formulation)
model = UnitCommitment.build_model(
instance = instance,
optimizer = Cbc.Optimizer,
formulation = Formulation(
pwl_costs = KnuOstWat2018.PwlCosts(),
ramping = MorLatRam2013.Ramping(),
startup_costs = MorLatRam2013.StartupCosts(),
transmission = ShiftFactorsFormulation(
isf_cutoff = 0.005,
lodf_cutoff = 0.001,
),
),
)
```
"""
function build_model(;
instance::UnitCommitmentInstance,

@ -9,6 +9,27 @@ abstract type StartupCostsFormulation end
abstract type StatusVarsFormulation end
abstract type ProductionVarsFormulation end
"""
struct Formulation
prod_vars::ProductionVarsFormulation
pwl_costs::PiecewiseLinearCostsFormulation
ramping::RampingFormulation
startup_costs::StartupCostsFormulation
status_vars::StatusVarsFormulation
transmission::TransmissionFormulation
end
Struct provided to `build_model` that holds various formulation components.
# Fields
- `prod_vars`: Formulation for the production decision variables
- `pwl_costs`: Formulation for the piecewise linear costs
- `ramping`: Formulation for ramping constraints
- `startup_costs`: Formulation for time-dependent start-up costs
- `status_vars`: Formulation for the status variables (e.g. `is_on`, `is_off`)
- `transmission`: Formulation for transmission and N-1 security constraints
"""
struct Formulation
prod_vars::ProductionVarsFormulation
pwl_costs::PiecewiseLinearCostsFormulation
@ -38,10 +59,10 @@ end
"""
struct ShiftFactorsFormulation <: TransmissionFormulation
isf_cutoff::Float64
lodf_cutoff::Float64
precomputed_isf::Union{Nothing,Matrix{Float64}}
precomputed_lodf::Union{Nothing,Matrix{Float64}}
isf_cutoff::Float64 = 0.005
lodf_cutoff::Float64 = 0.001
precomputed_isf=nothing
precomputed_lodf=nothing
end
Transmission formulation based on Injection Shift Factors (ISF) and Line
@ -49,15 +70,15 @@ Outage Distribution Factors (LODF). Constraints are enforced in a lazy way.
Arguments
---------
- `precomputed_isf::Union{Matrix{Float64},Nothing} = nothing`:
- `precomputed_isf`:
the injection shift factors matrix. If not provided, it will be computed.
- `precomputed_lodf::Union{Matrix{Float64},Nothing} = nothing`:
- `precomputed_lodf`:
the line outage distribution factors matrix. If not provided, it will be
computed.
- `isf_cutoff::Float64 = 0.005`:
- `isf_cutoff`:
the cutoff that should be applied to the ISF matrix. Entries with magnitude
smaller than this value will be set to zero.
- `lodf_cutoff::Float64 = 0.001`:
- `lodf_cutoff`:
the cutoff that should be applied to the LODF matrix. Entries with magnitude
smaller than this value will be set to zero.
"""

@ -2,14 +2,6 @@
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
"""
Lazy constraint solution method described in:
Xavier, A. S., Qiu, F., Wang, F., & Thimmapuram, P. R. (2019). Transmission
constraint filtering in large-scale security-constrained unit commitment.
IEEE Transactions on Power Systems, 34(3), 2457-2460.
DOI: https://doi.org/10.1109/TPWRS.2019.2892620
"""
module XavQiuWanThi2019
import ..SolutionMethod
"""
@ -21,6 +13,13 @@ import ..SolutionMethod
max_violations_per_period::Int
end
Lazy constraint solution method described in:
Xavier, A. S., Qiu, F., Wang, F., & Thimmapuram, P. R. (2019). Transmission
constraint filtering in large-scale security-constrained unit commitment.
IEEE Transactions on Power Systems, 34(3), 2457-2460.
DOI: https://doi.org/10.1109/TPWRS.2019.2892620
Fields
------

@ -3,9 +3,9 @@
# Released under the modified BSD license. See COPYING.md for more details.
"""
function optimize!(model::JuMP.Model)::Nothing
optimize!(model::JuMP.Model)::Nothing
Solve the given unit commitment model. Unlike JuMP.optimize!, this uses more
Solve the given unit commitment model. Unlike `JuMP.optimize!`, this uses more
advanced methods to accelerate the solution process and to enforce transmission
and N-1 security constraints.
"""

@ -2,6 +2,18 @@
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
"""
solution(model::JuMP.Model)::OrderedDict
Extracts the optimal solution from the UC.jl model. The model must be solved beforehand.
# Example
```julia
UnitCommitment.optimize!(model)
solution = UnitCommitment.solution(model)
```
"""
function solution(model::JuMP.Model)::OrderedDict
instance, T = model[:instance], model[:instance].time
function timeseries(vars, collection)

@ -2,6 +2,18 @@
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
"""
write(filename::AbstractString, solution::AbstractDict)::Nothing
Write the given solution to a JSON file.
# Example
```julia
solution = UnitCommitment.solution(model)
UnitCommitment.write("/tmp/output.json", solution)
```
"""
function write(filename::AbstractString, solution::AbstractDict)::Nothing
open(filename, "w") do file
return JSON.print(file, solution, 2)

@ -2,13 +2,6 @@
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
"""
Methods described in:
Xavier, Álinson S., Feng Qiu, and Shabbir Ahmed. "Learning to solve
large-scale security-constrained unit commitment problems." INFORMS
Journal on Computing 33.2 (2021): 739-756. DOI: 10.1287/ijoc.2020.0976
"""
module XavQiuAhm2021
using Distributions
@ -55,6 +48,13 @@ load profile, as follows:
The default parameters were obtained based on an analysis of publicly available
bid and hourly data from PJM, corresponding to the month of January, 2017. For
more details, see Section 4.2 of the paper.
# References
- **Xavier, Álinson S., Feng Qiu, and Shabbir Ahmed.** *"Learning to solve
large-scale security-constrained unit commitment problems."* INFORMS Journal
on Computing 33.2 (2021): 739-756. DOI: 10.1287/ijoc.2020.0976
"""
Base.@kwdef struct Randomization
cost = Uniform(0.95, 1.05)
@ -212,4 +212,31 @@ function randomize!(
return
end
"""
function randomize!(
instance::UnitCommitmentInstance;
method = UnitCommitment.XavQiuAhm2021.Randomization();
rng = MersenneTwister(),
)::Nothing
Randomizes instance parameters according to the provided randomization method.
# Example
```julia
instance = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
UnitCommitment.randomize!(instance)
model = UnitCommitment.build_model(; instance)
```
"""
function randomize!(
instance::UnitCommitment.UnitCommitmentInstance;
method = XavQiuAhm2021.Randomization(),
rng = MersenneTwister(),
)::Nothing
randomize!(instance, method; rng)
return
end
export randomize!

@ -12,10 +12,11 @@ conditions are also not modified.
Example
-------
# Build a 2-hour UC instance
instance = UnitCommitment.read_benchmark("test/case14")
modified = UnitCommitment.slice(instance, 1:2)
```julia
# Build a 2-hour UC instance
instance = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
modified = UnitCommitment.slice(instance, 1:2)
```
"""
function slice(
instance::UnitCommitmentInstance,

@ -30,7 +30,9 @@ test_approx(x, y) = @test isapprox(x, y, atol = 1e-3)
randomize!(
instance,
XavQiuAhm2021.Randomization(randomize_load_profile = false),
method = XavQiuAhm2021.Randomization(
randomize_load_profile = false,
),
rng = MersenneTwister(42),
)

Loading…
Cancel
Save