remove crit_supplier
This commit is contained in:
96
firm.py
96
firm.py
@@ -1,5 +1,4 @@
|
||||
import agentpy as ap
|
||||
import math
|
||||
|
||||
|
||||
class FirmAgent(ap.Agent):
|
||||
@@ -26,7 +25,6 @@ class FirmAgent(ap.Agent):
|
||||
self.str_cap_limit_prob_type = str(self.p.cap_limit_prob_type)
|
||||
self.flt_cap_limit_level = float(self.p.cap_limit_level)
|
||||
self.flt_diff_new_conn = float(self.p.diff_new_conn)
|
||||
self.flt_crit_supplier = float(self.p.crit_supplier)
|
||||
|
||||
# init size_stat (self para)
|
||||
# (size, time step)
|
||||
@@ -36,9 +34,14 @@ class FirmAgent(ap.Agent):
|
||||
for prod in a_lst_product:
|
||||
self.dct_prod_up_prod_stat[prod] = {
|
||||
# (Normal / Disrupted / Removed, time step)
|
||||
'status': [('N', 0)],
|
||||
'p_stat': [('N', 0)],
|
||||
# have or have no supply
|
||||
'supply': dict.fromkeys(prod.a_predecessors(), True)
|
||||
'supply': dict.fromkeys(prod.a_predecessors(), True),
|
||||
# supply for each component and respective disrupted supplier
|
||||
# lst_disrupt_firm is refreshed to [] at each update
|
||||
's_stat': dict.fromkeys(prod.a_predecessors(),
|
||||
{'stat': True,
|
||||
'lst_disrupt_firm': []})
|
||||
}
|
||||
|
||||
# init extra capacity (self para)
|
||||
@@ -62,45 +65,58 @@ class FirmAgent(ap.Agent):
|
||||
# print(firm_agent.name, extra_cap)
|
||||
self.dct_prod_capacity[product] = extra_cap
|
||||
|
||||
def remove_edge_to_cus_disrupt_cus_up_prod(self, disrupted_prod):
|
||||
def remove_edge_to_cus(self, disrupted_prod):
|
||||
# para disrupted_prod is the product that self got disrupted
|
||||
lst_out_edge = list(
|
||||
self.firm_network.graph.out_edges(
|
||||
self.firm_network.positions[self], keys=True, data='Product'))
|
||||
for n1, n2, key, product_code in lst_out_edge:
|
||||
if product_code == disrupted_prod.code:
|
||||
# update customer up product supplier status
|
||||
customer = ap.AgentIter(self.model, n2).to_list()[0]
|
||||
for prod in customer.dct_prod_up_prod_stat.keys():
|
||||
if disrupted_prod in \
|
||||
customer.dct_prod_up_prod_stat[
|
||||
prod]['s_stat'].keys():
|
||||
if self not in customer.dct_prod_up_prod_stat[
|
||||
prod]['s_stat'][disrupted_prod][
|
||||
'lst_disrupt_firm']:
|
||||
customer.dct_prod_up_prod_stat[
|
||||
prod]['s_stat'][disrupted_prod][
|
||||
'lst_disrupt_firm'].append(self)
|
||||
# remove edge to customer
|
||||
self.firm_network.graph.remove_edge(n1, n2, key)
|
||||
|
||||
# customer up product affected conditionally
|
||||
customer = ap.AgentIter(self.model, n2).to_list()[0]
|
||||
lst_in_edge = list(
|
||||
self.firm_network.graph.in_edges(n2,
|
||||
keys=True,
|
||||
data='Product'))
|
||||
lst_select_in_edge = [
|
||||
edge for edge in lst_in_edge
|
||||
if edge[-1] == disrupted_prod.code
|
||||
]
|
||||
prob_lost_supp = math.exp(-1 * self.flt_crit_supplier *
|
||||
len(lst_select_in_edge))
|
||||
if self.model.nprandom.choice([True, False],
|
||||
p=[prob_lost_supp,
|
||||
1 - prob_lost_supp]):
|
||||
customer.dct_n_trial_up_prod_disrupted[disrupted_prod] = 0
|
||||
for prod in customer.dct_prod_up_prod_stat.keys():
|
||||
if disrupted_prod in \
|
||||
customer.dct_prod_up_prod_stat[
|
||||
prod]['supply'].keys():
|
||||
customer.dct_prod_up_prod_stat[
|
||||
prod]['supply'][disrupted_prod] = False
|
||||
status, _ = customer.dct_prod_up_prod_stat[
|
||||
prod]['status'][-1]
|
||||
if status != 'D':
|
||||
customer.dct_prod_up_prod_stat[
|
||||
prod]['status'].append(('D', self.model.t))
|
||||
# print(self.name, disrupted_prod.code, 'disrupt',
|
||||
# customer.name, prod.code)
|
||||
def disrupt_cus_prod(self, prod, disrupted_up_prod):
|
||||
# para prod is the product that has disrupted_up_prod
|
||||
# para disrupted_up_prod is the product that
|
||||
# self's component exists disrupted supplier
|
||||
num_lost = \
|
||||
len(self.dct_prod_up_prod_stat[prod]['s_stat']
|
||||
[disrupted_up_prod]['lst_disrupt_firm'])
|
||||
num_remain = \
|
||||
len([u for u, _, _, d in
|
||||
self.firm_network.graph.in_edges(self.get_firm_network_node(),
|
||||
keys=True,
|
||||
data='Product')
|
||||
if d == disrupted_up_prod.code])
|
||||
lost_percent = num_lost / (num_lost + num_remain)
|
||||
lst_size = \
|
||||
[firm.size_stat[-1][0] for firm in self.model.a_lst_total_firms]
|
||||
std_size = (self.size_stat[-1][0] - min(lst_size) + 1) \
|
||||
/ (max(lst_size) - min(lst_size) + 1)
|
||||
prob_disrupt = 1 - std_size * (1 - lost_percent)
|
||||
if self.model.nprandom.choice([True, False],
|
||||
p=[prob_disrupt,
|
||||
1 - prob_disrupt]):
|
||||
self.dct_n_trial_up_prod_disrupted[disrupted_up_prod] = 0
|
||||
self.dct_prod_up_prod_stat[
|
||||
prod]['s_stat'][disrupted_up_prod]['stat'] = False
|
||||
status, _ = self.dct_prod_up_prod_stat[
|
||||
prod]['p_stat'][-1]
|
||||
if status != 'D':
|
||||
self.dct_prod_up_prod_stat[
|
||||
prod]['p_stat'].append(('D', self.model.t))
|
||||
|
||||
def seek_alt_supply(self, product):
|
||||
# para product is the product that self is seeking
|
||||
@@ -270,7 +286,7 @@ class FirmAgent(ap.Agent):
|
||||
down_firm.dct_prod_up_prod_stat[
|
||||
prod]['supply'][product] = True
|
||||
down_firm.dct_prod_up_prod_stat[
|
||||
prod]['status'].append(('N', self.model.t))
|
||||
prod]['p_stat'].append(('N', self.model.t))
|
||||
del down_firm.dct_n_trial_up_prod_disrupted[product]
|
||||
del down_firm.dct_cand_alt_supp_up_prod_disrupted[product]
|
||||
|
||||
@@ -296,17 +312,21 @@ class FirmAgent(ap.Agent):
|
||||
|
||||
# update the status of firm
|
||||
for prod in self.dct_prod_up_prod_stat.keys():
|
||||
status, ts = self.dct_prod_up_prod_stat[prod]['status'][-1]
|
||||
status, ts = self.dct_prod_up_prod_stat[prod]['p_stat'][-1]
|
||||
if ts != self.model.t:
|
||||
self.dct_prod_up_prod_stat[prod]['status'].append(
|
||||
self.dct_prod_up_prod_stat[prod]['p_stat'].append(
|
||||
(status, self.model.t))
|
||||
# refresh lst_disrupt_firm
|
||||
for up_prod in self.dct_prod_up_prod_stat[prod]['s_stat'].keys():
|
||||
self.dct_prod_up_prod_stat[prod][
|
||||
's_stat'][up_prod]['lst_disrupt_firm'] = []
|
||||
|
||||
def get_firm_network_node(self):
|
||||
return self.firm_network.positions[self]
|
||||
|
||||
def is_prod_in_current_normal(self, prod):
|
||||
if prod in self.dct_prod_up_prod_stat.keys():
|
||||
if self.dct_prod_up_prod_stat[prod]['status'][-1][0] == 'N':
|
||||
if self.dct_prod_up_prod_stat[prod]['p_stat'][-1][0] == 'N':
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user