HTSim/InventorySystem.py

135 lines
7.7 KiB
Python
Raw Normal View History

2023-07-24 15:07:19 +08:00
import agentpy as ap
import numpy as np
2023-07-25 21:32:08 +08:00
import pandas as pd
2023-07-24 15:07:19 +08:00
from collections import deque
class InventorySystem(ap.Agent):
2023-07-25 21:32:08 +08:00
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_ary_material_state_to_use: np.ndarray # 当期预期使用的原材料
ev_ary_material_to_use: np.ndarray # 当期实际消耗的原材料
2023-07-24 15:07:19 +08:00
2023-07-25 21:32:08 +08:00
ev_ary_is_order_material: np.ndarray # 是否订购产品
ev_ary_num_material_to_order: np.ndarray # 订购数量
ev_ary_num_material_order_done: np.ndarray # 当期送到的数量
2023-07-24 15:07:19 +08:00
# set the lead time of material replenishment
2023-07-25 21:32:08 +08:00
xv_ary_lead_time: np.ndarray # 原材料订货的等待时间
2023-07-24 15:07:19 +08:00
# the list of materials in transit
2023-07-25 21:32:08 +08:00
ev_lst_trans_quan_material: list # Iss传递给Pss的原材料数量
ev_lst_backtrans_quan_material: list # Pss退回的原材料数量
2023-07-24 15:07:19 +08:00
# Material list
2023-07-25 21:32:08 +08:00
xv_ary_material: np.ndarray
2023-07-24 15:07:19 +08:00
xv_ary_bom: np.ndarray
# 原材料订购的开始时间和到达时间
2023-07-25 21:32:08 +08:00
ev_ary_order_time: np.ndarray
ev_ary_arrive_time: np.ndarray
xv_product_num: int
xv_material_num: int
xv_ary_plan: np.ndarray
2023-07-24 15:07:19 +08:00
2023-07-25 21:32:08 +08:00
def setup(self, xv_ary_initial_material_num, xv_ary_initial_product_num, xv_product_num, xv_material_num,
xv_ary_bom, xv_ary_plan, xv_ary_material_id):
2023-07-24 15:07:19 +08:00
# 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
2023-07-25 21:32:08 +08:00
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.xv_product_num = xv_product_num # 产成品个数
self.xv_material_num = xv_material_num # 原材料个数
self.ev_ary_num_material_order_done = np.zeros((xv_material_num,)) # 当期原材料送到的数量 115x1
2023-07-24 15:07:19 +08:00
# set the lead time of materials
# 读取各个原材料的历史平均交货周期 bom table
2023-07-25 21:32:08 +08:00
self.xv_ary_lead_time = xv_ary_bom[:, (1, 4)] # 每一种原材料的到货时间(有重复)
2023-07-24 15:07:19 +08:00
# 切换成原材料
2023-07-25 21:32:08 +08:00
self.ev_ary_is_order_material = np.array([False for i in range(xv_material_num)]) # 是否订购原材料
self.ev_ary_num_material_to_order = np.zeros((xv_material_num,)) # 原材料订货数量
self.ev_ary_material_state_to_use = np.zeros((xv_material_num,)) # 一个周期内按照设定生产状态完全生产 原材料消耗数量 计划
self.ev_ary_material_to_use = np.zeros((xv_material_num,)) # 当期实际消耗的原材料数量
2023-07-24 15:07:19 +08:00
2023-07-25 21:32:08 +08:00
self.xv_ary_material = xv_ary_material_id # 原材料顺序
2023-07-24 15:07:19 +08:00
2023-07-25 21:32:08 +08:00
self.xv_ary_bom = xv_ary_bom # bom表
self.xv_ary_plan = xv_ary_plan # plan表
2023-07-24 15:07:19 +08:00
2023-07-25 23:17:57 +08:00
self.ev_lst_trans_quan_material = [0 for i in range(xv_material_num)] # Iss传递给Pss的原材料数量
self.ev_lst_backtrans_quan_material = [0 for i in range(xv_material_num)] # Pss退回的原材料数量
2023-07-24 15:07:19 +08:00
2023-07-25 21:32:08 +08:00
self.ev_ary_order_time = np.zeros((xv_material_num,)) # 原材料订货时间戳
self.ev_ary_arrive_time = np.zeros((xv_material_num,)) # 原材料到货时间戳
2023-07-24 15:07:19 +08:00
2023-07-25 21:32:08 +08:00
# def material_state_to_use(self, ev_int_produce_type, xv_plan_excel):
# # 读取Oss决定的生产状态根据生产状态所需的原材料进行汇总
# # self. ev_ary_material_state_to_use = np.multiply(self.xv_array_dlv_product, 原材料表 )
# produce_state = ev_int_produce_type # 获取生产状态
def material_state_to_use(self): # 根据生产状态 看生产一个周期需要多少原材料
2023-07-24 15:07:19 +08:00
# 读取Oss决定的生产状态根据生产状态所需的原材料进行汇总
# self. ev_ary_material_state_to_use = np.multiply(self.xv_array_dlv_product, 原材料表 )
2023-07-25 21:32:08 +08:00
produce_state = self.model.the_firm.the_os.ev_int_produce_type # 获取生产状态
produce_plan = self.xv_ary_plan[self.xv_ary_plan[:, 0] == produce_state] # 该生产状态下各产品的生产计划
for product_plan in produce_plan:
2023-07-24 15:07:19 +08:00
for bom in self.xv_ary_bom:
2023-07-25 21:32:08 +08:00
if product_plan[1] == bom[0]:
2023-07-25 23:17:57 +08:00
self.ev_ary_material_state_to_use[np.where(self.xv_ary_material == bom[1])] += float(
product_plan[3]) * \
float(bom[
2]) # 某原材料的生产数量加等产品生产量乘单位原材料消耗量
2023-07-24 15:07:19 +08:00
2023-07-25 21:32:08 +08:00
def material_check(self): # 检查库存是否充足
2023-07-24 15:07:19 +08:00
# 根据Iss决策核对库存是否充足并将拥有的原材料交给Pss
# 可能需要一部生成原材料列表在调用
# Check whether materials are enough and transfer material
2023-07-25 23:17:57 +08:00
# print(len(self.ev_ary_current_material), self.xv_material_num)
# print(self.ev_ary_current_material[0, 1])
2023-07-25 21:32:08 +08:00
for i in range(self.xv_material_num):
2023-07-25 23:17:57 +08:00
self.ev_lst_trans_quan_material[i] = float(min(float(self.ev_ary_current_material[i, 1]),
self.ev_ary_material_state_to_use[i])) # 需要数量和库存两者间的较小值
2023-07-25 21:32:08 +08:00
# 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]
# else:
# self.ev_lst_trans_quan_material[i] = self.ev_ary_current_material[i]
2023-07-25 23:17:57 +08:00
# print(type(self.ev_lst_trans_quan_material[i]))
2023-07-25 21:32:08 +08:00
def consume_and_store(self, ev_ary_produced_num, ev_changed_product,
2023-07-24 15:07:19 +08:00
ev_lst_backtrans_material):
2023-07-25 21:32:08 +08:00
self.ev_lst_backtrans_quan_material = ev_lst_backtrans_material # Pss传回的原材料数量
2023-07-24 15:07:19 +08:00
# Update the inventory after production
2023-07-25 21:32:08 +08:00
for i in range(self.xv_material_num):
2023-07-24 15:07:19 +08:00
self.ev_ary_material_to_use[i] = self.ev_lst_trans_quan_material[i] - \
self.ev_lst_backtrans_quan_material[i]
2023-07-25 21:32:08 +08:00
if self.ev_ary_arrive_time[i] == self.model.t: # 判断材料是否到达
2023-07-25 23:17:57 +08:00
self.ev_ary_current_material[i, 1] = float(self.ev_ary_current_material[i, 1]) - self.ev_ary_material_to_use[i] \
2023-07-25 21:32:08 +08:00
+ self.ev_ary_num_material_to_order[i] # 减消耗量 加订购量
2023-07-24 15:07:19 +08:00
self.ev_ary_num_material_to_order[i] = 0
self.ev_ary_is_order_material[i] = False
2023-07-25 23:17:57 +08:00
self.ev_ary_current_product[:, 1] = ev_changed_product + np.array([float(x) for x in ev_ary_produced_num[:, 1]]) # 上期期末加本期生产
2023-07-24 15:07:19 +08:00
2023-07-25 21:32:08 +08:00
# return self.ev_ary_current_material, self.ev_ary_current_product
def material_replenishment(self, xv_ary_s, xv_ary_S):
2023-07-24 15:07:19 +08:00
# Check the inventory of material to decide whether to replenish
# 核对原材料数量是否低于s
# 带时间戳
2023-07-25 21:32:08 +08:00
for i in range(self.xv_material_num):
if self.ev_ary_current_material[i, 1] <= xv_ary_s[i, 1] and self.ev_ary_is_order_material[i] == False:
2023-07-24 15:07:19 +08:00
self.ev_ary_is_order_material[i] = True
2023-07-25 23:17:57 +08:00
self.ev_ary_num_material_to_order[i] = float(xv_ary_S[i, 1]) - float(self.ev_ary_current_material[i, 1])
2023-07-25 21:32:08 +08:00
self.ev_ary_order_time[i] = self.model.t
2023-07-25 23:17:57 +08:00
self.ev_ary_arrive_time[i] = self.ev_ary_order_time[i] + float(self.xv_ary_lead_time[
self.xv_ary_lead_time[:, 0] == self.ev_ary_current_material[i, 0]][0, 1])
2023-07-24 15:07:19 +08:00
else:
self.ev_ary_num_material_to_order[i] = 0