From 821d48bdc6c237df42107b170490b8470515c527 Mon Sep 17 00:00:00 2001 From: Alinson S Xavier Date: Thu, 17 Jun 2021 10:17:50 -0500 Subject: [PATCH] Implement instance randomization --- Project.toml | 2 ++ src/UnitCommitment.jl | 1 + src/transform/randomize.jl | 53 ++++++++++++++++++++++++++++++++ src/utils/sysimage.jl | 10 +++++- test/runtests.jl | 1 + test/transform/randomize_test.jl | 43 ++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 src/transform/randomize.jl create mode 100644 test/transform/randomize_test.jl diff --git a/Project.toml b/Project.toml index a4096a4..888cf8e 100644 --- a/Project.toml +++ b/Project.toml @@ -6,6 +6,7 @@ version = "0.2.1" [deps] DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" GZip = "92fee26a-97fe-5a0c-ad85-20a5f3185b63" JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" @@ -19,6 +20,7 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [compat] Cbc = "0.7" DataStructures = "0.18" +Distributions = "0.25" GZip = "0.5" JSON = "0.21" JuMP = "0.21" diff --git a/src/UnitCommitment.jl b/src/UnitCommitment.jl index 9877392..5b727a6 100644 --- a/src/UnitCommitment.jl +++ b/src/UnitCommitment.jl @@ -48,6 +48,7 @@ include("solution/warmstart.jl") include("solution/write.jl") include("transform/initcond.jl") include("transform/slice.jl") +include("transform/randomize.jl") include("utils/log.jl") include("validation/repair.jl") include("validation/validate.jl") diff --git a/src/transform/randomize.jl b/src/transform/randomize.jl new file mode 100644 index 0000000..f8d5bbe --- /dev/null +++ b/src/transform/randomize.jl @@ -0,0 +1,53 @@ +# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment +# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved. +# Released under the modified BSD license. See COPYING.md for more details. + +using Distributions + +function randomize_unit_costs!( + instance::UnitCommitmentInstance; + distribution = Uniform(0.95, 1.05), +)::Nothing + for unit in instance.units + α = rand(distribution) + unit.min_power_cost *= α + for k in unit.cost_segments + k.cost *= α + end + for s in unit.startup_categories + s.cost *= α + end + end + return +end + +function randomize_load_distribution!( + instance::UnitCommitmentInstance; + distribution = Uniform(0.90, 1.10), +)::Nothing + α = rand(distribution, length(instance.buses)) + for t in 1:instance.time + total = sum(bus.load[t] for bus in instance.buses) + den = sum( + bus.load[t] / total * α[i] for + (i, bus) in enumerate(instance.buses) + ) + for (i, bus) in enumerate(instance.buses) + bus.load[t] *= α[i] / den + end + end + return +end + +function randomize_peak_load!( + instance::UnitCommitmentInstance; + distribution = Uniform(0.925, 1.075), +)::Nothing + α = rand(distribution) + for bus in instance.buses + bus.load *= α + end + return +end + +export randomize_unit_costs!, randomize_load_distribution!, randomize_peak_load! diff --git a/src/utils/sysimage.jl b/src/utils/sysimage.jl index 804c702..b51f6be 100644 --- a/src/utils/sysimage.jl +++ b/src/utils/sysimage.jl @@ -5,12 +5,20 @@ using PackageCompiler using DataStructures +using Distributions using JSON using JuMP using MathOptInterface using SparseArrays -pkg = [:DataStructures, :JSON, :JuMP, :MathOptInterface, :SparseArrays] +pkg = [ + :DataStructures, + :Distributions, + :JSON, + :JuMP, + :MathOptInterface, + :SparseArrays, +] @info "Building system image..." create_sysimage( diff --git a/test/runtests.jl b/test/runtests.jl index 2d9b31c..bec2a3b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -26,6 +26,7 @@ UnitCommitment._setup_logger() @testset "transform" begin include("transform/initcond_test.jl") include("transform/slice_test.jl") + include("transform/randomize_test.jl") end @testset "validation" begin include("validation/repair_test.jl") diff --git a/test/transform/randomize_test.jl b/test/transform/randomize_test.jl new file mode 100644 index 0000000..a1f415e --- /dev/null +++ b/test/transform/randomize_test.jl @@ -0,0 +1,43 @@ +# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment +# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. +# Released under the modified BSD license. See COPYING.md for more details. + +using UnitCommitment, Cbc, JuMP + +_get_instance() = UnitCommitment.read_benchmark("matpower/case118/2017-02-01") +_total_load(instance) = sum(b.load[1] for b in instance.buses) + +@testset "randomize_unit_costs!" begin + instance = _get_instance() + unit = instance.units[10] + prev_min_power_cost = unit.min_power_cost + prev_prod_cost = unit.cost_segments[1].cost + prev_startup_cost = unit.startup_categories[1].cost + randomize_unit_costs!(instance) + @test prev_min_power_cost != unit.min_power_cost + @test prev_prod_cost != unit.cost_segments[1].cost + @test prev_startup_cost != unit.startup_categories[1].cost +end + +@testset "randomize_load_distribution!" begin + instance = _get_instance() + bus = instance.buses[1] + prev_load = instance.buses[1].load[1] + prev_total_load = _total_load(instance) + randomize_load_distribution!(instance) + curr_total_load = _total_load(instance) + @test prev_load != instance.buses[1].load[1] + @test abs(prev_total_load - curr_total_load) < 1e-3 +end + +@testset "randomize_peak_load!" begin + instance = _get_instance() + bus = instance.buses[1] + prev_total_load = _total_load(instance) + prev_share = bus.load[1] / prev_total_load + randomize_peak_load!(instance) + curr_total_load = _total_load(instance) + curr_share = bus.load[1] / prev_total_load + @test curr_total_load != prev_total_load + @test abs(curr_share - prev_share) < 1e-3 +end