|
|
|
import random |
|
import numpy as np |
|
|
|
def _custom_pmf(population, weights, size): |
|
|
|
if len(size) == 2: |
|
ans = np.zeros(shape=size) |
|
for i in range(size[0]): |
|
ans[i,:] = random.choices( |
|
population=population, |
|
weights=weights, |
|
k=size[1] |
|
) |
|
else: |
|
ans = np.array(random.choices( |
|
population=population, |
|
weights=weights, |
|
k=size[0] |
|
)) |
|
return ans |
|
|
|
def _custom_item_specific(distributions, size): |
|
ans = np.zeros(size) |
|
|
|
for i, distr in enumerate(distributions): |
|
if distr['name'] == 'normal': |
|
ans[i,:] = np.random.normal( |
|
distr['mu'], |
|
distr['sigma'], |
|
size=ans[i,:].shape |
|
).astype(int) |
|
elif distr['name'] == 'discrete_uniform': |
|
ans[i,:] = np.random.randint( |
|
low=distr['low'], |
|
high=distr['high'], |
|
size=ans[i,:].shape |
|
) |
|
elif distr['name'] =='binomial': |
|
ans[i,:] = np.random.binomial( |
|
distr['n'], |
|
distr['p'], |
|
size=ans[i,:].shape |
|
) |
|
elif distr['name'] == 'probability_mass_function': |
|
ans[i,:] = _custom_pmf( |
|
population=distr['demand_distribution']['vals'], |
|
weights=distr['demand_distribution']['probs'], |
|
size=ans[i,:].shape |
|
) |
|
return ans |
|
|
|
|
|
class StochasticDemandModel(): |
|
def __init__(self, settings): |
|
self.settings = settings |
|
|
|
distr_dict = { |
|
'normal': lambda x: np.random.normal( |
|
self.settings['demand_distribution']['mu'], |
|
self.settings['demand_distribution']['sigma'], |
|
size=x |
|
), |
|
'discrete_uniform': lambda x: np.random.randint( |
|
low=self.settings['demand_distribution']['low'], |
|
high=self.settings['demand_distribution']['high'], |
|
size=x |
|
), |
|
'binomial': lambda x: np.random.binomial( |
|
self.settings['demand_distribution']['n'], |
|
self.settings['demand_distribution']['p'], |
|
size=x |
|
), |
|
'probability_mass_function': lambda x: _custom_pmf( |
|
population=self.settings['demand_distribution']['vals'], |
|
weights=self.settings['demand_distribution']['probs'], |
|
size=x |
|
), |
|
'item_specific_uniform': lambda x: _custom_item_specific( |
|
distributions=self.settings['demand_distribution']['distributions'], |
|
size=x |
|
) |
|
} |
|
if self.settings['demand_distribution']['name'] == 'probability_mass_function': |
|
if sum(self.settings['demand_distribution']['probs']) != 1: |
|
raise ValueError('sum of prob different than one') |
|
self.name_distribution = self.settings['demand_distribution']['name'] |
|
self.generate = distr_dict[self.settings['demand_distribution']['name']] |
|
self.n_items = self.settings['n_items'] |
|
|
|
def fit(self, data): |
|
pass |
|
|
|
def generate_scenario(self, history=None, n_time_steps=1): |
|
|
|
|
|
|
|
|
|
return self.generate( (self.n_items, n_time_steps) ) |
|
|