python">#!/usr/bin/env python3# -*- coding: utf-8 -*-"""
Created on Thu Nov 28 00:00:35 2024@author: zhenchen@Python version: 3.10@disp: stochastic dynamic programming to compute multi-period newsvendor problems;use @dataclass for ease of defining classes;parallel computing unsucessful, highly prone to make mistakes;
"""import scipy.stats as sp
from dataclasses import dataclass
from functools import lru_cache
import time@dataclass(frozen=True)classState:"""state in a period: initial inventory """t:intiniInventory:float@dataclassclassPmf:"""probability mass function for the demand distribution in each period"""truncQuantile:floatdistribution_type:strdefget_pmf(self, distribution_parameters):"""Parameters----------distribution_parameters: list, may be multi dimensionalDESCRIPTION. parameter values of the distributionReturns-------pmf : 3-D listDESCRIPTION. probability mass function for the demand in each period"""if(self.distribution_type =='poisson'): mean_demands = distribution_parametersmax_demands =[sp.poisson.ppf(self.truncQuantile, d).astype(int)for d in mean_demands]T =len(mean_demands)pmf =[[[k, sp.poisson.pmf(k, mean_demands[t])/self.truncQuantile]for k inrange(max_demands[t])]for t inrange(T)]return pmf@dataclass(eq =False)classStochasticInventory:"""multi period stochastic inventory model class""" T:int capacity:float# maximum ordering quantityfixOrderCost:floatvariOrderCost:floatholdCost:floatpenaCost:floattruncationQ:floatmax_inventory:floatmin_inventory:floatpmf:[[[]]]cache_actions ={}defget_feasible_action(self, state:State):"""feasible actions for a certain state"""returnrange(self.capacity +1)defstate_tran(self, state:State, action, demand):"""state transition function""" nextInventory = state.iniInventory + action - demandnextInventory = self.max_inventory if self.max_inventory < nextInventory else nextInventorynextInventory = self.min_inventory if self.min_inventory > nextInventory else nextInventoryreturn State(state.t +1, nextInventory)defimme_value(self, state:State, action, demand):"""immediate value function"""fixCost = self.fixOrderCost if action >0else0variCost = self.variOrderCost * actionnextInventory = state.iniInventory + action - demandnextInventory = self.max_inventory if nextInventory > self.max_inventory else nextInventorynextInventory = self.min_inventory if nextInventory < self.min_inventory else nextInventoryholdingCost = self.holdCost *max(0, nextInventory)penaltyCost = self.penaCost *max(0,-nextInventory)return fixCost + variCost + holdingCost + penaltyCost# recursion@ lru_cache(maxsize =None)deff(self, state:State):"""recursive function"""bestQValue =float('inf')bestQ =0for action in self.get_feasible_action(state):thisQValue =0for randDandP in self.pmf[state.t -1]:thisQValue += randDandP[1]* self.imme_value(state, action, randDandP[0])if state.t < T:thisQValue += randDandP[1]* self.f(self.state_tran(state, action, randDandP[0]))if thisQValue < bestQValue:bestQValue = thisQValuebestQ = actionself.cache_actions[str(state)]= bestQreturn bestQValuedemands =[10,20,10,20]
distribution_type ='poisson'
capacity =100# maximum ordering quantity
fixOrderCost =0
variOderCost =1
holdCost =2
penaCost =10
truncQuantile =0.9999# trancated quantile for the demand distribution
maxI =500# maximum possible inventory
minI =-300# minimum possible inventorypmf = Pmf(truncQuantile, distribution_type).get_pmf(demands)
T =len(demands)if __name__ =='__main__': start = time.process_time()model = StochasticInventory(T,capacity, fixOrderCost, variOderCost,holdCost, penaCost, truncQuantile,maxI, minI,pmf)ini_state = State(1,0)expect_total_cost = model.f(ini_state)print('****************************************')print('final expected total cost is %.2f'% expect_total_cost)optQ = model.cache_actions[str(State(1,0))]print('optimal Q_1 is %.2f'% optQ)end = time.process_time()cpu_time = end - startprint('cpu time is %.4f s'% cpu_time)
mfc110u.dll是Microsoft Foundation Classes (MFC)库的一个特定版本(版本11.0)的Unicode动态链接库文件。MFC是Microsoft为C开发者设计的一个应用程序框架,主要用于简化Windows应用程序的开发工作。这个框架封装了很多Windows API函数&#x…