without模型转型成功!但是without还无法插入表 o
This commit is contained in:
parent
60b402c043
commit
ede00b0403
|
@ -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.
Binary file not shown.
93
firm.py
93
firm.py
|
@ -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
|
||||||
|
|
149
my_model.py
149
my_model.py
|
@ -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():
|
||||||
|
|
Loading…
Reference in New Issue