This commit is contained in:
parent
2b59780e20
commit
5c7788e86e
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
220
computation.py
220
computation.py
|
@ -3,6 +3,7 @@ import os
|
|||
import datetime
|
||||
|
||||
import networkx as nx
|
||||
import pandas as pd
|
||||
from mesa import Model
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
@ -48,3 +49,222 @@ class Computation:
|
|||
print(i, datetime.datetime.now())
|
||||
model.end()
|
||||
return False
|
||||
|
||||
def initialize_firm_network(self):
|
||||
# Read the firm data
|
||||
|
||||
firm = pd.read_csv("input_data/input_firm_data/Firm_amended.csv")
|
||||
|
||||
firm['Code'] = firm['Code'].astype(str)
|
||||
|
||||
firm.fillna(0, inplace=True)
|
||||
|
||||
firm_attr = firm.loc[:, ["Code", "Type_Region", "Revenue_Log"]]
|
||||
|
||||
firm_industry_relation = pd.read_csv("input_data/firm_industry_relation.csv")
|
||||
firm_industry_relation['Firm_Code'] = firm_industry_relation['Firm_Code'].astype('string')
|
||||
|
||||
firm_product = []
|
||||
|
||||
grouped = firm_industry_relation.groupby('Firm_Code')['Product_Code'].apply(list)
|
||||
firm_product.append(grouped)
|
||||
|
||||
firm_attr['Product_Code'] = firm_attr['Code'].map(grouped)
|
||||
firm_attr.set_index('Code', inplace=True)
|
||||
|
||||
grouped = firm_industry_relation.groupby('Firm_Code')
|
||||
self.firm_prod_labels_dict = {code: group['Product_Code'].tolist() for code, group in grouped}
|
||||
|
||||
# 遍历'Product_Code' 与 index 交换
|
||||
for index, row in firm_attr.iterrows():
|
||||
id_index_list = []
|
||||
for i in row['Product_Code']:
|
||||
for key_values in self.id_code.items():
|
||||
if int(key_values[0]) == i:
|
||||
for id in key_values[1]:
|
||||
id_index_list.append(id)
|
||||
firm_attr.at[index, 'Product_Code'] = id_index_list
|
||||
|
||||
self.G_Firm.add_nodes_from(firm["Code"])
|
||||
# Assign attributes to the firm nodes
|
||||
firm_labels_dict = {code: firm_attr.loc[code].to_dict() for code in self.G_Firm.nodes}
|
||||
nx.set_node_attributes(self.G_Firm, firm_labels_dict)
|
||||
|
||||
self.Firm = firm
|
||||
|
||||
def initialize_firm_product_network(self):
|
||||
|
||||
firm_industry_relation = pd.read_csv("input_data/firm_industry_relation.csv")
|
||||
firm_industry_relation['Firm_Code'] = firm_industry_relation['Firm_Code'].astype('string')
|
||||
firm_industry_relation['Product_Code'] = firm_industry_relation['Product_Code'].apply(lambda x: [x])
|
||||
# 将 'firm_prod' 表中的每一行作为图中的节点
|
||||
self.G_FirmProd.add_nodes_from(firm_industry_relation.index)
|
||||
# 为每个节点分配属性
|
||||
|
||||
# 遍历'Product_Code' 与 index 交换
|
||||
for index, row in firm_industry_relation.iterrows():
|
||||
id_index_list = []
|
||||
for i in row['Product_Code']:
|
||||
for key_values in self.id_code.items():
|
||||
if int(key_values[0]) == i:
|
||||
for id in key_values[1]:
|
||||
id_index_list.append(id)
|
||||
firm_industry_relation.at[index, 'Product_Code'] = id_index_list
|
||||
|
||||
firm_prod_labels_dict = {code: firm_industry_relation.loc[code].to_dict() for code in
|
||||
firm_industry_relation.index}
|
||||
nx.set_node_attributes(self.G_FirmProd, firm_prod_labels_dict)
|
||||
|
||||
def add_edges_to_firm_network(self):
|
||||
""" Add edges between firms based on the product BOM relationships """
|
||||
# Add edges to G_Firm according to G_bom
|
||||
for node in nx.nodes(self.G_Firm):
|
||||
lst_pred_product_code = []
|
||||
for product_code in self.G_Firm.nodes[node]['Product_Code']:
|
||||
lst_pred_product_code += list(self.G_bom.predecessors(product_code))
|
||||
lst_pred_product_code = list(set(lst_pred_product_code))
|
||||
lst_pred_product_code = list(sorted(lst_pred_product_code)) # Ensure consistency
|
||||
|
||||
for pred_product_code in lst_pred_product_code:
|
||||
# Get a list of firms producing the component (pred_product_code)
|
||||
lst_pred_firm = [firm_code for firm_code, product in self.firm_prod_labels_dict.items() if
|
||||
pred_product_code in product]
|
||||
|
||||
# Select multiple suppliers (multi-sourcing)
|
||||
n_pred_firm = self.int_netw_prf_n
|
||||
if n_pred_firm > len(lst_pred_firm):
|
||||
n_pred_firm = len(lst_pred_firm)
|
||||
|
||||
if self.is_prf_size:
|
||||
# 获取 firm 的 size 列表
|
||||
lst_pred_firm_size = [self.G_Firm.nodes[pred_firm]['Revenue_Log'] for pred_firm in lst_pred_firm]
|
||||
# 检查 lst_pred_firm_size 是否为空或总和为 0
|
||||
if len(lst_pred_firm_size) == 0 or sum(lst_pred_firm_size) == 0:
|
||||
# print("警告: lst_pred_firm_size 为空或总和为 0,无法生成概率分布")
|
||||
lst_choose_firm = [] # 返回空结果,或根据需要处理
|
||||
else:
|
||||
# 计算总和
|
||||
sum_pred_firm_size = sum(lst_pred_firm_size)
|
||||
# 归一化生成 lst_prob
|
||||
lst_prob = [size / sum_pred_firm_size for size in lst_pred_firm_size]
|
||||
# 使用 np.isclose() 确保概率总和接近 1
|
||||
if not np.isclose(sum(lst_prob), 1.0):
|
||||
# print(f"警告: 概率总和为 {sum(lst_prob)},现在进行修正")
|
||||
lst_prob = [prob / sum(lst_prob) for prob in lst_prob]
|
||||
# 确保没有负值或 0
|
||||
lst_prob = [max(0, prob) for prob in lst_prob]
|
||||
# 根据修正后的概率选择 firm
|
||||
lst_choose_firm = self.nprandom.choice(lst_pred_firm, n_pred_firm, replace=False, p=lst_prob)
|
||||
else:
|
||||
# 直接进行随机选择
|
||||
lst_choose_firm = self.nprandom.choice(lst_pred_firm, n_pred_firm, replace=False)
|
||||
|
||||
# Add edges from predecessor firms to current node (firm)
|
||||
lst_add_edge = [(pred_firm, node, {'Product': pred_product_code}) for pred_firm in lst_choose_firm]
|
||||
self.G_Firm.add_edges_from(lst_add_edge)
|
||||
|
||||
# Add edges to firm-product network
|
||||
self.add_edges_to_firm_product_network(node, pred_product_code, lst_choose_firm)
|
||||
|
||||
def add_edges_to_firm_product_network(self, node, pred_product_code, lst_choose_firm):
|
||||
""" Helper function to add edges to the firm-product network """
|
||||
set_node_prod_code = set(self.G_Firm.nodes[node]['Product_Code'])
|
||||
set_pred_succ_code = set(self.G_bom.successors(pred_product_code))
|
||||
lst_use_pred_prod_code = list(set_node_prod_code & set_pred_succ_code)
|
||||
|
||||
if len(lst_use_pred_prod_code) == 0:
|
||||
print("错误")
|
||||
|
||||
pred_node_list = []
|
||||
for pred_firm in lst_choose_firm:
|
||||
for n, v in self.G_FirmProd.nodes(data=True):
|
||||
for v1 in v['Product_Code']:
|
||||
if v1 == pred_product_code and v['Firm_Code'] == pred_firm:
|
||||
pred_node_list.append(n)
|
||||
if len(pred_node_list) != 0:
|
||||
pred_node = pred_node_list[0]
|
||||
else:
|
||||
pred_node = -1
|
||||
current_node_list = []
|
||||
for use_pred_prod_code in lst_use_pred_prod_code:
|
||||
for n, v in self.G_FirmProd.nodes(data=True):
|
||||
for v1 in v['Product_Code']:
|
||||
if v1 == use_pred_prod_code and v['Firm_Code'] == node:
|
||||
current_node_list.append(n)
|
||||
if len(current_node_list) != 0:
|
||||
current_node = current_node_list[0]
|
||||
else:
|
||||
current_node = -1
|
||||
if current_node != -1 and pred_node != -1:
|
||||
self.G_FirmProd.add_edge(pred_node, current_node)
|
||||
|
||||
def connect_unconnected_nodes(self):
|
||||
""" Connect unconnected nodes in the firm network """
|
||||
for node in nx.nodes(self.G_Firm):
|
||||
if self.G_Firm.degree(node) == 0:
|
||||
current_node_list = []
|
||||
for product_code in self.G_Firm.nodes[node]['Product_Code']:
|
||||
for n, v in self.G_FirmProd.nodes(data=True):
|
||||
for v1 in v['Product_Code']:
|
||||
if v['Firm_Code'] == node and v1 == product_code:
|
||||
current_node_list.append(n)
|
||||
if len(current_node_list) != 0:
|
||||
current_node = current_node_list[0]
|
||||
else:
|
||||
current_node = -1
|
||||
lst_succ_product_code = list(self.G_bom.successors(product_code))
|
||||
|
||||
for succ_product_code in lst_succ_product_code:
|
||||
lst_succ_firm = [firm_code for firm_code, product in self.firm_prod_labels_dict.items() if
|
||||
succ_product_code in product]
|
||||
|
||||
n_succ_firm = self.int_netw_prf_n
|
||||
if n_succ_firm > len(lst_succ_firm):
|
||||
n_succ_firm = len(lst_succ_firm)
|
||||
|
||||
if self.is_prf_size:
|
||||
lst_succ_firm_size = [self.G_Firm.nodes[succ_firm]['Revenue_Log'] for succ_firm in
|
||||
lst_succ_firm]
|
||||
if len(lst_succ_firm_size) == 0 or sum(lst_succ_firm_size) == 0:
|
||||
# print("警告: lst_pred_firm_size 为空或总和为 0,无法生成概率分布")
|
||||
lst_choose_firm = [] # 返回空结果,或根据需要处理
|
||||
else:
|
||||
# 计算总和
|
||||
sum_pred_firm_size = sum(lst_succ_firm_size)
|
||||
# 归一化生成 lst_prob
|
||||
lst_prob = [size / sum_pred_firm_size for size in lst_succ_firm_size]
|
||||
# 使用 np.isclose() 确保概率总和接近 1
|
||||
if not np.isclose(sum(lst_prob), 1.0):
|
||||
# print(f"警告: 概率总和为 {sum(lst_prob)},现在进行修正")
|
||||
lst_prob = [prob / sum(lst_prob) for prob in lst_prob]
|
||||
|
||||
# 确保没有负值或 0
|
||||
lst_prob = [max(0, prob) for prob in lst_prob]
|
||||
|
||||
lst_choose_firm = self.nprandom.choice(lst_succ_firm, n_succ_firm, replace=False,
|
||||
p=lst_prob)
|
||||
else:
|
||||
lst_choose_firm = self.nprandom.choice(lst_succ_firm, n_succ_firm, replace=False)
|
||||
|
||||
lst_add_edge = [(node, succ_firm, {'Product': product_code}) for succ_firm in
|
||||
lst_choose_firm]
|
||||
self.G_Firm.add_edges_from(lst_add_edge)
|
||||
|
||||
# Add edges to firm-product network
|
||||
succ_node_list = []
|
||||
for succ_firm in lst_choose_firm:
|
||||
for n, v in self.G_FirmProd.nodes(data=True):
|
||||
for v1 in v['Product_Code']:
|
||||
if v1 == succ_product_code and v['Firm_Code'] == succ_firm:
|
||||
succ_node_list.append(n)
|
||||
if len(succ_node_list) != 0:
|
||||
succ_node = succ_node_list[0]
|
||||
else:
|
||||
succ_node = -1
|
||||
|
||||
if current_node != -1 and succ_node != -1:
|
||||
self.G_FirmProd.add_edge(current_node, succ_node)
|
||||
|
||||
self.sample.g_firm = json.dumps(nx.adjacency_data(self.G_Firm))
|
||||
self.firm_network = self.G_Firm # 直接使用 networkx 图对象
|
||||
self.firm_prod_network = self.G_FirmProd # 直接使用 networkx 图对象
|
||||
|
|
4
firm.py
4
firm.py
|
@ -39,9 +39,9 @@ class FirmAgent(Agent):
|
|||
for agent in self.model.company_agents if agent.unique_id == u]
|
||||
# 设备c的数量 (总量) 使用这个来判断设备数量
|
||||
self.n_equip_c = n_equip_c
|
||||
# 设备c产量 更具设备量进行估算
|
||||
# 设备c产量 根据设备量进行估算
|
||||
self.c_yield = production_output
|
||||
# 消耗材料量 根据设备量进行估算
|
||||
# 消耗材料量 根据设备量进行估算 { }
|
||||
self.c_consumption = demand_quantity
|
||||
# 设备c购买价格(初始值)
|
||||
# self.c_price = c_price
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
82
my_model.py
82
my_model.py
|
@ -236,7 +236,7 @@ class MyModel(Model):
|
|||
current_node = current_node_list[0]
|
||||
else:
|
||||
current_node = -1
|
||||
if current_node !=-1 and pred_node !=-1:
|
||||
if current_node != -1 and pred_node != -1:
|
||||
self.G_FirmProd.add_edge(pred_node, current_node)
|
||||
|
||||
def connect_unconnected_nodes(self):
|
||||
|
@ -298,10 +298,10 @@ class MyModel(Model):
|
|||
for v1 in v['Product_Code']:
|
||||
if v1 == succ_product_code and v['Firm_Code'] == succ_firm:
|
||||
succ_node_list.append(n)
|
||||
if len(succ_node_list)!=0:
|
||||
if len(succ_node_list) != 0:
|
||||
succ_node = succ_node_list[0]
|
||||
else:
|
||||
succ_node=-1
|
||||
succ_node = -1
|
||||
|
||||
if current_node != -1 and succ_node != -1:
|
||||
self.G_FirmProd.add_edge(current_node, succ_node)
|
||||
|
@ -315,25 +315,11 @@ class MyModel(Model):
|
|||
|
||||
for ag_node, attr in self.product_network.nodes(data=True):
|
||||
# 产业种类
|
||||
# 利用 BomNodes.csv 转换产业 和 id 前提是 一个产业一个产品id 且一一对应
|
||||
# product_id = self.type2.loc[self.type2['Code'] == ag_node, 'Code']
|
||||
# if not product_id.empty:
|
||||
# type2 = self.type2.loc[product_id.values[0], '产业种类']
|
||||
# else:
|
||||
# # 处理 product_id 为空的情况,例如设置为默认值或跳过
|
||||
# type2 = -1 # 或其他合适的默认值
|
||||
type2 = 0
|
||||
|
||||
type2 = self.type2[self.type2["Index"] == ag_node]["产业种类"]
|
||||
# depreciation ratio 折旧比值
|
||||
# product_id = product_id.iloc[0]
|
||||
|
||||
j_comp_data_consumed = self.data_consumed[ag_node]
|
||||
|
||||
j_comp_data_produced = self.data_produced[ag_node]
|
||||
|
||||
product = ProductAgent(ag_node, self, name=attr['Name'], type2=type2,
|
||||
j_comp_data_consumed=j_comp_data_consumed,
|
||||
j_comp_data_produced=j_comp_data_produced,
|
||||
)
|
||||
product = ProductAgent(ag_node, self, name=attr['Name'], type2=type2)
|
||||
self.add_agent(product)
|
||||
# self.grid.place_agent(product, ag_node)
|
||||
##print(f"Product agent created: {product.name}, ID: {product.unique_id}")
|
||||
|
@ -343,9 +329,9 @@ class MyModel(Model):
|
|||
firm_id = self.Firm['Code'] == ag_node
|
||||
n_equip_c = self.Firm.loc[firm_id, '设备数量'].values[0]
|
||||
|
||||
demand_quantity = self.Firm.loc[firm_id, 'production_output'].values[0]
|
||||
demand_quantity = self.data_consumed[self.data_consumed['Firm_Code'] == ag_node]
|
||||
|
||||
production_output = self.Firm.loc[firm_id, 'demand_quantity'].values[0]
|
||||
production_output = self.data_produced[self.data_consumed['Firm_Code'] == ag_node]
|
||||
|
||||
# c购买价格? 数据预处理
|
||||
# c_price = self.Firm.loc[self.Firm['Code'] == ag_node, 'c_price'].values[0]
|
||||
|
@ -432,16 +418,22 @@ class MyModel(Model):
|
|||
self.firm_resource_P = firm_resource_P
|
||||
|
||||
def j_comp_consumed_produced(self):
|
||||
data_consumed = pd.read_csv('input_data/input_product_data/products_consumed_materials.csv')
|
||||
data_produced = pd.read_csv('input_data/input_product_data/products_produced_products.csv')
|
||||
# 着重修改这 然后考虑逻辑 如何传递值
|
||||
data_consumed = pd.read_csv('input_data/input_firm_data/firms_materials.csv')
|
||||
data_produced = pd.read_csv('input_data/input_firm_data/firms_products.csv')
|
||||
|
||||
data_consumed = (data_consumed.groupby('产业id')['消耗材料id']
|
||||
.apply(lambda x: x.values.tolist()))
|
||||
data_produced = (data_produced.groupby('产业id')['制造产品id']
|
||||
.apply(lambda x: x.values.tolist()))
|
||||
data_not_consumed = data_consumed.groupby('Firm_Code')[['消耗材料id', '材料数量']] \
|
||||
.apply(lambda x: dict(zip(x['消耗材料id'], x['材料数量']))) \
|
||||
.reset_index(name='Material_not_Consumed')
|
||||
|
||||
# 这里简单设置为折半 考虑 企业的设备量
|
||||
# 可以引入 换算率 也就是 材料——计算产品比例 通过上游产业 现在假设为 2:1 的比例
|
||||
data_consumed = data_consumed.groupby('Firm_Code')[['消耗材料id', '材料数量']] \
|
||||
.apply(lambda x: dict(zip(x['消耗材料id'], x['材料数量'] / 2))) \
|
||||
.reset_index(name='Material_not_Consumed')
|
||||
|
||||
self.data_consumed = data_consumed
|
||||
self.data_produced = data_produced
|
||||
self.data_produced = data_consumed / 2
|
||||
|
||||
def step(self):
|
||||
# 1. Remove edge to customer and disrupt customer up product
|
||||
|
@ -542,38 +534,24 @@ class MyModel(Model):
|
|||
for C_list, C0_list in zip(firm.C, firm.C0):
|
||||
C_list[1] = C0_list[1] # 赋值回去
|
||||
C_list[2] = C0_list[2]
|
||||
|
||||
# 消耗资源过程
|
||||
consumed_material = []
|
||||
for product in firm.indus_i:
|
||||
for consumed_material_id in product.j_comp_data_consumed:
|
||||
consumed_material_num = 0.1
|
||||
# 这里需要修改
|
||||
for r_id, r_nums in firm.R.items():
|
||||
for consumed_id, consumed_nums in firm.c_consumption:
|
||||
if consumed_id == r_id:
|
||||
r_nums = r_nums - consumed_nums
|
||||
|
||||
consumed_material.append([consumed_material_id, consumed_material_num])
|
||||
|
||||
for sub_list_consumed_material in consumed_material:
|
||||
for sub_list_material in firm.R:
|
||||
if sub_list_material[0] == sub_list_consumed_material[0]:
|
||||
sub_list_material[1] = sub_list_material[1] - sub_list_consumed_material[1]
|
||||
# 生产产品过程
|
||||
produced_products = []
|
||||
for product in firm.indus_i:
|
||||
for produced_products_id in product.j_comp_data_consumed:
|
||||
produced_products_num = 0.1
|
||||
for p_id, p_nums in firm.P.items():
|
||||
for product_id, product_nums in firm.c_consumption:
|
||||
if product_id == p_id:
|
||||
p_nums = p_nums + product_nums
|
||||
|
||||
produced_products.append([produced_products_id, produced_products_num])
|
||||
|
||||
for sub_list_data_produced_products in produced_products:
|
||||
for sub_list_products in firm.P:
|
||||
if sub_list_products[0] == sub_list_data_produced_products[0]:
|
||||
sub_list_products[1] = sub_list_products[1] - sub_list_data_produced_products[1]
|
||||
# 刷新 R状态
|
||||
firm.refresh_R()
|
||||
# 刷新 C状态
|
||||
firm.refresh_C()
|
||||
# 刷新 P状态
|
||||
firm.refresh_P()
|
||||
|
||||
# Increment the time step
|
||||
self.t += 1
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ from mesa import Agent
|
|||
|
||||
|
||||
class ProductAgent(Agent):
|
||||
def __init__(self, unique_id, model, name, type2, j_comp_data_consumed, j_comp_data_produced):
|
||||
def __init__(self, unique_id, model, name, type2):
|
||||
# 调用超类的 __init__ 方法
|
||||
super().__init__(unique_id, model)
|
||||
|
||||
|
@ -16,9 +16,6 @@ class ProductAgent(Agent):
|
|||
# depreciation ratio 折旧比值
|
||||
# self.depreciation ratio
|
||||
|
||||
self.j_comp_data_produced = j_comp_data_produced
|
||||
self.j_comp_data_consumed = j_comp_data_consumed
|
||||
|
||||
def a_successors(self):
|
||||
# 从 product_network 中找到当前代理的后继节点
|
||||
successors = list(self.model.product_network.successors(self.unique_id))
|
||||
|
|
Loading…
Reference in New Issue