Air conditioning

Taken from Anthony Papavasiliou's notes on SDDP

Consider the following problem

  • Produce air conditioners for 3 months
  • 200 units/month at 100 $/unit
  • Overtime costs 300 $/unit
  • Known demand of 100 units for period 1
  • Equally likely demand, 100 or 300 units, for periods 2, 3
  • Storage cost is 50 $/unit
  • All demand must be met

The known optimal solution is $62,500

using SDDP, HiGHS, Test

function air_conditioning_model(duality_handler)
    model = SDDP.LinearPolicyGraph(
        stages = 3,
        lower_bound = 0.0,
        optimizer = HiGHS.Optimizer,
    ) do sp, stage
        @variable(
            sp,
            0 <= stored_production <= 100,
            Int,
            SDDP.State,
            initial_value = 0
        )
        @variable(sp, 0 <= production <= 200, Int)
        @variable(sp, overtime >= 0, Int)
        @variable(sp, demand)
        DEMAND = [[100.0], [100.0, 300.0], [100.0, 300.0]]
        SDDP.parameterize(ω -> JuMP.fix(demand, ω), sp, DEMAND[stage])
        @constraint(
            sp,
            stored_production.out ==
            stored_production.in + production + overtime - demand
        )
        @stageobjective(
            sp,
            100 * production + 300 * overtime + 50 * stored_production.out
        )
    end
    SDDP.train(
        model,
        iteration_limit = 20,
        log_frequency = 10,
        duality_handler = duality_handler,
    )
    @test isapprox(SDDP.calculate_bound(model), 62_500.0, atol = 0.1)
    return
end

for duality_handler in [SDDP.LagrangianDuality(), SDDP.ContinuousConicDuality()]
    air_conditioning_model(duality_handler)
end
------------------------------------------------------------------------------
          SDDP.jl (c) Oscar Dowson and SDDP.jl contributors, 2017-23

Problem
  Nodes           : 3
  State variables : 1
  Scenarios       : 4.00000e+00
  Existing cuts   : false
  Subproblem structure                      : (min, max)
    Variables                               : (6, 6)
    VariableRef in MOI.LessThan{Float64}    : (2, 3)
    VariableRef in MOI.GreaterThan{Float64} : (4, 4)
    AffExpr in MOI.EqualTo{Float64}         : (1, 1)
    VariableRef in MOI.Integer              : (3, 3)
Options
  Solver          : serial mode
  Risk measure    : SDDP.Expectation()
  Sampling scheme : SDDP.InSampleMonteCarlo

Numerical stability report
  Non-zero Matrix range     [1e+00, 1e+00]
  Non-zero Objective range  [1e+00, 3e+02]
  Non-zero Bounds range     [1e+02, 2e+02]
  Non-zero RHS range        [0e+00, 0e+00]
No problems detected

 Iteration    Simulation       Bound         Time (s)    Proc. ID   # Solves
       10L   5.500000e+04   6.250000e+04   4.939551e-01          1         80
       20L   9.500000e+04   6.250000e+04   5.550611e-01          1        160

Terminating training
  Status         : iteration_limit
  Total time (s) : 5.550611e-01
  Total solves   : 160
  Best bound     :  6.250000e+04
  Simulation CI  :  6.557500e+04 ± 9.305594e+03
------------------------------------------------------------------------------
------------------------------------------------------------------------------
          SDDP.jl (c) Oscar Dowson and SDDP.jl contributors, 2017-23

Problem
  Nodes           : 3
  State variables : 1
  Scenarios       : 4.00000e+00
  Existing cuts   : false
  Subproblem structure                      : (min, max)
    Variables                               : (6, 6)
    VariableRef in MOI.LessThan{Float64}    : (2, 3)
    VariableRef in MOI.GreaterThan{Float64} : (4, 4)
    AffExpr in MOI.EqualTo{Float64}         : (1, 1)
    VariableRef in MOI.Integer              : (3, 3)
Options
  Solver          : serial mode
  Risk measure    : SDDP.Expectation()
  Sampling scheme : SDDP.InSampleMonteCarlo

Numerical stability report
  Non-zero Matrix range     [1e+00, 1e+00]
  Non-zero Objective range  [1e+00, 3e+02]
  Non-zero Bounds range     [1e+02, 2e+02]
  Non-zero RHS range        [0e+00, 0e+00]
No problems detected

 Iteration    Simulation       Bound         Time (s)    Proc. ID   # Solves
       10    6.000000e+04   6.250000e+04   2.546906e-02          1         80
       20    6.000000e+04   6.250000e+04   5.238819e-02          1        160

Terminating training
  Status         : iteration_limit
  Total time (s) : 5.238819e-02
  Total solves   : 160
  Best bound     :  6.250000e+04
  Simulation CI  :  6.675000e+04 ± 1.095154e+04
------------------------------------------------------------------------------

This page was generated using Literate.jl.