This commit is contained in:
Cricial 2024-12-08 18:43:33 +08:00
parent 2b59780e20
commit 5c7788e86e
12 changed files with 25950 additions and 299 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3,6 +3,7 @@ import os
import datetime import datetime
import networkx as nx import networkx as nx
import pandas as pd
from mesa import Model from mesa import Model
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -48,3 +49,222 @@ class Computation:
print(i, datetime.datetime.now()) print(i, datetime.datetime.now())
model.end() model.end()
return False 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 图对象

View File

@ -39,9 +39,9 @@ class FirmAgent(Agent):
for agent in self.model.company_agents if agent.unique_id == u] for agent in self.model.company_agents if agent.unique_id == u]
# 设备c的数量 (总量) 使用这个来判断设备数量 # 设备c的数量 (总量) 使用这个来判断设备数量
self.n_equip_c = n_equip_c self.n_equip_c = n_equip_c
# 设备c产量 更具设备量进行估算 # 设备c产量 根据设备量进行估算
self.c_yield = production_output self.c_yield = production_output
# 消耗材料量 根据设备量进行估算 # 消耗材料量 根据设备量进行估算 { }
self.c_consumption = demand_quantity self.c_consumption = demand_quantity
# 设备c购买价格初始值 # 设备c购买价格初始值
# self.c_price = c_price # 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

View File

@ -236,7 +236,7 @@ class MyModel(Model):
current_node = current_node_list[0] current_node = current_node_list[0]
else: else:
current_node = -1 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) self.G_FirmProd.add_edge(pred_node, current_node)
def connect_unconnected_nodes(self): def connect_unconnected_nodes(self):
@ -298,10 +298,10 @@ class MyModel(Model):
for v1 in v['Product_Code']: for v1 in v['Product_Code']:
if v1 == succ_product_code and v['Firm_Code'] == succ_firm: if v1 == succ_product_code and v['Firm_Code'] == succ_firm:
succ_node_list.append(n) succ_node_list.append(n)
if len(succ_node_list)!=0: if len(succ_node_list) != 0:
succ_node = succ_node_list[0] succ_node = succ_node_list[0]
else: else:
succ_node=-1 succ_node = -1
if current_node != -1 and succ_node != -1: if current_node != -1 and succ_node != -1:
self.G_FirmProd.add_edge(current_node, succ_node) 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): 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'] type2 = self.type2[self.type2["Index"] == ag_node]["产业种类"]
# if not product_id.empty:
# type2 = self.type2.loc[product_id.values[0], '产业种类']
# else:
# # 处理 product_id 为空的情况,例如设置为默认值或跳过
# type2 = -1 # 或其他合适的默认值
type2 = 0
# depreciation ratio 折旧比值 # depreciation ratio 折旧比值
# product_id = product_id.iloc[0] # product_id = product_id.iloc[0]
product = ProductAgent(ag_node, self, name=attr['Name'], type2=type2)
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,
)
self.add_agent(product) self.add_agent(product)
# self.grid.place_agent(product, ag_node) # self.grid.place_agent(product, ag_node)
##print(f"Product agent created: {product.name}, ID: {product.unique_id}") ##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 firm_id = self.Firm['Code'] == ag_node
n_equip_c = self.Firm.loc[firm_id, '设备数量'].values[0] 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购买价格 数据预处理
# c_price = self.Firm.loc[self.Firm['Code'] == ag_node, 'c_price'].values[0] # 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 self.firm_resource_P = firm_resource_P
def j_comp_consumed_produced(self): 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'] data_not_consumed = data_consumed.groupby('Firm_Code')[['消耗材料id', '材料数量']] \
.apply(lambda x: x.values.tolist())) .apply(lambda x: dict(zip(x['消耗材料id'], x['材料数量']))) \
data_produced = (data_produced.groupby('产业id')['制造产品id'] .reset_index(name='Material_not_Consumed')
.apply(lambda x: x.values.tolist()))
# 这里简单设置为折半 考虑 企业的设备量
# 可以引入 换算率 也就是 材料——计算产品比例 通过上游产业 现在假设为 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_consumed = data_consumed
self.data_produced = data_produced self.data_produced = data_consumed / 2
def step(self): def step(self):
# 1. Remove edge to customer and disrupt customer up product # 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): for C_list, C0_list in zip(firm.C, firm.C0):
C_list[1] = C0_list[1] # 赋值回去 C_list[1] = C0_list[1] # 赋值回去
C_list[2] = C0_list[2] C_list[2] = C0_list[2]
# 消耗资源过程 # 消耗资源过程
consumed_material = [] # 这里需要修改
for product in firm.indus_i: for r_id, r_nums in firm.R.items():
for consumed_material_id in product.j_comp_data_consumed: for consumed_id, consumed_nums in firm.c_consumption:
consumed_material_num = 0.1 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 p_id, p_nums in firm.P.items():
for product in firm.indus_i: for product_id, product_nums in firm.c_consumption:
for produced_products_id in product.j_comp_data_consumed: if product_id == p_id:
produced_products_num = 0.1 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() firm.refresh_R()
# 刷新 C状态 # 刷新 C状态
firm.refresh_C() firm.refresh_C()
# 刷新 P状态 # 刷新 P状态
firm.refresh_P() firm.refresh_P()
# Increment the time step # Increment the time step
self.t += 1 self.t += 1

View File

@ -2,7 +2,7 @@ from mesa import Agent
class ProductAgent(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__ 方法 # 调用超类的 __init__ 方法
super().__init__(unique_id, model) super().__init__(unique_id, model)
@ -16,9 +16,6 @@ class ProductAgent(Agent):
# depreciation ratio 折旧比值 # depreciation ratio 折旧比值
# self.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): def a_successors(self):
# 从 product_network 中找到当前代理的后继节点 # 从 product_network 中找到当前代理的后继节点
successors = list(self.model.product_network.successors(self.unique_id)) successors = list(self.model.product_network.successors(self.unique_id))