# Simple Warehouse Problem (WHOUSE)#

`whouse.py`

```"""
## GAMSSOURCE: https://www.gams.com/latest/gamslib_ml/libhtml/gamslib_whouse.html
## MODELTYPE: LP
## KEYWORDS: linear programming, warehouse management, inventory

Simple Warehouse Problem (WHOUSE)

A warehouse can store limited units of a commodity. Given an
initial stock, the manager has to decide when to buy or sell in
order to minimize total cost.

Dantzig, G B, Chapter 3.6. In Linear Programming and Extensions.
Princeton University Press, Princeton, New Jersey, 1963.
"""

from __future__ import annotations

import os

import numpy as np
from gamspy import (
Container,
Equation,
Model,
Parameter,
Sense,
Set,
Sum,
Variable,
)

def main():
m = Container(
system_directory=os.getenv("SYSTEM_DIRECTORY", None),
)

# Sets
t = Set(
m,
name="t",
records=[f"q-{i}" for i in range(1, 5)],
description="time in quarters",
)

# Parameters
price = Parameter(
m,
name="price",
domain=t,
records=np.array([10, 12, 8, 9]),
description="selling price (\$ per unit)",
)
istock = Parameter(
m,
name="istock",
domain=t,
records=np.array([50, 0, 0, 0]),
description="initial stock      (units)",
)  # OR records=pd.DataFrame([["q-1", 50]])

# Scalars
storecost = Parameter(
m,
name="storecost",
records=1,
description="storage cost  (\$ per quarter per unit)",
)
storecap = Parameter(
m,
name="storecap",
records=100,
description="stocking capacity of warehouse (units)",
)

# Variables
stock = Variable(
m,
name="stock",
domain=t,
type="Positive",
description="stock stored at time t (units)",
)
sell = Variable(
m,
name="sell",
domain=t,
type="Positive",
description="stock sold at time t   (units)",
)
m,
domain=t,
type="Positive",
description="stock bought at time t (units)",
)

# Equations
sb = Equation(
m, name="sb", domain=t, description="stock balance at time t (units)"
)

sb[t] = (
stock[t] == stock[t.lag(1, "linear")] + buy[t] - sell[t] + istock[t]
)

# ObjectFunction; accounting: total cost      (\$)
at = Sum(t, price[t] * (buy[t] - sell[t]) + storecost * stock[t])

stock.up[t] = storecap

swp = Model(
m,
name="swp",
equations=m.getEquations(),
problem="LP",
sense=Sense.MIN,
objective=at,
)
swp.solve()

import math

assert math.isclose(swp.objective_value, -600, rel_tol=0.001)

print("Objective function value: ", swp.objective_value)

if __name__ == "__main__":
main()
```