2023-07-24 15:07:19 +08:00
|
|
|
|
import agentpy as ap
|
|
|
|
|
import numpy as np
|
|
|
|
|
from Order import Order
|
|
|
|
|
import pandas as pd
|
|
|
|
|
|
2023-07-25 21:32:08 +08:00
|
|
|
|
|
2023-07-24 15:07:19 +08:00
|
|
|
|
# 输出一个生产状态指令,一个交付情况,一个延期时间计算
|
|
|
|
|
class OrderSystem(ap.Agent):
|
|
|
|
|
a_lst_order: ap.AgentList[Order]
|
|
|
|
|
ev_int_produce_type: int
|
2023-07-25 21:32:08 +08:00
|
|
|
|
ev_ary_to_dlv: np.ndarray # 当前order list内所有产品的综合
|
2023-07-24 15:07:19 +08:00
|
|
|
|
ev_ary_product_to_produce: np.ndarray # 用于计算 production gap
|
|
|
|
|
ev_ave_delay_time: float
|
2023-07-25 21:32:08 +08:00
|
|
|
|
xv_ary_plan: np.ndarray
|
2023-07-24 15:07:19 +08:00
|
|
|
|
ev_changed_product: np.ndarray
|
2023-07-25 21:32:08 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xv_product_num: int
|
|
|
|
|
xv_ary_product: np.ndarray
|
2023-07-24 15:07:19 +08:00
|
|
|
|
# ev_ary_dlv_product: np.ndarray??????
|
|
|
|
|
|
2023-07-25 21:32:08 +08:00
|
|
|
|
def setup(self, xv_product_num, xv_ary_plan, xv_ary_product_id):
|
2023-07-24 15:07:19 +08:00
|
|
|
|
# Create a list of order
|
2023-07-25 21:32:08 +08:00
|
|
|
|
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,))
|
2023-07-24 15:07:19 +08:00
|
|
|
|
self.ev_ave_delay_time = 0
|
|
|
|
|
# self.ev_ary_dlv_product = np.zeros((23,)) ????
|
2023-07-25 21:32:08 +08:00
|
|
|
|
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
|
2023-07-24 15:07:19 +08:00
|
|
|
|
|
|
|
|
|
def accept_order(self, new_order):
|
|
|
|
|
# Determine whether the order is received and all are currently received
|
|
|
|
|
if new_order is not None:
|
|
|
|
|
new_order.ev_is_accepted = True
|
|
|
|
|
self.a_lst_order.append(new_order)
|
|
|
|
|
|
|
|
|
|
def rank_order(self):
|
|
|
|
|
# Sort order
|
2023-07-25 21:32:08 +08:00
|
|
|
|
self.a_lst_order = self.a_lst_order.sort('xv_dlv_t', reverse=False) # 按预期交付时间排序
|
2023-07-24 15:07:19 +08:00
|
|
|
|
|
|
|
|
|
def produce_status(self):
|
|
|
|
|
# 计算a_lst_order内所有订单包含的产品总量与当期库存的gap,排序最大缺口量,选定生产状态
|
2023-07-25 21:32:08 +08:00
|
|
|
|
self.ev_ary_to_dlv = np.zeros((self.xv_product_num,)) # 产品需求总和
|
|
|
|
|
for order in self.a_lst_order:
|
2023-07-24 15:07:19 +08:00
|
|
|
|
self.ev_ary_to_dlv += order.ev_ary_dlv_product # 当前天之前所有的还未满足的需求求和
|
2023-07-25 23:17:57 +08:00
|
|
|
|
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]])
|
2023-07-24 15:07:19 +08:00
|
|
|
|
# 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进行排序,选择能给库存最低的产品带来最高生产率的状态
|
2023-07-25 21:32:08 +08:00
|
|
|
|
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: # 判断是否存在库存不足
|
2023-07-24 15:07:19 +08:00
|
|
|
|
pass
|
|
|
|
|
else:
|
|
|
|
|
sorted_indices = np.argsort(self.model.the_firm.the_is.ev_ary_current_product[:, 1]) # 对库存进行从小到大排序
|
2023-07-25 21:32:08 +08:00
|
|
|
|
sorted_data = self.model.the_firm.the_is.ev_ary_current_product[:, sorted_indices][:, 0] # 库存从小到大的产品id
|
2023-07-24 15:07:19 +08:00
|
|
|
|
|
2023-07-25 21:32:08 +08:00
|
|
|
|
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]
|
2023-07-24 15:07:19 +08:00
|
|
|
|
self.ev_int_produce_type = sorted_data[0, 0]
|
2023-07-25 21:32:08 +08:00
|
|
|
|
# return self.ev_int_produce_type
|
2023-07-24 15:07:19 +08:00
|
|
|
|
|
2023-07-25 21:32:08 +08:00
|
|
|
|
def do_shipment(self, ev_ary_current_product):
|
2023-07-24 15:07:19 +08:00
|
|
|
|
# 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_ave_delay_time = 0
|
2023-07-25 23:17:57 +08:00
|
|
|
|
self.ev_changed_product = np.array([float(x) for x in ev_ary_current_product[:, 1]]) # 23x1 ndarray 存储本次库存的改变
|
2023-07-24 15:07:19 +08:00
|
|
|
|
for order in self.a_lst_order:
|
|
|
|
|
if order.xv_dlv_t == self.model.t: # 第一次交付
|
|
|
|
|
# Check and make shipment
|
|
|
|
|
order.ev_is_delivered = True
|
2023-07-25 21:32:08 +08:00
|
|
|
|
for i in range(self.xv_product_num):
|
2023-07-24 15:07:19 +08:00
|
|
|
|
if order.ev_ary_dlv_product[i] <= self.ev_changed_product[i]:
|
|
|
|
|
self.ev_changed_product[i] -= order.ev_ary_dlv_product[i]
|
2023-07-25 21:32:08 +08:00
|
|
|
|
order.ev_ary_dlv_product[i] = 0
|
2023-07-24 15:07:19 +08:00
|
|
|
|
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
|
2023-07-25 21:32:08 +08:00
|
|
|
|
for i in range(self.xv_product_num):
|
2023-07-24 15:07:19 +08:00
|
|
|
|
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)
|
|
|
|
|
self.ev_changed_product = self.ev_changed_product - order.ev_ary_dlv_product
|
2023-07-25 21:32:08 +08:00
|
|
|
|
order.ev_ary_dlv_product = np.zeros((self.xv_product_num,))
|
2023-07-24 15:07:19 +08:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2023-07-25 21:32:08 +08:00
|
|
|
|
# return self.ev_changed_product, self.ev_ave_delay_time
|