HTSim/InventorySystem.py

135 lines
7.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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