dct_prod_up_prod_stat + no need for dct_list_remove_firm_prod/dct_list_disrupt_firm_prod

This commit is contained in:
2023-06-18 17:29:11 +08:00
parent 09ea2e9527
commit dd8a786f6c
8 changed files with 247 additions and 129 deletions

128
firm.py
View File

@@ -14,10 +14,20 @@ class FirmAgent(ap.Agent):
self.a_lst_product = a_lst_product
self.dct_prod_capacity = dict.fromkeys(self.a_lst_product)
self.a_lst_up_product_removed = ap.AgentList(self.model, [])
self.a_lst_product_disrupted = ap.AgentList(self.model, [])
# self.a_lst_up_product_removed = ap.AgentList(self.model, [])
# 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_cand_alt_supply_up_prod_removed = {}
self.dct_request_prod_from_firm = {}
@@ -52,30 +62,43 @@ class FirmAgent(ap.Agent):
if self.model.nprandom.choice([True, False],
p=[prod_remove,
1 - prod_remove]):
# print(self.name, remove_product.code, 'affect',
# customer.name)
if remove_product not in \
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
# if remove_product not in \
# 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
def seek_alt_supply(self):
for product in self.a_lst_up_product_removed:
# print(f"{self.name} seek alt supply for {product.code}")
if self.dct_n_trial_up_prod_removed[
product] <= self.model.int_n_max_trial:
if self.dct_n_trial_up_prod_removed[product] == 0:
# select a list of candidate firm that has the product
self.dct_cand_alt_supply_up_prod_removed[product] = \
self.model.a_lst_total_firms.select([
product in firm.a_lst_product
and product not in firm.a_lst_product_removed
for firm in self.model.a_lst_total_firms
])
if not self.dct_cand_alt_supply_up_prod_removed[product]:
continue
for prod in customer.dct_prod_up_prod_stat.keys():
if remove_product in \
customer.dct_prod_up_prod_stat[
prod]['supply'].keys():
customer.dct_prod_up_prod_stat[
prod]['supply'][remove_product] = False
customer.dct_prod_up_prod_stat[
prod]['status'].append(('D', self.model.t))
customer.dct_n_trial_up_prod_removed[
remove_product] = 0
print(self.name, remove_product.code, 'affect',
customer.name, prod.code)
# print(customer.dct_prod_up_prod_stat)
def seek_alt_supply(self, product):
# para product is the product that self is seeking
# for product in self.a_lst_up_product_removed:
print(f"{self.name} seek alt supply for {product.code}")
if self.dct_n_trial_up_prod_removed[
product] <= self.model.int_n_max_trial:
if self.dct_n_trial_up_prod_removed[product] == 0:
# select a list of candidate firm that has the product
self.dct_cand_alt_supply_up_prod_removed[product] = \
self.model.a_lst_total_firms.select([
product in firm.a_lst_product
and product not in firm.a_lst_product_removed
for firm in self.model.a_lst_total_firms
])
if self.dct_cand_alt_supply_up_prod_removed[product]:
# select based on connection
lst_firm_connect = []
if self.is_prf_conn:
@@ -99,8 +122,8 @@ class FirmAgent(ap.Agent):
if self.is_prf_size:
lst_size = \
[size for size in
self.dct_cand_alt_supply_up_prod_removed[
product].revenue_log]
self.dct_cand_alt_supply_up_prod_removed[
product].revenue_log]
lst_prob = [size / sum(lst_size)
for size in lst_size]
select_alt_supply = self.model.nprandom.choice(
@@ -123,10 +146,10 @@ class FirmAgent(ap.Agent):
else:
select_alt_supply = \
self.model.nprandom.choice(lst_firm_connect)
# print(
# f"{self.name} selct alt supply for {product.code} "
# f"from {select_alt_supply.name}"
# )
print(
f"{self.name} selct alt supply for {product.code} "
f"from {select_alt_supply.name}"
)
assert product in select_alt_supply.a_lst_product, \
f"{select_alt_supply} \
does not produce requested product {product}"
@@ -139,17 +162,17 @@ class FirmAgent(ap.Agent):
select_alt_supply.dct_request_prod_from_firm[product] = [
self
]
# print(
# select_alt_supply.name, 'dct_request_prod_from_firm', {
# key.code: [v.name for v in value]
# for key, value in
# select_alt_supply.dct_request_prod_from_firm.items()
# })
print(
select_alt_supply.name, 'dct_request_prod_from_firm', {
key.code: [v.name for v in value]
for key, value in
select_alt_supply.dct_request_prod_from_firm.items()
})
self.dct_n_trial_up_prod_removed[product] += 1
def handle_request(self):
# print(self.name, 'handle_request')
print(self.name, 'handle_request')
for product, lst_firm in self.dct_request_prod_from_firm.items():
if self.dct_prod_capacity[product] > 0:
if len(lst_firm) == 0:
@@ -210,6 +233,7 @@ class FirmAgent(ap.Agent):
self.accept_request(select_customer, product)
def accept_request(self, down_firm, product):
# para product is the product that self is selling
prod_accept = self.flt_diff_new_conn
if self.model.nprandom.choice([True, False],
p=[prod_accept, 1 - prod_accept]):
@@ -221,11 +245,23 @@ class FirmAgent(ap.Agent):
])
self.dct_prod_capacity[product] -= 1
self.dct_request_prod_from_firm[product].remove(down_firm)
down_firm.a_lst_up_product_removed.remove(product)
# print(
# f"{self.name} accept {product.code} request "
# f"from {down_firm.name}"
# )
# down_firm.a_lst_up_product_removed.remove(product)
for prod in down_firm.dct_prod_up_prod_stat.keys():
if product in down_firm.dct_prod_up_prod_stat[
prod]['supply'].keys():
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))
# print(down_firm.dct_prod_up_prod_stat)
del down_firm.dct_n_trial_up_prod_removed[product]
del down_firm.dct_cand_alt_supply_up_prod_removed[product]
print(
f"{self.name} accept {product.code} request "
f"from {down_firm.name}"
)
else:
down_firm.dct_cand_alt_supply_up_prod_removed[product].remove(self)
@@ -233,8 +269,10 @@ class FirmAgent(ap.Agent):
self.dct_request_prod_from_firm = {}
def clean_before_time_step(self):
self.dct_n_trial_up_prod_removed = {}
self.a_lst_up_product_removed = ap.AgentList(self.model, [])
self.dct_n_trial_up_prod_removed = \
dict.fromkeys(self.dct_n_trial_up_prod_removed.keys(), 0)
self.dct_cand_alt_supply_up_prod_removed = {}
# self.a_lst_up_product_removed = ap.AgentList(self.model, [])
def get_firm_network_node(self):
return self.firm_network.positions[self]