Deterministic All Blacks

using SDDP, HiGHS, Test

function all_blacks()
    # Number of time periods, number of seats, R_ij = evenue from selling seat
    # i at time j, offer_ij = whether an offer for seat i will come at time j
    (T, N, R, offer) = (3, 2, [3 3 6; 3 3 6], [1 1 0; 1 0 1])
    model = SDDP.LinearPolicyGraph(
        stages = T,
        sense = :Max,
        upper_bound = 100.0,
        optimizer = HiGHS.Optimizer,
    ) do sp, stage
        # Seat remaining?
        @variable(sp, 0 <= x[1:N] <= 1, SDDP.State, Bin, initial_value = 1)
        # Action: accept offer, or don't accept offer
        @variable(sp, accept_offer, Bin)
        # Balance on seats
        @constraint(
            sp,
            [i in 1:N],
            x[i].out == x[i].in - offer[i, stage] * accept_offer
        )
        @stageobjective(
            sp,
            sum(R[i, stage] * offer[i, stage] * accept_offer for i in 1:N)
        )
    end
    SDDP.train(
        model,
        iteration_limit = 10,
        log_frequency = 5,
        duality_handler = SDDP.LagrangianDuality(),
    )
    @test SDDP.calculate_bound(model) ≈ 9.0
    return
end

all_blacks()
------------------------------------------------------------------------------
          SDDP.jl (c) Oscar Dowson and SDDP.jl contributors, 2017-23

Problem
  Nodes           : 3
  State variables : 2
  Scenarios       : 1.00000e+00
  Existing cuts   : false
  Subproblem structure                      : (min, max)
    Variables                               : (6, 6)
    VariableRef in MOI.LessThan{Float64}    : (3, 3)
    VariableRef in MOI.ZeroOne              : (3, 3)
    VariableRef in MOI.GreaterThan{Float64} : (2, 3)
    AffExpr in MOI.EqualTo{Float64}         : (2, 2)
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, 6e+00]
  Non-zero Bounds range     [1e+00, 1e+02]
  Non-zero RHS range        [0e+00, 0e+00]
No problems detected

 Iteration    Simulation       Bound         Time (s)    Proc. ID   # Solves
        5L   9.000000e+00   9.000000e+00   6.640577e-02          1         30
       10L   9.000000e+00   9.000000e+00   7.874584e-02          1         60

Terminating training
  Status         : iteration_limit
  Total time (s) : 7.874584e-02
  Total solves   : 60
  Best bound     :  9.000000e+00
  Simulation CI  :  8.700000e+00 ± 5.880000e-01
------------------------------------------------------------------------------

This page was generated using Literate.jl.