The SteelT3 problem

The steelT3 model from AMPL: A Modeling Language for Mathematical Programming, 2nd ed by Robert Fourer, David Gay, and Brian W. Kernighan.

Originally contributed by Louis Luangkesorn, April 3, 2015.

using JuMP
import HiGHS
import Test

function example_steelT3(; verbose = true)
    T = 4
    prod = ["bands", "coils"]
    area = Dict(
        "bands" => ("east", "north"),
        "coils" => ("east", "west", "export"),
    )
    avail = [40, 40, 32, 40]
    rate = Dict("bands" => 200, "coils" => 140)
    inv0 = Dict("bands" => 10, "coils" => 0)
    prodcost = Dict("bands" => 10, "coils" => 11)
    invcost = Dict("bands" => 2.5, "coils" => 3)
    revenue = Dict(
        "bands" => Dict(
            "east" => [25.0, 26.0, 27.0, 27.0],
            "north" => [26.5, 27.5, 28.0, 28.5],
        ),
        "coils" => Dict(
            "east" => [30, 35, 37, 39],
            "west" => [29, 32, 33, 35],
            "export" => [25, 25, 25, 28],
        ),
    )
    market = Dict(
        "bands" => Dict(
            "east" => [2000, 2000, 1500, 2000],
            "north" => [4000, 4000, 2500, 4500],
        ),
        "coils" => Dict(
            "east" => [1000, 800, 1000, 1100],
            "west" => [2000, 1200, 2000, 2300],
            "export" => [1000, 500, 500, 800],
        ),
    )
    # Model
    model = Model(HiGHS.Optimizer)
    # Decision Variables
    @variables(
        model,
        begin
            make[p in prod, t in 1:T] >= 0
            inventory[p in prod, t in 0:T] >= 0
            0 <= sell[p in prod, a in area[p], t in 1:T] <= market[p][a][t]
        end
    )
    @constraints(
        model,
        begin
            [p = prod, a = area[p], t = 1:T], sell[p, a, t] <= market[p][a][t]
            # Total of hours used by all products may not exceed hours available,
            # in each week
            [t in 1:T], sum(1 / rate[p] * make[p, t] for p in prod) <= avail[t]
            # Initial inventory must equal given value
            [p in prod], inventory[p, 0] == inv0[p]
            # Tons produced and taken from inventory must equal tons sold and put
            # into inventory.
            [p in prod, t in 1:T],
            make[p, t] + inventory[p, t-1] ==
            sum(sell[p, a, t] for a in area[p]) + inventory[p, t]
        end
    )
    # Maximize total profit: total revenue less costs for all products in all
    # weeks.
    @objective(
        model,
        Max,
        sum(
            revenue[p][a][t] * sell[p, a, t] - prodcost[p] * make[p, t] -
            invcost[p] * inventory[p, t] for p in prod, a in area[p], t in 1:T
        )
    )
    optimize!(model)
    Test.@test termination_status(model) == OPTIMAL
    Test.@test primal_status(model) == FEASIBLE_POINT
    Test.@test objective_value(model) == 172850.0
    if verbose
        println("RESULTS:")
        for p in prod
            println("make $(p)")
            for t in 1:T
                print(value(make[p, t]), "\t")
            end
            println()
            println("Inventory $(p)")
            for t in 1:T
                print(value(inventory[p, t]), "\t")
            end
            println()
            for a in area[p]
                println("sell $(p) $(a)")
                for t in 1:T
                    print(value(sell[p, a, t]), "\t")
                end
                println()
            end
        end
    end
    return
end

example_steelT3()
Presolving model
12 rows, 36 cols, 50 nonzeros
11 rows, 32 cols, 45 nonzeros
Presolve : Reductions: rows 11(-23); columns 32(-6); elements 45(-29)
Solving the presolved LP
Using EKK dual simplex solver - serial
  Iteration        Objective     Infeasibilities num(sum)
          0     0.0000000000e+00 Ph1: 0(0) 0s
         13    -1.7285000000e+05 Pr: 0(0) 0s
Solving the original LP from the solution after postsolve
Model   status      : Optimal
Simplex   iterations: 13
Objective value     :  1.7285000000e+05
HiGHS run time      :          0.00
RESULTS:
make bands
5990.0	6000.0	4000.0	6500.0
Inventory bands
0.0	0.0	0.0	0.0
sell bands east
2000.0	2000.0	1500.0	2000.0
sell bands north
4000.0	4000.0	2500.0	4500.0
make coils
-0.0	800.0	1000.0	1050.0
Inventory coils
0.0	0.0	0.0	0.0
sell coils east
0.0	800.0	1000.0	1050.0
sell coils west
0.0	0.0	0.0	0.0
sell coils export
0.0	0.0	0.0	0.0

Tip

This tutorial was generated using Literate.jl. View the source .jl file on GitHub.