experiments in model and firm py

This commit is contained in:
HaoYizhi 2023-05-15 18:18:41 +08:00
parent a5f278c4cb
commit 839e47cf0b
10 changed files with 90 additions and 41 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -74,7 +74,7 @@ class ControllerDB:
# insert exp # insert exp
df_xv = pd.read_csv("xv.csv", index_col=None) df_xv = pd.read_csv("xv.csv", index_col=None)
# read the OA table # read the OA table
df_oa = pd.read_fwf("oa.csv", index_col=None) df_oa = pd.read_csv("oa.csv", index_col=None)
for idx_scenario, row in df_oa.iterrows(): for idx_scenario, row in df_oa.iterrows():
dct_exp_para = {} dct_exp_para = {}
for idx_col, para_level in enumerate(row): for idx_col, para_level in enumerate(row):
@ -91,7 +91,11 @@ class ControllerDB:
f"init_removal {idx_init_removal}!") f"init_removal {idx_init_removal}!")
def add_experiment_1(self, idx_scenario, idx_init_removal, def add_experiment_1(self, idx_scenario, idx_init_removal,
dct_lst_init_remove_firm_prod, g_bom, n_max_trial): 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,
diff_remove,):
e = Experiment( e = Experiment(
idx_scenario=idx_scenario, idx_scenario=idx_scenario,
idx_init_removal=idx_init_removal, idx_init_removal=idx_init_removal,
@ -99,7 +103,16 @@ class ControllerDB:
n_iter=int(self.dct_parameter['n_iter']), n_iter=int(self.dct_parameter['n_iter']),
dct_lst_init_remove_firm_prod=dct_lst_init_remove_firm_prod, dct_lst_init_remove_firm_prod=dct_lst_init_remove_firm_prod,
g_bom=g_bom, g_bom=g_bom,
n_max_trial=n_max_trial) n_max_trial=n_max_trial,
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,
cap_limit=cap_limit,
diff_new_conn=diff_new_conn,
diff_remove=diff_remove,
)
db_session.add(e) db_session.add(e)
db_session.commit() db_session.commit()

44
firm.py
View File

