From 1229d9e3c20e00c46b07b0f0054719fd191c3c12 Mon Sep 17 00:00:00 2001 From: Yofuria <20377277@buaa.edu.cn> Date: Tue, 25 Jul 2023 21:32:08 +0800 Subject: [PATCH] update --- .idea/HTSim.iml | 5 +- .idea/misc.xml | 2 +- .idea/other.xml | 6 ++ Environment.py | 57 ++++++++++------ Firm.py | 44 +++++++++--- InventorySystem.py | 154 ++++++++++++++++++++---------------------- Order.py | 27 ++++---- OrderSystem.py | 70 +++++++++---------- ProduceSystem.py | 75 ++++++++++++-------- demand23.xlsx | Bin 9870 -> 9591 bytes initial_material.xlsx | Bin 0 -> 11285 bytes initial_product.xlsx | Bin 0 -> 9563 bytes rawmaterial - s.xlsx | Bin 0 -> 11260 bytes rawmaterial.xlsx | Bin 10695 -> 0 bytes rawmaterialS.xlsx | Bin 0 -> 11256 bytes 15 files changed, 249 insertions(+), 191 deletions(-) create mode 100644 .idea/other.xml create mode 100644 initial_material.xlsx create mode 100644 initial_product.xlsx create mode 100644 rawmaterial - s.xlsx delete mode 100644 rawmaterial.xlsx create mode 100644 rawmaterialS.xlsx diff --git a/.idea/HTSim.iml b/.idea/HTSim.iml index d870a4a..7f92818 100644 --- a/.idea/HTSim.iml +++ b/.idea/HTSim.iml @@ -2,7 +2,10 @@ - + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index ab530bf..2479c47 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/.idea/other.xml b/.idea/other.xml new file mode 100644 index 0000000..a708ec7 --- /dev/null +++ b/.idea/other.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/Environment.py b/Environment.py index 0ca7f73..cf6239a 100644 --- a/Environment.py +++ b/Environment.py @@ -18,7 +18,7 @@ class FMSEnv(ap.Model): # xv_int_max_order: int # ev_n_order_created: int - the_firm: Firm + the_firm: Firm # Firm类 # record data, define below # op_os_n_total_order: int @@ -28,7 +28,7 @@ class FMSEnv(ap.Model): # op_is_flt_material_room_left: float # op_is_flt_product_room_left: float - op_ps_str_status: str + op_os_int_status: int op_os_to_dlv: np.ndarray op_is_current_product: np.ndarray op_is_current_material: np.ndarray @@ -39,6 +39,7 @@ class FMSEnv(ap.Model): op_ip_prd_s: np.ndarray op_ip_prd_big_s: np.ndarray op_ip_prd_est_pfm: int + op_os_n_total_order: int def __init__(self, dct_all_para, _run_id=None): super().__init__() @@ -47,11 +48,13 @@ class FMSEnv(ap.Model): self.the_firm = Firm(env=self, dct_all_para=dct_all_para) # get the input parameter values from the dictionary - self.int_stop_time = int(dct_all_para['time']) + self.int_stop_time = int(dct_all_para['time']) # 停止接单时间 # self.xv_int_max_order = int(dct_all_para['xv_int_max_order']) - self.xv_dlv_product_para = np.asarray(dct_all_para['xv_dlv_product_para']) + # self.xv_dlv_product_para = np.asarray(dct_all_para['xv_dlv_product_para']) # self.xv_int_dlv_period_lam = int(dct_all_para['xv_int_dlv_period_lam']) # self.ev_n_order_created = 0 + self.op_os_n_total_order = 0 + self.op_os_int_status = 0 self.running = True self.t = 0 @@ -62,17 +65,16 @@ class FMSEnv(ap.Model): xv_int_create_order_num = 1 # xv_int_create_order_num = random.poisson(lam=xv_int_create_order_lam, size=None) # if self.ev_n_order_created < xv_int_max_order: - for i in range(xv_int_create_order_num): - new_order = Order(model=self, time_created=self.t, xv_dlv_product_para=self.xv_dlv_product_para, - leadtime=max(self.the_firm.xv_ary_lead_time)) - return new_order - return None + # for i in range(xv_int_create_order_num): + new_order = Order(model=self, time_created=self.t) + return new_order + # return None # Execute the interactions of each time step in the simulation. def step(self): # organize the interactions of agents in each time step here - new_order = self.create_order() - self.the_firm.the_os.accept_order(new_order) + new_order = self.create_order() # 接收创建的订单 + self.the_firm.the_os.accept_order(new_order=new_order) self.the_firm.operating() self.update() @@ -82,16 +84,17 @@ class FMSEnv(ap.Model): self.stop() else: print(f"running the {self.t} step") + print(self.the_firm.the_os.ev_ave_delay_time) # Record data after each simulation - def update(self): - self.op_os_n_total_order = len(self.the_firm.the_os.a_lst_order) + def update(self): # ? + self.op_os_n_total_order = len(self.the_firm.the_os.a_lst_order) # 订单个数 # self.op_os_n_total_order_delayed = len([e for e in self.the_firm.the_os.a_lst_order if e.xv_dlv_t < self.t]) - self.op_os_to_dlv = self.the_firm.the_os.ev_ary_to_dlv + self.op_os_to_dlv = self.the_firm.the_os.ev_ary_to_dlv # 当期及之前未满足需求总和 # self.op_os_all_delay_time = self.the_firm.the_os.ev_lst_all_delay_time - self.op_ps_produced_num = self.the_firm.the_ps.ev_ary_produced_num - self.op_ps_str_status = self.the_firm.the_ps.ev_str_status + self.op_ps_produced_num = self.the_firm.the_ps.ev_ary_produced_num # 当期产品生产数量 + self.op_ps_str_status = self.the_firm.the_os.ev_int_produce_type # 当期生产状态 # self.op_is_current_product = self.model.the_firm.the_is.ev_ary_current_product # @@ -101,13 +104,14 @@ class FMSEnv(ap.Model): self.op_ps_back_trans_material = self.model.the_firm.the_ps.ev_lst_backtrans_material - self.record([att for att in self.__dict__.keys() if att.startswith('op_')]) - pass + self.record([att for att in self.__dict__.keys() if att.startswith('op_')]) # ? + + # pass if __name__ == '__main__': dct_para = { - 'time': 60, + 'time': 60, # 进行总时间数 # 'xv_int_max_order': random.randint(30, 50), # 'xv_dlv_product_para': tuple([(30, 100), (30, 50)]), # 'xv_dlv_product_para': tuple([30,40,30,20]), # 读取生产率 np.read. @@ -117,11 +121,20 @@ if __name__ == '__main__': # 'xv_ary_cost_material_per': tuple([0.1,0.1,0.2,0.4]), # 'xv_ary_volume_material': tuple([1.0, 1.5]), # 'xv_ary_volume_product': tuple([3.0, 5.0]), - 'xv_array_lead_time': 2, # 读取原材料表格 np.read.,暂时不读 + # 'xv_array_lead_time': 2, # 读取原材料表格 np.read, 暂时不读 变量代表的含义 # 'xv_int_lead_time_c': 3, # 'xv_int_lead_time_d': 1, - 'xv_ary_initial_product_num': pd.read_excel("initial_product.xlsx").to_numpy(), - 'xv_ary_initial_material_num': pd.read_excel("initial_material.xlsx").to_numpy(), # 应读取遗传算法中随机生成的s,暂写为'1' 创建两个excel分别存储产品和原材料的库存 每个excel中存系统代码和库存 + 'xv_ary_product_id': pd.read_excel("initial_product.xlsx").to_numpy()[:, 0], # 产成品id顺序 + 'xv_ary_material_id': pd.read_excel("initial_material.xlsx").to_numpy()[:, 0], # 原材料id顺序 + 'xv_product_num': len(pd.read_excel("initial_product.xlsx").to_numpy()), # 产成品个数 + 'xv_material_num': len(pd.read_excel("initial_material.xlsx").to_numpy()), # 原材料个数 + 'xv_ary_initial_product_num': pd.read_excel("initial_product.xlsx").to_numpy(), # 初始产成品库存 23x2 + 'xv_ary_initial_material_num': pd.read_excel("initial_material.xlsx").to_numpy(), # 初始原材料库存 115x2 + 'xv_ary_bom': pd.read_excel("bom23.xlsx").to_numpy(), # bom表 + 'xv_ary_plan': pd.read_excel("plan.xlsx").to_numpy(), # plan表 + 'xv_ary_s': pd.read_excel("rawmaterial - s.xlsx").to_numpy(), # s + 'xv_ary_S': pd.read_excel("rawmaterialS.xlsx").to_numpy(), # S + # 应读取遗传算法中随机生成的s,暂写为'1' 创建两个excel分别存储产品和原材料的库存 每个excel中存系统代码和库存 # 'xv_flt_initial_cash': 50000.0, # 'dct_status_info': json.dumps({ #需要引入生产状态表 # "0": {"xv_flt_produce_rate": tuple([0.0, 0.0]), diff --git a/Firm.py b/Firm.py index 22607b7..8a9e897 100644 --- a/Firm.py +++ b/Firm.py @@ -5,6 +5,7 @@ from InventorySystem import InventorySystem from OrderSystem import OrderSystem from ProduceSystem import ProduceSystem + # Create Company Instance class Firm: the_os: OrderSystem @@ -15,23 +16,46 @@ class Firm: self.env = env # get the parameters here - self.xv_ary_initial_product_num = np.asarray(dct_all_para['xv_ary_initial_product_num']) - self.xv_ary_initial_material_num = np.asarray(dct_all_para['xv_ary_initial_material_num']) - self.dct_status_info = json.loads(dct_all_para['dct_status_info']) - self.xv_ary_lead_time = np.array([dct_all_para['xv_int_lead_time_a'], dct_all_para['xv_int_lead_time_b']]) + self.xv_ary_initial_product_num = np.asarray(dct_all_para['xv_ary_initial_product_num']) # 初始产成品库存 + self.xv_ary_initial_material_num = np.asarray(dct_all_para['xv_ary_initial_material_num']) # 初始原材料库存 + self.xv_product_num = int(dct_all_para['xv_product_num']) # 产成品个数 + self.xv_material_num = int(dct_all_para['xv_material_num']) # 原材料个数 + self.xv_ary_plan = np.asarray(dct_all_para['xy_ary_plan']) + self.xv_ary_bom = np.asarray(dct_all_para['xv_ary_bom']) + self.xv_ary_product_id = np.asarray(dct_all_para['xv_ary_product_id']) + self.xv_ary_material_id = np.asarray(dct_all_para['xv_ary_material_id']) + self.xv_ary_s = np.asarray(dct_all_para['xv_ary_s']) + self.xv_ary_S = np.asarray(dct_all_para['xv_ary_S']) + # self.dct_status_info = json.loads(dct_all_para['dct_status_info']) # 生产状态表 + # self.xv_ary_lead_time = np.array([dct_all_para['xv_int_lead_time_a'], dct_all_para['xv_int_lead_time_b']]) # create agents here - self.the_os = OrderSystem(env) + self.the_os = OrderSystem(env, xv_produt_num=self.xv_product_num, xv_ary_plan=self.xv_ary_plan, + xv_ary_product_id=self.xv_ary_product_id) # 实例Oss self.the_is = InventorySystem(env, xv_ary_initial_material_num=self.xv_ary_initial_material_num, xv_ary_initial_product_num=self.xv_ary_initial_product_num, - xv_ary_lead_time=self.xv_ary_lead_time) - self.the_ps = ProduceSystem(env, dct_status_info=self.dct_status_info) + xv_product_num=self.xv_product_num, + xv_material_num=self.xv_material_num, + xv_ary_bom=self.xv_ary_bom, xv_ary_pan=self.xv_ary_plan, + xv_ary_material_id=self.xv_ary_material_id) # 实例Iss + self.the_ps = ProduceSystem(env, xv_ary_bom=self.xv_ary_bom, xv_ary_plan=self.xv_ary_plan, + xv_product_num=self.xv_product_num, + xv_ary_product_id=self.xv_ary_product_id, + xv_ary_material_id=self.xv_ary_material_id) # 实例Pss # self.the_fs = FinancialSystem(env, xv_flt_initial_cash=self.xv_flt_initial_cash) - def operating(self): + def operating(self): # 按步骤进行 self.the_os.rank_order() + self.the_os.produce_status() + self.the_is.material_state_to_use() + self.the_is.material_check() self.the_ps.change_status() - self.the_ps.run_produce() - self.the_os.do_shipment() + self.the_ps.run_produce(ev_lst_trans_quan_material=self.the_is.ev_lst_trans_quan_material, + ev_ary_product_to_produce=self.the_os.ev_ary_product_to_produce) + self.the_is.consume_and_store(ev_ary_produced_num=self.the_ps.ev_ary_produce_number, + ev_changed_product=self.the_os.ev_changed_product, + ev_lst_backtrans_material=self.the_ps.ev_lst_backtrans_material) + self.the_is.material_replenishment() + self.the_os.do_shipment(ev_ary_current_product=self.the_is.ev_ary_current_product) # self.the_is.inventory_cost() # self.the_fs.financial_calculating() diff --git a/InventorySystem.py b/InventorySystem.py index e91548b..18ad354 100644 --- a/InventorySystem.py +++ b/InventorySystem.py @@ -1,135 +1,131 @@ 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 # 当期实际消耗的原材料 - 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 # 当期送到的数量 + 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 + 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_trans_quan_material: list # Iss传递给Pss的原材料数量 + ev_lst_backtrans_quan_material: list # Pss退回的原材料数量 - ev_lst_material_inventory: list - ev_lst_product_inventory: list # Material list - xv_lst_material: np.ndarray + xv_ary_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 # 当期原材料到货量 + ev_ary_order_time: np.ndarray + ev_ary_arrive_time: np.ndarray - def setup(self, xv_ary_initial_material_num, - xv_ary_initial_product_num, xv_ary_lead_time): + 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.ev_ary_num_material_order_done = np.zeros((115, )) + 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 = pd.read_excel("bom23.xlsx").iloc[:, 4].to_numpy() + self.xv_ary_lead_time = xv_ary_bom[:, (1, 4)] # 每一种原材料的到货时间(有重复) # 切换成原材料 - 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_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.ev_lst_material_inventory = [] - self.ev_lst_product_inventory = [] + self.xv_ary_material = xv_ary_material_id # 原材料顺序 - self.xv_lst_material = pd.read_excel("rawmaterial.xlsx").to_numpy() - - self.xv_ary_bom = pd.read_excel("bom23.xlsx").to_numpy() + self.xv_ary_bom = xv_ary_bom # bom表 + self.xv_ary_plan = xv_ary_plan # plan表 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,)) + self.ev_ary_order_time = np.zeros((xv_material_num,)) # 原材料订货时间戳 + self.ev_ary_arrive_time = np.zeros((xv_material_num,)) # 原材料到货时间戳 -<<<<<<< HEAD - def material_state_to_use(self, ev_int_produce_type, xv_plan_excel): + # 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 = ev_int_produce_type # 获取生产状态 -======= - 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 # 获取生产状态 ->>>>>>> 6027857189fa76bd175eb941904972de305532a4 - produce_plan = xv_plan_excel[xv_plan_excel[:, 0] == produce_state] - for plan in produce_plan: + 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 plan[1] == bom[0]: - self.ev_ary_material_state_to_use[np.where(self.xv_lst_material == bom[1])] += plan[3] * bom[ - 2] # 某原材料的生产数量加等产品生产量乘单位原材料消耗量 + if product_plan[1] == bom[0]: + self.ev_ary_material_state_to_use[np.where(self.xv_ary_material == bom[1])] += product_plan[3] * \ + bom[ + 2] # 某原材料的生产数量加等产品生产量乘单位原材料消耗量 - def material_check(self, ev_ary_material_state_to_use): + def material_check(self): # 检查库存是否充足 # 根据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] + for i in range(self.xv_material_num): + self.ev_lst_trans_quan_material[i] = min(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] - def consume_and_store(self, ev_ary_material_to_use, ev_ary_produced_num,ev_changed_product, + 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 + self.ev_lst_backtrans_quan_material = ev_lst_backtrans_material # Pss传回的原材料数量 # Update the inventory after production - for i in range(115): + 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_int_arrive_time == self.model.t: # 判断材料是否到达 - self.ev_ary_num_material_order_done[i] += self.ev_ary_num_material_to_order[i] + if self.ev_ary_arrive_time[i] == self.model.t: # 判断材料是否到达 + self.ev_ary_current_material[i, 1] = 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_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 + self.ev_ary_current_product[:, 1] = ev_changed_product + ev_ary_produced_num[:, 1] # 上期期末加本期生产 - def material_replenishment(self): + # 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(115): - if self.ev_ary_current_material[i] <= 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] = 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] + self.ev_ary_num_material_to_order[i] = xv_ary_S[i, 1] - self.ev_ary_current_material[i, 1] + self.ev_ary_order_time[i] = self.model.t + self.ev_ary_arrive_time[i] = self.ev_int_order_time[i] + 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 - diff --git a/Order.py b/Order.py index c6a8e89..3720ed5 100644 --- a/Order.py +++ b/Order.py @@ -6,30 +6,27 @@ import pandas as pd class Order(ap.Agent): + xv_time_created: int # 订单创建时间 + xv_time_circle: int # 随机生成的交货周期 + xv_dlv_t: int # 客户希望的交货时间 + ev_actual_dlv_t: int # 实际交付时间 - xv_time_created: int # 订单创建时间 - xv_time_circle: int # 随机生成的交货周期 - xv_dlv_t: int # 客户希望的交货时间 - ev_actual_dlv_t: int # 实际交付时间 - - ev_is_delivered: bool # 订单是否已交付 - ev_is_accepted: bool # 订单是否被接受 - ev_int_delay_time: int # total delay time + ev_is_delivered: bool # 订单是否已交付 + ev_is_accepted: bool # 订单是否被接受 + ev_int_delay_time: int # 订单延迟交付时间 xv_ary_dlv_product: np.ndarray ev_ary_dlv_product: np.ndarray def setup(self, time_created): - self.xv_time_created = time_created + self.xv_time_created = time_created # 订单创建时间 # read the demand of 23 productions - df = pd.read_excel("demand23.xlsx") - self.xv_ary_dlv_product = df.to_numpy() - df = df.iloc[:, 1] - self.ev_ary_dlv_product = df.to_numpy() + self.xv_ary_dlv_product = pd.read_excel("demand23.xlsx").to_numpy() # 接神经网络结果 + self.ev_ary_dlv_product = pd.read_excel("demand23.xlsx").to_numpy()[:, 1] # 23x1 把产品的顺序按照xv_ary_product_id重新排列!!! self.xv_time_circle = np.random.randint(7, 11, 1) - self.xv_dlv_t = self.xv_time_created + self.xv_time_circle + self.xv_dlv_t = self.xv_time_created + self.xv_time_circle # 随机生成期望交付时间 self.ev_actual_dlv_t = self.xv_dlv_t - self.ev_int_delay_time = self.ev_actual_dlv_t - self.xv_dlv_t + self.ev_int_delay_time = 0 # Set the initial status of order to be undelivered, accepted self.ev_is_delivered = False diff --git a/OrderSystem.py b/OrderSystem.py index 004d0b6..99b7ff5 100644 --- a/OrderSystem.py +++ b/OrderSystem.py @@ -3,31 +3,34 @@ import numpy as np from Order import Order import pandas as pd + # 输出一个生产状态指令,一个交付情况,一个延期时间计算 class OrderSystem(ap.Agent): a_lst_order: ap.AgentList[Order] ev_int_produce_type: int - ev_ary_to_dlv: np.ndarray # 当前order list内所有产品的综合 + ev_ary_to_dlv: np.ndarray # 当前order list内所有产品的综合 ev_ary_product_to_produce: np.ndarray # 用于计算 production gap - ev_lst_all_delay_time: list ev_ave_delay_time: float - xv_plan_excel: np.ndarray - ev_lst_flag: list + xv_ary_plan: np.ndarray ev_changed_product: np.ndarray + + + xv_product_num: int + xv_ary_product: np.ndarray # ev_ary_dlv_product: np.ndarray?????? - def setup(self): + def setup(self, xv_product_num, xv_ary_plan, xv_ary_product_id): # Create a list of order - self.a_lst_order = ap.AgentList(self, []) - self.ev_ary_to_dlv = np.zeros((23, 1)) - self.ev_int_produce_type = 0 - self.ev_ary_product_to_produce = np.zeros((23,)) - self.ev_lst_all_delay_time = [] + self.a_lst_order = ap.AgentList(self, []) # + self.ev_ary_to_dlv = np.zeros((xv_product_num,)) + self.ev_int_produce_type = 0 # 生产状态(方案) + self.ev_ary_product_to_produce = np.zeros((xv_product_num,)) self.ev_ave_delay_time = 0 # self.ev_ary_dlv_product = np.zeros((23,)) ???? - self.ev_changed_product = np.zeros((23, )) - self.xv_plan_excel = pd.read_excel("plan.xlsx").to_numpy() - pass + self.ev_changed_product = np.zeros((xv_product_num,)) + self.xv_ary_plan = xv_ary_plan + self.xv_product_num = xv_product_num + self.xv_ary_product = xv_ary_product_id def accept_order(self, new_order): # Determine whether the order is received and all are currently received @@ -37,67 +40,66 @@ class OrderSystem(ap.Agent): def rank_order(self): # Sort order - self.a_lst_order = self.a_lst_order.sort('xv_dlv_t', reverse=False) + self.a_lst_order = self.a_lst_order.sort('xv_dlv_t', reverse=False) # 按预期交付时间排序 def produce_status(self): # 计算a_lst_order内所有订单包含的产品总量与当期库存的gap,排序最大缺口量,选定生产状态 - self.ev_ary_to_dlv = np.zeros((23,)) - for order in self.model.the_firm.the_os.a_lst_order: + self.ev_ary_to_dlv = np.zeros((self.xv_product_num,)) # 产品需求总和 + for order in self.a_lst_order: self.ev_ary_to_dlv += order.ev_ary_dlv_product # 当前天之前所有的还未满足的需求求和 - self.ev_ary_product_to_produce[:, 1] = self.ev_ary_to_dlv - self.model.the_firm.the_is.ev_ary_current_product + self.ev_ary_product_to_produce = self.ev_ary_to_dlv - self.model.the_firm.the_is.ev_ary_current_product[:, 1] # self.ev_ary_product_to_produce = self.model.the_firm.the_is.ev_ary_current_product - self.ev_ary_to_dlv # self.ev_ary_product_to_produce > 0: # 选出这些产品,按照数值大小进行分类,数值最大的产品对应的能带来最大生产率的状态,则选定为ev_int_produce_type # 如果均<=0, 按照产品库存ev_ary_current_material进行排序,选择能给库存最低的产品带来最高生产率的状态 - sorted_indices = np.argsort(self.ev_ary_product_to_produce[:, 1])[::-1] - sorted_data = self.ev_ary_product_to_produce[sorted_indices] - if sorted_data[0, 1] > 0: # 判断是否存在库存不足 + sorted_indices = np.argsort(self.ev_ary_product_to_produce)[::-1] + sorted_data = self.xv_ary_product[sorted_indices] # gap从大到小的产品id + gap_sorted = self.ev_ary_product_to_produce[sorted_indices] + if gap_sorted[0] > 0: # 判断是否存在库存不足 pass else: sorted_indices = np.argsort(self.model.the_firm.the_is.ev_ary_current_product[:, 1]) # 对库存进行从小到大排序 - sorted_data = self.model.the_firm.the_is.ev_ary_current_product[sorted_indices] + sorted_data = self.model.the_firm.the_is.ev_ary_current_product[:, sorted_indices][:, 0] # 库存从小到大的产品id - a = self.xv_plan_excel[self.xv_plan_excel[:, 1] == sorted_data[0, 0]] # 检索最大值的产品的四种方案或者最小库存产品的四种方案 - sorted_indices = np.argsort(a[:, 3])[::-1] - sorted_data = a[sorted_indices] - # return sorted_data[0, 0] + option = self.xv_ary_plan[self.xv_ary_plan[:, 1] == sorted_data[0]] # 检索最大值的产品的四种方案或者最小库存产品的四种方案 + sorted_indices = np.argsort(option[:, 3])[::-1] + sorted_data = option[sorted_indices] self.ev_int_produce_type = sorted_data[0, 0] - return self.ev_int_produce_type + # return self.ev_int_produce_type - def do_shipment(self,ev_ary_current_product): + def do_shipment(self, ev_ary_current_product): # Make shipments based on ranked order list # 交付两次,第一次未交付完成的订单要标记,交货的时候先便利delay的订单,如果能够满足全部剩余量,就交货,如果不能 # 就继续在列表中存在 # 只有完全交付的订单,才计算delay time = order.ev_int_delay_time * 第二次交付的订单内的各类产品之和 # 需要更新 order.ev_ary_dlv_product # Make shipments based on ranked order list - self.ev_lst_all_delay_time = [] self.ev_ave_delay_time = 0 - self.ev_changed_product = ev_ary_current_product # 23x1 ndarray 存储本次库存的改变 + self.ev_changed_product = ev_ary_current_product[:, 1] # 23x1 ndarray 存储本次库存的改变 for order in self.a_lst_order: if order.xv_dlv_t == self.model.t: # 第一次交付 # Check and make shipment order.ev_is_delivered = True - for i in range(len(order.ev_ary_dlv_product)): + for i in range(self.xv_product_num): if order.ev_ary_dlv_product[i] <= self.ev_changed_product[i]: - order.ev_ary_dlv_product[i] = 0 self.ev_changed_product[i] -= order.ev_ary_dlv_product[i] + order.ev_ary_dlv_product[i] = 0 else: order.ev_is_delivered = False elif order.xv_dlv_t < self.model.t and order.ev_is_delivered == False: # 第二次交付 order.ev_is_delivered = True - for i in range(len(order.ev_ary_dlv_product)): + for i in range(self.xv_product_num): if order.ev_ary_dlv_product[i] > self.ev_changed_product[i]: # 先判断能不能一次性交付 order.ev_is_delivered = False if order.ev_is_delivered: # 如果一次性交付 delay_num = np.sum(order.ev_ary_dlv_product) - order.ev_ary_dlv_product = np.zeros((23,)) self.ev_changed_product = self.ev_changed_product - order.ev_ary_dlv_product + order.ev_ary_dlv_product = np.zeros((self.xv_product_num,)) order.ev_actual_dlv_t = self.model.t order.ev_int_delay_time = order.ev_actual_dlv_t - order.xv_dlv_t self.ev_ave_delay_time += order.ev_int_delay_time * delay_num / 10000 - return self.ev_changed_product, self.ev_ave_delay_time + # return self.ev_changed_product, self.ev_ave_delay_time \ No newline at end of file diff --git a/ProduceSystem.py b/ProduceSystem.py index 63d25b7..7de0f74 100644 --- a/ProduceSystem.py +++ b/ProduceSystem.py @@ -4,57 +4,74 @@ import random class ProduceSystem(ap.Agent): - ev_str_status: str # 0,6,8,10 pp_id + ev_str_status: int # 0,6,8,10 pp_id ev_lst_backtrans_material: list # 退回Iss的原材料 ev_ary_produce_number: np.ndarray - def setup(self, dct_status_info): - self.ev_str_status = 0 + xv_ary_bom: np.ndarray + xv_ary_plan: np.ndarray + xv_product_num: int + ev_ary_product: np.ndarray + xv_ary_material: np.ndarray + + def setup(self, xv_ary_bom, xv_ary_plan, xv_product_num, xv_ary_product_id, xv_ary_material_id): + self.ev_str_status = 0 # 设置初始生产状态 self.ev_lst_backtrans_material = [] + self.ev_ary_produce_number = np.zeros((xv_product_num, 2)) + self.xv_ary_bom = xv_ary_bom + self.xv_ary_plan = xv_ary_plan + self.xv_product_num = xv_product_num + self.ev_ary_product = xv_ary_product_id + self.xv_ary_material = xv_ary_material_id def change_status(self): - self.ev_str_status = self.model.the_firm.the_os.produce_status() + self.ev_str_status = self.model.the_firm.the_os.ev_int_produce_type - - def run_produce(self, ev_lst_material, ev_lst_trans_quan_material, ev_ary_product_to_produce, xv_plan_excel, - xv_ary_bom): # ev_ary_product_to_produce 是 需求和库存的gap 23x2 + def run_produce(self, ev_lst_trans_quan_material, + ev_ary_product_to_produce): # ev_ary_product_to_produce 是 需求和库存的gap 23x1 # 生产状态由Iss确定,这个函数需要计算生产数量和原材料消耗量。 # 如果原材料不足,就按照production gap(ev_ary_product_to_produce) 大小进行生产;如果没有gap的产品了,就按照库存水平由少到多进行生产。 # 输出生产结果和原材料消耗结果 - produce_plan = xv_plan_excel[xv_plan_excel[:, 0] == self.ev_str_status] - sorted_indices = np.argsort(ev_ary_product_to_produce[:, 1])[::-1] + produce_plan = self.xv_ary_plan[self.xv_ary_plan[:, 0] == self.ev_str_status] # 当前生产状态下的产品生产速度 + sorted_indices = np.argsort(ev_ary_product_to_produce)[::-1] sorted_data = ev_ary_product_to_produce[sorted_indices] # 对gap进行从大到小排序 + self.ev_ary_product = self.ev_ary_product[sorted_indices] sorted_indices_product = np.argsort(self.model.the_firm.the_is.ev_ary_current_product[:, 1]) # 对库存进行从小到大排序 - sorted_data_product = self.model.the_firm.the_is.ev_ary_current_product[sorted_indices_product] - self.ev_lst_backtrans_material = ev_lst_trans_quan_material - self.ev_ary_produce_number = [] - for product in sorted_data: - if product[1] > 0: # gap存在 - product_material = xv_ary_bom[xv_ary_bom[:, 0] == product[0]] - produce_number = produce_plan[produce_plan[:, 1] == product[0]][3] + sorted_data_product = self.model.the_firm.the_is.ev_ary_current_product[:, sorted_indices_product] + self.ev_lst_backtrans_material = ev_lst_trans_quan_material # 存储退回给Iss的原材料 + self.ev_ary_produce_number = np.zeros((self.xv_product_num, 2)) + produce_number_lst = [] + for i in range(self.xv_product_num): + if sorted_data[i] > 0: # gap存在 + product_material = self.xv_ary_bom[self.xv_ary_bom[:, 0] == self.ev_ary_product[i]] + produce_number = produce_plan[produce_plan[:, 1] == self.ev_ary_product[i]][3] for material in product_material: produce_number = min(produce_number, int( - self.ev_lst_backtrans_material[np.where(ev_lst_material == material[1])] / material[ + self.ev_lst_backtrans_material[np.where(self.xv_ary_material == material[1])] / material[ 2])) # 取能生产的最小个数 for material in product_material: - self.ev_lst_backtrans_material[np.where(ev_lst_material == material[1])] -= produce_number * material[ - 2] # 更新原材料消耗情况 - self.ev_ary_produce_number.append([product[0], produce_number]) - sorted_data_product = sorted_data_product[sorted_data_product[:, 0] != product[0]] + self.ev_lst_backtrans_material[np.where(self.xv_ary_material == material[1])] -= produce_number * \ + material[ + 2] # 更新原材料消耗情况 + produce_number_lst.append([self.ev_ary_product[i], produce_number]) + sorted_data_product = sorted_data_product[sorted_data_product[:, 0] != self.ev_ary_product[i]] else: for current_product in sorted_data_product: - product_material = xv_ary_bom[xv_ary_bom[:, 0] == current_product[0]] + product_material = self.xv_ary_bom[self.xv_ary_bom[:, 0] == current_product[0]] produce_number = produce_plan[produce_plan[:, 1] == current_product[0]][3] for material in product_material: produce_number = min(produce_number, int( - self.ev_lst_backtrans_material[np.where(ev_lst_material == material[1])] / material[ + self.ev_lst_backtrans_material[np.where(self.xv_ary_material == material[1])] / material[ 2])) # 取能生产的最小个数 for material in product_material: - self.ev_lst_backtrans_material[np.where(ev_lst_material == material[1])] -= produce_number * \ - material[2] # 更新原材料消耗情况 - self.ev_ary_produce_number.append([current_product[0], produce_number]) - break + self.ev_lst_backtrans_material[ + np.where(self.xv_ary_material == material[1])] -= produce_number * \ + material[ + 2] # 更新原材料消耗情况 + produce_number_lst.append([current_product[0], produce_number]) - self.ev_ary_produce_number = np.array(self.ev_ary_produce_number) + break - return self.ev_ary_produce_number, self.ev_lst_backtrans_material \ No newline at end of file + self.ev_ary_produce_number = np.array(produce_number_lst) + + # return self.ev_ary_produce_number, self.ev_lst_backtrans_material diff --git a/demand23.xlsx b/demand23.xlsx index b661fffd58e34620cc5de805011c0efa60e6b671..cb5a8407aa8468bbd6cb1352ed691e4ce6546b41 100644 GIT binary patch literal 9591 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 literal 9870 zcmeG?1y@|j(u2DU?(PyCg1bv_cNp9uxO;$v1PKrvf(;TNSa1vO4ugk;phJQN{U&+) z&hF;z_Y2;;bI!eWrn{=Ux~#jZHB}K12>{3dQ~&@#3$Q-Ubufnm0A3;j0Qdk@coSK7 zHy@CjkA-f42guv(k-w`8O%WnIO922L*8hLcfAI=brHyLzapTHgD&5NNaH_1ee$S z7vlOjc*xjAOq$|lYy>SJAeZ7HwXk?@mkr4DZ0^(Mm)nw7sUmYAB$5dKl)Eyh58N2| zfC)A(7aoH2Y-;GQ10Ro6%;J8U#-DR?WDPPu{luw^m`E42O5|%^qDgD0!)mSl!RtCh zwbPrWg>T-{27aA8_GJh5+QbHOTc;3}IzL%`MZy`_c;KZodsnb&a9|h9i^Ma{>sCQR z2MbPMUqz1ZfjO2i`&rEl`9j?K9Ce2T)xy?vudj!=sSNtf03oA62Riyk<3=v zQeLP!yg{!p`%SJ6ck+<|85({GMJ$ncR)q0@y3xAzRSn#{jLuPYY;Chp!G7vwcG%+U z(mgE6cwx1}nJmH~Z)^MIn&2T9+VdY|dO8lmj7Pc2k=20 zwe{|xqOwYFzLYq};Za{?O>V4(Q0x*z=$i8~bxqTNboL}hRcdl0qoC-}4UI#p`m|Dz zinmrhsyJWFBjk;)T=!_x@fbrRfF>9fWNc9Qshq(ENzcB>n$e#~hDf(h_YtL@vVu-J zPif++Cl7W`JH>EbOT|`RI;O-h+ma0u3U_2zl7f_RqrQyNI`j0cxDYYc1hJUC-*X>M zW4$g1E4Flc_A-@Zof;#u!bfT!V=0Mf*gn+6I_E_#Vg)xR=k%CQ@S)+C-+^kfI4bPu zwVYnAytp<1>DeUn!qGL=EawYkV6IcX#EnLvSCd{!Bj0j>d0kbHEVg zE9)JbQ~LIi^^Kv-sVx(y&HnQU2s7pTDA#kG5@(Dz+fvE?SM`ZEdCvzaH!cE07Uu>V z70nM{+#Nrr!U@r#o?YyFm|k;oj5|WQ?n5Zq$}pyPwSmjc+^2>9nc?Bxk~ zh=KSnP*EiJ@zZexRO_Q^sz^m7e7wW`gUTZe>^I){A0$$SIPwS{f4O2|B#kRBrIS1R zFcZt~G{OCp*U5W|as=ivM;ms+ucLJit0Nnln`z##+I@cbAPc!b&W{YBo<1c-Qx?Mt z08D?Kqh-J9k-tFw-hOMR9x&nDQ+$p2nW9pa3M?QV9P2|9H>5}%#+u^&xhShm54z3<4L-L#ITaFnT!| zFS&aeR6RtLld-_xFyy7ujS5kD@AMUFkzCBmDB&^d1;XM#1LUo9Nrb(DR+-#T(cm(W zY)nZ+7ut;_Qt@AAQFd=C+2?+NlUz&q(F5l`OIK}}wM#f_N*2g4cT5y}B*MDclkglF z{{=2e0?OFNrPm4b8=~e-e!qipZajUQctaJ&K3Zwk>7r00(t|5)tF;^JUZiEwcGchk z=B&A}lD8!u3y?>)N_K-e??&_MNIz|>wbnc^sqt80H}Se{BI$*4lx!c5v2oRYL$R7C zB?`-^6smXq>U{q|w$&C-+Z8>#L~b@_@=TPXk`B8yHk5V$-FqHTVgTdY+2Av-rF8n4GBn_@{7aK7WEFukN8`f52d4BT1vK9U{|$*fai%9> zes5!5xa(e7`AyOogh*|n>62A!H^-rzz>6o$7>$@1#vmrijruQ4SqF!W=`|I)f90

szJ^}Am1EWAC4C!5e2UeB!4!ebSKXq>Ckqw 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 v4*$GLwAXENrMdC4gVSOyZ7pM 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 U;pb$? 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 literal 0 HcmV?d00001 diff --git a/rawmaterial.xlsx b/rawmaterial.xlsx deleted file mode 100644 index fd5bbd16d3be7ca40cf191f47e7613a6f14f4bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10695 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 BwG{vW diff --git a/rawmaterialS.xlsx b/rawmaterialS.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7495f47b24c2eed640524f8bd8121871224f2e98 GIT binary patch literal 11256 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