without模型转型成功!但是without还无法插入表 o

This commit is contained in:
Cricial 2024-09-17 14:17:58 +08:00
parent 60b402c043
commit ede00b0403
6 changed files with 176 additions and 109 deletions

View File

@ -3,6 +3,13 @@
<component name="CsvFileAttributes"> <component name="CsvFileAttributes">
<option name="attributeMap"> <option name="attributeMap">
<map> <map>
<entry key="\input_data\BomCateNet.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\input_data\BomNodes.csv"> <entry key="\input_data\BomNodes.csv">
<value> <value>
<Attribute> <Attribute>

Binary file not shown.

Binary file not shown.

93
firm.py
View File

@ -1,5 +1,4 @@
from mesa import Agent from mesa import Agent
import numpy as np
class FirmAgent(Agent): class FirmAgent(Agent):
@ -55,47 +54,71 @@ class FirmAgent(Agent):
self.dct_prod_capacity[product] = extra_cap self.dct_prod_capacity[product] = extra_cap
def remove_edge_to_cus(self, disrupted_prod): def remove_edge_to_cus(self, disrupted_prod):
# parameter disrupted_prod is the product that self got disrupted
lst_out_edge = list( lst_out_edge = list(
self.firm_network.neighbors(self.unique_id)) self.firm_network.out_edges(
for n2 in lst_out_edge: self.unique_id, keys=True, data='Product'))
edge_data = self.firm_network.edges[self.unique_id, n2] for n1, n2, key, product_code in lst_out_edge:
if edge_data.get('Product') == disrupted_prod.code: if product_code == disrupted_prod.unique_id:
customer = self.model.schedule.get_agent(n2) # update customer up product supplier status
customer = next(agent for agent in self.model.company_agents if agent.unique_id == n2)
for prod in customer.dct_prod_up_prod_stat.keys(): for prod in customer.dct_prod_up_prod_stat.keys():
if disrupted_prod in customer.dct_prod_up_prod_stat[prod]['s_stat'].keys(): if disrupted_prod in customer.dct_prod_up_prod_stat[prod]['s_stat'].keys():
customer.dct_prod_up_prod_stat[prod]['s_stat'][disrupted_prod][ customer.dct_prod_up_prod_stat[prod]['s_stat'][disrupted_prod][
'set_disrupt_firm'].add(self) 'set_disrupt_firm'].add(self)
self.firm_network.remove_edge(self.unique_id, n2) # print(f"{self.name} disrupt {customer.name}'s "
# f"{prod.code} due to {disrupted_prod.code}")
# remove edge to customer
self.firm_network.remove_edge(n1, n2, key)
def disrupt_cus_prod(self, prod, disrupted_up_prod): def disrupt_cus_prod(self, prod, disrupted_up_prod):
num_lost = len(self.dct_prod_up_prod_stat[prod]['s_stat'][disrupted_up_prod]['set_disrupt_firm']) # parameter prod is the product that has disrupted_up_prod
num_remain = len([ # parameter disrupted_up_prod is the product that
u for u in self.firm_network.neighbors(self.unique_id) # self's component exists disrupted supplier
if self.firm_network.G.edges[u, self.unique_id].get('Product') == disrupted_up_prod.code]) num_lost = \
len(self.dct_prod_up_prod_stat[prod]['s_stat']
[disrupted_up_prod]['set_disrupt_firm'])
num_remain = \
len([u for u, _, _, d in
self.firm_network.in_edges(self.get_firm_network_unique_id(),
keys=True,
data='Product')
if d == disrupted_up_prod.unique_id])
lost_percent = num_lost / (num_lost + num_remain) lost_percent = num_lost / (num_lost + num_remain)
lst_size = [firm.size_stat[-1][0] for firm in self.model.schedule.agents] lst_size = \
std_size = (self.size_stat[-1][0] - min(lst_size) + 1) / (max(lst_size) - min(lst_size) + 1) [firm.size_stat[-1][0] for firm in self.model.company_agents]
std_size = (self.size_stat[-1][0] - min(lst_size) + 1) \
/ (max(lst_size) - min(lst_size) + 1)
# calculate probability of disruption
prob_disrupt = 1 - std_size * (1 - lost_percent) prob_disrupt = 1 - std_size * (1 - lost_percent)
if self.random.choice([True, False], p=[prob_disrupt, 1 - prob_disrupt]): if self.model.nprandom.choice([True, False],
p=[prob_disrupt,
1 - prob_disrupt]):
self.dct_n_trial_up_prod_disrupted[disrupted_up_prod] = 0 self.dct_n_trial_up_prod_disrupted[disrupted_up_prod] = 0
self.dct_prod_up_prod_stat[prod]['s_stat'][disrupted_up_prod]['stat'] = False self.dct_prod_up_prod_stat[
status, _ = self.dct_prod_up_prod_stat[prod]['p_stat'][-1] prod]['s_stat'][disrupted_up_prod]['stat'] = False
status, _ = self.dct_prod_up_prod_stat[
prod]['p_stat'][-1]
if status != 'D': if status != 'D':
self.dct_prod_up_prod_stat[prod]['p_stat'].append(('D', self.model.schedule.time)) self.dct_prod_up_prod_stat[
prod]['p_stat'].append(('D', self.model.t))
# print(f"{self.name}'s {prod.code} turn to D status due to "
# f"disrupted supplier of {disrupted_up_prod.code}")
def seek_alt_supply(self, product): def seek_alt_supply(self, product):
if self.dct_n_trial_up_prod_disrupted[product] <= self.model.int_n_max_trial: if self.dct_n_trial_up_prod_disrupted[product] <= self.model.int_n_max_trial:
if self.dct_n_trial_up_prod_disrupted[product] == 0: if self.dct_n_trial_up_prod_disrupted[product] == 0:
self.dct_cand_alt_supp_up_prod_disrupted[product] = [ self.dct_cand_alt_supp_up_prod_disrupted[product] = [
firm for firm in self.model.schedule.agents firm for firm in self.model.company_agents
if firm.is_prod_in_current_normal(product)] if firm.is_prod_in_current_normal(product)]
if self.dct_cand_alt_supp_up_prod_disrupted[product]: if self.dct_cand_alt_supp_up_prod_disrupted[product]:
lst_firm_connect = [] lst_firm_connect = []
if self.is_prf_conn: if self.is_prf_conn:
for firm in self.dct_cand_alt_supp_up_prod_disrupted[product]: for firm in self.dct_cand_alt_supp_up_prod_disrupted[product]:
if self.firm_network.G.has_edge(self.unique_id, firm.unique_id) or \ if self.firm_network.has_edge(self.unique_id, firm.unique_id) or \
self.firm_network.G.has_edge(firm.unique_id, self.unique_id): self.firm_network.has_edge(firm.unique_id, self.unique_id):
lst_firm_connect.append(firm) lst_firm_connect.append(firm)
if len(lst_firm_connect) == 0: if len(lst_firm_connect) == 0:
if self.is_prf_size: if self.is_prf_size:
@ -133,8 +156,8 @@ class FirmAgent(Agent):
lst_firm_connect = [] lst_firm_connect = []
if self.is_prf_conn: if self.is_prf_conn:
for firm in lst_firm: for firm in lst_firm:
if self.firm_network.G.has_edge(self.unique_id, firm.unique_id) or \ if self.firm_network.has_edge(self.unique_id, firm.unique_id) or \
self.firm_network.G.has_edge(firm.unique_id, self.unique_id): self.firm_network.has_edge(firm.unique_id, self.unique_id):
lst_firm_connect.append(firm) lst_firm_connect.append(firm)
if len(lst_firm_connect) == 0: if len(lst_firm_connect) == 0:
if self.is_prf_size: if self.is_prf_size:
@ -157,13 +180,13 @@ class FirmAgent(Agent):
down_firm.dct_cand_alt_supp_up_prod_disrupted[product].remove(self) down_firm.dct_cand_alt_supp_up_prod_disrupted[product].remove(self)
def accept_request(self, down_firm, product): def accept_request(self, down_firm, product):
if self.firm_network.G.has_edge(self.unique_id, down_firm.unique_id) or \ if self.firm_network.has_edge(self.unique_id, down_firm.unique_id) or \
self.firm_network.G.has_edge(down_firm.unique_id, self.unique_id): self.firm_network.has_edge(down_firm.unique_id, self.unique_id):
prod_accept = 1.0 prod_accept = 1.0
else: else:
prod_accept = self.flt_diff_new_conn prod_accept = self.flt_diff_new_conn
if self.random.choice([True, False], p=[prod_accept, 1 - prod_accept]): if self.model.nprandom.choice([True, False], p=[prod_accept, 1 - prod_accept]):
self.firm_network.G.add_edge(self.unique_id, down_firm.unique_id, Product=product.code) self.firm_network.add_edge(self.unique_id, down_firm.unique_id, Product=product.unique_id)
self.dct_prod_capacity[product] -= 1 self.dct_prod_capacity[product] -= 1
self.dct_request_prod_from_firm[product].remove(down_firm) self.dct_request_prod_from_firm[product].remove(down_firm)
@ -171,7 +194,7 @@ class FirmAgent(Agent):
if product in down_firm.dct_prod_up_prod_stat[prod]['s_stat']: if product in down_firm.dct_prod_up_prod_stat[prod]['s_stat']:
down_firm.dct_prod_up_prod_stat[prod]['s_stat'][product]['stat'] = True down_firm.dct_prod_up_prod_stat[prod]['s_stat'][product]['stat'] = True
down_firm.dct_prod_up_prod_stat[prod]['p_stat'].append( down_firm.dct_prod_up_prod_stat[prod]['p_stat'].append(
('N', self.model.schedule.time)) ('N', self.model.t))
del down_firm.dct_n_trial_up_prod_disrupted[product] del down_firm.dct_n_trial_up_prod_disrupted[product]
del down_firm.dct_cand_alt_supp_up_prod_disrupted[product] del down_firm.dct_cand_alt_supp_up_prod_disrupted[product]
else: else:
@ -188,13 +211,25 @@ class FirmAgent(Agent):
# Update the status of products and refresh disruption sets # Update the status of products and refresh disruption sets
for prod in self.dct_prod_up_prod_stat.keys(): for prod in self.dct_prod_up_prod_stat.keys():
status, ts = self.dct_prod_up_prod_stat[prod]['p_stat'][-1] status, ts = self.dct_prod_up_prod_stat[prod]['p_stat'][-1]
if ts != self.model.schedule.time: if ts != self.model.t:
self.dct_prod_up_prod_stat[prod]['p_stat'].append((status, self.model.schedule.time)) self.dct_prod_up_prod_stat[prod]['p_stat'].append((status, self.model.t))
# Refresh the set of disrupted firms # Refresh the set of disrupted firms
for up_prod in self.dct_prod_up_prod_stat[prod]['s_stat'].keys(): for up_prod in self.dct_prod_up_prod_stat[prod]['s_stat'].keys():
self.dct_prod_up_prod_stat[prod]['s_stat'][up_prod]['set_disrupt_firm'] = set() self.dct_prod_up_prod_stat[prod]['s_stat'][up_prod]['set_disrupt_firm'] = set()
def get_firm_network_unique_id(self):
return self.unique_id
def is_prod_in_current_normal(self, prod):
if prod in self.dct_prod_up_prod_stat.keys():
if self.dct_prod_up_prod_stat[prod]['p_stat'][-1][0] == 'N':
return True
else:
return False
else:
return False
def step(self): def step(self):
# 在每个时间步进行的操作 # 在每个时间步进行的操作
pass pass