@ -22,6 +22,12 @@ class FirmAgent(ap.Agent):
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
self.flt_crit_supplier = float(self.p.crit_supplier)
self.flt_firm_pref_request = float(self.p.firm_pref_request)
self.flt_firm_pref_accept = float(self.p.firm_pref_accept)
self.flt_diff_new_conn = float(self.p.diff_new_conn)
def remove_edge_to_cus_remove_cus_up_prod(self, remove_product): def remove_edge_to_cus_remove_cus_up_prod(self, remove_product):
lst_out_edge = list( lst_out_edge = list(
self.firm_network.graph.out_edges( self.firm_network.graph.out_edges(
@ -41,7 +47,8 @@ class FirmAgent(ap.Agent):
edge for edge in lst_in_edge edge for edge in lst_in_edge
if edge[-1] == remove_product.code if edge[-1] == remove_product.code
] ]
prod_remove = math.exp(-1 * len(lst_select_in_edge)) prod_remove = math.exp(-1 * self.flt_crit_supplier *
len(lst_select_in_edge))
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]):
@ -70,12 +77,12 @@ class FirmAgent(ap.Agent):
if not self.dct_cand_alt_supply_up_prod_removed[product]: if not self.dct_cand_alt_supply_up_prod_removed[product]:
continue continue
# select based on size # select based on size
lst_prob = [ lst_size_damp = \
size / [size ** self.flt_firm_pref_request for size in
sum(self.dct_cand_alt_supply_up_prod_removed[ self.dct_cand_alt_supply_up_prod_removed[
product].revenue_log) product].revenue_log]
for size in self.dct_cand_alt_supply_up_prod_removed[ lst_prob = [size_damp / sum(lst_size_damp)
product].revenue_log for size_damp in lst_size_damp
] ]
select_alt_supply = self.model.nprandom.choice( select_alt_supply = self.model.nprandom.choice(
self.dct_cand_alt_supply_up_prod_removed[product], self.dct_cand_alt_supply_up_prod_removed[product],
@ -132,10 +139,12 @@ class FirmAgent(ap.Agent):
lst_firm_connect.append(firm) lst_firm_connect.append(firm)
if len(lst_firm_connect) == 0: if len(lst_firm_connect) == 0:
# handling based on size # handling based on size
lst_firm_size = [firm.revenue_log for firm in lst_firm] lst_firm_size_damp = \
lst_prob = [ [firm.revenue_log ** self.flt_firm_pref_accept
size / sum(lst_firm_size) for size in lst_firm_size for firm in lst_firm]
] lst_prob = \
[size_damp / sum(lst_firm_size_damp)
for size_damp in lst_firm_size_damp]
select_customer = \ select_customer = \
self.model.nprandom.choice(lst_firm, p=lst_prob) self.model.nprandom.choice(lst_firm, p=lst_prob)
self.accept_request(select_customer, product) self.accept_request(select_customer, product)
@ -143,11 +152,12 @@ class FirmAgent(ap.Agent):
self.accept_request(lst_firm_connect[0], product) self.accept_request(lst_firm_connect[0], product)
elif len(lst_firm_connect) > 1: elif len(lst_firm_connect) > 1:
# handling based on size of firm that has connection # handling based on size of firm that has connection
lst_firm_size = [ lst_firm_size_damp = \
firm.revenue_log for firm in lst_firm_connect] [firm.revenue_log ** self.flt_firm_pref_accept
lst_prob = [ for firm in lst_firm_connect]
size / sum(lst_firm_size) for size in lst_firm_size lst_prob = \
] [size_damp / sum(lst_firm_size_damp)
for size_damp in lst_firm_size_damp]
select_customer = \ select_customer = \
self.model.nprandom.choice(lst_firm_connect, self.model.nprandom.choice(lst_firm_connect,
p=lst_prob) p=lst_prob)
@ -160,6 +170,8 @@ class FirmAgent(ap.Agent):
and product not in firm.a_lst_product_removed and product not in firm.a_lst_product_removed
] ]
prod_accept = self.revenue_log / sum(lst_firm_size) prod_accept = self.revenue_log / sum(lst_firm_size)
# damp prod
prod_accept = prod_accept ** self.flt_diff_new_conn
if self.model.nprandom.choice([True, False], if self.model.nprandom.choice([True, False],
p=[prod_accept, 1 - prod_accept]): p=[prod_accept, 1 - prod_accept]):
self.firm_network.graph.add_edges_from([ self.firm_network.graph.add_edges_from([

View File

@ -17,9 +17,15 @@ class Model(ap.Model):
self.random = random.Random(self.p.seed) self.random = random.Random(self.p.seed)
self.nprandom = np.random.default_rng(self.p.seed) self.nprandom = np.random.default_rng(self.p.seed)
self.int_n_iter = int(self.p.n_iter) self.int_n_iter = int(self.p.n_iter)
self.int_n_max_trial = int(self.p.n_max_trial)
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
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_cap_limit = int(self.p.cap_limit)
self.flt_diff_remove = float(self.p.diff_remove)
# init graph bom # init graph bom
G_bom = nx.adjacency_graph(json.loads(self.p.g_bom)) G_bom = nx.adjacency_graph(json.loads(self.p.g_bom))
self.product_network = ap.Network(self, G_bom) self.product_network = ap.Network(self, G_bom)
@ -51,15 +57,16 @@ class Model(ap.Model):
# get a list of firm producing this successor # get a list of firm producing this successor
lst_succ_firm = Firm['Code'][Firm[succ_product_code] == lst_succ_firm = Firm['Code'][Firm[succ_product_code] ==
1].to_list() 1].to_list()
lst_succ_firm_size = [ lst_succ_firm_size_damp = \
G_Firm.nodes[succ_firm]['Revenue_Log'] [G_Firm.nodes[succ_firm]['Revenue_Log'] **
self.flt_netw_pref_cust_size
for succ_firm in lst_succ_firm for succ_firm in lst_succ_firm
] ]
lst_prob = [ lst_prob = \
size / sum(lst_succ_firm_size) [size_damp / sum(lst_succ_firm_size_damp)
for size in lst_succ_firm_size for size_damp in lst_succ_firm_size_damp
] ]
# select multiple successors # select multiple customer
# based on relative size of this firm # based on relative size of this firm
lst_same_prod_firm = Firm['Code'][Firm[product_code] == lst_same_prod_firm = Firm['Code'][Firm[product_code] ==
1].to_list() 1].to_list()
@ -69,6 +76,8 @@ class Model(ap.Model):
] ]
share = G_Firm.nodes[node]['Revenue_Log'] / sum( share = G_Firm.nodes[node]['Revenue_Log'] / sum(
lst_same_prod_firm_size) 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( n_succ_firm = round(share * len(lst_succ_firm)) if round(
share * len(lst_succ_firm)) > 0 else 1 # at least one share * len(lst_succ_firm)) > 0 else 1 # at least one
lst_choose_firm = self.nprandom.choice(lst_succ_firm, lst_choose_firm = self.nprandom.choice(lst_succ_firm,
@ -106,8 +115,10 @@ class Model(ap.Model):
])) ]))
# init extra capacity based on discrete uniform distribution # init extra capacity based on discrete uniform distribution
for product in firm_agent.a_lst_product: for product in firm_agent.a_lst_product:
firm_agent.dct_prod_capacity[product] = self.nprandom.integers( firm_agent.dct_prod_capacity[product] = \
firm_agent.revenue_log / 5, firm_agent.revenue_log / 5 + 2) self.nprandom.integers(firm_agent.revenue_log / 5,
firm_agent.revenue_log / 5 +
self.flt_cap_limit)
self.firm_network.add_agents([firm_agent], [ag_node]) self.firm_network.add_agents([firm_agent], [ag_node])
self.a_lst_total_firms = ap.AgentList(self, self.firm_network.agents) self.a_lst_total_firms = ap.AgentList(self, self.firm_network.agents)
@ -220,13 +231,17 @@ class Model(ap.Model):
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.revenue_log lst_size = self.a_lst_total_firms.revenue_log
lst_size = [firm.revenue_log for firm in self.a_lst_total_firms lst_size = [firm.revenue_log for firm
in self.a_lst_total_firms
if product in firm.a_lst_product if product in firm.a_lst_product
and product not in firm.a_lst_product_removed and product
not in firm.a_lst_product_removed
] ]
std_size = (firm.revenue_log - min(lst_size) + std_size = (firm.revenue_log - min(lst_size) +
1) / (max(lst_size) - min(lst_size) + 1) 1) / (max(lst_size) - min(lst_size) + 1)
prod_remove = 1 - std_size * (1 - lost_percent) prod_remove = 1 - std_size * (1 - lost_percent)
# damp prod
prod_remove = prod_remove ** self.flt_diff_remove
if self.nprandom.choice([True, False], if self.nprandom.choice([True, False],
p=[prod_remove, p=[prod_remove,
1 - prod_remove]): 1 - prod_remove]):

