from dotenv import dotenv_values
= "../notebooks/.env"
fp = dotenv_values(fp) config
= "cbc"
SOLVER
from amplpy import AMPL, ampl_notebook
= ampl_notebook(
ampl =["cbc"], # modules to install
modules=config["AMPL_UUID"], # license to use
license_uuid# instantiate AMPL object and register magics )
%%writefile bakery.mod
; # number of samples
param N
;
param c;
param p;
param h
set indices := 1..N;
;
param xi{indices}
# first stage variable: x (amount of baguettes baked)
>=0;
var x integer
= -c * x;
var first_stage_profit
# second stage variables: y (sold) and z (unsold)
>=0;
var y{indices} integer >=0;
var z{indices} integer
# second stage constraints
in indices}: y[i] <= xi[i];
s.t. cantsellbaguettedonthave {i in indices}: y[i] + z[i] == x;
s.t. baguettedonotdisappear {i
= sum{i in indices}(p * y[i] - h * z[i]) / N;
var second_stage_profit
# objective
+ second_stage_profit; maximize total_expected_profit: first_stage_profit
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
import scipy.stats as stats
from scipy.stats import nbinom
# Two-stage stochastic LP using SAA
# Setting parameters
## TL;DR version on pricing Profit Index. Costs = Selling Price, selling price is known from data, profit index is 1.7
= 52
c = 90
p = 1
h # Two-stage stochastic LP using SAA
1)
np.random.seed(= 5000
N = 9.42
shape = (1/6.97)
intensity = nbinom.rvs(shape,intensity,size=N)
samples = AMPL()
ampl "bakery.mod")
ampl.read(
# Load the data
"N"] = int(N)
ampl.param["xi"] = samples
ampl.param["c"] = c
ampl.param["p"] = p
ampl.param["h"] = h
ampl.param[
=SOLVER)
ampl.solve(solverassert ampl.solve_result == "solved", ampl.solve_result
= ampl.var["x"].value()
xval = (ampl.obj["total_expected_profit"].value()/100) # The divide by 100 is to convert from cent to euro
total_expected_profit
print(
f"Approximate solution with fitted deman distribution using N={N:.0f} samples"
)print(f"Approximate optimal solution: x = {xval:.2f} baguettes")
print(f"Approximate expected daily profit: {total_expected_profit:.2f}€")
= ampl.var["z"]
zs
= ampl.var["y"]
ys
= ys.numInstances()
ny
= [ ys[i].value() for i in range(1, ny +1)]
yvals
= [ zs[i].value() for i in range(1, ny +1)]
zvals
= pd.DataFrame.from_records({"yi": yvals, "zi": zvals}) df_soln
df_soln