sample removal + seek connect first

This commit is contained in:
HaoYizhi 2023-06-10 18:59:38 +08:00
parent 813a3cf2ff
commit 0e40f90559
12 changed files with 142 additions and 58 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -113,8 +113,8 @@ class ControllerDB:
def add_experiment_1(self, idx_scenario, idx_init_removal,
dct_lst_init_remove_firm_prod, g_bom,
n_max_trial, crit_supplier, firm_pref_request,
firm_pref_accept, netw_pref_cust_n,
netw_pref_cust_size, cap_limit, diff_new_conn,
firm_pref_accept, netw_pref_supp_n,
netw_pref_supp_size, cap_limit, diff_new_conn,
diff_remove, proactive_ratio):
e = Experiment(
idx_scenario=idx_scenario,
@ -127,8 +127,8 @@ class ControllerDB:
crit_supplier=crit_supplier,
firm_pref_request=firm_pref_request,
firm_pref_accept=firm_pref_accept,
netw_pref_cust_n=netw_pref_cust_n,
netw_pref_cust_size=netw_pref_cust_size,
netw_pref_supp_n=netw_pref_supp_n,
netw_pref_supp_size=netw_pref_supp_size,
cap_limit=cap_limit,
diff_new_conn=diff_new_conn,
diff_remove=diff_remove,

61
firm.py
View File

@ -76,17 +76,44 @@ class FirmAgent(ap.Agent):
])
if not self.dct_cand_alt_supply_up_prod_removed[product]:
continue
# select based on size
lst_size_damp = \
[size ** self.flt_firm_pref_request for size in
self.dct_cand_alt_supply_up_prod_removed[
product].revenue_log]
lst_prob = [size_damp / sum(lst_size_damp)
for size_damp in lst_size_damp
]
select_alt_supply = self.model.nprandom.choice(
self.dct_cand_alt_supply_up_prod_removed[product],
p=lst_prob)
# select based on connection
lst_firm_connect = []
for firm in self.dct_cand_alt_supply_up_prod_removed[product]:
out_edges = self.model.firm_network.graph.out_edges(
self.model.firm_network.positions[firm], keys=True)
in_edges = self.model.firm_network.graph.in_edges(
self.model.firm_network.positions[firm], keys=True)
lst_adj_firm = []
lst_adj_firm += \
[ap.AgentIter(self.model, edge[1]).to_list()[
0].code for edge in out_edges]
lst_adj_firm += \
[ap.AgentIter(self.model, edge[0]).to_list()[
0].code for edge in in_edges]
if self.code in lst_adj_firm:
lst_firm_connect.append(firm)
if len(lst_firm_connect) == 0:
# select based on size
lst_size_damp = \
[size ** self.flt_firm_pref_request for size in
self.dct_cand_alt_supply_up_prod_removed[
product].revenue_log]
lst_prob = [size_damp / sum(lst_size_damp)
for size_damp in lst_size_damp]
select_alt_supply = self.model.nprandom.choice(
self.dct_cand_alt_supply_up_prod_removed[product],
p=lst_prob)
elif len(lst_firm_connect) > 0:
# select based on size of firm that has connection
lst_firm_size_damp = \
[size ** self.flt_firm_pref_accept
for size in lst_firm_connect.revenue_log]
lst_prob = \
[size_damp / sum(lst_firm_size_damp)
for size_damp in lst_firm_size_damp]
select_alt_supply = \
self.model.nprandom.choice(lst_firm_connect,
p=lst_prob)
# print(
# f"{self.name} selct alt supply for {product.code} "
# f"from {select_alt_supply.name}"
@ -140,21 +167,19 @@ class FirmAgent(ap.Agent):
if len(lst_firm_connect) == 0:
# handling based on size
lst_firm_size_damp = \
[firm.revenue_log ** self.flt_firm_pref_accept
for firm in lst_firm]
[size ** self.flt_firm_pref_accept
for size in lst_firm.revenue_log]
lst_prob = \
[size_damp / sum(lst_firm_size_damp)
for size_damp in lst_firm_size_damp]
select_customer = \
self.model.nprandom.choice(lst_firm, p=lst_prob)
self.accept_request(select_customer, product)
elif len(lst_firm_connect) == 1:
self.accept_request(lst_firm_connect[0], product)
elif len(lst_firm_connect) > 1:
elif len(lst_firm_connect) > 0:
# handling based on size of firm that has connection
lst_firm_size_damp = \
[firm.revenue_log ** self.flt_firm_pref_accept
for firm in lst_firm_connect]
[size ** self.flt_firm_pref_accept
for size in lst_firm_connect.revenue_log]
lst_prob = \
[size_damp / sum(lst_firm_size_damp)
for size_damp in lst_firm_size_damp]

