2023-07-24 15:07:19 +08:00
|
|
|
|
import agentpy as ap
|
|
|
|
|
import numpy as np
|
|
|
|
|
import random
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ProduceSystem(ap.Agent):
|
2023-07-25 21:32:08 +08:00
|
|
|
|
ev_str_status: int # 0,6,8,10 pp_id
|
2023-07-24 15:07:19 +08:00
|
|
|
|
ev_lst_backtrans_material: list # 退回Iss的原材料
|
|
|
|
|
ev_ary_produce_number: np.ndarray
|
|
|
|
|
|
2023-07-25 21:32:08 +08:00
|
|
|
|
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 # 设置初始生产状态
|
2023-07-24 15:07:19 +08:00
|
|
|
|
self.ev_lst_backtrans_material = []
|
2023-07-25 21:32:08 +08:00
|
|
|
|
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
|
2023-07-24 15:07:19 +08:00
|
|
|
|
|
|
|
|
|
def change_status(self):
|
2023-07-25 21:32:08 +08:00
|
|
|
|
self.ev_str_status = self.model.the_firm.the_os.ev_int_produce_type
|
2023-07-24 15:07:19 +08:00
|
|
|
|
|
2023-07-25 21:32:08 +08:00
|
|
|
|
def run_produce(self, ev_lst_trans_quan_material,
|
|
|
|
|
ev_ary_product_to_produce): # ev_ary_product_to_produce 是 需求和库存的gap 23x1
|
2023-07-24 15:07:19 +08:00
|
|
|
|
# 生产状态由Iss确定,这个函数需要计算生产数量和原材料消耗量。
|
|
|
|
|
# 如果原材料不足,就按照production gap(ev_ary_product_to_produce) 大小进行生产;如果没有gap的产品了,就按照库存水平由少到多进行生产。
|
|
|
|
|
# 输出生产结果和原材料消耗结果
|
2023-07-25 21:32:08 +08:00
|
|
|
|
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]
|
2023-07-24 15:07:19 +08:00
|
|
|
|
sorted_data = ev_ary_product_to_produce[sorted_indices] # 对gap进行从大到小排序
|
2023-07-25 21:32:08 +08:00
|
|
|
|
self.ev_ary_product = self.ev_ary_product[sorted_indices]
|
2023-07-24 15:07:19 +08:00
|
|
|
|
sorted_indices_product = np.argsort(self.model.the_firm.the_is.ev_ary_current_product[:, 1]) # 对库存进行从小到大排序
|
2023-07-25 23:17:57 +08:00
|
|
|
|
# print(sorted_indices_product)
|
|
|
|
|
sorted_data_product = self.model.the_firm.the_is.ev_ary_current_product[sorted_indices_product, :]
|
2023-07-25 21:32:08 +08:00
|
|
|
|
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]]
|
2023-07-25 23:17:57 +08:00
|
|
|
|
# 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))
|
2023-07-24 15:07:19 +08:00
|
|
|
|
for material in product_material:
|
2023-07-25 23:17:57 +08:00
|
|
|
|
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)) # 取能生产的最小个数
|
2023-07-24 15:07:19 +08:00
|
|
|
|
for material in product_material:
|
2023-07-25 23:17:57 +08:00
|
|
|
|
# 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]) # 更新原材料消耗情况
|
2023-07-25 21:32:08 +08:00
|
|
|
|
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]]
|
2023-07-24 15:07:19 +08:00
|
|
|
|
else:
|
|
|
|
|
for current_product in sorted_data_product:
|
2023-07-25 21:32:08 +08:00
|
|
|
|
product_material = self.xv_ary_bom[self.xv_ary_bom[:, 0] == current_product[0]]
|
2023-07-25 23:17:57 +08:00
|
|
|
|
produce_number = float(produce_plan[produce_plan[:, 1] == current_product[0]][0, 3])
|
2023-07-24 15:07:19 +08:00
|
|
|
|
for material in product_material:
|
2023-07-25 23:17:57 +08:00
|
|
|
|
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)) # 取能生产的最小个数
|
2023-07-24 15:07:19 +08:00
|
|
|
|
for material in product_material:
|
2023-07-25 21:32:08 +08:00
|
|
|
|
self.ev_lst_backtrans_material[
|
2023-07-25 23:17:57 +08:00
|
|
|
|
np.where(self.xv_ary_material == material[1])[0][0]] -= produce_number * \
|
|
|
|
|
float(material[
|
|
|
|
|
2]) # 更新原材料消耗情况
|
2023-07-25 21:32:08 +08:00
|
|
|
|
produce_number_lst.append([current_product[0], produce_number])
|
|
|
|
|
|
|
|
|
|
break
|
2023-07-24 15:07:19 +08:00
|
|
|
|
|
2023-07-25 21:32:08 +08:00
|
|
|
|
self.ev_ary_produce_number = np.array(produce_number_lst)
|
2023-07-24 15:07:19 +08:00
|
|
|
|
|
2023-07-25 21:32:08 +08:00
|
|
|
|
# return self.ev_ary_produce_number, self.ev_lst_backtrans_material
|