5
oa.csv
View File

@ -1,3 +1,2 @@
X1 X1,X2,X3,X4,X5,X6,X7,X8,X9
0 1,1,1,1,1,1,1,1,1
1

1 X1 X2 X3 X4 X5 X6 X7 X8 X9
2 0 1 1 1 1 1 1 1 1 1
1

11
orm.py
View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from sqlalchemy import create_engine, inspect from sqlalchemy import create_engine, inspect
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import (Column, Integer, String, ForeignKey, BigInteger, from sqlalchemy import (Column, Integer, DECIMAL, String, ForeignKey, BigInteger,
DateTime, PickleType, Boolean, Text) DateTime, PickleType, Boolean, Text)
from sqlalchemy.sql import func from sqlalchemy.sql import func
from sqlalchemy.orm import relationship, Session from sqlalchemy.orm import relationship, Session
@ -53,7 +53,16 @@ class Experiment(Base):
# variables # variables
dct_lst_init_remove_firm_prod = Column(PickleType, nullable=False) dct_lst_init_remove_firm_prod = Column(PickleType, nullable=False)
g_bom = Column(Text(4294000000), nullable=False) g_bom = Column(Text(4294000000), nullable=False)
n_max_trial = Column(Integer, nullable=False) n_max_trial = Column(Integer, nullable=False)
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)
cap_limit = Column(Integer, nullable=False)
diff_new_conn = Column(DECIMAL(8, 4), nullable=False)
diff_remove = Column(DECIMAL(8, 4), nullable=False)
sample = relationship( sample = relationship(
'Sample', back_populates='experiment', lazy='dynamic') 'Sample', back_populates='experiment', lazy='dynamic')

7
xv.csv
View File

@ -1,3 +1,4 @@
n_max_trial 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
5 12,2,2,2,0.5,2,4,0.5,0.5
10 8,1,1,1,1,1,2,1,1
4,0.5,0.5,0.5,2,0.5,0,2,2

1 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
2 5 12 2 2 2 0.5 2 4 0.5 0.5
3 10 8 1 1 1 1 1 2 1 1
4 4 0.5 0.5 0.5 2 0.5 0 2 2