This commit is contained in:
2023-06-18 21:03:11 +08:00
parent 1d8f319adb
commit a19860bdb2
4 changed files with 26 additions and 110 deletions

View File

@@ -10,12 +10,16 @@ import json
class Model(ap.Model):
def setup(self):
# self para
self.sample = self.p.sample
self.int_stop_times, self.int_stop_t = 0, None
self.int_n_iter = int(self.p.n_iter)
self.product_network = None # agentpy network
self.firm_network = None # agentpy network
self.firm_prod_network = None # networkx
self.dct_lst_remove_firm_prod = self.p.dct_lst_init_remove_firm_prod
# external variable
self.int_n_max_trial = int(self.p.n_max_trial)
self.is_prf_size = bool(self.p.prf_size)
self.flt_diff_remove = float(self.p.diff_remove)
@@ -215,15 +219,9 @@ class Model(ap.Model):
code in lst_product for code in self.a_lst_total_products.code
])
self.dct_lst_remove_firm_prod = t_dct
# self.dct_lst_disrupt_firm_prod = t_dct
# # init output
# self.lst_dct_lst_remove_firm_prod = []
# self.lst_dct_lst_disrupt_firm_prod = []
# self.dct_ts_dct_a_lst_remove = {}
# set the initial firm product that are removed
print('\n', '=' * 20, 'step', self.t, '=' * 20)
for firm, a_lst_product in self.dct_lst_remove_firm_prod.items():
for product in a_lst_product:
assert product in firm.a_lst_product, \
@@ -333,24 +331,13 @@ class Model(ap.Model):
# change capacity
select_cand.dct_prod_capacity[di_supp_prod] -= 1
break
# nx.to_pandas_adjacency(G_Firm).to_csv('adj_g_firm_proactive.csv')
# draw network
# self.draw_network()
def update(self):
self.a_lst_total_firms.clean_before_time_step()
# # output
# self.lst_dct_lst_remove_firm_prod.append(
# (self.t, self.dct_lst_remove_firm_prod))
# self.lst_dct_lst_disrupt_firm_prod.append(
# (self.t, self.dct_lst_disrupt_firm_prod))
# # stop simulation if reached terminal number of iteration
# if self.t == self.int_n_iter or len(
# self.dct_lst_remove_firm_prod) == 0:
# self.int_stop_times = self.t
# self.stop()
# reduce the size of removed firm
for firm in self.a_lst_total_firms:
@@ -364,6 +351,7 @@ class Model(ap.Model):
firm.dct_prod_up_prod_stat[
prod]['status'].append(('N', self.t))
# stop simulation if all firm returned to normal except inital removal
if self.t > 0:
for firm in self.a_lst_total_firms:
for prod in firm.dct_prod_up_prod_stat.keys():
@@ -380,11 +368,6 @@ class Model(ap.Model):
def step(self):
print('\n', '=' * 20, 'step', self.t, '=' * 20)
# print(
# 'dct_list_remove_firm_prod', {
# key.name: value.code
# for key, value in self.dct_lst_remove_firm_prod.items()
# })
# remove_edge_to_cus_and_cus_up_prod
for firm in self.a_lst_total_firms:
@@ -400,8 +383,6 @@ class Model(ap.Model):
self.a_lst_total_firms = self.a_lst_total_firms.shuffle()
is_stop_trial = True
for firm in self.a_lst_total_firms:
# if len(firm.a_lst_up_product_removed) > 0:
# firm.seek_alt_supply()
lst_seek_prod = []
for prod in firm.dct_prod_up_prod_stat.keys():
status = firm.dct_prod_up_prod_stat[prod]['status'][-1][0]
@@ -432,16 +413,8 @@ class Model(ap.Model):
# do not use:
# self.a_lst_total_firms.dct_request_prod_from_firm = {} why?
# based on dct_prod_up_prod_stat
# update a_lst_product_disrupted / a_lst_product_removed
# update dct_lst_disrupt_firm_prod / dct_lst_remove_firm_prod
# self.dct_lst_remove_firm_prod = {}
# self.dct_lst_disrupt_firm_prod = {}
# turn disrupted firm into removed firm conditionally
for firm in self.a_lst_total_firms:
# if len(firm.a_lst_up_product_removed) > 0:
# print(firm.name, 'a_lst_up_product_removed', [
# product.code for product in firm.a_lst_up_product_removed
# ])
for product in firm.dct_prod_up_prod_stat.keys():
status = firm.dct_prod_up_prod_stat[product]['status'][-1][0]
if status == 'D':
@@ -450,28 +423,9 @@ class Model(ap.Model):
sum([not stat for stat in
firm.dct_prod_up_prod_stat[
product]['supply'].values()])
# for product in firm.a_lst_product:
# n_up_product_removed = 0
# for up_product_removed in firm.a_lst_up_product_removed:
# if product in up_product_removed.a_successors():
# n_up_product_removed += 1
if n_up_product_removed == 0:
continue
else:
# # update a_lst_product_disrupted
# # update dct_lst_disrupt_firm_prod
# if product not in firm.a_lst_product_disrupted:
# firm.a_lst_product_disrupted.append(product)
# if firm in self.dct_lst_disrupt_firm_prod.keys():
# self.dct_lst_disrupt_firm_prod[firm].append(
# product)
# else:
# self.dct_lst_disrupt_firm_prod[
# firm] = ap.AgentList(
# self.model, [product])
# update a_lst_product_removed
# update dct_list_remove_firm_prod
# mark disrupted firm as removed based conditionally
lost_percent = n_up_product_removed / len(
product.a_predecessors())
lst_size = self.a_lst_total_firms.size
@@ -484,7 +438,7 @@ class Model(ap.Model):
std_size = (firm.size - min(lst_size) +
1) / (max(lst_size) - min(lst_size) + 1)
prob_remove = 1 - std_size * (1 - lost_percent)
# damp prod
# damp prob
prob_remove = prob_remove ** self.flt_diff_remove
# sample prob
prob_remove = self.nprandom.uniform(
@@ -495,14 +449,6 @@ class Model(ap.Model):
p=[prob_remove,
1 - prob_remove]):
firm.a_lst_product_removed.append(product)
# if firm in self.dct_lst_remove_firm_prod.keys():
# self.dct_lst_remove_firm_prod[firm].append(
# product)
# else:
# self.dct_lst_remove_firm_prod[
# firm] = ap.AgentList(
# self.model, [product])
firm.dct_prod_up_prod_stat[
product]['status'].append(('R', self.t))
print(firm.name, 'removed product: ', product.code)
@@ -510,24 +456,8 @@ class Model(ap.Model):
firm.dct_prod_up_prod_stat[
product]['status'].append(('N', self.t))
# print(
# 'dct_list_remove_firm_prod', {
# key.name: value.code
# for key, value in self.dct_lst_remove_firm_prod.items()
# })
def end(self):
print('/' * 20, 'output', '/' * 20)
# print('dct_list_remove_firm_prod')
# for t, dct in self.lst_dct_lst_remove_firm_prod:
# for firm, a_lst_product in dct.items():
# for product in a_lst_product:
# print(t, firm.name, product.code)
# print('dct_lst_disrupt_firm_prod')
# for t, dct in self.lst_dct_lst_disrupt_firm_prod:
# for firm, a_lst_product in dct.items():
# for product in a_lst_product:
# print(t, firm.name, product.code)
# qry_result = db_session.query(Result).filter_by(s_id=self.sample.id)
# if qry_result.count() == 0: