proactive strategy 2 based on graph firm prod

This commit is contained in:
HaoYizhi 2023-06-05 15:08:45 +08:00
parent 907d6cb179
commit 83eeeb9d14
3 changed files with 150 additions and 4 deletions

Binary file not shown.

154
model.py
View File

@ -48,6 +48,26 @@ class Model(ap.Model):
firm_labels_dict[code] = Firm_attr.loc[code].to_dict()
nx.set_node_attributes(G_Firm, firm_labels_dict)
# init graph firm prod
Firm_Prod = pd.read_csv("Firm_amended.csv")
# Firm['Code'] = Firm['Code'].astype('string')
Firm_Prod.fillna(0, inplace=True)
# Firm_attr = Firm.loc[:, ["Code", "Name", "Type_Region", "Revenue_Log"]]
# Firm_attr.set_index('Code', inplace=True)
firm_prod = pd.DataFrame({'bool': Firm_Prod.loc[:, '1':].stack()})
firm_prod = firm_prod[firm_prod['bool'] == 1].reset_index()
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['Firm_Code'] = firm_prod['Firm_Code'].astype('string')
G_FirmProd = nx.MultiDiGraph()
G_FirmProd.add_nodes_from(firm_prod.index)
firm_prod_labels_dict = {}
for code in firm_prod.index:
firm_prod_labels_dict[code] = firm_prod.loc[code].to_dict()
nx.set_node_attributes(G_FirmProd, firm_prod_labels_dict)
# add edge to G_firm according to G_bom
for node in nx.nodes(G_Firm):
for product_code in G_Firm.nodes[node]['Product_Code']:
@ -82,17 +102,26 @@ class Model(ap.Model):
share * len(lst_succ_firm)) > 0 else 1 # at least one
lst_choose_firm = self.nprandom.choice(lst_succ_firm,
n_succ_firm,
replace=False,
p=lst_prob)
lst_choose_firm = list(
set(lst_choose_firm
)) # nprandom.choice may have duplicates
lst_add_edge = [(node, succ_firm, {
'Product': product_code
}) for succ_firm in lst_choose_firm]
G_Firm.add_edges_from(lst_add_edge)
# graph firm prod
pred_node = [n for n, v in G_FirmProd.nodes(data=True)
if v['Firm_Code'] == node and
v['Product_Code'] == product_code][0]
for succ_firm in lst_choose_firm:
succ_node = [n for n, v in G_FirmProd.nodes(data=True)
if v['Firm_Code'] == succ_firm and
v['Product_Code'] == succ_product_code][0]
G_FirmProd.add_edge(pred_node, succ_node)
self.sample.g_firm = json.dumps(nx.adjacency_data(G_Firm))
self.firm_network = ap.Network(self, G_Firm)
self.firm_prod_network = G_FirmProd
# init product
for ag_node, attr in self.product_network.graph.nodes(data=True):
@ -145,6 +174,112 @@ class Model(ap.Model):
f"product {product.code} not in firm {firm.code}"
firm.a_lst_product_removed.append(product)
# proactive strategy
proactive_ratio = 1.0
# get all the firm prod affected
for firm, a_lst_product in self.dct_lst_remove_firm_prod.items():
for product in a_lst_product:
init_node = \
[n for n, v in
self.firm_prod_network.nodes(data=True)
if v['Firm_Code'] == firm.code and
v['Product_Code'] == product.code][0]
dct_affected = \
nx.dfs_successors(self.firm_prod_network,
init_node)
lst_affected = set()
for i, (u, vs) in enumerate(dct_affected.items()):
# at least 2 hops away
if i > 0:
pred_node = self.firm_prod_network.nodes[u]
for v in vs:
succ_node = self.firm_prod_network.nodes[v]
lst_affected.add((succ_node['Firm_Code'],
succ_node['Product_Code']))
lst_affected = list(lst_affected)
lst_firm_proactive = \
[lst_affected[i] for i in
self.nprandom.choice(range(len(lst_affected)),
round(len(lst_affected) *
proactive_ratio))]
print(lst_firm_proactive)
for firm_code, prod_code in lst_firm_proactive:
pro_firm_prod_code = \
[n for n, v in
self.firm_prod_network.nodes(data=True)
if v['Firm_Code'] == firm_code and
v['Product_Code'] == prod_code][0]
pro_firm_prod_node = \
self.firm_prod_network.nodes[pro_firm_prod_code]
pro_firm = \
self.a_lst_total_firms.select(
[firm.code == pro_firm_prod_node['Firm_Code']
for firm in self.a_lst_total_firms])[0]
# print(list(self.firm_prod_network.predecessors(firm_prod_node)))
lst_shortest_path = \
list(nx.all_shortest_paths(self.firm_prod_network,
source=init_node,
target=pro_firm_prod_code))
dct_drs = {}
for di_supp_code in self.firm_prod_network.predecessors(
pro_firm_prod_code):
di_supp_node = \
self.firm_prod_network.nodes[di_supp_code]
di_supp_prod = \
self.a_lst_total_products.select(
[product.code == di_supp_node['Product_Code']
for product in self.a_lst_total_products])[0]
di_supp_firm = \
self.a_lst_total_firms.select(
[firm.code == di_supp_node['Firm_Code']
for firm in self.a_lst_total_firms])[0]
lst_cand = self.model.a_lst_total_firms.select([
di_supp_prod in firm.a_lst_product
and di_supp_prod not in firm.a_lst_product_removed
for firm in self.model.a_lst_total_firms
])
n2n_betweenness = \
sum([True if di_supp_code in path else False
for path in lst_shortest_path]) \
/ len(lst_shortest_path)
# print(lst_shortest_path)
# print(sum([True if di_supp_code in path else False
# for path in lst_shortest_path]), len(lst_shortest_path))
drs = n2n_betweenness / \
(len(lst_cand) * di_supp_firm.revenue_log)
# print(drs)
dct_drs[di_supp_code] = drs
dct_drs = dict(sorted(
dct_drs.items(), key=lambda kv: kv[1], reverse=True))
print(dct_drs)
for di_supp_code in dct_drs.keys():
di_supp_node = \
self.firm_prod_network.nodes[di_supp_code]
di_supp_prod = \
self.a_lst_total_products.select(
[product.code == di_supp_node['Product_Code']
for product in self.a_lst_total_products])[0]
# find a dfferent firm can produce the same product
lst_cand = self.model.a_lst_total_firms.select([
di_supp_prod in firm.a_lst_product
and di_supp_prod not in firm.a_lst_product_removed
and firm.code != di_supp_node['Firm_Code']
for firm in self.model.a_lst_total_firms
])
if len(lst_cand) > 0:
select_cand = self.nprandom.choice(lst_cand)
self.firm_network.graph.add_edges_from([
(self.firm_network.positions[select_cand],
self.firm_network.positions[pro_firm], {
'Product': di_supp_prod.code
})
])
select_cand.dct_prod_capacity[di_supp_prod] -= 1
# draw network
self.draw_network()
@ -165,7 +300,18 @@ class Model(ap.Model):
print(list(self.dfs_edges_prod(self.firm_network.graph,
self.a_lst_total_firms[133],
self.a_lst_total_firms[133].a_lst_product[0])))
print(self.betweenness_centrality_firm_prod(self.firm_network.graph))
# print(self.betweenness_centrality_firm_prod(self.firm_network.graph))
t = nx.dfs_successors(self.firm_prod_network, [n for n, v in self.firm_prod_network.nodes(data=True)
if v['Firm_Code'] == self.a_lst_total_firms[133].code and
v['Product_Code'] == self.a_lst_total_firms[133].a_lst_product[0].code][0])
print(t)
for key, values in t.items():
pred_node = self.firm_prod_network.nodes[key]
for value in values:
succ_node = self.firm_prod_network.nodes[value]
print(pred_node['Firm_Code'], pred_node['Product_Code'],
succ_node['Firm_Code'], succ_node['Product_Code'])
print()
def update(self):

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 MiB

After

Width:  |  Height:  |  Size: 2.8 MiB