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

Binary file not shown.

Binary file not shown.

46
firm.py
View File

@ -7,33 +7,23 @@ class FirmAgent(ap.Agent):
self.firm_network = self.model.firm_network self.firm_network = self.model.firm_network
self.product_network = self.model.product_network self.product_network = self.model.product_network
# self para
self.code = code self.code = code
self.name = name self.name = name
self.type_region = type_region self.type_region = type_region
self.ori_size = revenue_log self.ori_size = revenue_log
self.size = revenue_log self.size = revenue_log
self.a_lst_product = a_lst_product self.a_lst_product = a_lst_product
self.a_lst_product_removed = ap.AgentList(self.model, [])
self.dct_prod_up_prod_stat = {}
self.dct_prod_capacity = {} self.dct_prod_capacity = {}
# self.a_lst_up_product_removed = ap.AgentList(self.model, []) # para in trial
# self.a_lst_product_disrupted = ap.AgentList(self.model, [])
self.a_lst_product_removed = ap.AgentList(self.model, [])
self.dct_prod_up_prod_stat = {}
for prod in a_lst_product:
self.dct_prod_up_prod_stat[prod] = {
# Normal / Disrupted / Removed + time step
'status': [('N', 0)],
# have or have no supply
'supply': dict.fromkeys(prod.a_predecessors(), True)
}
# print(self.dct_prod_up_prod_stat)
self.dct_n_trial_up_prod_removed = {} self.dct_n_trial_up_prod_removed = {}
self.dct_cand_alt_supply_up_prod_removed = {} self.dct_cand_alt_supply_up_prod_removed = {}
self.dct_request_prod_from_firm = {} self.dct_request_prod_from_firm = {}
# para # external variable
self.is_prf_size = self.model.is_prf_size self.is_prf_size = self.model.is_prf_size
self.is_prf_conn = bool(self.p.prf_conn) self.is_prf_conn = bool(self.p.prf_conn)
self.str_cap_limit_prob_type = str(self.p.cap_limit_prob_type) self.str_cap_limit_prob_type = str(self.p.cap_limit_prob_type)
@ -41,7 +31,16 @@ class FirmAgent(ap.Agent):
self.flt_diff_new_conn = float(self.p.diff_new_conn) self.flt_diff_new_conn = float(self.p.diff_new_conn)
self.flt_crit_supplier = float(self.p.crit_supplier) self.flt_crit_supplier = float(self.p.crit_supplier)
# init extra capacity # init dct_prod_up_prod_stat (self para)
for prod in a_lst_product:
self.dct_prod_up_prod_stat[prod] = {
# Normal / Disrupted / Removed + time step
'status': [('N', 0)],
# have or have no supply
'supply': dict.fromkeys(prod.a_predecessors(), True)
}
# init extra capacity (self para)
for product in self.a_lst_product: for product in self.a_lst_product:
# init extra capacity based on discrete uniform distribution # init extra capacity based on discrete uniform distribution
assert self.str_cap_limit_prob_type in ['uniform', 'normal'], \ assert self.str_cap_limit_prob_type in ['uniform', 'normal'], \
@ -86,13 +85,7 @@ class FirmAgent(ap.Agent):
if self.model.nprandom.choice([True, False], if self.model.nprandom.choice([True, False],
p=[prod_remove, p=[prod_remove,
1 - prod_remove]): 1 - prod_remove]):
# if remove_product not in \ customer.dct_n_trial_up_prod_removed[remove_product] = 0
# customer.a_lst_up_product_removed:
# customer.a_lst_up_product_removed.append(
# remove_product)
# customer.dct_n_trial_up_prod_removed[
# remove_product] = 0
for prod in customer.dct_prod_up_prod_stat.keys(): for prod in customer.dct_prod_up_prod_stat.keys():
if remove_product in \ if remove_product in \
customer.dct_prod_up_prod_stat[ customer.dct_prod_up_prod_stat[
@ -101,12 +94,8 @@ class FirmAgent(ap.Agent):
prod]['supply'][remove_product] = False prod]['supply'][remove_product] = False
customer.dct_prod_up_prod_stat[ customer.dct_prod_up_prod_stat[
prod]['status'].append(('D', self.model.t)) prod]['status'].append(('D', self.model.t))
customer.dct_n_trial_up_prod_removed[
remove_product] = 0
print(self.name, remove_product.code, 'affect', print(self.name, remove_product.code, 'affect',
customer.name, prod.code) customer.name, prod.code)
# print(customer.dct_prod_up_prod_stat)
def seek_alt_supply(self, product): def seek_alt_supply(self, product):
# para product is the product that self is seeking # para product is the product that self is seeking
@ -269,7 +258,6 @@ class FirmAgent(ap.Agent):
]) ])
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)
# down_firm.a_lst_up_product_removed.remove(product)
for prod in down_firm.dct_prod_up_prod_stat.keys(): for prod in down_firm.dct_prod_up_prod_stat.keys():
if product in down_firm.dct_prod_up_prod_stat[ if product in down_firm.dct_prod_up_prod_stat[
@ -278,7 +266,6 @@ class FirmAgent(ap.Agent):
prod]['supply'][product] = True prod]['supply'][product] = True
down_firm.dct_prod_up_prod_stat[ down_firm.dct_prod_up_prod_stat[
prod]['status'].append(('N', self.model.t)) prod]['status'].append(('N', self.model.t))
# print(down_firm.dct_prod_up_prod_stat)
del down_firm.dct_n_trial_up_prod_removed[product] del down_firm.dct_n_trial_up_prod_removed[product]
del down_firm.dct_cand_alt_supply_up_prod_removed[product] del down_firm.dct_cand_alt_supply_up_prod_removed[product]
@ -296,7 +283,6 @@ class FirmAgent(ap.Agent):
self.dct_n_trial_up_prod_removed = \ self.dct_n_trial_up_prod_removed = \
dict.fromkeys(self.dct_n_trial_up_prod_removed.keys(), 0) dict.fromkeys(self.dct_n_trial_up_prod_removed.keys(), 0)
self.dct_cand_alt_supply_up_prod_removed = {} self.dct_cand_alt_supply_up_prod_removed = {}
# self.a_lst_up_product_removed = ap.AgentList(self.model, [])
def get_firm_network_node(self): def get_firm_network_node(self):
return self.firm_network.positions[self] return self.firm_network.positions[self]

View File

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