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

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">
<option name="attributeMap">
<map>
<entry key="\input_data\BomNodes.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\input_data\Firm_amended.csv">
<value>
<Attribute>
@ -10,6 +17,20 @@
</Attribute>
</value>
</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">
<value>
<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 model import MyModel
from my_model import MyModel
if TYPE_CHECKING:
from controller_db import ControllerDB

13
firm.py
View File

@ -1,5 +1,5 @@
from mesa import Agent
from model import MyModel
import numpy as np
class FirmAgent(Agent):
@ -47,17 +47,18 @@ class FirmAgent(Agent):
"cap_limit_prob_type must be either 'uniform' or 'normal'"
extra_cap_mean = self.size_stat[0][0] / self.flt_cap_limit_level
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':
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
def remove_edge_to_cus(self, disrupted_prod):
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:
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:
customer = self.model.schedule.get_agent(n2)
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):
num_lost = len(self.dct_prod_up_prod_stat[prod]['s_stat'][disrupted_up_prod]['set_disrupt_firm'])
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])
lost_percent = num_lost / (num_lost + num_remain)
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
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
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):
# 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.cap_limit_prob_type = params['cap_limit_prob_type']
self.cap_limit_level = params['cap_limit_level']
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 图对象
self.t = 0
self.network_graph = nx.MultiDiGraph()
# NetworkGrid 用于管理网格
self.grid = NetworkGrid(self.network_graph)
self.data_collector = DataCollector(
@ -48,20 +51,21 @@ class MyModel(Model):
self.remove_t = int(params['remove_t'])
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_firm_network()
self.initialize_firm_product_network()
self.add_edges_to_firm_network()
self.connect_unconnected_nodes()
self.initialize_agents()
self.initialize_disruptions()
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.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):
""" Initialize the firm network and add it to the model. """
@ -98,6 +102,11 @@ class MyModel(Model):
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):
""" Add edges to the firm network based on product BOM. """
Firm = pd.read_csv("input_data/Firm_amended.csv")
@ -176,8 +185,11 @@ class MyModel(Model):
self.add_agent(product)
# 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):
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(
ag_node, self,
type_region=attr['Type_Region'],
@ -185,16 +197,37 @@ class MyModel(Model):
a_lst_product=a_lst_product,
)
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)
def initialize_disruptions(self):
""" Initialize disruptions in the network. """
for firm_code, lst_product in self.dct_lst_init_disrupt_firm_prod.items():
for product_code in lst_product:
self.firm_network.nodes[firm_code]['Product_Code'].remove(product_code)
# 初始化一部字典,用于存储每个公司及其对应的受干扰产品列表
t_dct = {}
# 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):
if isinstance(agent, FirmAgent):

View File

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