update
This commit is contained in:
parent
9c19357d59
commit
6027857189
|
@ -0,0 +1,3 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
|
@ -0,0 +1 @@
|
||||||
|
OrderSystem.py
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.10 (2)" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (2)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/HTSim.iml" filepath="$PROJECT_DIR$/.idea/HTSim.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,42 @@
|
||||||
|
!按子系统功能!
|
||||||
|
|
||||||
|
Oss:
|
||||||
|
接收订单。
|
||||||
|
计算到当期为止,未交付订单的各类产品与其库存之差,得到gap最大的产品,并将能获得该商品最大生产率的生产状态通知Iss和Pss。
|
||||||
|
|
||||||
|
交付当期到期和已经出现延期的订单,先进先出。
|
||||||
|
|
||||||
|
计算(env)延期平均时间:延期时间 * 延期产品数/10000
|
||||||
|
|
||||||
|
Iss:
|
||||||
|
按照Oss指定的生产状态,准备原材料并交付Pss(如果原材料不充足,就将能交付的先交付)
|
||||||
|
|
||||||
|
每期末统计原材料使用情况,按照遗传算法提供的Sspolicy,选择是否订货(初始原材料备货为s),如果订货要随机生成该原材料的交货期。
|
||||||
|
|
||||||
|
每期末要更新原材料剩余情况(上一次余值+当期到货量-当期使用量)
|
||||||
|
|
||||||
|
更新产成品期末库存。
|
||||||
|
|
||||||
|
|
||||||
|
Pss:
|
||||||
|
根据Oss的指示,开始生产,如果原材料不充足,就按照gap大小进行生产;如果没有gap的产品了,就按照库存水平由少到多进行生产。
|
||||||
|
(此处如果出现原材料余料,回交Iss)
|
||||||
|
生成最终生产结果,产成品交付Iss。
|
||||||
|
|
||||||
|
|
||||||
|
!按流程 !
|
||||||
|
|
||||||
|
Oss:接收订单。计算到当期为止,未交付订单的各类产品与其库存之差,得到gap最大的产品,并将能获得该商品最大生产率的生产状态通知Iss和Pss。
|
||||||
|
|
||||||
|
Iss:按照Oss指定的生产状态,准备原材料并交付Pss(如果原材料不充足,就将能交付的先交付)。
|
||||||
|
|
||||||
|
Pss:根据Oss的指示,开始生产,如果原材料不充足,就按照gap大小进行生产;如果没有gap的产品了,就按照库存水平由少到多进行生产。
|
||||||
|
(此处如果出现原材料余料,回交Iss)
|
||||||
|
生成最终生产结果,产成品交付Iss。
|
||||||
|
|
||||||
|
Iss:统计原材料使用情况,按照遗传算法提供的Sspolicy,选择是否订货(初始原材料备货为s),如果订货要随机生成该原材料的交货期。
|
||||||
|
每期末要更新原材料剩余情况(上一次余值+当期到货量-当期使用量)。
|
||||||
|
更新产成品期末库存。
|
||||||
|
|
||||||
|
Oss:交付当期到期和已经出现延期的订单,先进先出。计算(env)延期平均时间:延期时间 * 延期产品数/10000
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
import random
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
import agentpy as ap
|
||||||
|
from datetime import datetime
|
||||||
|
from numpy import random
|
||||||
|
import json
|
||||||
|
|
||||||
|
from Firm import Firm
|
||||||
|
# import passive agents
|
||||||
|
from Order import Order
|
||||||
|
|
||||||
|
from fake_api import get_plan_by_pp_id, get_bom_by_prd_id
|
||||||
|
|
||||||
|
|
||||||
|
class FMSEnv(ap.Model):
|
||||||
|
# put all parameters here, not in any other places
|
||||||
|
# xv_int_max_order: int
|
||||||
|
# ev_n_order_created: int
|
||||||
|
|
||||||
|
the_firm: Firm
|
||||||
|
|
||||||
|
# record data, define below
|
||||||
|
# op_os_n_total_order: int
|
||||||
|
# op_os_n_total_order_delayed: int
|
||||||
|
op_os_all_delay_time: list
|
||||||
|
# op_os_delay_ratio: float
|
||||||
|
# op_is_flt_material_room_left: float
|
||||||
|
# op_is_flt_product_room_left: float
|
||||||
|
|
||||||
|
op_ps_str_status: str
|
||||||
|
op_os_to_dlv: np.ndarray
|
||||||
|
op_is_current_product: np.ndarray
|
||||||
|
op_is_current_material: np.ndarray
|
||||||
|
op_is_trans_material: np.ndarray
|
||||||
|
op_ps_back_trans_material: np.ndarray
|
||||||
|
op_ps_produced_num: np.ndarray
|
||||||
|
op_is_ip_mat_id: np.ndarray
|
||||||
|
op_ip_prd_s: np.ndarray
|
||||||
|
op_ip_prd_big_s: np.ndarray
|
||||||
|
op_ip_prd_est_pfm: int
|
||||||
|
|
||||||
|
def __init__(self, dct_all_para, _run_id=None):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
# create agents here
|
||||||
|
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.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_int_dlv_period_lam = int(dct_all_para['xv_int_dlv_period_lam'])
|
||||||
|
# self.ev_n_order_created = 0
|
||||||
|
|
||||||
|
self.running = True
|
||||||
|
self.t = 0
|
||||||
|
|
||||||
|
# Creation of orders should be done in the environment
|
||||||
|
def create_order(self):
|
||||||
|
# Check if maximum number of orders has been reached
|
||||||
|
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
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
self.the_firm.operating()
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
if self.t >= self.int_stop_time:
|
||||||
|
self.running = False
|
||||||
|
self.stop()
|
||||||
|
else:
|
||||||
|
print(f"running the {self.t} step")
|
||||||
|
|
||||||
|
# Record data after each simulation
|
||||||
|
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_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_is_current_product = self.model.the_firm.the_is.ev_ary_current_product
|
||||||
|
#
|
||||||
|
# self.op_is_current_material = self.model.the_firm.the_is.ev_ary_current_material
|
||||||
|
#
|
||||||
|
# self.op_is_trans_material= self.model.the_firm.the_is.ev_lst_trans_material
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
dct_para = {
|
||||||
|
'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.
|
||||||
|
# 'xv_int_dlv_period_lam': 8.5,
|
||||||
|
# 'xv_int_create_order_lam': 2,
|
||||||
|
# 'xv_ary_price_product': tuple([0.3,0.2,0.5,1]),
|
||||||
|
# '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_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_flt_initial_cash': 50000.0,
|
||||||
|
# 'dct_status_info': json.dumps({ #需要引入生产状态表
|
||||||
|
# "0": {"xv_flt_produce_rate": tuple([0.0, 0.0]),
|
||||||
|
# "xv_ary_mat_material": tuple([0.0, 0.0]),
|
||||||
|
# "xv_flt_broken_rate": 0,
|
||||||
|
# "xv_flt_run_cost": 0.0,
|
||||||
|
# "name": "wait"
|
||||||
|
# },
|
||||||
|
# "1": {"xv_flt_produce_rate": tuple([90.0, 0.0]),
|
||||||
|
# "xv_ary_mat_material": tuple([4.0, 1.0]),
|
||||||
|
# "xv_flt_broken_rate": 0.03,
|
||||||
|
# "xv_flt_run_cost": 40.0,
|
||||||
|
# "name": "produceA"
|
||||||
|
# },
|
||||||
|
# "2": {"xv_flt_produce_rate": tuple([0.0, 60.0]),
|
||||||
|
# "xv_ary_mat_material": tuple([1.5, 5.0]),
|
||||||
|
# "xv_flt_broken_rate": 0.05,
|
||||||
|
# "xv_flt_run_cost": 50.0,
|
||||||
|
# "name": "produceB"
|
||||||
|
# },
|
||||||
|
# "3": {"xv_flt_produce_rate": tuple([55.0, 30.0]),
|
||||||
|
# "xv_ary_mat_material": tuple([2.0, 1.5]),
|
||||||
|
# "xv_flt_broken_rate": 0.07,
|
||||||
|
# "xv_flt_run_cost": 60.0,
|
||||||
|
# "name": "produceAB"
|
||||||
|
# },
|
||||||
|
# "-1": {"xv_flt_produce_rate": 0.0,
|
||||||
|
# "xv_ary_mat_material": tuple([0.0, 0.0]),
|
||||||
|
# "xv_flt_broken_rate": 0.1,
|
||||||
|
# "xv_flt_run_cost": 100.0,
|
||||||
|
# "name": "failed"
|
||||||
|
# }
|
||||||
|
# })
|
||||||
|
|
||||||
|
}
|
||||||
|
sample = ap.Sample(dct_para)
|
||||||
|
|
||||||
|
exp = ap.Experiment(FMSEnv, sample, iterations=1, record=True)
|
||||||
|
results = exp.run()
|
||||||
|
# results['variables']['FMSEnv'].to_excel(f"simulation-results-{datetime.today().strftime('%Y-%m-%d-%H-%M-%S')}.xlsx",
|
||||||
|
# engine='openpyxl')
|
|
@ -0,0 +1,37 @@
|
||||||
|
import numpy as np
|
||||||
|
import json
|
||||||
|
|
||||||
|
from InventorySystem import InventorySystem
|
||||||
|
from OrderSystem import OrderSystem
|
||||||
|
from ProduceSystem import ProduceSystem
|
||||||
|
|
||||||
|
# Create Company Instance
|
||||||
|
class Firm:
|
||||||
|
the_os: OrderSystem
|
||||||
|
the_is: InventorySystem
|
||||||
|
the_ps: ProduceSystem
|
||||||
|
|
||||||
|
def __init__(self, env, dct_all_para):
|
||||||
|
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']])
|
||||||
|
|
||||||
|
# create agents here
|
||||||
|
self.the_os = OrderSystem(env)
|
||||||
|
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)
|
||||||
|
# self.the_fs = FinancialSystem(env, xv_flt_initial_cash=self.xv_flt_initial_cash)
|
||||||
|
|
||||||
|
def operating(self):
|
||||||
|
self.the_os.rank_order()
|
||||||
|
self.the_ps.change_status()
|
||||||
|
self.the_ps.run_produce()
|
||||||
|
self.the_os.do_shipment()
|
||||||
|
# self.the_is.inventory_cost()
|
||||||
|
# self.the_fs.financial_calculating()
|
|
@ -0,0 +1,128 @@
|
||||||
|
import agentpy as ap
|
||||||
|
import numpy as np
|
||||||
|
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_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 # 当期送到的数量
|
||||||
|
|
||||||
|
# set the lead time of material replenishment
|
||||||
|
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_material_inventory: list
|
||||||
|
ev_lst_product_inventory: list
|
||||||
|
|
||||||
|
# Material list
|
||||||
|
xv_lst_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 # 当期原材料到货量
|
||||||
|
|
||||||
|
def setup(self, xv_ary_initial_material_num,
|
||||||
|
xv_ary_initial_product_num, xv_ary_lead_time):
|
||||||
|
|
||||||
|
# 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, ))
|
||||||
|
|
||||||
|
# set the lead time of materials
|
||||||
|
# 读取各个原材料的历史平均交货周期 bom table
|
||||||
|
self.xv_ary_lead_time = pd.read_excel("bom23.xlsx").iloc[:, 4].to_numpy()
|
||||||
|
# 切换成原材料
|
||||||
|
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_lst_material_inventory = []
|
||||||
|
self.ev_lst_product_inventory = []
|
||||||
|
|
||||||
|
self.xv_lst_material = pd.read_excel("rawmaterial.xlsx").to_numpy()
|
||||||
|
|
||||||
|
self.xv_ary_bom = pd.read_excel("bom23.xlsx").to_numpy()
|
||||||
|
|
||||||
|
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,))
|
||||||
|
|
||||||
|
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 # 获取生产状态
|
||||||
|
produce_plan = xv_plan_excel[xv_plan_excel[:, 0] == produce_state]
|
||||||
|
for 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] # 某原材料的生产数量加等产品生产量乘单位原材料消耗量
|
||||||
|
|
||||||
|
def material_check(self, ev_ary_material_state_to_use):
|
||||||
|
# 根据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]
|
||||||
|
|
||||||
|
def consume_and_store(self, ev_ary_material_to_use, ev_ary_produced_num,ev_changed_product,
|
||||||
|
ev_lst_backtrans_material):
|
||||||
|
self.ev_lst_backtrans_quan_material = ev_lst_backtrans_material
|
||||||
|
# Update the inventory after production
|
||||||
|
for i in range(115):
|
||||||
|
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]
|
||||||
|
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
|
||||||
|
|
||||||
|
def material_replenishment(self):
|
||||||
|
# Check the inventory of material to decide whether to replenish
|
||||||
|
# 核对原材料数量是否低于s
|
||||||
|
# 带时间戳
|
||||||
|
for i in range(115):
|
||||||
|
if self.ev_ary_current_material[i] <= s:
|
||||||
|
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]
|
||||||
|
else:
|
||||||
|
self.ev_ary_num_material_to_order[i] = 0
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import agentpy as ap
|
||||||
|
import random
|
||||||
|
import numpy as np
|
||||||
|
from numpy import random
|
||||||
|
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 # 实际交付时间
|
||||||
|
|
||||||
|
ev_is_delivered: bool # 订单是否已交付
|
||||||
|
ev_is_accepted: bool # 订单是否被接受
|
||||||
|
ev_int_delay_time: int # total delay time
|
||||||
|
|
||||||
|
xv_ary_dlv_product: np.ndarray
|
||||||
|
ev_ary_dlv_product: np.ndarray
|
||||||
|
|
||||||
|
def setup(self, 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_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
|
||||||
|
self.ev_int_delay_time = self.ev_actual_dlv_t - self.xv_dlv_t
|
||||||
|
|
||||||
|
# Set the initial status of order to be undelivered, accepted
|
||||||
|
self.ev_is_delivered = False
|
||||||
|
self.ev_is_accepted = False
|
|
@ -0,0 +1,103 @@
|
||||||
|
import agentpy as ap
|
||||||
|
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_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
|
||||||
|
ev_changed_product: np.ndarray
|
||||||
|
# ev_ary_dlv_product: np.ndarray??????
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
# 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.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
|
||||||
|
|
||||||
|
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
|
||||||
|
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 += 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.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: # 判断是否存在库存不足
|
||||||
|
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]
|
||||||
|
|
||||||
|
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]
|
||||||
|
self.ev_int_produce_type = sorted_data[0, 0]
|
||||||
|
return self.ev_int_produce_type
|
||||||
|
|
||||||
|
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 存储本次库存的改变
|
||||||
|
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)):
|
||||||
|
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]
|
||||||
|
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)):
|
||||||
|
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_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
|
|
@ -0,0 +1,60 @@
|
||||||
|
import agentpy as ap
|
||||||
|
import numpy as np
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
class ProduceSystem(ap.Agent):
|
||||||
|
ev_str_status: str # 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
|
||||||
|
self.ev_lst_backtrans_material = []
|
||||||
|
|
||||||
|
def change_status(self):
|
||||||
|
self.ev_str_status = self.model.the_firm.the_os.produce_status()
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
# 生产状态由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]
|
||||||
|
sorted_data = ev_ary_product_to_produce[sorted_indices] # 对gap进行从大到小排序
|
||||||
|
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]
|
||||||
|
for material in product_material:
|
||||||
|
produce_number = min(produce_number, int(
|
||||||
|
self.ev_lst_backtrans_material[np.where(ev_lst_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]]
|
||||||
|
else:
|
||||||
|
for current_product in sorted_data_product:
|
||||||
|
product_material = xv_ary_bom[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[
|
||||||
|
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_ary_produce_number = np.array(self.ev_ary_produce_number)
|
||||||
|
|
||||||
|
return self.ev_ary_produce_number, self.ev_lst_backtrans_material
|
|
@ -0,0 +1,208 @@
|
||||||
|
prd_id,mtr_id,qty,unit
|
||||||
|
ADTB331M0611,Z013V09501055,0.000347,平方米
|
||||||
|
ADTB331M0611,F00VC50A055,0.000418,平方米
|
||||||
|
ADTB331M0611,SM26040B070,0.000033,千克
|
||||||
|
ADTB331M0611,D12073G2126b,0.0001,万对
|
||||||
|
ADTB331M0611,YG00002,9.33E-06,卷
|
||||||
|
ADTB331M0611,YHCP50A,0.00017,千克
|
||||||
|
ADTB331M0611,L063-109Y,0.0001,万支
|
||||||
|
ADTB331M0611,P06-30I,0.0001,万只
|
||||||
|
ADTB331M0611,GT063T,0.000039,千克
|
||||||
|
AGTR4R7V0812,Z510V12001070,0.000623,平方米
|
||||||
|
AGTR4R7V0812,F30VC20A070,0.000784,平方米
|
||||||
|
AGTR4R7V0812,EHD450Z085,0.000094,千克
|
||||||
|
AGTR4R7V0812,D12087F2126,0.0001,万对
|
||||||
|
AGTR4R7V0812,YG00001,2.07E-05,卷
|
||||||
|
AGTR4R7V0812,YHBH421H,0.00019,千克
|
||||||
|
AGTR4R7V0812,N080-130Y,0.0001,万支
|
||||||
|
AGTR4R7V0812,P08-30I,0.0001,万只
|
||||||
|
AGTR4R7V0812,GT080C,0.000071,千克
|
||||||
|
AMSR2R2M0609,Z530V12001050,0.000295,平方米
|
||||||
|
AMSR2R2M0609,F30VC30A050,0.000345,平方米
|
||||||
|
AMSR2R2M0609,W19040X065,0.000045,千克
|
||||||
|
AMSR2R2M0609,D12073T2126b,0.0001,万对
|
||||||
|
AMSR2R2M0609,YG00001,9.33E-06,卷
|
||||||
|
AMSR2R2M0609,YHBH421H,0.00011,千克
|
||||||
|
AMSR2R2M0609,T063-100Y,0.0001,万支
|
||||||
|
AMSR2R2M0609,P06-26T,0.0001,万只
|
||||||
|
AMSR2R2M0609,MS063T,0.000039,千克
|
||||||
|
RD1H108M12025,Z067V10201160,0.00576,平方米
|
||||||
|
RD1H108M12025,F00VC40A160,0.006224,平方米
|
||||||
|
RD1H108M12025,SM26040B190,0.000519,千克
|
||||||
|
RD1H108M12025,D15147G2328y,0.0001,万对
|
||||||
|
RD1H108M12025,YG00006,0.000031,卷
|
||||||
|
RD1H108M12025,YHCP50A,0.00121,千克
|
||||||
|
RD1H108M12025,L125-257+,0.0001,万支
|
||||||
|
RD1H108M12025,GNH-12.5M,0.0001,万只
|
||||||
|
RD1H108M12025,AW125T,0.000181,千克
|
||||||
|
RD1E108M10020,Z036V09001140,0.002408,平方米
|
||||||
|
RD1E108M10020,F00VC40A140,0.002982,平方米
|
||||||
|
RD1E108M10020,SM26040B160,0.000209,千克
|
||||||
|
RD1E108M10020,D15147G2328y,0.0001,万对
|
||||||
|
RD1E108M10020,YG00005,0.000031,卷
|
||||||
|
RD1E108M10020,YHCP50A,0.00057,千克
|
||||||
|
RD1E108M10020,L100-215+,0.0001,万支
|
||||||
|
RD1E108M10020,GNH-10F,0.0001,万只
|
||||||
|
RD1E108M10020,AW100T,0.000121,千克
|
||||||
|
AMSR100V1013I,Z530V12001070,0.00126,平方米
|
||||||
|
AMSR100V1013I,F30VC20A070,0.00147,平方米
|
||||||
|
AMSR100V1013I,W19040X085,0.00018,千克
|
||||||
|
AMSR100V1013I,D15091TL2328,0.0001,万对
|
||||||
|
AMSR100V1013I,YG00007,,千克
|
||||||
|
AMSR100V1013I,YHBH421H,0.00026,千克
|
||||||
|
AMSR100V1013I,T100-135Y,0.0001,万支
|
||||||
|
AMSR100V1013I,P10-35T,0.0001,万只
|
||||||
|
AMSR100V1013I,MS100T,0.000086,千克
|
||||||
|
AGEN181V1625,Z280V12002170,0.009673,平方米
|
||||||
|
AGEN181V1625,F30VC20A170,0.010948,平方米
|
||||||
|
AGEN181V1625,EHD440Z200,0.001346,千克
|
||||||
|
AGEN181V1625,D20180G2530,0.0001,万对
|
||||||
|
AGEN181V1625,YG00006,0.000065,卷
|
||||||
|
AGEN181V1625,YHBH250H,0.0028,千克
|
||||||
|
AGEN181V1625,T160-270Y,0.0001,万支
|
||||||
|
AGEN181V1625,P16-50I,0.0001,万只
|
||||||
|
AGEN181V1625,EF160T,0.000261,千克
|
||||||
|
CEGM680M1020,Z210V11501140,0.002884,平方米
|
||||||
|
CEGM680M1020,F30VC20A140,0.003164,平方米
|
||||||
|
CEGM680M1020,W28540X1160,0.000334,千克
|
||||||
|
CEGM680M1020,D15131G2328,0.0001,万对
|
||||||
|
CEGM680M1020,YG00005,0.000031,卷
|
||||||
|
CEGM680M1020,YHBH250H,0.00057,千克
|
||||||
|
CEGM680M1020,N100-210Y,0.0001,万支
|
||||||
|
CEGM680M1020,P10-35I,0.0001,万只
|
||||||
|
CEGM680M1020,EG100T,0.000117,千克
|
||||||
|
RD2G475M1012M,Z660V12002070,0.000819,平方米
|
||||||
|
RD2G475M1012M,F30VC20A070,0.001057,平方米
|
||||||
|
RD2G475M1012M,WS28050K085,0.000127,千克
|
||||||
|
RD2G475M1012M,TX15084*G2328,0.0001,万对
|
||||||
|
RD2G475M1012M,YG00003,0.0000285,卷
|
||||||
|
RD2G475M1012M,YHBH450H,0.00025,千克
|
||||||
|
RD2G475M1012M,L100-130+,0.0001,万支
|
||||||
|
RD2G475M1012M,GNH-10L,0.0001,万只
|
||||||
|
RD2G475M1012M,AW100T,0.000082,千克
|
||||||
|
AMSR4R7M0812,Z530V12001070,0.00063,平方米
|
||||||
|
AMSR4R7M0812,F30VC20A070,0.000735,平方米
|
||||||
|
AMSR4R7M0812,EHD450Z085,0.000095,千克
|
||||||
|
AMSR4R7M0812,D12087T2126d,0.0001,万对
|
||||||
|
AMSR4R7M0812,YG00001,2.07E-05,卷
|
||||||
|
AMSR4R7M0812,YHBH421H,0.00019,千克
|
||||||
|
AMSR4R7M0812,T080-130Y,0.0001,万支
|
||||||
|
AMSR4R7M0812,P08-30T,0.0001,万只
|
||||||
|
AMSR4R7M0812,MS080T,0.000072,千克
|
||||||
|
AVSR2R2V0609,Z530V12001050,0.000305,平方米
|
||||||
|
AVSR2R2V0609,F30VC30A050,0.00037,平方米
|
||||||
|
AVSR2R2V0609,W19040X065,0.000046,千克
|
||||||
|
AVSR2R2V0609,D12073F2126b,0.0001,万对
|
||||||
|
AVSR2R2V0609,YG00001,9.33E-06,卷
|
||||||
|
AVSR2R2V0609,YHBH421H,0.00011,千克
|
||||||
|
AVSR2R2V0609,L063-100Y,0.0001,万支
|
||||||
|
AVSR2R2V0609,P06-26I,0.0001,万只
|
||||||
|
AVSR2R2V0609,EF063C,0.000034,千克
|
||||||
|
AMSR6R8M1013,Z530V12001070,0.000903,平方米
|
||||||
|
AMSR6R8M1013,F30VC20A070,0.001043,平方米
|
||||||
|
AMSR6R8M1013,EHD450Z085,0.000136,千克
|
||||||
|
AMSR6R8M1013,D15091T2328,0.0001,万对
|
||||||
|
AMSR6R8M1013,YG00002,1.93E-05,卷
|
||||||
|
AMSR6R8M1013,YHBH421H,0.00026,千克
|
||||||
|
AMSR6R8M1013,T100-135Y,0.0001,万支
|
||||||
|
AMSR6R8M1013,P10-35T,0.0001,万只
|
||||||
|
AMSR6R8M1013,MS100T,0.000086,千克
|
||||||
|
AMSR3R3M0810,Z530V12001050,0.000445,平方米
|
||||||
|
AMSR3R3M0810,F30VC30A050,0.00052,平方米
|
||||||
|
AMSR3R3M0810,EHD450Z065,0.000072,千克
|
||||||
|
AMSR3R3M0810,D12073T2126b,0.0001,万对
|
||||||
|
AMSR3R3M0810,YG00002,0.000019,卷
|
||||||
|
AMSR3R3M0810,YHBH421H,0.00017,千克
|
||||||
|
AMSR3R3M0810,T080-103Y,0.0001,万支
|
||||||
|
AMSR3R3M0810,P08-26T,0.0001,万只
|
||||||
|
AMSR3R3M0810,MS080T,0.000059,千克
|
||||||
|
AMSN120M0812I,Z280V12001070,0.000651,平方米
|
||||||
|
AMSN120M0812I,F30VC20A070,0.000826,平方米
|
||||||
|
AMSN120M0812I,EHD450Z085,0.000098,千克
|
||||||
|
AMSN120M0812I,D12087TL2126d,0.0001,万对
|
||||||
|
AMSN120M0812I,YG00003,0.000031,卷
|
||||||
|
AMSN120M0812I,YHBH250H,0.00019,千克
|
||||||
|
AMSN120M0812I,T080-130Y,0.0001,万支
|
||||||
|
AMSN120M0812I,P08-30T,0.0001,万只
|
||||||
|
AMSN120M0812I,MS080T,0.000072,千克
|
||||||
|
WL1H476M6L011,Z082V10001065,0.000371,平方米
|
||||||
|
WL1H476M6L011,F20VC50A065,0.000436,平方米
|
||||||
|
WL1H476M6L011,MJ24540K080,0.001368,千克
|
||||||
|
WL1H476M6L011,D12087G2126,0.0001,万对
|
||||||
|
WL1H476M6L011,YG00024,0.00001,卷
|
||||||
|
WL1H476M6L011,YHCP50A,0.00012,千克
|
||||||
|
WL1H476M6L011,L063-117+,0.0001,万支
|
||||||
|
WL1H476M6L011,GAH-6.3L,0.0001,万只
|
||||||
|
WL1H476M6L011,AW063T,0.000043,千克
|
||||||
|
AMSR8R2M1013,Z530V12001070,0.001085,平方米
|
||||||
|
AMSR8R2M1013,F30VC20A070,0.001225,平方米
|
||||||
|
AMSR8R2M1013,EHD450Z085,0.000164,千克
|
||||||
|
AMSR8R2M1013,D15091T2328,0.0001,万对
|
||||||
|
AMSR8R2M1013,YG00001,1.93E-05,卷
|
||||||
|
AMSR8R2M1013,YHBH421H,0.00026,千克
|
||||||
|
AMSR8R2M1013,T100-135Y,0.0001,万支
|
||||||
|
AMSR8R2M1013,P10-35T,0.0001,万只
|
||||||
|
AMSR8R2M1013,MS100T,0.000086,千克
|
||||||
|
AGFM121M1320,Z210V11501140,0.004998,平方米
|
||||||
|
AGFM121M1320,F30VC20A140,0.005348,平方米
|
||||||
|
AGFM121M1320,EHD440Z160,0.000579,千克
|
||||||
|
AGFM121M1320,D15147G2328bd,0.0001,万对
|
||||||
|
AGFM121M1320,YG00004,0.0000375,卷
|
||||||
|
AGFM121M1320,YHBH250H,0.00099,千克
|
||||||
|
AGFM121M1320,L130-215Y,0.0001,万支
|
||||||
|
AGFM121M1320,P13-35I,0.0001,万只
|
||||||
|
AGFM121M1320,EF130T,0.000155,千克
|
||||||
|
AGSS100V1013,Z590V10503075,0.001493,平方米
|
||||||
|
AGSS100V1013,F30VC20A075,0.00162,平方米
|
||||||
|
AGSS100V1013,W19040X090,0.00021,千克
|
||||||
|
AGSS100V1013,D15091F2328,0.0001,万对
|
||||||
|
AGSS100V1013,YG00003,0.000029,卷
|
||||||
|
AGSS100V1013,YHBH450H,0.00049,千克
|
||||||
|
AGSS100V1013,L100-140Y,0.0001,万支
|
||||||
|
AGSS100V1013,P10-35I,0.0001,万只
|
||||||
|
AGSS100V1013,GS100C,0.000099,千克
|
||||||
|
AVSR3R3V0609,Z490V12501055,0.000358,平方米
|
||||||
|
AVSR3R3V0609,F30VC20A055,0.000413,平方米
|
||||||
|
AVSR3R3V0609,W19040X070,0.000053,千克
|
||||||
|
AVSR3R3V0609,D12073F2126b,0.0001,万对
|
||||||
|
AVSR3R3V0609,YG00001,9.33E-06,卷
|
||||||
|
AVSR3R3V0609,YHBH421H,0.00011,千克
|
||||||
|
AVSR3R3V0609,L063-100Y,0.0001,万支
|
||||||
|
AVSR3R3V0609,P06-20I,0.0001,万只
|
||||||
|
AVSR3R3V0609,EF063C,0.000034,千克
|
||||||
|
ACSR4R7V0812,Z530V12001070,0.000623,平方米
|
||||||
|
ACSR4R7V0812,F30VC20A070,0.000728,平方米
|
||||||
|
ACSR4R7V0812,EHD450Z085,0.000094,千克
|
||||||
|
ACSR4R7V0812,D12087F2126,0.0001,万对
|
||||||
|
ACSR4R7V0812,YG00001,2.07E-05,卷
|
||||||
|
ACSR4R7V0812,YHBH421H,0.00019,千克
|
||||||
|
ACSR4R7V0812,N080-130Y,0.0001,万支
|
||||||
|
ACSR4R7V0812,P08-30I,0.0001,万只
|
||||||
|
ACSR4R7V0812,GS080T,0.000072,千克
|
||||||
|
AMSR1R0M0609VI,Z480V12002050,0.000115,平方米
|
||||||
|
AMSR1R0M0609VI,F30VC30A050,0.000165,平方米
|
||||||
|
AMSR1R0M0609VI,EHD450Z065,0.000018,千克
|
||||||
|
AMSR1R0M0609VI,D12073TL2126b,0.0001,万对
|
||||||
|
AMSR1R0M0609VI,YG00002,9.33E-06,卷
|
||||||
|
AMSR1R0M0609VI,YHBH421H,0.00011,千克
|
||||||
|
AMSR1R0M0609VI,T063-100Y,0.0001,万支
|
||||||
|
AMSR1R0M0609VI,P06-26T,0.0001,万只
|
||||||
|
AMSR1R0M0609VI,MS063T,0.000039,千克
|
||||||
|
AGTR4R7V0812V,Z510V12001070,0.000623,平方米
|
||||||
|
AGTR4R7V0812V,F30VC20A070,0.000784,平方米
|
||||||
|
AGTR4R7V0812V,W19020K085,0.000094,千克
|
||||||
|
AGTR4R7V0812V,D12087F2126,0.0001,万对
|
||||||
|
AGTR4R7V0812V,YG00001,2.07E-05,卷
|
||||||
|
AGTR4R7V0812V,YHBH421H,0.00019,千克
|
||||||
|
AGTR4R7V0812V,N080-130Y,0.0001,万支
|
||||||
|
AGTR4R7V0812V,P08-30I,0.0001,万只
|
||||||
|
AGTR4R7V0812V,GT080C,0.000071,千克
|
||||||
|
WL1V477M10016,Z047V10401100,0.00153,平方米
|
||||||
|
WL1V477M10016,F00VC40A100,0.00202,平方米
|
||||||
|
WL1V477M10016,SM26050B120,0.00017,千克
|
||||||
|
WL1V477M10016,D15131G2328,0.0001,万对
|
||||||
|
WL1V477M10016,YG00004,0.00003,卷
|
||||||
|
WL1V477M10016,YHCP50A,0.00049,千克
|
||||||
|
WL1V477M10016,L100-175+,0.0001,万支
|
||||||
|
WL1V477M10016,GNH-10F,0.0001,万只
|
||||||
|
WL1V477M10016,AW100T,0.000101,千克
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,20 @@
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
df_bom = pd.read_excel('bom23.xlsx', engine='openpyxl')
|
||||||
|
|
||||||
|
df_plan = pd.read_excel('plan.xlsx', engine='openpyxl')
|
||||||
|
|
||||||
|
|
||||||
|
def get_bom_by_prd_id(prd_id):
|
||||||
|
df_sub = df_bom.loc[df_bom['prd_id'] == prd_id]
|
||||||
|
return df_sub[['mtr_id', 'qty']]
|
||||||
|
|
||||||
|
|
||||||
|
def get_plan_by_pp_id(pp_id):
|
||||||
|
df_sub = df_plan.loc[df_plan['pp_id'] == int(pp_id)]
|
||||||
|
return df_sub[['prd_id', 'size', 'rate']]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print(get_bom_by_prd_id('ADTB331M0611'))
|
||||||
|
print(get_plan_by_pp_id('0')) # 0, 6, 8, 10
|
Binary file not shown.
Loading…
Reference in New Issue