129 lines
6.3 KiB
Python
129 lines
6.3 KiB
Python
|
import agentpy as ap
|
|||
|
import numpy as np
|
|||
|
from collections import deque
|
|||
|
|
|||
|
|
|||
|
class InventorySystem(ap.Agent):
|
|||
|
|
|||
|
xv_ary_initial_material_num: np.ndarray
|
|||
|
xv_ary_initial_product_num: np.ndarray
|
|||
|
ev_ary_current_material: np.ndarray #期末库存
|
|||
|
ev_ary_current_product: np.ndarray #期末库存
|
|||
|
ev_lst_trans_quan_material: np.ndarray # Iss传递给Pss的原材料数量
|
|||
|
ev_lst_backtrans_quan_material: np.ndarray # Pss退回的原材料数量
|
|||
|
ev_ary_material_state_to_use: np.ndarray # 当期预期使用的原材料
|
|||
|
ev_ary_material_to_use: np.ndarray # 当期实际消耗的原材料
|
|||
|
xv_array_dlv_product: np.ndarray # 产品交付
|
|||
|
|
|||
|
ev_ary_is_order_material: np.ndarray # 是否订购产品
|
|||
|
ev_ary_num_material_to_order: np.ndarray # 订购数量
|
|||
|
ev_ary_num_material_order_done: np.ndarray # 当期送到的数量
|
|||
|
|
|||
|
# set the lead time of material replenishment
|
|||
|
xv_ary_lead_time: np.ndarray
|
|||
|
|
|||
|
# the list of materials in transit
|
|||
|
ev_lst_trans_material: list # Iss交给Pss的原材料
|
|||
|
ev_list_back_trans_material: list # Pss返回的原材料
|
|||
|
|
|||
|
ev_lst_material_inventory: list
|
|||
|
ev_lst_product_inventory: list
|
|||
|
|
|||
|
# Material list
|
|||
|
xv_lst_material: np.ndarray
|
|||
|
xv_ary_bom: np.ndarray
|
|||
|
|
|||
|
# 原材料订购的开始时间和到达时间
|
|||
|
ev_int_order_time: np.ndarray
|
|||
|
ev_int_arrive_time: np.ndarray
|
|||
|
ev_ary_num_material_order_done: np.ndarray # 当期原材料到货量
|
|||
|
|
|||
|
def setup(self, xv_ary_initial_material_num,
|
|||
|
xv_ary_initial_product_num, xv_ary_lead_time):
|
|||
|
|
|||
|
# Set up the initial inventory quantity
|
|||
|
self.xv_ary_initial_material_num = xv_ary_initial_material_num
|
|||
|
self.xv_ary_initial_product_num = xv_ary_initial_product_num
|
|||
|
self.ev_ary_current_material = xv_ary_initial_material_num # 115*2
|
|||
|
self.ev_ary_current_product = xv_ary_initial_product_num #23*2
|
|||
|
self.ev_ary_num_material_order_done = np.zeros((115, ))
|
|||
|
|
|||
|
# set the lead time of materials
|
|||
|
# 读取各个原材料的历史平均交货周期 bom table
|
|||
|
self.xv_ary_lead_time = pd.read_excel("bom23.xlsx").iloc[:, 4].to_numpy()
|
|||
|
# 切换成原材料
|
|||
|
self.ev_ary_is_order_material = np.array([False for i in range(115)])
|
|||
|
self.ev_ary_num_material_to_order = np.zeros((115,)) # 初始化
|
|||
|
self.ev_ary_material_state_to_use = np.zeros((115,))
|
|||
|
|
|||
|
self.ev_lst_material_inventory = []
|
|||
|
self.ev_lst_product_inventory = []
|
|||
|
|
|||
|
self.xv_lst_material = pd.read_excel("rawmaterial.xlsx").to_numpy()
|
|||
|
|
|||
|
self.xv_ary_bom = pd.read_excel("bom23.xlsx").to_numpy()
|
|||
|
|
|||
|
self.ev_lst_trans_quan_material = [] # Iss传递给Pss的原材料数量
|
|||
|
self.ev_lst_backtrans_quan_material = [] # Pss退回的原材料数量
|
|||
|
|
|||
|
self.ev_int_order_time = np.zeros((115,))
|
|||
|
self.ev_int_arrive_time = np.zeros((115,))
|
|||
|
|
|||
|
def material_state_to_use(self, xv_ary_dlv_product, ev_int_produce_type):
|
|||
|
# 读取Oss决定的生产状态,根据生产状态所需的原材料进行汇总
|
|||
|
# self. ev_ary_material_state_to_use = np.multiply(self.xv_array_dlv_product, 原材料表 )
|
|||
|
produce_state = 1 # 获取生产状态
|
|||
|
produce_plan = xv_plan_excel[xv_plan_excel[:, 0] == produce_state]
|
|||
|
for plan in produce_plan:
|
|||
|
for bom in self.xv_ary_bom:
|
|||
|
if plan[1] == bom[0]:
|
|||
|
self.ev_ary_material_state_to_use[np.where(self.xv_lst_material == bom[1])] += plan[3] * bom[
|
|||
|
2] # 某原材料的生产数量加等产品生产量乘单位原材料消耗量
|
|||
|
|
|||
|
def material_check(self, ev_ary_material_state_to_use):
|
|||
|
# 根据Iss决策,核对库存是否充足,并将拥有的原材料交给Pss
|
|||
|
# 可能需要一部生成原材料列表在调用
|
|||
|
# Check whether materials are enough and transfer material
|
|||
|
index_mapping = {value: idx for idx, value in enumerate(self.ev_ary_current_material[:, 0])}
|
|||
|
sorted_indices = [index_mapping[value] for value in self.xv_lst_material]
|
|||
|
self.ev_ary_current_material = self.ev_ary_current_material[sorted_indices] # 按照原材料制定顺序进行重排
|
|||
|
for i in range(115):
|
|||
|
if self.ev_ary_current_material[i, 1] >= ev_ary_material_state_to_use[i]:
|
|||
|
self.ev_lst_trans_quan_material[i] = ev_ary_material_state_to_use[i]
|
|||
|
# return (self.ev_ary_current_material >= ev_ary_material_to_use).all()
|
|||
|
else:
|
|||
|
self.ev_lst_trans_quan_material[i] = self.ev_ary_current_material[i]
|
|||
|
|
|||
|
def consume_and_store(self, ev_ary_material_to_use, ev_ary_produced_num,ev_changed_product,
|
|||
|
ev_lst_backtrans_material):
|
|||
|
self.ev_lst_backtrans_quan_material = ev_lst_backtrans_material
|
|||
|
# Update the inventory after production
|
|||
|
for i in range(115):
|
|||
|
self.ev_ary_material_to_use[i] = self.ev_lst_trans_quan_material[i] - \
|
|||
|
self.ev_lst_backtrans_quan_material[i]
|
|||
|
|
|||
|
if self.ev_int_arrive_time == self.model.t: # 判断材料是否到达
|
|||
|
self.ev_ary_num_material_order_done[i] += self.ev_ary_num_material_to_order[i]
|
|||
|
self.ev_ary_num_material_to_order[i] = 0
|
|||
|
self.ev_ary_is_order_material[i] = False
|
|||
|
|
|||
|
self.ev_ary_current_material = self.ev_ary_current_material - ev_ary_material_to_use \
|
|||
|
+ self.ev_ary_num_material_order_done
|
|||
|
self.ev_ary_current_product = ev_changed_product + ev_ary_produced_num
|
|||
|
return self.ev_ary_current_material, self.ev_ary_current_product
|
|||
|
|
|||
|
def material_replenishment(self):
|
|||
|
# Check the inventory of material to decide whether to replenish
|
|||
|
# 核对原材料数量是否低于s
|
|||
|
# 带时间戳
|
|||
|
for i in range(115):
|
|||
|
if self.ev_ary_current_material[i] <= s:
|
|||
|
self.ev_ary_is_order_material[i] = True
|
|||
|
self.ev_ary_num_material_to_order[i] = S - self.ev_ary_current_material[i]
|
|||
|
self.ev_int_order_time[i] = self.model.t
|
|||
|
self.ev_int_arrive_time[i] = self.ev_int_order_time[i] + \
|
|||
|
self.xv_ary_bom[self.xv_ary_bom[:, 1] == self.xv_lst_material[i]][0, 4]
|
|||
|
else:
|
|||
|
self.ev_ary_num_material_to_order[i] = 0
|
|||
|
|