View File

@ -6,8 +6,8 @@ import pandas as pd
from mesa import Model from mesa import Model
from mesa.space import MultiGrid, NetworkGrid from mesa.space import MultiGrid, NetworkGrid
from mesa.datacollection import DataCollector from mesa.datacollection import DataCollector
from mesa.time import RandomActivation
import numpy as np
from firm import FirmAgent from firm import FirmAgent
from product import ProductAgent from product import ProductAgent
@ -35,10 +35,20 @@ class MyModel(Model):
self.data_collector = DataCollector( self.data_collector = DataCollector(
agent_reporters={"Product": "name"} agent_reporters={"Product": "name"}
) )
# initialize graph bom
self.G_bom = nx.adjacency_graph(json.loads(params['g_bom']))
# Create the firm-product network graph
self.G_FirmProd = nx.MultiDiGraph()
# Create the firm network graph
self.G_Firm = nx.MultiDiGraph()
self.company_agents = [] self.company_agents = []
self.product_agents = [] self.product_agents = []
self.nprandom = np.random.default_rng(params['seed'])
# Initialize parameters from `params` # Initialize parameters from `params`
self.sample = params['sample'] self.sample = params['sample']
self.int_stop_ts = 0 self.int_stop_ts = 0
@ -62,121 +72,136 @@ class MyModel(Model):
def initialize_product_network(self, params): def initialize_product_network(self, params):
try: try:
self.product_network = nx.adjacency_graph(json.loads(params['g_bom'])) self.product_network = nx.adjacency_graph(json.loads(params['g_bom']))
print(
f"Product network initialized with {self.product_network.number_of_nodes()} nodes and {self.product_network.number_of_edges()} edges.")
except Exception as e: except Exception as e:
print(f"Failed to initialize product network: {e}") print(f"Failed to initialize product network: {e}")
def initialize_firm_network(self): def initialize_firm_network(self):
""" Initialize the firm network and add it to the model. """ """ Initialize the firm network by reading firm data from a CSV file """
# Read the firm data
Firm = pd.read_csv("input_data/Firm_amended.csv") Firm = pd.read_csv("input_data/Firm_amended.csv")
Firm['Code'] = Firm['Code'].astype('string') Firm['Code'] = Firm['Code'].astype('string')
Firm.fillna(0, inplace=True) Firm.fillna(0, inplace=True)
Firm_attr = Firm.loc[:, ["Code", "Type_Region", "Revenue_Log"]] Firm_attr = Firm.loc[:, ["Code", "Type_Region", "Revenue_Log"]]
firm_product = [row[row == 1].index.to_list() for _, row in Firm.loc[:, '1':].iterrows()]
firm_product = []
for _, row in Firm.loc[:, '1':].iterrows():
firm_product.append(row[row == 1].index.to_list())
Firm_attr.loc[:, 'Product_Code'] = firm_product Firm_attr.loc[:, 'Product_Code'] = firm_product
Firm_attr.set_index('Code', inplace=True) Firm_attr.set_index('Code', inplace=True)
self.firm_network = nx.MultiDiGraph()
self.firm_network.add_nodes_from(Firm["Code"])
firm_labels_dict = {code: Firm_attr.loc[code].to_dict() for code in self.firm_network.nodes} self.G_Firm.add_nodes_from(Firm["Code"])
nx.set_node_attributes(self.firm_network, firm_labels_dict)
# 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): def initialize_firm_product_network(self):
""" Initialize the firm-product network and add it to the model. """ """ Initialize the firm-product network """
# Read the firm-product data
Firm_Prod = pd.read_csv("input_data/Firm_amended.csv") Firm_Prod = pd.read_csv("input_data/Firm_amended.csv")
Firm_Prod.fillna(0, inplace=True) Firm_Prod.fillna(0, inplace=True)
# Stack the firm-product relationships into a DataFrame
firm_prod = pd.DataFrame({'bool': Firm_Prod.loc[:, '1':].stack()}) firm_prod = pd.DataFrame({'bool': Firm_Prod.loc[:, '1':].stack()})
firm_prod = firm_prod[firm_prod['bool'] == 1].reset_index() firm_prod = firm_prod[firm_prod['bool'] == 1].reset_index()
firm_prod.drop('bool', axis=1, inplace=True) firm_prod.drop('bool', axis=1, inplace=True)
firm_prod.rename({'level_0': 'Firm_Code', 'level_1': 'Product_Code'}, axis=1, inplace=True) firm_prod.rename({'level_0': 'Firm_Code', 'level_1': 'Product_Code'}, axis=1, inplace=True)
firm_prod['Firm_Code'] = firm_prod['Firm_Code'].astype('string') firm_prod['Firm_Code'] = firm_prod['Firm_Code'].astype('string')
self.firm_prod_network = nx.MultiDiGraph() self.G_FirmProd.add_nodes_from(firm_prod.index)
self.firm_prod_network.add_nodes_from(firm_prod.index) # Assign attributes to the firm-product nodes
firm_prod_labels_dict = {code: firm_prod.loc[code].to_dict() for code in firm_prod.index} firm_prod_labels_dict = {code: firm_prod.loc[code].to_dict() for code in firm_prod.index}
nx.set_node_attributes(self.firm_prod_network, firm_prod_labels_dict) nx.set_node_attributes(self.G_FirmProd, firm_prod_labels_dict)
self.add_edges_to_firm_network()
self.connect_unconnected_nodes()
print(
f"Firm network has {self.firm_network.number_of_nodes()} nodes and {self.firm_network.number_of_edges()} edges.")
print(
f"Product network has {self.product_network.number_of_nodes()} nodes and {self.product_network.number_of_edges()} edges.")
def add_edges_to_firm_network(self): def add_edges_to_firm_network(self):
""" Add edges to the firm network based on product BOM. """ """ Add edges between firms based on the product BOM relationships """
Firm = pd.read_csv("input_data/Firm_amended.csv") # Add edges to G_Firm according to G_bom
Firm['Code'] = Firm['Code'].astype('string') for node in nx.nodes(self.G_Firm):
Firm.fillna(0, inplace=True)
for node in nx.nodes(self.firm_network):
lst_pred_product_code = [] lst_pred_product_code = []
for product_code in self.firm_network.nodes[node]['Product_Code']: for product_code in self.G_Firm.nodes[node]['Product_Code']:
lst_pred_product_code += list(self.product_network.predecessors(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(set(lst_pred_product_code))
lst_pred_product_code = list(sorted(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: for pred_product_code in lst_pred_product_code:
lst_pred_firm = Firm['Code'][Firm[pred_product_code] == 1].to_list() # Get a list of firms producing the component (pred_product_code)
lst_pred_firm = self.Firm['Code'][self.Firm[pred_product_code] == 1].to_list()
# Select multiple suppliers (multi-sourcing)
n_pred_firm = self.int_netw_prf_n n_pred_firm = self.int_netw_prf_n
if n_pred_firm > len(lst_pred_firm): if n_pred_firm > len(lst_pred_firm):
n_pred_firm = len(lst_pred_firm) n_pred_firm = len(lst_pred_firm)
if self.is_prf_size: if self.is_prf_size:
lst_pred_firm_size = [self.firm_network.nodes[pred_firm]['Revenue_Log'] for pred_firm in lst_pred_firm_size = [self.G_Firm.nodes[pred_firm]['Revenue_Log'] for pred_firm in
lst_pred_firm] lst_pred_firm]
lst_prob = [size / sum(lst_pred_firm_size) for size in lst_pred_firm_size] lst_prob = [size / sum(lst_pred_firm_size) for size in lst_pred_firm_size]
lst_choose_firm = self.random.choices(lst_pred_firm, k=n_pred_firm, weights=lst_prob) lst_choose_firm = self.nprandom.choice(lst_pred_firm, n_pred_firm, replace=False, p=lst_prob)
else: else:
lst_choose_firm = self.random.choices(lst_pred_firm, k=n_pred_firm) lst_choose_firm = self.nprandom.choice(lst_pred_firm, n_pred_firm, replace=False)
lst_add_edge = [(pred_firm, node, {'Product': pred_product_code}) for pred_firm in lst_choose_firm]
self.firm_network.add_edges_from(lst_add_edge)
# Add edges to firm-prod network # Add edges from predecessor firms to current node (firm)
set_node_prod_code = set(self.firm_network.nodes[node]['Product_Code']) lst_add_edge = [(pred_firm, node, {'Product': pred_product_code}) for pred_firm in lst_choose_firm]
set_pred_succ_code = set(self.product_network.successors(pred_product_code)) 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) lst_use_pred_prod_code = list(set_node_prod_code & set_pred_succ_code)
for pred_firm in lst_choose_firm: for pred_firm in lst_choose_firm:
pred_node = [n for n, v in self.firm_prod_network.nodes(data=True) if pred_node = [n for n, v in self.G_FirmProd.nodes(data=True) if
v['Firm_Code'] == pred_firm and v['Product_Code'] == pred_product_code][0] v['Firm_Code'] == pred_firm and v['Product_Code'] == pred_product_code][0]
for use_pred_prod_code in lst_use_pred_prod_code: for use_pred_prod_code in lst_use_pred_prod_code:
current_node = [n for n, v in self.firm_prod_network.nodes(data=True) if current_node = [n for n, v in self.G_FirmProd.nodes(data=True) if
v['Firm_Code'] == node and v['Product_Code'] == use_pred_prod_code][0] v['Firm_Code'] == node and v['Product_Code'] == use_pred_prod_code][0]
self.firm_prod_network.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):
""" Connect unconnected nodes in the firm network. """ """ Connect unconnected nodes in the firm network """
Firm = pd.read_csv("input_data/Firm_amended.csv") for node in nx.nodes(self.G_Firm):
Firm['Code'] = Firm['Code'].astype('string') if self.G_Firm.degree(node) == 0:
Firm.fillna(0, inplace=True) for product_code in self.G_Firm.nodes[node]['Product_Code']:
for node in nx.nodes(self.firm_network): current_node = [n for n, v in self.G_FirmProd.nodes(data=True) if
if self.firm_network.degree(node) == 0:
for product_code in self.firm_network.nodes[node]['Product_Code']:
current_node = [n for n, v in self.firm_prod_network.nodes(data=True) if
v['Firm_Code'] == node and v['Product_Code'] == product_code][0] v['Firm_Code'] == node and v['Product_Code'] == product_code][0]
lst_succ_product_code = list(self.product_network.successors(product_code)) lst_succ_product_code = list(self.G_bom.successors(product_code))
for succ_product_code in lst_succ_product_code: for succ_product_code in lst_succ_product_code:
lst_succ_firm = Firm['Code'][Firm[succ_product_code] == 1].to_list() lst_succ_firm = self.Firm['Code'][self.Firm[succ_product_code] == 1].to_list()
n_succ_firm = self.int_netw_prf_n n_succ_firm = self.int_netw_prf_n
if n_succ_firm > len(lst_succ_firm): if n_succ_firm > len(lst_succ_firm):
n_succ_firm = len(lst_succ_firm) n_succ_firm = len(lst_succ_firm)
if self.is_prf_size: if self.is_prf_size:
lst_succ_firm_size = [self.firm_network.nodes[succ_firm]['Revenue_Log'] for succ_firm in lst_succ_firm_size = [self.G_Firm.nodes[succ_firm]['Revenue_Log'] for succ_firm in
lst_succ_firm] lst_succ_firm]
lst_prob = [size / sum(lst_succ_firm_size) for size in lst_succ_firm_size] lst_prob = [size / sum(lst_succ_firm_size) for size in lst_succ_firm_size]
lst_choose_firm = self.random.choices(lst_succ_firm, k=n_succ_firm, weights=lst_prob) lst_choose_firm = self.nprandom.choice(lst_succ_firm, n_succ_firm, replace=False,
p=lst_prob)
else: else:
lst_choose_firm = self.random.choices(lst_succ_firm, k=n_succ_firm) 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.firm_network.add_edges_from(lst_add_edge)
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
for succ_firm in lst_choose_firm: for succ_firm in lst_choose_firm:
succ_node = [n for n, v in self.firm_prod_network.nodes(data=True) if succ_node = [n for n, v in self.G_FirmProd.nodes(data=True) if
v['Firm_Code'] == succ_firm and v['Product_Code'] == succ_product_code][0] v['Firm_Code'] == succ_firm and v['Product_Code'] == succ_product_code][0]
self.firm_prod_network.add_edge(current_node, succ_node) 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 图对象
def initialize_agents(self): def initialize_agents(self):
""" Initialize agents and add them to the model. """ """ Initialize agents and add them to the model. """
@ -189,7 +214,6 @@ class MyModel(Model):
for ag_node, attr in self.firm_network.nodes(data=True): for ag_node, attr in self.firm_network.nodes(data=True):
a_lst_product = [agent for agent in self.product_agents if agent.unique_id in attr['Product_Code']] a_lst_product = [agent for agent in self.product_agents if agent.unique_id in attr['Product_Code']]
print(a_lst_product)
firm_agent = FirmAgent( firm_agent = FirmAgent(
ag_node, self, ag_node, self,
type_region=attr['Type_Region'], type_region=attr['Type_Region'],
@ -208,7 +232,8 @@ class MyModel(Model):
# 遍历初始公司-产品干扰数据,将其转化为基于公司和产品的映射 # 遍历初始公司-产品干扰数据,将其转化为基于公司和产品的映射
for firm_code, lst_product in self.dct_lst_init_disrupt_firm_prod.items(): for firm_code, lst_product in self.dct_lst_init_disrupt_firm_prod.items():
# 从 company_agents 列表中选择指定公司 # 从 company_agents 列表中选择指定公司
firm = next(firm for firm in self.company_agents if firm.unique_id == firm_code) firms = [firm for firm in self.company_agents if firm.unique_id == firm_code]
firm = firms[0] if firms else None
# 从总产品列表中选择该公司受干扰的产品 # 从总产品列表中选择该公司受干扰的产品
disrupted_products = [product for product in self.product_agents if product.unique_id in lst_product] disrupted_products = [product for product in self.product_agents if product.unique_id in lst_product]
@ -219,6 +244,7 @@ class MyModel(Model):
# 更新 self.dct_lst_init_disrupt_firm_prod 字典,存储公司及其受干扰的产品 # 更新 self.dct_lst_init_disrupt_firm_prod 字典,存储公司及其受干扰的产品
self.dct_lst_init_disrupt_firm_prod = t_dct self.dct_lst_init_disrupt_firm_prod = t_dct
# 设置初始受干扰的公司产品状态 # 设置初始受干扰的公司产品状态
for firm, a_lst_product in self.dct_lst_init_disrupt_firm_prod.items(): for firm, a_lst_product in self.dct_lst_init_disrupt_firm_prod.items():
for product in a_lst_product: for product in a_lst_product:
@ -236,7 +262,6 @@ class MyModel(Model):
self.product_agents.append(agent) self.product_agents.append(agent)
def step(self): def step(self):
print(f"Running step {self.t}")
# 1. Remove edge to customer and disrupt customer up product # 1. Remove edge to customer and disrupt customer up product
for firm in self.company_agents: for firm in self.company_agents:
for prod in firm.dct_prod_up_prod_stat.keys(): for prod in firm.dct_prod_up_prod_stat.keys():