diff --git a/.vscode/launch.json b/.vscode/launch.json index 9e95ab0..2c06221 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,9 +8,13 @@ "name": "Python: Current File", "type": "python", "request": "launch", - "program": "C:\\Users\\ASUS\\OneDrive\\Project\\ScrAbm\\Dissertation\\IIabm\\analysis.py", + "program": "C:\\Users\\ASUS\\OneDrive\\Project\\ScrAbm\\Dissertation\\IIabm\\main.py", "console": "integratedTerminal", - "justMyCode": true + "justMyCode": true, + "args": [ + "--exp", "test", + "--reset_db", "True" + ] } ] } \ No newline at end of file diff --git a/__pycache__/computation.cpython-38.pyc b/__pycache__/computation.cpython-38.pyc index 7da4cf3..a9c3639 100644 Binary files a/__pycache__/computation.cpython-38.pyc and b/__pycache__/computation.cpython-38.pyc differ diff --git a/__pycache__/controller_db.cpython-38.pyc b/__pycache__/controller_db.cpython-38.pyc index c56b41c..e923c1b 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 f81d560..6edc95e 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 7f42806..2d9380b 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 4a7776e..9097824 100644 Binary files a/__pycache__/orm.cpython-38.pyc and b/__pycache__/orm.cpython-38.pyc differ diff --git a/__pycache__/product.cpython-38.pyc b/__pycache__/product.cpython-38.pyc index 7dbec77..e37a3c6 100644 Binary files a/__pycache__/product.cpython-38.pyc and b/__pycache__/product.cpython-38.pyc differ diff --git a/computation.py b/computation.py index f7e4f28..d7953e7 100644 --- a/computation.py +++ b/computation.py @@ -6,7 +6,7 @@ from model import Model from typing import TYPE_CHECKING if TYPE_CHECKING: from controller_db import ControllerDB - + class Computation: @@ -21,7 +21,8 @@ class Computation: # lock this row by update is_done_flag to 0 self.c_db.lock_the_sample(sample_random) - print(f"Pid {self.pid} ({str_code}) is running sample {sample_random.id} at {datetime.datetime.now()}") + print( + f"Pid {self.pid} ({str_code}) is running sample {sample_random.id} at {datetime.datetime.now()}") dct_exp = {column: getattr(sample_random.experiment, column) for column in sample_random.experiment.__table__.c.keys()} diff --git a/conf_db_prefix.yaml b/conf_db_prefix.yaml index c8a49af..42cedea 100644 --- a/conf_db_prefix.yaml +++ b/conf_db_prefix.yaml @@ -1 +1 @@ -db_name_prefix: not_test +db_name_prefix: test diff --git a/controller_db.py b/controller_db.py index 0639dc2..6c1bec4 100644 --- a/controller_db.py +++ b/controller_db.py @@ -52,7 +52,7 @@ class ControllerDB: dct = {code: [product_code]} list_dct.append(dct) # list_dct = [{'140': ['1.4.5.1']}] - # list_dct = [{'133': ['1.4.4.1']}] + list_dct = [{'133': ['1.4.4.1']}] # list_dct = [{'2': ['1.1.3']}] # list_dct = [{'135': ['1.3.2.1']}] # list_dct = [{'79': ['2.1.3.4']}] diff --git a/firm.py b/firm.py index e0e8b45..bb4f4e3 100644 --- a/firm.py +++ b/firm.py @@ -18,7 +18,8 @@ class FirmAgent(ap.Agent): self.a_lst_product_disrupted = ap.AgentList(self.model, []) self.a_lst_product_removed = ap.AgentList(self.model, []) - self.dct_n_trial_up_product_removed = {} + self.dct_n_trial_up_prod_removed = {} + self.dct_cand_alt_supply_up_prod_removed = {} self.dct_request_prod_from_firm = {} def remove_edge_to_cus_remove_cus_up_prod(self, remove_product): @@ -50,32 +51,39 @@ class FirmAgent(ap.Agent): customer.a_lst_up_product_removed: customer.a_lst_up_product_removed.append( remove_product) - customer.dct_n_trial_up_product_removed[ + 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_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: - # select a list of candidate firm that has the product - candidate_alt_supply = 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 candidate_alt_supply: + 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 # select based on size lst_prob = [ - size / sum(candidate_alt_supply.revenue_log) - for size in candidate_alt_supply.revenue_log + 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 ] select_alt_supply = self.model.nprandom.choice( - candidate_alt_supply, p=lst_prob) - # print( - # f"{self.name} selct alt supply for {product.code} from {select_alt_supply.name}" - # ) + self.dct_cand_alt_supply_up_prod_removed[product], + p=lst_prob) + 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}" @@ -95,10 +103,10 @@ class FirmAgent(ap.Agent): # select_alt_supply.dct_request_prod_from_firm.items() # }) - self.dct_n_trial_up_product_removed[product] += 1 + 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: @@ -114,8 +122,12 @@ class FirmAgent(ap.Agent): 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] + 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: @@ -124,19 +136,21 @@ class FirmAgent(ap.Agent): lst_prob = [ size / sum(lst_firm_size) for size in lst_firm_size ] - select_customer = self.model.nprandom.choice(lst_firm, - p=lst_prob) + 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: # handling based on size of firm that has connection - lst_firm_size = [firm.revenue_log for firm in lst_firm_connect] + 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 ] - select_customer = self.model.nprandom.choice(lst_firm_connect, - p=lst_prob) + select_customer = \ + self.model.nprandom.choice(lst_firm_connect, + p=lst_prob) self.accept_request(select_customer, product) def accept_request(self, down_firm, product): @@ -151,18 +165,21 @@ class FirmAgent(ap.Agent): (self.firm_network.positions[self], self.firm_network.positions[down_firm], { 'Product': product.code - }) + }) ]) 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 from {down_firm.name}" - # ) + 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) def clean_before_trial(self): self.dct_request_prod_from_firm = {} def clean_before_time_step(self): - self.dct_n_trial_up_product_removed = {} + self.dct_n_trial_up_prod_removed = {} self.a_lst_up_product_removed = ap.AgentList(self.model, []) diff --git a/main.py b/main.py index 04618b7..485fd3c 100644 --- a/main.py +++ b/main.py @@ -38,7 +38,7 @@ if __name__ == '__main__': from controller_db import ControllerDB controller_db = ControllerDB(args.exp, reset_flag=args.reset_sample) # controller_db.reset_db() - + # force drop controller_db.reset_db(force_drop=args.reset_db) diff --git a/model.py b/model.py index 8015860..e76e44f 100644 --- a/model.py +++ b/model.py @@ -221,7 +221,7 @@ class Model(ap.Model): 1) / (max(lst_size) - min(lst_size) + 1) prod_remove = 1 - std_size * (1 - lost_percent) if self.nprandom.choice( - [True, False], p=[prod_remove, 1 - prod_remove]): + [True, False], p=[prod_remove, 1 - prod_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( diff --git a/orm.py b/orm.py index 4bc80a8..5e12c73 100644 --- a/orm.py +++ b/orm.py @@ -23,9 +23,11 @@ with open('conf_db_prefix.yaml') as file: str_login = 'mysql://{}:{}@{}:{}/{}'.format(dct_conf_db['user_name'], dct_conf_db['password'], dct_conf_db['address'], dct_conf_db['port'], dct_conf_db['db_name']) -print('DB is {}:{}/{}'.format(dct_conf_db['address'], dct_conf_db['port'], dct_conf_db['db_name'])) +print('DB is {}:{}/{}'.format(dct_conf_db['address'], + dct_conf_db['port'], dct_conf_db['db_name'])) -engine = create_engine(str_login, poolclass=NullPool) # must be null pool to avoid connection lost error +# must be null pool to avoid connection lost error +engine = create_engine(str_login, poolclass=NullPool) ins = inspect(engine) Base = declarative_base() @@ -48,7 +50,8 @@ class Experiment(Base): dct_lst_init_remove_firm_prod = Column(PickleType, nullable=False) g_bom = Column(Text(4294000000), nullable=False) - sample = relationship('Sample', back_populates='experiment', lazy='dynamic') + sample = relationship( + 'Sample', back_populates='experiment', lazy='dynamic') def __repr__(self): return f'' @@ -57,18 +60,21 @@ class Experiment(Base): class Sample(Base): __tablename__ = f"{db_name_prefix}_sample" id = Column(Integer, primary_key=True, autoincrement=True) - e_id = Column(Integer, ForeignKey('{}.id'.format(f"{db_name_prefix}_experiment")), nullable=False) + e_id = Column(Integer, ForeignKey('{}.id'.format( + f"{db_name_prefix}_experiment")), nullable=False) idx_sample = Column(Integer, nullable=False) seed = Column(BigInteger, nullable=False) - is_done_flag = Column(Integer, nullable=False) # -1, waiting; 0, running; 1, done + # -1, waiting; 0, running; 1, done + is_done_flag = Column(Integer, nullable=False) computer_name = Column(String(64), nullable=True) ts_done = Column(DateTime(timezone=True), onupdate=func.now()) stop_t = Column(Integer, nullable=True) g_firm = Column(Text(4294000000), nullable=True) - - experiment = relationship('Experiment', back_populates='sample', uselist=False) + + experiment = relationship( + 'Experiment', back_populates='sample', uselist=False) result = relationship('Result', back_populates='sample', lazy='dynamic') def __repr__(self): @@ -78,7 +84,8 @@ class Sample(Base): class Result(Base): __tablename__ = f"{db_name_prefix}_result" id = Column(Integer, primary_key=True, autoincrement=True) - s_id = Column(Integer, ForeignKey('{}.id'.format(f"{db_name_prefix}_sample")), nullable=False) + s_id = Column(Integer, ForeignKey('{}.id'.format( + f"{db_name_prefix}_sample")), nullable=False) id_firm = Column(String(10), nullable=False) id_product = Column(String(10), nullable=False) diff --git a/product.py b/product.py index b0cb415..09238f9 100644 --- a/product.py +++ b/product.py @@ -14,10 +14,10 @@ class ProductAgent(ap.Agent): return ap.AgentList( self.model, [ap.AgentIter(self.model, node).to_list()[0] for node in nodes]) - + def a_predecessors(self): - nodes = self.product_network.graph.predecessors( - self.product_network.positions[self]) - return ap.AgentList( - self.model, - [ap.AgentIter(self.model, node).to_list()[0] for node in nodes]) \ No newline at end of file + nodes = self.product_network.graph.predecessors( + self.product_network.positions[self]) + return ap.AgentList( + self.model, + [ap.AgentIter(self.model, node).to_list()[0] for node in nodes])