sample removal + seek connect first
This commit is contained in:
parent
813a3cf2ff
commit
0e40f90559
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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
61
firm.py
|
@ -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]
|
||||
|
|
72
model.py
72
model.py
|
@ -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(
|
||||
|
|
BIN
network.png
BIN
network.png
Binary file not shown.
Before Width: | Height: | Size: 3.6 MiB After Width: | Height: | Size: 2.8 MiB |
4
orm.py
4
orm.py
|
@ -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)
|
||||
|
|
49
test.ipynb
49
test.ipynb
|
@ -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": {
|
||||
|
|
|
@ -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,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
|
||||
|
|
|
Loading…
Reference in New Issue