mirror of
https://github.com/ANL-CEEESA/UnitCommitment.jl.git
synced 2025-12-09 17:48:52 -06:00
stochastic extension
This commit is contained in:
@@ -5,18 +5,18 @@
|
||||
using JuMP
|
||||
|
||||
"""
|
||||
generate_initial_conditions!(instance, optimizer)
|
||||
generate_initial_conditions!(sc, optimizer)
|
||||
|
||||
Generates feasible initial conditions for the given instance, by constructing
|
||||
Generates feasible initial conditions for the given scenario, by constructing
|
||||
and solving a single-period mixed-integer optimization problem, using the given
|
||||
optimizer. The instance is modified in-place.
|
||||
optimizer. The scenario is modified in-place.
|
||||
"""
|
||||
function generate_initial_conditions!(
|
||||
instance::UnitCommitmentInstance,
|
||||
sc::UnitCommitmentScenario,
|
||||
optimizer,
|
||||
)::Nothing
|
||||
G = instance.units
|
||||
B = instance.buses
|
||||
G = sc.units
|
||||
B = sc.buses
|
||||
t = 1
|
||||
mip = JuMP.Model(optimizer)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ module XavQiuAhm2021
|
||||
|
||||
using Distributions
|
||||
import ..UnitCommitmentInstance
|
||||
import ..UnitCommitmentScenario
|
||||
|
||||
"""
|
||||
struct Randomization
|
||||
@@ -119,10 +120,10 @@ end
|
||||
|
||||
function _randomize_costs(
|
||||
rng,
|
||||
instance::UnitCommitmentInstance,
|
||||
sc::UnitCommitmentScenario,
|
||||
distribution,
|
||||
)::Nothing
|
||||
for unit in instance.units
|
||||
for unit in sc.units
|
||||
α = rand(rng, distribution)
|
||||
unit.min_power_cost *= α
|
||||
for k in unit.cost_segments
|
||||
@@ -137,17 +138,15 @@ end
|
||||
|
||||
function _randomize_load_share(
|
||||
rng,
|
||||
instance::UnitCommitmentInstance,
|
||||
sc::UnitCommitmentScenario,
|
||||
distribution,
|
||||
)::Nothing
|
||||
α = rand(rng, 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)
|
||||
α = rand(rng, distribution, length(sc.buses))
|
||||
for t in 1:sc.time
|
||||
total = sum(bus.load[t] for bus in sc.buses)
|
||||
den =
|
||||
sum(bus.load[t] / total * α[i] for (i, bus) in enumerate(sc.buses))
|
||||
for (i, bus) in enumerate(sc.buses)
|
||||
bus.load[t] *= α[i] / den
|
||||
end
|
||||
end
|
||||
@@ -156,12 +155,12 @@ end
|
||||
|
||||
function _randomize_load_profile(
|
||||
rng,
|
||||
instance::UnitCommitmentInstance,
|
||||
sc::UnitCommitmentScenario,
|
||||
params::Randomization,
|
||||
)::Nothing
|
||||
# Generate new system load
|
||||
system_load = [1.0]
|
||||
for t in 2:instance.time
|
||||
for t in 2:sc.time
|
||||
idx = (t - 1) % length(params.load_profile_mu) + 1
|
||||
gamma = rand(
|
||||
rng,
|
||||
@@ -169,14 +168,14 @@ function _randomize_load_profile(
|
||||
)
|
||||
push!(system_load, system_load[t-1] * gamma)
|
||||
end
|
||||
capacity = sum(maximum(u.max_power) for u in instance.units)
|
||||
capacity = sum(maximum(u.max_power) for u in sc.units)
|
||||
peak_load = rand(rng, params.peak_load) * capacity
|
||||
system_load = system_load ./ maximum(system_load) .* peak_load
|
||||
|
||||
# Scale bus loads to match the new system load
|
||||
prev_system_load = sum(b.load for b in instance.buses)
|
||||
for b in instance.buses
|
||||
for t in 1:instance.time
|
||||
prev_system_load = sum(b.load for b in sc.buses)
|
||||
for b in sc.buses
|
||||
for t in 1:sc.time
|
||||
b.load[t] *= system_load[t] / prev_system_load[t]
|
||||
end
|
||||
end
|
||||
@@ -199,15 +198,26 @@ function randomize!(
|
||||
instance::UnitCommitment.UnitCommitmentInstance,
|
||||
method::XavQiuAhm2021.Randomization;
|
||||
rng = MersenneTwister(),
|
||||
)::Nothing
|
||||
for sc in instance.scenarios
|
||||
randomize!(sc; method, rng)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
function randomize!(
|
||||
sc::UnitCommitment.UnitCommitmentScenario;
|
||||
method::XavQiuAhm2021.Randomization,
|
||||
rng = MersenneTwister(),
|
||||
)::Nothing
|
||||
if method.randomize_costs
|
||||
XavQiuAhm2021._randomize_costs(rng, instance, method.cost)
|
||||
XavQiuAhm2021._randomize_costs(rng, sc, method.cost)
|
||||
end
|
||||
if method.randomize_load_share
|
||||
XavQiuAhm2021._randomize_load_share(rng, instance, method.load_share)
|
||||
XavQiuAhm2021._randomize_load_share(rng, sc, method.load_share)
|
||||
end
|
||||
if method.randomize_load_profile
|
||||
XavQiuAhm2021._randomize_load_profile(rng, instance, method)
|
||||
XavQiuAhm2021._randomize_load_profile(rng, sc, method)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
@@ -24,31 +24,33 @@ function slice(
|
||||
)::UnitCommitmentInstance
|
||||
modified = deepcopy(instance)
|
||||
modified.time = length(range)
|
||||
modified.power_balance_penalty = modified.power_balance_penalty[range]
|
||||
for r in modified.reserves
|
||||
r.amount = r.amount[range]
|
||||
end
|
||||
for u in modified.units
|
||||
u.max_power = u.max_power[range]
|
||||
u.min_power = u.min_power[range]
|
||||
u.must_run = u.must_run[range]
|
||||
u.min_power_cost = u.min_power_cost[range]
|
||||
for s in u.cost_segments
|
||||
s.mw = s.mw[range]
|
||||
s.cost = s.cost[range]
|
||||
for sc in modified.scenarios
|
||||
sc.power_balance_penalty = sc.power_balance_penalty[range]
|
||||
for r in sc.reserves
|
||||
r.amount = r.amount[range]
|
||||
end
|
||||
for u in sc.units
|
||||
u.max_power = u.max_power[range]
|
||||
u.min_power = u.min_power[range]
|
||||
u.must_run = u.must_run[range]
|
||||
u.min_power_cost = u.min_power_cost[range]
|
||||
for s in u.cost_segments
|
||||
s.mw = s.mw[range]
|
||||
s.cost = s.cost[range]
|
||||
end
|
||||
end
|
||||
for b in sc.buses
|
||||
b.load = b.load[range]
|
||||
end
|
||||
for l in sc.lines
|
||||
l.normal_flow_limit = l.normal_flow_limit[range]
|
||||
l.emergency_flow_limit = l.emergency_flow_limit[range]
|
||||
l.flow_limit_penalty = l.flow_limit_penalty[range]
|
||||
end
|
||||
for ps in sc.price_sensitive_loads
|
||||
ps.demand = ps.demand[range]
|
||||
ps.revenue = ps.revenue[range]
|
||||
end
|
||||
end
|
||||
for b in modified.buses
|
||||
b.load = b.load[range]
|
||||
end
|
||||
for l in modified.lines
|
||||
l.normal_flow_limit = l.normal_flow_limit[range]
|
||||
l.emergency_flow_limit = l.emergency_flow_limit[range]
|
||||
l.flow_limit_penalty = l.flow_limit_penalty[range]
|
||||
end
|
||||
for ps in modified.price_sensitive_loads
|
||||
ps.demand = ps.demand[range]
|
||||
ps.revenue = ps.revenue[range]
|
||||
end
|
||||
return modified
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user