From 382efa2139d329907d78f0df97d5dd371b41a37d Mon Sep 17 00:00:00 2001 From: Yofuria <20377277@buaa.edu.cn> Date: Tue, 25 Jul 2023 23:17:57 +0800 Subject: [PATCH] Step Success --- Environment.py | 20 +++++++++-------- Firm.py | 8 +++---- InventorySystem.py | 29 +++++++++++++------------ Order.py | 4 ++-- OrderSystem.py | 4 ++-- ProduceSystem.py | 52 ++++++++++++++++++++++++++++++++------------- bom23.xlsx | Bin 17116 -> 16213 bytes 7 files changed, 72 insertions(+), 45 deletions(-) diff --git a/Environment.py b/Environment.py index cf6239a..6143305 100644 --- a/Environment.py +++ b/Environment.py @@ -93,7 +93,7 @@ class FMSEnv(ap.Model): 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_produced_num = self.the_firm.the_ps.ev_ary_produce_number # 当期产品生产数量 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 @@ -124,16 +124,18 @@ if __name__ == '__main__': # 'xv_array_lead_time': 2, # 读取原材料表格 np.read, 暂时不读 变量代表的含义 # 'xv_int_lead_time_c': 3, # 'xv_int_lead_time_d': 1, - '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_ary_product_id': tuple(pd.read_excel("initial_product.xlsx").iloc[:, 0]), # 产成品id顺序 + 'xv_ary_material_id': tuple(pd.read_excel("initial_material.xlsx").iloc[:, 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 + 'xv_ary_initial_product_num': tuple([tuple(x) for x in pd.read_excel("initial_product.xlsx").values]), + # 初始产成品库存 23x2 + 'xv_ary_initial_material_num': tuple([tuple(x) for x in pd.read_excel("initial_material.xlsx").values]), + # 初始原材料库存 115x2 + 'xv_ary_bom': tuple([tuple(x) for x in pd.read_excel("bom23.xlsx").values]), # bom表 + 'xv_ary_plan': tuple([tuple(x) for x in pd.read_excel("plan.xlsx").values]), # plan表 + 'xv_ary_s': tuple([tuple(x) for x in pd.read_excel("rawmaterial - s.xlsx").values]), # s + 'xv_ary_S': tuple([tuple(x) for x in pd.read_excel("rawmaterialS.xlsx").values]), # S # 应读取遗传算法中随机生成的s,暂写为'1' 创建两个excel分别存储产品和原材料的库存 每个excel中存系统代码和库存 # 'xv_flt_initial_cash': 50000.0, # 'dct_status_info': json.dumps({ #需要引入生产状态表 diff --git a/Firm.py b/Firm.py index 8a9e897..fcd96e2 100644 --- a/Firm.py +++ b/Firm.py @@ -20,7 +20,7 @@ class Firm: 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_plan = np.asarray(dct_all_para['xv_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']) @@ -30,13 +30,13 @@ class Firm: # 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, xv_produt_num=self.xv_product_num, xv_ary_plan=self.xv_ary_plan, + self.the_os = OrderSystem(env, xv_product_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_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_bom=self.xv_ary_bom, xv_ary_plan=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, @@ -55,7 +55,7 @@ class Firm: 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_is.material_replenishment(xv_ary_s=self.xv_ary_s, xv_ary_S=self.xv_ary_S) 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 18ad354..8391ec1 100644 --- a/InventorySystem.py +++ b/InventorySystem.py @@ -23,7 +23,6 @@ class InventorySystem(ap.Agent): 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 @@ -63,8 +62,8 @@ class InventorySystem(ap.Agent): 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_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,)) # 原材料到货时间戳 @@ -82,21 +81,25 @@ class InventorySystem(ap.Agent): 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])] += product_plan[3] * \ - bom[ - 2] # 某原材料的生产数量加等产品生产量乘单位原材料消耗量 + 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] = min(self.ev_ary_current_material[i, 1], - self.ev_ary_material_state_to_use[i]) # 需要数量和库存两者间的较小值 + 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): @@ -107,12 +110,12 @@ class InventorySystem(ap.Agent): self.ev_lst_backtrans_quan_material[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_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 + ev_ary_produced_num[:, 1] # 上期期末加本期生产 + 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 @@ -123,9 +126,9 @@ class InventorySystem(ap.Agent): 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] = xv_ary_S[i, 1] - self.ev_ary_current_material[i, 1] + 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_int_order_time[i] + self.xv_ary_lead_time[ - self.xv_ary_lead_time[:, 0] == self.ev_ary_current_material[i, 0]][0, 1] + 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 diff --git a/Order.py b/Order.py index 3720ed5..a4a3fa9 100644 --- a/Order.py +++ b/Order.py @@ -21,8 +21,8 @@ class Order(ap.Agent): def setup(self, time_created): self.xv_time_created = time_created # 订单创建时间 # read the demand of 23 productions - 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_ary_dlv_product = np.asarray(pd.read_excel("demand23.xlsx").to_records(index=False)) # 接神经网络结果 + self.ev_ary_dlv_product = np.asarray(tuple(pd.read_excel("demand23.xlsx").iloc[:, 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.ev_actual_dlv_t = self.xv_dlv_t diff --git a/OrderSystem.py b/OrderSystem.py index 99b7ff5..f32fe42 100644 --- a/OrderSystem.py +++ b/OrderSystem.py @@ -47,7 +47,7 @@ class OrderSystem(ap.Agent): 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 = self.ev_ary_to_dlv - self.model.the_firm.the_is.ev_ary_current_product[:, 1] + self.ev_ary_product_to_produce = self.ev_ary_to_dlv - np.array([float(x) for x in 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 @@ -75,7 +75,7 @@ class OrderSystem(ap.Agent): # 需要更新 order.ev_ary_dlv_product # Make shipments based on ranked order list self.ev_ave_delay_time = 0 - self.ev_changed_product = ev_ary_current_product[:, 1] # 23x1 ndarray 存储本次库存的改变 + self.ev_changed_product = np.array([float(x) for x in 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 diff --git a/ProduceSystem.py b/ProduceSystem.py index 7de0f74..bf728d4 100644 --- a/ProduceSystem.py +++ b/ProduceSystem.py @@ -37,37 +37,59 @@ class ProduceSystem(ap.Agent): 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] + # print(sorted_indices_product) + 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] + # print(product_material) + # print(self.xv_ary_material) + # print(len(self.xv_ary_material)) + # print(np.where(self.xv_ary_material == 'D12087F2126')[0][0]) + # print(produce_plan[produce_plan[:, 1] == self.ev_ary_product[i]]) + produce_number = float(produce_plan[produce_plan[:, 1] == self.ev_ary_product[i]][0, 3]) + # print(type(produce_number)) for material in product_material: - produce_number = min(produce_number, int( - self.ev_lst_backtrans_material[np.where(self.xv_ary_material == material[1])] / material[ - 2])) # 取能生产的最小个数 + if np.isnan( + self.ev_lst_backtrans_material[np.where(self.xv_ary_material == material[1])[0][0]] / float( + material[ + 2])): + number = 100000 + else: + number = self.ev_lst_backtrans_material[ + np.where(self.xv_ary_material == material[1])[0][0]] / float(material[ + 2]) + produce_number = min(produce_number, int(number)) # 取能生产的最小个数 for material in product_material: - self.ev_lst_backtrans_material[np.where(self.xv_ary_material == material[1])] -= produce_number * \ - material[ - 2] # 更新原材料消耗情况 + # print(type(np.where(self.xv_ary_material == material[1]))) + self.ev_lst_backtrans_material[ + np.where(self.xv_ary_material == material[1])[0][0]] -= produce_number * \ + float(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 = self.xv_ary_bom[self.xv_ary_bom[:, 0] == current_product[0]] - produce_number = produce_plan[produce_plan[:, 1] == current_product[0]][3] + produce_number = float(produce_plan[produce_plan[:, 1] == current_product[0]][0, 3]) for material in product_material: - produce_number = min(produce_number, int( - self.ev_lst_backtrans_material[np.where(self.xv_ary_material == material[1])] / material[ - 2])) # 取能生产的最小个数 + if np.isnan(self.ev_lst_backtrans_material[ + np.where(self.xv_ary_material == material[1])[0][0]] / float(material[ + 2])): + number = 100000 + else: + number = self.ev_lst_backtrans_material[ + np.where(self.xv_ary_material == material[1])[0][0]] / float(material[ + 2]) + produce_number = min(produce_number, int(number)) # 取能生产的最小个数 for material in product_material: self.ev_lst_backtrans_material[ - np.where(self.xv_ary_material == material[1])] -= produce_number * \ - material[ - 2] # 更新原材料消耗情况 + np.where(self.xv_ary_material == material[1])[0][0]] -= produce_number * \ + float(material[ + 2]) # 更新原材料消耗情况 produce_number_lst.append([current_product[0], produce_number]) break diff --git a/bom23.xlsx b/bom23.xlsx index 43a982b8d61cdec67d832604dc66a8ba25e9b240..25d5d0fe77f0518b519f1ac923309ed2a6cb4983 100644 GIT binary patch literal 16213 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 literal 17116 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 ZI7T@sh>zX{0AN2pJ|E6gRN#+a{~s%51_b~B