diff --git a/__pycache__/controller_db.cpython-38.pyc b/__pycache__/controller_db.cpython-38.pyc index 526c82d..77f8a4b 100644 Binary files a/__pycache__/controller_db.cpython-38.pyc and b/__pycache__/controller_db.cpython-38.pyc differ diff --git a/__pycache__/firm.cpython-38.pyc b/__pycache__/firm.cpython-38.pyc index 46f7a84..544c94f 100644 Binary files a/__pycache__/firm.cpython-38.pyc and b/__pycache__/firm.cpython-38.pyc differ diff --git a/__pycache__/model.cpython-38.pyc b/__pycache__/model.cpython-38.pyc index ddceffa..0bb9127 100644 Binary files a/__pycache__/model.cpython-38.pyc and b/__pycache__/model.cpython-38.pyc differ diff --git a/__pycache__/orm.cpython-38.pyc b/__pycache__/orm.cpython-38.pyc index 2005766..a1ab659 100644 Binary files a/__pycache__/orm.cpython-38.pyc and b/__pycache__/orm.cpython-38.pyc differ diff --git a/controller_db.py b/controller_db.py index 4931aa7..0b22ab3 100644 --- a/controller_db.py +++ b/controller_db.py @@ -74,7 +74,7 @@ class ControllerDB: # insert exp df_xv = pd.read_csv("xv.csv", index_col=None) # 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(): dct_exp_para = {} for idx_col, para_level in enumerate(row): @@ -91,7 +91,11 @@ class ControllerDB: f"init_removal {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( idx_scenario=idx_scenario, idx_init_removal=idx_init_removal, @@ -99,7 +103,16 @@ class ControllerDB: n_iter=int(self.dct_parameter['n_iter']), dct_lst_init_remove_firm_prod=dct_lst_init_remove_firm_prod, 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.commit() diff --git a/firm.py b/firm.py index 05c0b7e..b577e50 100644 --- a/firm.py +++ b/firm.py @@ -22,6 +22,12 @@ class FirmAgent(ap.Agent): self.dct_cand_alt_supply_up_prod_removed = {} 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): lst_out_edge = list( self.firm_network.graph.out_edges( @@ -41,7 +47,8 @@ class FirmAgent(ap.Agent): edge for edge in lst_in_edge 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], p=[prod_remove, 1 - prod_remove]): @@ -70,13 +77,13 @@ class FirmAgent(ap.Agent): if not self.dct_cand_alt_supply_up_prod_removed[product]: continue # select based on size - lst_prob = [ - size / - sum(self.dct_cand_alt_supply_up_prod_removed[ - product].revenue_log) - for size in self.dct_cand_alt_supply_up_prod_removed[ - product].revenue_log - ] + 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) @@ -132,10 +139,12 @@ class FirmAgent(ap.Agent): lst_firm_connect.append(firm) if len(lst_firm_connect) == 0: # handling based on size - lst_firm_size = [firm.revenue_log for firm in lst_firm] - lst_prob = [ - size / sum(lst_firm_size) for size in lst_firm_size - ] + lst_firm_size_damp = \ + [firm.revenue_log ** self.flt_firm_pref_accept + for firm in lst_firm] + 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) @@ -143,11 +152,12 @@ class FirmAgent(ap.Agent): self.accept_request(lst_firm_connect[0], product) elif len(lst_firm_connect) > 1: # handling based on size of firm that has connection - lst_firm_size = [ - firm.revenue_log for firm in lst_firm_connect] - lst_prob = [ - size / sum(lst_firm_size) for size in lst_firm_size - ] + lst_firm_size_damp = \ + [firm.revenue_log ** self.flt_firm_pref_accept + for firm in lst_firm_connect] + 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_connect, p=lst_prob) @@ -160,6 +170,8 @@ class FirmAgent(ap.Agent): and product not in firm.a_lst_product_removed ] 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], p=[prod_accept, 1 - prod_accept]): self.firm_network.graph.add_edges_from([ diff --git a/model.py b/model.py index 1c47f75..1c53064 100644 --- a/model.py +++ b/model.py @@ -17,9 +17,15 @@ class Model(ap.Model): 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.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.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 G_bom = nx.adjacency_graph(json.loads(self.p.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 lst_succ_firm = Firm['Code'][Firm[succ_product_code] == 1].to_list() - lst_succ_firm_size = [ - G_Firm.nodes[succ_firm]['Revenue_Log'] - for succ_firm in lst_succ_firm - ] - lst_prob = [ - size / sum(lst_succ_firm_size) - for size in lst_succ_firm_size - ] - # select multiple successors + 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_prob = \ + [size_damp / sum(lst_succ_firm_size_damp) + for size_damp in lst_succ_firm_size_damp + ] + # select multiple customer # based on relative size of this firm lst_same_prod_firm = Firm['Code'][Firm[product_code] == 1].to_list() @@ -69,6 +76,8 @@ 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, @@ -106,8 +115,10 @@ class Model(ap.Model): ])) # init extra capacity based on discrete uniform distribution for product in firm_agent.a_lst_product: - firm_agent.dct_prod_capacity[product] = self.nprandom.integers( - firm_agent.revenue_log / 5, firm_agent.revenue_log / 5 + 2) + firm_agent.dct_prod_capacity[product] = \ + 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.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( product.a_predecessors()) 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 - 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) + 1) / (max(lst_size) - min(lst_size) + 1) prod_remove = 1 - std_size * (1 - lost_percent) + # damp prod + prod_remove = prod_remove ** self.flt_diff_remove if self.nprandom.choice([True, False], p=[prod_remove, 1 - prod_remove]): diff --git a/oa.csv b/oa.csv index f2b804b..f139061 100644 --- a/oa.csv +++ b/oa.csv @@ -1,3 +1,2 @@ -X1 -0 -1 +X1,X2,X3,X4,X5,X6,X7,X8,X9 +1,1,1,1,1,1,1,1,1 diff --git a/orm.py b/orm.py index 3b90e57..6fd6b44 100644 --- a/orm.py +++ b/orm.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from sqlalchemy import create_engine, inspect 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) from sqlalchemy.sql import func from sqlalchemy.orm import relationship, Session @@ -53,7 +53,16 @@ class Experiment(Base): # variables dct_lst_init_remove_firm_prod = Column(PickleType, nullable=False) g_bom = Column(Text(4294000000), 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', back_populates='experiment', lazy='dynamic') diff --git a/xv.csv b/xv.csv index 1459667..564a51d 100644 --- a/xv.csv +++ b/xv.csv @@ -1,3 +1,4 @@ -n_max_trial -5 -10 +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 +12,2,2,2,0.5,2,4,0.5,0.5 +8,1,1,1,1,1,2,1,1 +4,0.5,0.5,0.5,2,0.5,0,2,2