模型修改基本结束,到达模型开始执行风险传递处

This commit is contained in:
Cricial 2024-09-13 16:58:14 +08:00
parent be701c2fe9
commit 60b402c043
12 changed files with 92 additions and 34 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\BomNodes.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\input_data\Firm_amended.csv"> <entry key="\input_data\Firm_amended.csv">
<value> <value>
<Attribute> <Attribute>
@ -10,6 +17,20 @@
</Attribute> </Attribute>
</value> </value>
</entry> </entry>
<entry key="\input_data\oa_with_exp.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\input_data\oa_without_exp.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\input_data\xv_with_exp.csv"> <entry key="\input_data\xv_with_exp.csv">
<value> <value>
<Attribute> <Attribute>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -5,7 +5,7 @@ from mesa import Model
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from model import MyModel from my_model import MyModel
if TYPE_CHECKING: if TYPE_CHECKING:
from controller_db import ControllerDB from controller_db import ControllerDB

13
firm.py
View File

@ -1,5 +1,5 @@
from mesa import Agent from mesa import Agent
from model import MyModel import numpy as np
class FirmAgent(Agent): class FirmAgent(Agent):
@ -47,17 +47,18 @@ class FirmAgent(Agent):
"cap_limit_prob_type must be either 'uniform' or 'normal'" "cap_limit_prob_type must be either 'uniform' or 'normal'"
extra_cap_mean = self.size_stat[0][0] / self.flt_cap_limit_level extra_cap_mean = self.size_stat[0][0] / self.flt_cap_limit_level
if self.str_cap_limit_prob_type == 'uniform': if self.str_cap_limit_prob_type == 'uniform':
extra_cap = self.model.random.randint(extra_cap_mean - 2, extra_cap_mean + 2) extra_cap = self.model.random.uniform(extra_cap_mean - 2, extra_cap_mean + 2)
extra_cap = 0 if round(extra_cap) < 0 else round(extra_cap)
elif self.str_cap_limit_prob_type == 'normal': elif self.str_cap_limit_prob_type == 'normal':
extra_cap = self.model.random.normalvariate(extra_cap_mean, 1) extra_cap = self.model.random.normalvariate(extra_cap_mean, 1)
extra_cap = max(0, round(extra_cap)) extra_cap = 0 if round(extra_cap) < 0 else round(extra_cap)
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):
lst_out_edge = list( lst_out_edge = list(
self.firm_network.get_neighbors(self.unique_id)) self.firm_network.neighbors(self.unique_id))
for n2 in lst_out_edge: for n2 in lst_out_edge:
edge_data = self.firm_network.G.edges[self.unique_id, n2] edge_data = self.firm_network.edges[self.unique_id, n2]
if edge_data.get('Product') == disrupted_prod.code: if edge_data.get('Product') == disrupted_prod.code:
customer = self.model.schedule.get_agent(n2) customer = self.model.schedule.get_agent(n2)
for prod in customer.dct_prod_up_prod_stat.keys(): for prod in customer.dct_prod_up_prod_stat.keys():
@ -69,7 +70,7 @@ class FirmAgent(Agent):
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']) num_lost = len(self.dct_prod_up_prod_stat[prod]['s_stat'][disrupted_up_prod]['set_disrupt_firm'])
num_remain = len([ num_remain = len([
u for u in self.firm_network.get_neighbors(self.unique_id) u for u in self.firm_network.neighbors(self.unique_id)
if self.firm_network.G.edges[u, self.unique_id].get('Product') == disrupted_up_prod.code]) if self.firm_network.G.edges[u, self.unique_id].get('Product') == disrupted_up_prod.code])
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 = [firm.size_stat[-1][0] for firm in self.model.schedule.agents]

View File

@ -1,3 +1,2 @@
X1,X2,X3,X4,X5,X6,X7,X8 X1,X2,X3,X4,X5,X6,X7,X8
0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0
,,,,,,,
1 X1 X2 X3 X4 X5 X6 X7 X8
2 0 0 0 0 0 0 0 0

View File

@ -1,3 +1,2 @@
n_max_trial,prf_size,prf_conn,cap_limit_prob_type,cap_limit_level,diff_new_conn,remove_t,netw_prf_n n_max_trial,prf_size,prf_conn,cap_limit_prob_type,cap_limit_level,diff_new_conn,remove_t,netw_prf_n
5,TRUE,TRUE,uniform,10,0.5,5,2 5,TRUE,TRUE,uniform,10,0.5,5,2
,,,,,,,
1 n_max_trial prf_size prf_conn cap_limit_prob_type cap_limit_level diff_new_conn remove_t netw_prf_n
2 5 TRUE TRUE uniform 10 0.5 5 2

View File