View File

@ -1,7 +1,7 @@
import agentpy as ap
import pandas as pd
import numpy as np
import random
# import random
import networkx as nx
from firm import FirmAgent
from product import ProductAgent
@ -14,15 +14,15 @@ class Model(ap.Model):
def setup(self):
self.sample = self.p.sample
self.int_stop_times, self.int_stop_t = 0, None
self.random = random.Random(self.p.seed)
# self.random = random.Random(self.p.seed)
self.nprandom = np.random.default_rng(self.p.seed)
self.int_n_iter = int(self.p.n_iter)
self.dct_lst_remove_firm_prod = self.p.dct_lst_init_remove_firm_prod
self.int_n_max_trial = int(self.p.n_max_trial)
self.flt_netw_pref_cust_n = float(self.p.netw_pref_cust_n)
self.flt_netw_pref_cust_size = float(self.p.netw_pref_cust_size)
self.flt_netw_pref_supp_n = float(self.p.netw_pref_supp_n)
self.flt_netw_pref_supp_size = float(self.p.netw_pref_supp_size)
self.flt_cap_limit = int(self.p.cap_limit)
self.flt_diff_remove = float(self.p.diff_remove)
self.proactive_ratio = float(self.p.proactive_ratio)
@ -69,22 +69,23 @@ class Model(ap.Model):
# 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']:
for succ_product_code in list(G_bom.successors(product_code)):
for pred_product_code in \
list(G_bom.predecessors(product_code)):
# for each product of a certain firm
# get each successor (finished product) of this product
# get a list of firm producing this successor
lst_succ_firm = Firm['Code'][Firm[succ_product_code] ==
# get each predecessor (component) of this product
# get a list of firm producing this component
lst_pred_firm = Firm['Code'][Firm[pred_product_code] ==
1].to_list()
lst_succ_firm_size_damp = \
[G_Firm.nodes[succ_firm]['Revenue_Log'] **
self.flt_netw_pref_cust_size
for succ_firm in lst_succ_firm
lst_pred_firm_size_damp = \
[G_Firm.nodes[pred_firm]['Revenue_Log'] **
self.flt_netw_pref_supp_size
for pred_firm in lst_pred_firm
]
lst_prob = \
[size_damp / sum(lst_succ_firm_size_damp)
for size_damp in lst_succ_firm_size_damp
[size_damp / sum(lst_pred_firm_size_damp)
for size_damp in lst_pred_firm_size_damp
]
# select multiple customer
# select multiple supplier
# based on relative size of this firm
lst_same_prod_firm = Firm['Code'][Firm[product_code] ==
1].to_list()
@ -95,27 +96,31 @@ class Model(ap.Model):
share = G_Firm.nodes[node]['Revenue_Log'] / sum(
lst_same_prod_firm_size)
# damp share
share = share ** self.flt_netw_pref_cust_n
n_succ_firm = round(share * len(lst_succ_firm)) if round(
share * len(lst_succ_firm)) > 0 else 1 # at least one
lst_choose_firm = self.nprandom.choice(lst_succ_firm,
n_succ_firm,
share = share ** self.flt_netw_pref_supp_n
n_pred_firm = round(share * len(lst_pred_firm)) if round(
share * len(lst_pred_firm)) > 0 else 1 # at least one
lst_choose_firm = self.nprandom.choice(lst_pred_firm,
n_pred_firm,
replace=False,
p=lst_prob)
lst_add_edge = [(node, succ_firm, {
lst_add_edge = [(node, pred_firm, {
'Product': product_code
}) for succ_firm in lst_choose_firm]
}) for pred_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)
for pred_firm in lst_choose_firm:
pred_node = [n for n, v in G_FirmProd.nodes(data=True)
if v['Firm_Code'] == pred_firm and
v['Product_Code'] == pred_product_code][0]
G_FirmProd.add_edge(pred_node, pred_node)
# unconnected node
# for node in nx.nodes(G_Firm):
# if node.
self.sample.g_firm = json.dumps(nx.adjacency_data(G_Firm))
self.firm_network = ap.Network(self, G_Firm)
@ -367,12 +372,17 @@ class Model(ap.Model):
]
std_size = (firm.revenue_log - min(lst_size) +
1) / (max(lst_size) - min(lst_size) + 1)
prod_remove = 1 - std_size * (1 - lost_percent)
prob_remove = 1 - std_size * (1 - lost_percent)
# sample prob
prob_remove = self.nprandom.uniform(
prob_remove - 0.1, prob_remove + 0.1)
prob_remove = 1 if prob_remove > 1 else prob_remove
prob_remove = 0 if prob_remove < 0 else prob_remove
# damp prod
prod_remove = prod_remove ** self.flt_diff_remove
prob_remove = prob_remove ** self.flt_diff_remove
if self.nprandom.choice([True, False],
p=[prod_remove,
1 - prod_remove]):
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(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

After

Width:  |  Height:  |  Size: 2.8 MiB

4
orm.py
View File

@ -58,8 +58,8 @@ class Experiment(Base):
crit_supplier = Column(DECIMAL(8, 4), nullable=False)
firm_pref_request = Column(DECIMAL(8, 4), nullable=False)
firm_pref_accept = Column(DECIMAL(8, 4), nullable=False)
netw_pref_cust_n = Column(DECIMAL(8, 4), nullable=False)
netw_pref_cust_size = Column(DECIMAL(8, 4), nullable=False)
netw_pref_supp_n = Column(DECIMAL(8, 4), nullable=False)
netw_pref_supp_size = Column(DECIMAL(8, 4), nullable=False)
cap_limit = Column(Integer, nullable=False)
diff_new_conn = Column(DECIMAL(8, 4), nullable=False)
diff_remove = Column(DECIMAL(8, 4), nullable=False)

View File

@ -168,6 +168,55 @@
"list_dct = result.loc[result['count']>=9, 'dct_lst_init_remove_firm_prod'].to_list()\n",
"print(len(list_dct))"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"ename": "ValueError",
"evalue": "probabilities do not sum to 1",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[2], line 3\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[39mimport\u001b[39;00m \u001b[39mnumpy\u001b[39;00m \u001b[39mas\u001b[39;00m \u001b[39mnp\u001b[39;00m\n\u001b[1;32m----> 3\u001b[0m np\u001b[39m.\u001b[39;49mrandom\u001b[39m.\u001b[39;49mchoice([\u001b[39m1\u001b[39;49m], p\u001b[39m=\u001b[39;49m[\u001b[39m0.9\u001b[39;49m])\n",
"File \u001b[1;32mmtrand.pyx:933\u001b[0m, in \u001b[0;36mnumpy.random.mtrand.RandomState.choice\u001b[1;34m()\u001b[0m\n",
"\u001b[1;31mValueError\u001b[0m: probabilities do not sum to 1"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"np.random.choice([1], p=[0.9])"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.004495606232695251"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"prob_remove = 0\n",
"prob_remove = np.random.uniform(\n",
" prob_remove - 0.1, prob_remove + 0.1)\n",
"prob_remove = 1 if prob_remove > 1 else prob_remove\n",
"prob_remove = 0 if prob_remove < 0 else prob_remove\n",
"prob_remove"
]
}
],
"metadata": {

View File

@ -1,4 +1,4 @@
n_max_trial,crit_supplier,firm_pref_request,firm_pref_accept,netw_pref_cust_n,netw_pref_cust_size,cap_limit,diff_new_conn,diff_remove,proactive_ratio
n_max_trial,crit_supplier,firm_pref_request,firm_pref_accept,netw_pref_supp_n,netw_pref_supp_size,cap_limit,diff_new_conn,diff_remove,proactive_ratio
15,2,2,2,0.5,2,4,0.5,0.5,0.4
10,1,1,1,1,1,2,1,1,0.6
5,0.5,0.5,0.5,2,0.5,1,2,2,0.8

1 n_max_trial crit_supplier firm_pref_request firm_pref_accept netw_pref_cust_n netw_pref_supp_n netw_pref_cust_size netw_pref_supp_size cap_limit diff_new_conn diff_remove proactive_ratio
2 15 2 2 2 0.5 0.5 2 2 4 0.5 0.5 0.4
3 10 1 1 1 1 1 1 1 2 1 1 0.6
4 5 0.5 0.5 0.5 2 2 0.5 0.5 1 2 2 0.8

View File

@ -1,2 +1,2 @@
n_max_trial,crit_supplier,firm_pref_request,firm_pref_accept,netw_pref_cust_n,netw_pref_cust_size,cap_limit,diff_new_conn,diff_remove,proactive_ratio
10,1,1,1,1,1,2,1,1,0
n_max_trial,crit_supplier,firm_pref_request,firm_pref_accept,netw_pref_supp_n,netw_pref_supp_size,cap_limit,diff_new_conn,diff_remove,proactive_ratio
10,1,1,1,1,1,2,1,1,0.8

1 n_max_trial crit_supplier firm_pref_request firm_pref_accept netw_pref_cust_n netw_pref_supp_n netw_pref_cust_size netw_pref_supp_size cap_limit diff_new_conn diff_remove proactive_ratio
2 10 1 1 1 1 1 1 1 2 1 1 0 0.8