@ -16,17 +16,20 @@ class MyModel(Model):
def __init__(self, params): def __init__(self, params):
# self.num_agents = N # self.num_agents = N
self.is_prf_size = params['is_prf_size'] self.is_prf_size = params['prf_size']
self.prf_conn = params['prf_conn'] self.prf_conn = params['prf_conn']
self.cap_limit_prob_type = params['cap_limit_prob_type'] self.cap_limit_prob_type = params['cap_limit_prob_type']
self.cap_limit_level = params['cap_limit_level'] self.cap_limit_level = params['cap_limit_level']
self.diff_new_conn = params['diff_new_conn'] self.diff_new_conn = params['diff_new_conn']
self.firm_network = nx.MultiDiGraph() # 有向多重图
self.firm_prod_network = nx.MultiDiGraph()
self.product_network = nx.MultiDiGraph() # 有向多重图
# NetworkGrid 用于管理网格
# NetworkX 图对象 # NetworkX 图对象
self.t = 0 self.t = 0
self.network_graph = nx.MultiDiGraph() self.network_graph = nx.MultiDiGraph()
# NetworkGrid 用于管理网格
self.grid = NetworkGrid(self.network_graph) self.grid = NetworkGrid(self.network_graph)
self.data_collector = DataCollector( self.data_collector = DataCollector(
@ -48,20 +51,21 @@ class MyModel(Model):
self.remove_t = int(params['remove_t']) self.remove_t = int(params['remove_t'])
self.int_netw_prf_n = int(params['netw_prf_n']) self.int_netw_prf_n = int(params['netw_prf_n'])
self.product_network = None
self.firm_network = None
self.firm_prod_network = None
self.initialize_product_network(params) self.initialize_product_network(params)
self.initialize_firm_network() self.initialize_firm_network()
self.initialize_firm_product_network() self.initialize_firm_product_network()
self.add_edges_to_firm_network()
self.connect_unconnected_nodes()
self.initialize_agents() self.initialize_agents()
self.initialize_disruptions() self.initialize_disruptions()
def initialize_product_network(self, params): def initialize_product_network(self, params):
""" Initialize the product network and add it to the model. """ try:
self.product_network = nx.adjacency_graph(json.loads(params['g_bom'])) self.product_network = nx.adjacency_graph(json.loads(params['g_bom']))
self.network_graph.add_edges_from(self.product_network.edges) 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:
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 and add it to the model. """
@ -98,6 +102,11 @@ class MyModel(Model):
self.add_edges_to_firm_network() self.add_edges_to_firm_network()
self.connect_unconnected_nodes() 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 to the firm network based on product BOM. """
Firm = pd.read_csv("input_data/Firm_amended.csv") Firm = pd.read_csv("input_data/Firm_amended.csv")
@ -176,8 +185,11 @@ class MyModel(Model):
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}")
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'],
@ -185,16 +197,37 @@ class MyModel(Model):
a_lst_product=a_lst_product, a_lst_product=a_lst_product,
) )
self.add_agent(firm_agent) self.add_agent(firm_agent)
##print(f"Firm agent created: {firm_agent.unique_id}, Products: {[p.name for p in a_lst_product]}")
# self.grid.place_agent(firm_agent, ag_node) # self.grid.place_agent(firm_agent, ag_node)
def initialize_disruptions(self): def initialize_disruptions(self):
""" Initialize disruptions in the network. """ # 初始化一部字典,用于存储每个公司及其对应的受干扰产品列表
for firm_code, lst_product in self.dct_lst_init_disrupt_firm_prod.items(): t_dct = {}
for product_code in lst_product:
self.firm_network.nodes[firm_code]['Product_Code'].remove(product_code)
# Log disruptions for visualization # 遍历初始公司-产品干扰数据,将其转化为基于公司和产品的映射
self.dct_lst_init_disrupt_firm_prod[firm_code].append(product_code) for firm_code, lst_product in self.dct_lst_init_disrupt_firm_prod.items():
# 从 company_agents 列表中选择指定公司
firm = next(firm for firm in self.company_agents if firm.unique_id == firm_code)
# 从总产品列表中选择该公司受干扰的产品
disrupted_products = [product for product in self.product_agents if product.unique_id in lst_product]
# 将公司与其受干扰的产品映射到字典中
t_dct[firm] = disrupted_products
# 更新 self.dct_lst_init_disrupt_firm_prod 字典,存储公司及其受干扰的产品
self.dct_lst_init_disrupt_firm_prod = t_dct
# 设置初始受干扰的公司产品状态
for firm, a_lst_product in self.dct_lst_init_disrupt_firm_prod.items():
for product in a_lst_product:
# 确保产品存在于公司的生产状态字典中
assert product in firm.dct_prod_up_prod_stat.keys(), \
f"Product {product.code} not in firm {firm.code}"
# 将产品状态更新为干扰状态,并记录干扰时间
firm.dct_prod_up_prod_stat[product]['p_stat'].append(('D', self.t))
def add_agent(self, agent): def add_agent(self, agent):
if isinstance(agent, FirmAgent): if isinstance(agent, FirmAgent):

View File

@ -10,14 +10,19 @@ class ProductAgent(Agent):
self.product_network = self.model.product_network self.product_network = self.model.product_network
def a_successors(self): def a_successors(self):
# Find successors of the current product and return them as a list of ProductAgent # 从 product_network 中找到当前代理的后继节点
successors = list(self.product_network.successors(self)) successors = list(self.model.product_network.successors(self.unique_id))
return [self.model.schedule.agents[successor] for successor in successors]
# 通过 unique_id 查找后继节点对应的代理对象,从 self.product_agents 中获取
return [agent for agent in self.model.product_agents if agent.unique_id in successors]
def a_predecessors(self): def a_predecessors(self):
# Find predecessors of the current product and return them as a list of ProductAgent # 找到当前代理的前驱节点
predecessors = list(self.product_network.predecessors(self)) predecessors = list(self.model.product_network.predecessors(self.unique_id))
return [self.model.schedule.agents[predecessor] for predecessor in predecessors]
# 通过 unique_id 查找前驱节点对应的代理对象,直接从 self.product_agents 列表中获取
return [agent for agent in self.model.product_agents if agent.unique_id in predecessors]
def step(self): def step(self):
# 在每个时间步 进行的操作 # 在每个时间步 进行的操作
pass pass