class TDISModel(Model): """A model with some number of agents.""" def __init__(self, graph): self.Graph = graph self.schedule = StagedActivation(self, ["step", "selectNextCooperation", "selectNextActive"]) # Create agents for i in self.Graph.NodeList: cooperationInit = random.choice(['C', 'D']) if cooperationInit == 'C': trustfulInit = 1 else: trustfulInit = 0 activeInit = random.choice([0, 1]) neighborListInit = self.Graph.neighbor(i) a = TDISAgent(i, trustfulInit, activeInit, cooperationInit, 2, neighborListInit, self) self.schedule.add(a) self.datacollector = DataCollector( model_reporters={"trust": compute_trust_porportion,"active":compute_Active_porportion}, agent_reporters={"Score": "Score"}) def step(self): self.datacollector.collect(self) self.schedule.step()
class EF_Model(Model): def __init__(self, N, threshold, memory_size, nb_strategies, width, height, type_network=None, param_network=None): self.num_agents = N self.G = nx.Graph() self.memory_size = memory_size self.threshold = threshold self.constant = 0 self.bar_location = (5, 5) self.initial_history = [ random.randint(0, self.num_agents) for i in range(self.memory_size) ] self.grid = MultiGrid(width, height, True) self.schedule = StagedActivation(self, ['evaluate', 'decide']) self.running = True #set history n-values (memory-size * 2) [random 100] #check model reporters if they can be accessed by agents: dictionnary # Create agents for i in range(self.num_agents): #threshold=random threshold #memory=random memory size a = Attendee(i, self, nb_strategies) self.schedule.add(a) #add the condition that agents start at home: in this model, as there are no visuals, it doesn't really matter where they are as going to the bar is only defined by self.attend x = self.random.randrange(self.grid.width) y = self.random.randrange(self.grid.height) self.grid.place_agent(a, (x, y)) #Create the graph and links and neighborhood if type_network is not None: self.G.add_node(a) if type_network is not None: set_edges(self.G, type_network, param_network) #find the adjacent agents in the graph for ag in self.schedule.agents: ag.find_friends() self.datacollector = DataCollector( model_reporters={"Attendance": compute_attendance}) def step(self): self.datacollector.collect(self) self.schedule.step()
class MockModel(Model): def __init__(self, shuffle): self.log = [] model_stages = ["stage_one", "stage_two"] self.schedule = StagedActivation(self, model_stages, shuffle=shuffle) # Make agents for name in ["A", "B"]: agent = MockStagedAgent(name) self.schedule.add(agent) def step(self): self.schedule.step()
class MockModel(Model): def __init__(self, shuffle): self.log = [] model_stages = ["stage_one", "stage_two"] self.schedule = StagedActivation(self, model_stages, shuffle=shuffle) # Make agents for name in ["A", "B"]: agent = MockStagedAgent(name) self.schedule.add(agent) def step(self): self.schedule.step()
class BIDModel(Model): """A model with some number of agents.""" def __init__(self, alpha, teta, uncertaintyL, uncertaintyU, graph, ActiveInit): self.Graph = graph self.schedule = StagedActivation(self, ["step", "selectNextActive"]) self.Alpha = alpha self.Teta = teta self.uncertaintyL = uncertaintyL self.uncertaintyU = uncertaintyU self.Active = ActiveInit activeInit = np.random.choice([0, 1], len(self.Graph.NodeList), p=[1 - self.Active, self.Active]) # Create agents for i in self.Graph.NodeList: if activeInit[i] == 1: beliefInit = random.randint(0, 1) else: beliefInit = random.randint(-1, 0) neighborListInit = self.Graph.neighbor(i) a = BIDAgent(i, beliefInit, activeInit[i], 0, neighborListInit, self.Alpha, self.Teta, self.uncertaintyL, self.uncertaintyU, self) self.schedule.add(a) self.datacollector = DataCollector( model_reporters={"BeliefCount": compute_Belief_porportion, "DisbeliefCount": compute_Disbelief_porportion, "UncertainCount": compute_Uncertain_porportion, "active": compute_Active_porportion} , agent_reporters={"Belief": "Belief"}) def step(self): self.datacollector.collect(self) self.schedule.step()
class CityModel(Model): def __init__(self, N=2, PassengerPooling=.5, PassengerPopulation=.2, PassengerBlocks={}, width=20, height=10, city_map=[], roads={}, city_blocks=[], routes={}): super().__init__() self.N = N # num of cabs self.grid = MultiGrid(width, height, torus=False) model_stages = ['stage_1', 'stage_2', 'stage_3', 'stage_4', 'step'] self.schedule = StagedActivation(self, model_stages, shuffle=True) self.roads = roads self.routes = routes self.passenger_blocks = PassengerBlocks self.unique_id_counter = 0 self.city_blocks = city_blocks self.passenger_population = PassengerPopulation self.passenger_pooling = PassengerPooling self.max_seats = 3 #Bidding properties self.current_bidding_results = {} self.all_biddings = {} self.datacollector = DataCollector(model_reporters={ "Normal Passenger": get_average_time_normal_passenger, "Pooling Passenger": get_average_time_pooling_passenger, "Average": get_average_time_all_passenger, "Cars carpooling": get_count_cars_carpooling, "Cars not carpooling": get_count_cars_not_carpooling, "Empty cars": get_count_cars_empty, "Passengers Travelling (not pooling)": get_count_passengers_not_pooling_travelling, "Passengers Travelling (pooling)": get_count_passengers_pooling_travelling, "Passengers Travelling": get_count_passengers_travelling, "Overtravelled (in percentage)": get_average_perc_over_travelled_pool_passengers}) self.fill_blocks_agents() self.make_taxi_agents() self.addPassengers() self.running = True self.datacollector.collect(self) def clear_biddings(self): self.current_bidding_results = None self.all_biddings = {} def update_winners(self): #Check if it is the first time being called if (self.current_bidding_results == None): self.current_bidding_results = {} if (len(self.all_biddings) == 0): return passenger_assignment = {} number_of_cabs_bidding = len(self.all_biddings) first_cab = next(iter(self.all_biddings.keys())) passengers_being_bidded = set() for cab in self.all_biddings.keys(): for psg in self.all_biddings[cab].keys(): passengers_being_bidded.add(psg) number_of_passengers = len(passengers_being_bidded) while(len(passenger_assignment) < number_of_cabs_bidding and len(passenger_assignment) < number_of_passengers): passengers_all_distances = {} passenger_assignment_temp = {} for cab in self.all_biddings.keys(): if (cab not in passenger_assignment.values()): for psg in passengers_being_bidded: if (psg not in passenger_assignment.keys()): cab_bidding_for_this_pass = psg in self.all_biddings[cab].keys() if(cab_bidding_for_this_pass): pass_dist = self.all_biddings[cab][psg] else: pass_dist = math.inf if(psg not in passengers_all_distances or passengers_all_distances[psg] > pass_dist): passengers_all_distances[psg] = pass_dist passenger_assignment_temp[psg] = cab if cab_bidding_for_this_pass else None #order the passengers by the distance to the closest cab passengers_all_distances = sorted(passengers_all_distances.items(), key=lambda kv: kv[1]) #get the passenger who has the closest cab passenger = passengers_all_distances[0][0] #get the cab cab = passenger_assignment_temp[passenger] passenger_assignment[passenger] = cab self.current_bidding_results = passenger_assignment def bid(self, cab, passengers_offers): self.all_biddings[cab] = passengers_offers def fill_blocks_agents(self): for block in self.city_blocks: agent = Grass(self.unique_id_counter, self, block[0], block[1]) self.schedule.add(agent) self.grid.place_agent(agent, block[0]) self.unique_id_counter = self.unique_id_counter + 1 def make_taxi_agents(self): r = random.SystemRandom() for _ in range(self.N): possible_places = list(self.roads.keys()) r.shuffle(possible_places) pos = possible_places[0] agent = Cab(self.unique_id_counter, self, pos, (1, 0)) self.schedule.add(agent) self.grid.place_agent(agent, pos) self.unique_id_counter = self.unique_id_counter + 1 def step(self): self.addPassengers() self.clear_biddings() self.schedule.step() self.datacollector.collect(self) def addPassengers(self): passengers_waiting = [agent.pos for agent in self.schedule.agents if isinstance(agent, Passenger)] free_spot = list(set(self.passenger_blocks.keys()) - set(passengers_waiting)) r = random.SystemRandom() r.shuffle(free_spot) destinations = set(self.passenger_blocks.keys()) while(len(free_spot)> 0 and \ (len(passengers_waiting)/len(self.passenger_blocks) < self.passenger_population)): pos = free_spot.pop(0) possible_destinations = list(destinations - set([pos])) destination = self.random.choice(possible_destinations) #Just to find another position wich has a road block different from # the current passenger while(self.passenger_blocks[destination] == self.passenger_blocks[pos]): destination = self.random.choice(possible_destinations) isCarPooler = random.random() < self.passenger_pooling passenger = Passenger(self.unique_id_counter, self, pos, self.passenger_blocks[destination], self.passenger_blocks[pos], isCarPooler) self.schedule.add(passenger) self.grid.place_agent(passenger, pos) self.unique_id_counter = self.unique_id_counter + 1 passengers_waiting.append(pos)
class HometimeModel(Model): """This is a model that allows simulation of secondary school children to commute home from school and/or stop off at restaurants""" def __init__(self, db_connection, N=100, width=100, height=100, school_x_pos=50, school_y_pos=50): """Makes the new model Arguments ========= - N - number of agents, default: 100 - width - the width of grid, default: 100 - height - height of grid, default: 100 """ self.num_agents = N model_stages = ["stage_one", "stage_two"] self.schedule = StagedActivation(self, model_stages, True) self.restaurants = get_all_restaurants(db_connection) self.school_x_pos = school_x_pos self.school_y_pos = school_y_pos self.decay = 0.2 # this is true when the weather is good, false otherwise self.good_weather = True for i in range(0, self.num_agents): id = i model = self # Generate weather weight as Normal distribution # Mean - 0.5. SD - 0.25 weather_weight = np.random.normal(0.5, 0.25) # Generate likelihood to eat out as Normal distribution # Mean - 0.5. SD - 0.25 likelihood_to_eat_out = np.random.normal(0.5, 0.25) likelihood_to_eat_out_weight = 1.0 # Randomizes likability for each restaurant restaurant_likability = {} for restaurant in self.restaurants: restaurant_name = restaurant[0] restaurant_likability[restaurant_name] = np.random.normal( 0.5, 0.25) restaurant_likability_weight = 1.0 # Previous visit values previous_visits = {} for restaurant in self.restaurants: restaurant_name = restaurant[0] previous_visits[restaurant_name] = 0 previous_visit_weight = 1.0 home_x_pos = np.random.uniform(0, width) home_y_pos = np.random.uniform(0, height) distance_weight = np.random.normal(-0.5, 0.25) agent = HometimeAgent( id, model, weather_weight, likelihood_to_eat_out, likelihood_to_eat_out_weight, restaurant_likability, restaurant_likability_weight, previous_visits, previous_visit_weight, home_x_pos, home_y_pos, distance_weight) self.schedule.add(agent) self.running = True self.datacollector = DataCollector( agent_reporters={"Last Choice": "last_choice"}, model_reporters={"Good weather": "good_weather"}) def step(self): self.datacollector.collect(self) # change the weather if random() < config.percentage_bad_weather: self.good_weather = False else: self.good_weather = True self.schedule.step()
class ReputationSim(Model): def __init__(self, study_path='study.json', opened_config=False): if opened_config: config = study_path else: with open(study_path) as json_file: config = json.load(json_file, object_pairs_hook=OrderedDict) #save the config with the output self.transaction_numbers = [] transaction_number = 0 # print(json.dumps(config['ontology'], indent=2)) self.parameters = config['parameters'] super().__init__(self.parameters['seed']) self.time = dt.datetime.now().isoformat() #filename = self.parameters['output_path'] + 'params_' + self.parameters['param_str'] + self.time[0:10] + '.json' filename = self.parameters['output_path'] + 'params_' + self.parameters[ 'param_str'][:-1] + '.json' pretty = json.dumps(config, indent=2, separators=(',', ':')) with open(filename, 'w') as outfile: outfile.write(pretty) outfile.close() self.transaction_report = self.transaction_report() self.seconds_per_day = 86400 tuplist = [ (good, []) for good, chance in self.parameters["chance_of_supplying"].items() ] self.suppliers = OrderedDict(tuplist) tuplist = [(good, []) for good, chance in self.parameters["criminal_chance_of_supplying"].items()] self.criminal_suppliers = OrderedDict(tuplist) self.initial_epoch = self.get_epoch(self.parameters['initial_date']) self.final_epoch = self.get_epoch(self.parameters['final_date']) self.next_transaction = 0 self.end_tick = self.get_end_tick() self.goodness_distribution = self.get_truncated_normal( *tuple(self.parameters['goodness'])) self.fire_supplier_threshold_distribution = self.get_truncated_normal( *tuple(self.parameters['fire_supplier_threshold'])) self.forget_discount_distribution = self.get_truncated_normal( *tuple(self.parameters['forget_discount'])) self.criminal_transactions_per_day_distribution = self.get_truncated_normal( *tuple(self.parameters['criminal_transactions_per_day'])) self.transactions_per_day_distribution = self.get_truncated_normal( *tuple(self.parameters['transactions_per_day'])) self.criminal_agent_ring_size_distribution = self.get_truncated_normal( *tuple(self.parameters['criminal_agent_ring_size'])) self.open_to_new_experiences_distribution = self.get_truncated_normal( *tuple(self.parameters['open_to_new_experiences'])) self.criminal_goodness_distribution = self.get_truncated_normal( *tuple(self.parameters['criminal_goodness'])) self.rating_perception_distribution = self.get_truncated_normal( *tuple(self.parameters['rating_perception'])) self.cobb_douglas_distributions = { good: self.get_truncated_normal(*tuple(statlist)) for good, statlist in self.parameters['cobb_douglas_utilities'].items() } self.price_distributions = { good: self.get_truncated_normal(*tuple(statlist)) for good, statlist in self.parameters['prices'].items() } self.need_cycle_distributions = { good: self.get_truncated_normal(*tuple(statlist)) for good, statlist in self.parameters['need_cycle'].items() } self.criminal_need_cycle_distributions = { good: self.get_truncated_normal(*tuple(statlist)) for good, statlist in self.parameters['criminal_need_cycle'].items() } #this stage_list facilitiates ten different time periods within a day for trades stage_list = [ 'step', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners' ] self.schedule = StagedActivation(self, stage_list=stage_list, shuffle=True, shuffle_between_stages=True) # Create agents agent_count = 0 if self.parameters['deterministic_mode']: num_criminals = math.ceil(self.parameters['num_users'] * self.parameters['chance_of_criminal']) # nsuppliers = {good:int(self.parameters['num_users']*chance # ) for good, chance in self.parameters['chance_of_supplying'].items()} # First get the number of suppliers that is to be had in the scenario, by adding up all of the # chances of being a supplier , and then taking the percent of the total, flooring with an int again # then create a dict for how many of each supplier there are. then, go through the agents designated # as good and assing suppliers, starting from the highest likelihood down to the lowest # these are for the good agents. The bad agents go by another algorithm of what they supply, that is # related to the price #criminal suppliers chance_of_supplier = 0 for good, chance in self.parameters[ 'criminal_chance_of_supplying'].items(): chance_of_supplier += chance num_suppliers1 = round(num_criminals * chance_of_supplier) sorted_suppliers = sorted( self.parameters['criminal_chance_of_supplying'].items(), key=lambda x: x[1], reverse=True) sup_count = 0 nsuppliers = OrderedDict() for good, chance in sorted_suppliers: if sup_count < num_suppliers1: rounded = round(num_suppliers1 * chance) num_sup_this_good = rounded if rounded > 0 else 1 num_sup_this_good = min(num_sup_this_good, (num_suppliers1 - sup_count)) sup_count = sup_count + num_sup_this_good nsuppliers[good] = num_sup_this_good for good, num_suppliers in nsuppliers.items(): for _ in range(num_suppliers): a = globals()['ReputationAgent'](agent_count, self, criminal=True, supply_list=[good]) self.schedule.add(a) self.criminal_suppliers[good].append(agent_count) agent_count += 1 #criminal consumers for _ in range(num_criminals - num_suppliers1): a = globals()['ReputationAgent'](agent_count, self, criminal=True, supply_list=[]) self.schedule.add(a) agent_count += 1 #good suppliers chance_of_supplier = 0 for good, chance in self.parameters['chance_of_supplying'].items(): chance_of_supplier += chance num_suppliers1 = round( (self.parameters['num_users'] - num_criminals) * chance_of_supplier) sorted_suppliers = sorted( self.parameters['chance_of_supplying'].items(), key=lambda x: x[1], reverse=True) sup_count = 0 nsuppliers = OrderedDict() for good, chance in sorted_suppliers: if sup_count < num_suppliers1: rounded = round(num_suppliers1 * chance) num_sup_this_good = rounded if rounded > 0 else 1 num_sup_this_good = min(num_sup_this_good, (num_suppliers1 - sup_count)) sup_count = sup_count + num_sup_this_good nsuppliers[good] = num_sup_this_good for good, num_suppliers in nsuppliers.items(): for _ in range(num_suppliers): a = globals()['ReputationAgent'](agent_count, self, criminal=False, supply_list=[good]) self.schedule.add(a) agent_count += 1 #good consumers for i in range(agent_count, self.parameters['num_users']): a = globals()['ReputationAgent'](agent_count, self, criminal=False, supply_list=[]) self.schedule.add(a) agent_count += 1 else: for _ in range(self.parameters['num_users']): a = globals()['ReputationAgent'](agent_count, self) self.schedule.add(a) agent_count += 1 self.print_agent_goodness() def get_end_tick(self): #final_tick = (final_epoch - initial_epoch) / (days / tick * miliseconds / day) secs = self.final_epoch - self.initial_epoch final_tick = secs / (self.parameters['days_per_tick'] * self.seconds_per_day) return final_tick def transaction_report(self): #path = self.parameters['output_path'] + 'transactions_' +self.parameters['param_str'] + self.time[0:10] + '.tsv' path = self.parameters[ 'output_path'] + 'transactions_' + self.parameters[ 'param_str'][:-1] + '.tsv' file = open(path, "w") return (file) def get_epoch(self, date_time): #date_time = '29.08.2011 11:05:02' pattern = '%d.%m.%Y %H:%M:%S' epoch = int(time.mktime(time.strptime(date_time, pattern))) return epoch def get_next_transaction(self): if not self.transaction_numbers: self.transaction_numbers = list(range(0, 10000)) shuffle(self.transaction_numbers) self.next_transaction = self.transaction_numbers.pop() return self.next_transaction def print_transaction_report_line(self, from_agent, to_agent, payment, tags, payment_unit='', parent='', rating='', type='payment'): time = (self.schedule.time * self.parameters['days_per_tick'] * self.seconds_per_day) + self.initial_epoch time = int(time + random.uniform(0, self.seconds_per_day / 10)) network_val = self.parameters['network'] timestamp_val = time type_val = type from_val = from_agent to_val = to_agent value_val = rating if rating else payment unit_val = '' if rating else payment_unit parent_val = self.get_next_transaction() if rating else parent child_val = self.get_next_transaction() title_val = '' input_val = '' tags_val = tags format_val = '' block_val = '' parent_value_val = payment if rating else '' parent_unit_val = payment_unit if rating else '' self.transaction_report.write( "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\t{15}\n" .format(network_val, timestamp_val, type_val, from_val, to_val, value_val, unit_val, child_val, parent_val, title_val, input_val, tags_val, format_val, block_val, parent_value_val, parent_unit_val)) #self.transaction_report.flush() def print_agent_goodness(self, userlist=[-1]): #output a list of given users, sorted by goodness. if the first item of the list is -1, then output all users #path = self.parameters['output_path'] + 'users_' + self.parameters['param_str'] + self.time[0:10] + '.tsv' path = self.parameters['output_path'] + 'users_' + self.parameters[ 'param_str'][:-1] + '.tsv' with open(path, 'w') as outfile: agents = self.schedule.agents if userlist and userlist[ 0] == -1 else userlist outlist = [(agent.unique_id, agent.goodness) for agent in agents] sorted_outlist = sorted(outlist, key=operator.itemgetter(1), reverse=True) for id, goodness in sorted_outlist: outfile.write("{0}\t{1}\n".format(id, goodness)) outfile.close() def get_truncated_normal(self, mean=0.5, sd=0.2, low=0, upp=1.0): rv = truncnorm((low - mean) / sd, (upp - mean) / sd, loc=mean, scale=sd) return rv def step(self): """Advance the model by one step.""" self.schedule.step() self.transaction_report.flush() def go(self): while self.schedule.time < self.get_end_tick(): self.step() self.transaction_report.close()
class CorruptionModel(Model): """A model with population agents.""" def __init__(self, b_bar=3, b_range=1, alpha=0.5, gamma=0.5, theta=0.1, q_start=0.1, population=1000, k_bar=0.5, k_range=1): """Create the model with the following parameters: Average level of risk aversion = b_bar Range of risk aversion = b_range Proportion of income spent on vigilance = gamma Mean human capital endowment in first generation = k_bar Equality in access to human capital = theta Initial value of social corruption = q_start Population = population Number of generations = generations Range of human capital endowment: k_range""" #Set parameters self.running = True self.num_agents = population self.b_bar = b_bar self.b_range = b_range self.alpha = alpha self.gamma = gamma self.theta = theta self.q = q_start self.k_bar = k_bar self.k_range = k_range self.k_min = k_bar - 0.5 * k_range self.k_max = k_bar + 0.5 * k_range self.S = alpha * (k_bar * population) self.schedule = StagedActivation(self, stage_list=["corrupt", "procreate"]) self.running = True #Create agents for i in range(self.num_agents): a = CorruptionAgent(i, self) self.schedule.add(a) #Add data to report self.datacollector = DataCollector( model_reporters={ "Total capital": total_capital, "Corruption Index": corruption_index, "National Income": national_income }, agent_reporters={"Dishonesty": lambda a: a.p}) def step(self): ''' Advance the model by one step. Do this in two stages: In first stage, corrupt, then report data and update model parameters. In second stage, breed and die.''' for stage in self.schedule.stage_list: for agent in self.schedule.agents[:]: getattr(agent, stage)() if stage == "corrupt": self.q = corruption_index(self) self.datacollector.collect(self) self.y_min, self.y_max = min_max_income(self) #self.k_min, self.k_max = min_max_capital(self) self.K = total_capital(self) self.S = social_capital(self)
class RegimeModel(Model): # A model of a regime def __init__(self, num_nodes, productivity, demand, shape, network_param, resource_inequality, capacity_inequality, uncertainty, shock): # Initialize graph self.num_nodes = num_nodes self.G = create_graph(shape, num_nodes, network_param) self.G = max(nx.connected_component_subgraphs(self.G), key=lambda g: len(g.nodes())) # Initialize other attributes self.grid = NetworkGrid(self.G) self.schedule = StagedActivation(self, stage_list=[ 'add_link', 'cut_link', 'settle_env_transfer', 'settle_link_transfer' ], shuffle=True, shuffle_between_stages=True) self.productivity = productivity self.demand = demand self.resource_inequality = resource_inequality self.capacity_inequality = capacity_inequality self.uncertainty = uncertainty self.datacollector = DataCollector({ "Gini Coeff. of Capacity": gini_capacity, "Gini Coeff. of Resources": gini_resources, "Satisfied": num_satisfied, "Dissatisfied": num_dissatisfied }) self.shock = shock # Initialize agents on graph (cap capacity at 25 to avoid overflow errors) for i, node in enumerate(self.G.nodes()): a = RegimeAgent(i, self, self.demand, math.exp(paretovariate(1 / resource_inequality)), min(25, paretovariate(1 / capacity_inequality)), True) self.schedule.add(a) self.grid.place_agent(a, node) for e in self.G.edges(): capacity_transfer = expovariate(1 / self.uncertainty) agents = ([ self.G.nodes[e[0]]['agent'][0], self.G.nodes[e[1]]['agent'][0] ]) resource_transfer = calculate_transfer( self.productivity, agents[0].capacity + capacity_transfer, agents[1].capacity + capacity_transfer, capacity_transfer) # Give the agent with the higher capacity 2*transfer capacity to # simulate a prior interaction where the transfer was made, when # both the nodes had their current capacity + transfer. max_capacity_agent = max(agents, key=attrgetter('capacity')) min_capacity_agent = min(agents, key=attrgetter('capacity')) max_capacity_agent.capacity += 2 * capacity_transfer min_capacity_agent.exp_resources += resource_transfer # Initialize edge attributes for transfer rates, memory of # resource transfers, and which agent is the patron. self.G.edges[e]['capacity_t'] = capacity_transfer self.G.edges[e]['resource_t'] = resource_transfer self.G.edges[e]['exp_resources'] = [ resource_transfer, resource_transfer ] self.G.edges[e]['patron'] = max_capacity_agent self.running = True self.datacollector.collect(self) def step(self): self.schedule.step() self.datacollector.collect(self) def run_model(self, n): for i in range(n): if i == n // 2: # Halfway through simulation, add shock. self.productivity *= self.shock self.step()
class RoadModel(Model): """ A model with a number of cars, Nagel-Schreckenberg """ def __init__(self, N, length=100, lanes=1, timer=3): self.num_agents = N self.grid = SingleGrid(length, lanes, torus=True) model_stages = [ "acceleration", "braking", "randomisation", "move", "delete" ] self.schedule = StagedActivation(self, stage_list=model_stages) # Create agent for i in range(self.num_agents): agent = CarAgent(i, self, False) # Add to schedule self.schedule.add(agent) # Add to grid (randomly) self.grid.position_agent(agent) # Add the traffic light self.traffic_light = TrafficLight(0, self, timer, 20, 20) self.average_velocity = CarAgent.init_velocity self.datacollector = DataCollector(agent_reporters={ "Position": "pos", "Velocity": "velocity" }, model_reporters={ "Average Velocity": "average_velocity", "Amount of cars": "agent_count", "On Ramp Queue": get_on_ramp_queue, "Waiting Queue": get_waiting_queue }) self.running = True def step(self): """ The model takes a new step and updates """ # Calculate amount of agents self.agent_count = len(self.schedule.agents) # Calculate average velocity self.average_velocity = np.mean( [a.velocity for a in self.schedule.agents]) # Collect data self.datacollector.collect(self) # Run a step of the traffic light self.traffic_light.step() # Run next step self.schedule.step() def add_agent(self, label, x_corr): """ Adds an agent to the scheduler and model on a particular coordinate :param label: The label of the agents that gets created :param x_corr: The x-coordinate of where the agent will be spawned """ # Create agent agent = CarAgent(label, self, True) # Add to schedule self.schedule.add(agent) # Add to grid on a certain position self.grid.position_agent(agent, x_corr, 0) def delete_agent(self, agent): """ Deletes an agent from the scheduler and model :param agent: The agents that gets deleted """ # remove from schedule self.schedule.remove(agent) # remove from grid self.grid.remove_agent(agent)
class FestivalModel(Model): def __init__(self, num_party: int = 20, num_guard: int = 5, num_trouble: int = 5, num_celeb: int = 5, num_hippie: int = 20, learning=True, pareto_fight=False, pareto=False, lucia=False): super().__init__() self.num_agents = num_party + num_guard + num_trouble + num_celeb + num_hippie self.num_party = num_party self.num_guard = num_guard self.num_trouble = num_trouble self.num_celeb = num_celeb self.num_hippie = num_hippie self.pareto = pareto self.pareto_fight = pareto_fight self.lucia = lucia self.schedule = StagedActivation( self, ['send_proposes', 'process_proposes', 'step', 'die']) self.space = ContinuousSpace(100, 100, False) self.datacollector = DataCollector( model_reporters={ "Alive agents": lambda model: model.schedule.get_agent_count(), "Mean happiness": lambda model: np.mean([ a.happiness for a in filter(lambda x: x.type == 'guest', model.schedule.agents) ]), "Mean fullness": lambda model: np.mean([ a.fullness for a in filter(lambda x: x.type == 'guest', model.schedule.agents) ]) }) for i in range(self.num_party): x, y = np.random.rand(2) * 100 a_ = PartyPerson('Party%d' % i, self, (x, y), learning) self.schedule.add(a_) self.space.place_agent(a_, (x, y)) for i in range(self.num_guard): x, y = np.random.rand(2) * 100 a_ = Guard('Guard%d' % i, self, (x, y), learning) self.schedule.add(a_) self.space.place_agent(a_, (x, y)) for i in range(self.num_trouble): x, y = np.random.rand(2) * 100 a_ = Troublemaker('Trouble%d' % i, self, (x, y), learning) self.schedule.add(a_) self.space.place_agent(a_, (x, y)) for i in range(self.num_celeb): x, y = np.random.rand(2) * 100 a_ = Celebrity('Celeb%d' % i, self, (x, y), learning) self.schedule.add(a_) self.space.place_agent(a_, (x, y)) for i in range(self.num_hippie): x, y = np.random.rand(2) * 100 a_ = Hippie('Hippie%d' % i, self, (x, y), learning) self.schedule.add(a_) self.space.place_agent(a_, (x, y)) for x, y in ((x, y) for x in [40, 60] for y in [40, 60]): s_ = Store('StoreX%dY%d' % (x, y), self, (x, y)) self.schedule.add(s_) self.space.place_agent(s_, (x, y)) for x, y in ((x, y) for x in [20, 80] for y in [20, 80]): s_ = Stage('StageX%dY%d' % (x, y), self, (x, y)) self.schedule.add(s_) self.space.place_agent(s_, (x, y)) if lucia: x, y = 0, 0 a_ = Lucia('Lucia%d' % i, self, (x, y), learning) self.schedule.add(a_) self.space.place_agent(a_, (x, y)) def step(self): self.datacollector.collect(self) self.schedule.step() def fight(self, agent1: Guest, agent2: Guest): assert self == agent1.model == agent2.model, "Can't fight between other festival's guests" buffers = {agent1: 0., agent2: 0.} buffers_joy = {agent1: 0., agent2: 0.} for agent in (agent1, agent2): if agent.role == 'troublemaker': buffers[agent] += 1 else: buffers[agent] -= 3 if self.pareto_fight: p1 = [0.25, 0.25, 0.25, 0.25] p2 = [0.04, 0.16, 0.16, 0.64] index = np.random.choice(np.arange(0, 4), p=p1 if self.pareto else p2) store = [(0, 0), (0.2, -0.7), (-0.7, 0.2), (-0.5, -0.5)] select = store[index] buffers_joy[agent] += select[ 0] if agent.role == 'troublemaker' else select[1] buffers[agent] += agent.tastes['fight'] buffers[agent] += 0.5 * random.random() - 0.25 for agent in (agent1, agent2): agent.happiness += buffers[agent] if self.pareto_fight: agent.enjoyment += buffers_joy[agent] agent1.learn((agent2.role, 'fight'), buffers[agent1]) agent2.learn((agent1.role, 'fight'), buffers[agent2]) print("A fight is happening") def party(self, agent1: Guest, agent2: Guest): assert self == agent1.model == agent2.model buffers = {agent1: 0., agent2: 0.} for agent in (agent1, agent2): if agent.role == 'party': buffers[agent] += 1 if agent.role == 'guard': buffers[agent] -= 3 buffers[agent] += agent.tastes['party'] buffers[agent] += 0.5 * random.random() - 0.25 for agent in (agent1, agent2): agent.happiness += buffers[agent] agent1.learn((agent2.role, 'party'), buffers[agent1]) agent2.learn((agent1.role, 'party'), buffers[agent2]) print("A party is happening") def calm(self, agent1: Guest, agent2: Guest): # Incorporate this in fight? assert self == agent1.model == agent2.model assert agent1.role == 'guard' or agent2.role == 'guard', "This interaction is forbidden" buffers = {agent1: 0., agent2: 0.} if agent1.role == 'guard': guard = agent1 guest = agent2 elif agent2.role == 'guard': guard = agent2 guest = agent1 else: guard = None guest = None print( "This interaction should not be happening, we don't have a guard involved" ) return if guest.role == 'troublemaker': buffers[guard] += 1 buffers[guest] -= 1 else: buffers[guard] -= 2 buffers[guest] -= 2 for agent in (agent1, agent2): agent.happiness += buffers[agent] agent1.learn((agent2.role, 'calm'), buffers[agent1]) agent2.learn((agent1.role, 'calm'), buffers[agent2]) print("Calming is happening") def selfie(self, agent1: Guest, agent2: Guest): assert self == agent1.model == agent2.model buffers = {agent1: 0, agent2: 0} if agent1.role == 'celebrity': celeb = agent1 guest = agent2 elif agent2.role == 'celebrity': celeb = agent2 guest = agent1 else: print("No celeb in selfie") return if guest.role == 'troublemaker': self.fight(celeb, guest) return elif guest.role == 'guard': buffers[celeb] += 1 buffers[guest] -= 1 else: buffers[celeb] += 1 buffers[guest] += 1 for agent in (celeb, guest): buffers[agent] += agent.tastes['selfie'] buffers[agent] += 0.5 * random.random() - 0.25 for agent in (agent1, agent2): agent.happiness += buffers[agent] agent1.learn((agent2.role, 'selfie'), buffers[agent1]) agent2.learn((agent1.role, 'selfie'), buffers[agent2]) print("Selfie is happening") def smoke(self, agent1: Guest, agent2: Guest): assert self == agent1.model == agent2.model buffers = {agent1: 0., agent2: 0.} if agent1.role == 'hippie': hippie = agent1 guest = agent2 elif agent2.role == 'hippie': hippie = agent2 guest = agent1 else: print("No hippie in smoking") return if guest.role == 'hippie': buffers[hippie] += 2 buffers[guest] += 2 elif guest.role == 'celebrity': buffers[hippie] += 1 buffers[guest] -= 2 elif guest.role == 'guard': buffers[hippie] -= 2 buffers[guest] += 1 else: buffers[hippie] += 1 buffers[guest] += 0.5 for agent in (hippie, guest): buffers[agent] += agent.tastes['smoke'] buffers[agent] += 0.5 * random.random() - 0.25 for agent in (agent1, agent2): agent.happiness += buffers[agent] agent1.learn((agent2.role, 'smoke'), buffers[agent1]) agent2.learn((agent1.role, 'smoke'), buffers[agent2]) print("Smoking is happening") def blessing(self, agent1: Guest, agent2: Guest): assert self == agent1.model == agent2.model buffers = {agent1: 0., agent2: 0.} if agent1.role == 'lucia': lucia = agent1 guest = agent2 elif agent2.role == 'lucia': lucia = agent2 guest = agent1 else: print("No hippie in smoking") return buffers[lucia] += 0.5 buffers[guest] += 0.5 for agent in (lucia, guest): buffers[agent] += agent.tastes['blessing'] buffers[agent] += 0.5 * random.random() - 0.25 for agent in (agent1, agent2): agent.happiness += buffers[agent] agent1.learn((agent2.role, 'blessing'), buffers[agent1]) agent2.learn((agent1.role, 'blessing'), buffers[agent2]) print("blessing is happening")
class Contact_Trace_Model(Model): """ The model class holds the model-level attributes, manages the agents, and generally handles the global level of our model. There is only one model-level parameter: how many agents the model contains. When a new model is started, we want it to populate itself with the given number of agents. The scheduler is a special model component which controls the order in which agents are activated. """ def __init__( self, num_agents=10, num_sick=1, infection_chance=0.1, incubation_period=[2, 6], presypmtomatic_infectious_period=[0, 3], infectious_period=[5, 10], percent_asymptomatic=0, immunity_percent=1, percent_employed_small=0.5, perecent_employed_medium=0.25, percent_employed_large=0.25, family_size=[0, 8], random_contact_mean=5, random_contact_sd=2, contact_trace_percent=0.75, false_positive_rate=0.1, false_negative_rate=0.1, percent_tested_per_day=0.01, turn_around_time=2, ): super().__init__() self.num_agents = num_agents # self.schedule = RandomActivation(self) self.schedule = StagedActivation(self, stage_list=["move", "infect", "test"]) # self.grid = MultiGrid(width=width, height=height, torus=False) # get workplaces self.infection_chance = infection_chance self.incubation = incubation_period self.infectious_period = infectious_period self.infection_chance = infection_chance self.incubation_period = incubation_period self.presypmtomatic_infectious_period = presypmtomatic_infectious_period self.percent_asymptomatic = percent_asymptomatic self.immunity_percent = immunity_percent self.percent_employed_small = percent_employed_small self.perecent_employed_medium = perecent_employed_medium self.percent_employed_large = percent_employed_large self.family_size = family_size self.random_contact_mean = random_contact_mean self.random_contact_sd = random_contact_sd self.contact_trace_percent = contact_trace_percent self.false_positive_rate = false_positive_rate self.false_negative_rate = false_negative_rate self.percent_tested_per_day = percent_tested_per_day self.turn_around_time = turn_around_time # num_classrooms = math.ceil(num_agents / max_class_size) # for i in range(1, num_classrooms + 1): # self.class_dict[i] = { # "students": [], # "count": 0, # "infected": False, # } random_contacts = np.random.normal( self.random_contact_mean, self.random_contact_sd, self.num_agents ) family_dict = {} # people still available to be in a family. if this gets to 0, remaining # agents will have no family members (should be at end only) family_available = self.num_agents non_family = set(range(1, self.num_agents, 1)) for i in range(self.num_agents): agent = Contact_Trace_Agent(i, self) agent.random_contacts = max(math.floor(random_contacts[i]), 0) if family_available <= 0: print(f"agent {i} has no one left to be in their family") # if you're in a family already, that's your family, if not generate one if agent.unique_id in family_dict: agent.family = family_dict[agent.unique_id] else: family_size = min( family_available, random.randrange(self.family_size[0], self.family_size[1] + 1, 1,), ) family_list = [] # grab random id in range of num_agents, if that person is not in a # family already, add them to list, repeat until the family is the # right size family_counter = 0 while family_counter < family_size: person = random.randrange(0, self.num_agents, 1,) if person not in family_dict: family_list.append(person) family_counter += 1 # now that we have the list of family members, assingn them all # to the family for f in family_list: family_dict[f] = family_list # assign the agent's family list agent.family = family_list # remove these people from family_available family_available += -family_size agent.random_people = list(non_family - set(agent.family)) if num_sick > 0: agent.sick = True agent.pre_infectious = True agent.state = "pre_infectious" agent.incubation = random.randrange( self.incubation[0], self.incubation[1] + 1, 1 ) agent.infectious_period = random.randrange( self.infectious_period[0], (self.infectious_period[1]) + 1, 1, ) num_sick += -1 # job_asigned = False # while not dining_asigned: # dining_option = random.choice(list(self.dining_dict.keys())) # if self.dining_dict[dining_option]["count"] < max_dining: # agent.dining = dining_option # self.dining_dict[dining_option]["count"] += 1 # dining_asigned = True # break # else: # continue self.schedule.add(agent) self.running = True # self.datacollector = DataCollector(model_reporters={"Number Sick": num_sick}) self.datacollector = DataCollector( model_reporters={ "Percent Ever Sick": percent_sick, "Number Infectious": num_infectious, "Tested and Quarantined": quarantined, } ) def step(self): """ A model step. Used for collecting data and advancing the schedule """ self.step_tests = self.percent_tested_per_day * self.num_agents self.datacollector.collect(self) self.schedule.step()
class MarketModel(Model): def __init__(self, n_agents, population_composition={'zero_information': { 'R': 1 }}, settle_type='limit', dt=1 / 252, init_rf=0.02, n_shares=1000, init_agent_wealth=1000, glob_risk_aversion=0.5, glob_loss_aversion=2.5, confidance_levels=(0.7, 3), glob_interact_rate=0.25, agent_particip_rate=1, init_price=50, init_dividend=5, dividend_freq=4, dividend_growth=0.01, dividend_vol=0.2, div_noise_sig=0.1, price_adj_speed=0.1, max_short=0.0001, max_long=0.02): super().__init__() self.running = True self.n_agents = n_agents self.population_composition = population_composition #self.glob_risk_aversion = glob_risk_aversion self.confidance_levels = confidance_levels self.glob_interact_rate = glob_interact_rate self.rf_rate = init_rf #to be controlled by a regulator agent in the future self.eta = price_adj_speed self.max_short = max_short self.max_long = max_long self.current_step = 0 self.dt = dt self.stock = Stock(ticker="STK", model=self, init_price=init_price, outstanding_shares=n_shares, init_dividend=init_dividend, dividend_freq=dividend_freq, dividend_growth=dividend_growth, dividend_vol=dividend_vol, div_noise_sig=div_noise_sig) self.schedule = StagedActivation(self, ['stage1', 'stage2', 'stage3']) self.order_book = OrderBook() self.settle_type = settle_type agent_id = 0 # if sum(population_composition[strat] for strat in population_composition) - 1.0 > 1e-06: if sum(population_composition[strat][beh] for strat in population_composition for beh in population_composition[strat]) - 1.0 > 1e-06: raise NameError( 'population_compositions elements must sum up to 1') init_shares = n_shares / n_agents for strat in population_composition: for beh in population_composition[strat]: for i in range( int(population_composition[strat][beh] * self.n_agents)): a = MarketAgent(agent_id, self, init_shares, init_agent_wealth, glob_risk_aversion, glob_loss_aversion, beh, strat, agent_particip_rate) self.schedule.add(a) agent_id += 1 while agent_id < self.n_agents: init_shares = n_shares / n_agents strat = choice(list(population_composition.keys())) beh = choice(list(population_composition[strat].keys())) a = MarketAgent(agent_id, self, init_shares, init_agent_wealth, glob_risk_aversion, glob_loss_aversion, beh, strat, agent_particip_rate) self.schedule.add(a) agent_id += 1 self.global_wealth = sum( [agent.wealth for agent in self.schedule.agents]) self.agg_sells = 0 self.agg_buys = 0 self.available_sells = 0 self.available_buys = 0 self.buy_ratio = 0 self.sell_ratio = 0 self.matched_trades = [] self.datacollector = ModDataCollector(model_reporters={ "Global Wealth": "global_wealth", "Price": "stock.price", "Return": "stock.last_return", "Vol": "stock.vol", "Skew": "stock.skew", "Kurt": "stock.kurt", "Dividend": "stock.dividend", "Agg Sells": "agg_sells", "Agg Buys": "agg_buys", "Av Sells": "available_sells", "Av Buys": "available_buys", "Buy Ratio": "buy_ratio", "Sell Ratio": "sell_ratio", "Matched Trades": "matched_trades" }, agent_reporters={ "Wealth": "wealth", "Cash": "cash", "Stock Weight": "stock_weight", "Stock Shares": "stock_shares", "Demand": "share_demand", "Target Trade": "target_shares", "Actual Trade": "trade_shares", "Price Expectation": "strategy.exp_p_d" }) self.net = self.generate_net() def step(self): self.datacollector.collect(self) self.schedule.step() self.settle() for agent in self.schedule.agents: agent.cash *= (1 + self.rf_rate)**self.dt if self.current_step % ((self.dt**-1) / self.stock.dividend_freq) == 0: self.stock.update_dividend() for agent in self.schedule.agents: agent.cash += (self.stock.dividend / self.stock.dividend_freq) * agent.stock_shares self.global_wealth = sum( [agent.wealth for agent in self.schedule.agents]) self.current_step += 1 def settle(self): if self.settle_type == 'limit': self.matched_trades = self.order_book.get_matched_trades() self.order_book.clear() for trade in self.matched_trades: buy_agent = self.schedule.agents[trade.buy_agent] sell_agent = self.schedule.agents[trade.sell_agent] buy_agent.stock_shares += trade.quantity buy_agent.cash -= trade.quantity * trade.price sell_agent.stock_shares -= trade.quantity sell_agent.cash += trade.quantity * trade.price self.stock.price = self.calculate_VWAP() elif self.settle_type == 'market': sells = [x for x in self.order_book.orders if x.side == 'sell'] buys = [x for x in self.order_book.orders if x.side == 'buy'] self.agg_sells = sum([x.quantity for x in sells]) self.agg_buys = sum([x.quantity for x in buys]) if self.agg_sells == 0 or self.agg_buys == 0: self.stock.price = self.stock.price return self.available_sells = min( self.agg_sells, self.stock.outstanding_shares) #add Inventory self.available_buys = min(self.agg_buys, self.stock.outstanding_shares) self.buy_ratio = (min(self.agg_buys, self.available_sells) / self.agg_buys) self.sell_ratio = (min(self.agg_sells, self.available_buys) / self.agg_sells) self.stock.price = self.stock.price * ( 1 + self.eta * (self.agg_buys - self.agg_sells) ) # find a better price mechanism # rho = 0.95 # f = rho / (1 + self.rf_rate - rho) # g = (1/self.rf_rate) * (1 + f) * (self.stock.init_dividend - self.glob_risk_aversion # * (self.stock.div_noise_sig**2) * (1000/self.n_agents)) # self.stock.price = f * self.stock.dividend + g for order in self.order_book.orders: # need to prelist if using RandomScheduler agent = self.schedule.agents[order.agent_id] if order.side == 'buy': trade_quantity = self.buy_ratio * order.quantity agent.stock_shares += trade_quantity agent.cash -= trade_quantity * self.stock.price if order.side == 'sell': trade_quantity = self.sell_ratio * order.quantity agent.stock_shares -= trade_quantity agent.cash += trade_quantity * self.stock.price self.order_book.clear() def calculate_VWAP(self): trades = [x for x in self.matched_trades if x.quantity > 0] volume = sum([x.quantity for x in trades]) if volume <= 0: return self.stock.price return sum( multiply([x.quantity for x in trades], [x.price for x in trades])) / volume def generate_net(self): net = nx.scale_free_graph(self.n_agents, alpha=0.1, beta=0.01, gamma=0.89) net = nx.to_undirected(net) nodes = list(net.nodes) shuffle(nodes) for agent, node in zip(self.schedule.agents, nodes): agent.node = node net.nodes[node]['agent_id'] = agent.agent_id net.nodes[node]['strat'] = agent.strategy.strat_name return net
class SnetSim(Model): def __init__(self, study_path='study.json'): self.gepResult = None with open(study_path) as json_file: config = json.load(json_file, object_pairs_hook=OrderedDict) #save the config with the output filename = config['parameters']['output_path'] + study_path #make sure the output_path folder exists if not os.path.exists(config['parameters']['output_path']): os.makedirs(config['parameters']['output_path']) pretty = json.dumps(config, indent=2, separators=(',', ':')) with open(filename, 'w') as outfile: outfile.write(pretty) outfile.close() # print(json.dumps(config['ontology'], indent=2)) self.parameters = config['parameters'] super().__init__(self.parameters['seed']) self.reproduction_report = self.reproduction_report() self.blackboard = config['blackboard'] self.ontology = config['ontology'] self.registry = registry self.emergent_functions = OrderedDict() self.emergent_functions_arity = OrderedDict() self.emergent_functions_call_number = 0 self.stochastic_pattern = re.compile(r'_stochastic\d+') self.prefix_pattern = re.compile(r'^f\d+_') pickle_config_path = config['parameters'][ 'output_path'] + 'pickles/' + 'index.p' if pickle_config_path and os.path.exists(pickle_config_path): with open(pickle_config_path, 'rb') as cachehandle: pickle_config = pickle.load(cachehandle) else: pickle_config = OrderedDict([("count", 0), ("pickles", OrderedDict())]) self.pickle_count = pickle_config[ 'count'] # contains the next number for the pickle file self.pickles = pickle_config['pickles'] self.resultTuple = () # self.cache = LRU(max_size = 512) self.cache = LRU() # Buyers gather offers by ranking those who offer to sell the product that have a price overlap. # call choose partners several times to ensure that all parts that the supply chain has a # chance to be settled in multiple trades, or offer networks have a chance to be filled. # In step the agent has a chance to put out a new message given the knowledge of purchases # made on the last round stage_list = [ 'step', 'gather_offers', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', 'choose_partners', ] self.schedule = StagedActivation(self, stage_list=stage_list, shuffle=True, shuffle_between_stages=True) # Create agents # first initial agents then random agents initial_blackboard = copy.deepcopy(self.blackboard) self.blackboard = [] agent_count = 0 for i, message in enumerate(initial_blackboard): if message['type'] in self.parameters['agent_parameters']: agent_parameters = self.parameters['agent_parameters'][ message['type']] else: agent_parameters = None for _ in range(self.parameters['blackboard_agents'][i]): a = globals()[message['type']](agent_count, self, message, agent_parameters) self.schedule.add(a) agent_count += 1 for agent_type, n in self.parameters['random_agents'].items(): if agent_type in self.parameters['agent_parameters']: agent_parameters = self.parameters['agent_parameters'][ agent_type] else: agent_parameters = None for i in range(n): a = globals()[agent_type](agent_count, self, None, agent_parameters) self.schedule.add(a) agent_count += 1 print("Final line of snet sim init") def remove_suffix(self, func_name): cut_tuple = func_name if (func_name): stochastic_suffix = self.stochastic_pattern.search(func_name) if (stochastic_suffix): stochastic_suffix = stochastic_suffix.group() cut_tuple = func_name[:-len(stochastic_suffix)] return cut_tuple @cachedmethod('cache') @pickleThis def memoise_pickle(self, tuple_key): result = None try: cut_tuple = self.remove_suffix(tuple_key[0]) if len(self.resultTuple) and cut_tuple: result = self.registry[cut_tuple](*self.resultTuple)() else: result = self.registry[cut_tuple]() except IOError as e: print("I/O error({0})".format(e)) except ValueError as e: print("ValueError({0})".format(e)) except AttributeError as e: print("AttributeError({0})".format(e)) except TypeError as e: print("TypeError({0})".format(e)) except RuntimeError as e: print("RuntimeError({0})".format(e)) except IndexError as e: print("IndexError({0})".format(e)) except: print("Unexpected error:", sys.exc_info()[0]) raise return result def remove_prefix(self, func_name): cut_tuple = func_name if (func_name): call_number_prefix = self.prefix_pattern.search(func_name) if (call_number_prefix): call_number_prefix = call_number_prefix.group() cut_tuple = func_name[len(call_number_prefix):] return cut_tuple def get_call_prefix(self, func_name): call_prefix = None if (func_name): call_number_prefix = self.prefix_pattern.search(func_name) if (call_number_prefix): call_prefix = call_number_prefix.group() return call_prefix def call_emergent_function(self, gep_result, root): print("SnetSim calling emergent function with root {0} : {1}".format( root, gep_result)) self.gepResult = copy.deepcopy(gep_result) func_tuple = self.call_memoise_pickle(root) print("SnetSim called emergent function with root {0} with result {1}". format(root, func_tuple)) return func_tuple def call_memoise_pickle(self, root): # right now, self.emergentfunctions looks like: # f1: a,b,f2,c,d # f2: e,d,f3,f,g # f3: h,i,j # #You should go through the original problem that you had in the modulargep.txt file in the singularitynet directory #its going to be a matter of creating a registry for a functionlist on the fly from the real registry I think. result = None func_tuple = (None, None) if root: result_list = [] func_list = [] # argTuple = () if root in self.gepResult: args = self.gepResult[root] # argTuple = tuple(args) for arg in args: temp_func_tuple, temp_result = self.call_memoise_pickle( arg) result_list.append(temp_result) func_list.append(temp_func_tuple) carried_back = tuple(func_list) strip_prefix = self.remove_prefix(root) func_tuple = (strip_prefix, carried_back) self.resultTuple = tuple( result_list ) # You have to set a global to memoise and pickle correctly if strip_prefix is not None: result = self.memoise_pickle(func_tuple) return func_tuple, result def reproduction_report(self): file = None path = self.parameters['output_path'] + 'reproduction_report.csv' file = open(path, "w") file.write( "time;agent;label;utility;agi_tokens;buyer_score;seller_score;sign_displayed;bought_items\n" ) return file def print_reproduction_report_line(self, agent, utility, bought_items): a = self.schedule.time b = agent.unique_id c = agent.message['label'] d = utility e = agent.agiTokens f = agent.max_buyer_score g = agent.max_seller_score h = agent.message['sign'] i = bought_items self.reproduction_report.write( "{0};{1};{2};{3};{4};{5};{6};{7};{8}\n".format( a, b, c, d, e, f, g, h, i)) self.reproduction_report.flush() def print_logs(self): filename = self.parameters['output_path'] + "logs/log" + str( self.schedule.time) + ".txt" pretty = json.dumps(self.blackboard, indent=2, separators=(',', ':')) with open(filename, 'w') as outfile: outfile.write(pretty) outfile.close() #json.dump(self.blackboard, outfile) pickle_config_path = self.parameters[ 'output_path'] + 'pickles/' + 'index.p' pickle_config = OrderedDict([('count', self.pickle_count), ('pickles', self.pickles)]) with open(pickle_config_path, 'wb') as outfile: pickle.dump(pickle_config, outfile) outfile.close() def visualize(self): # todo: visualize changes in price and test score and relative wealth pass def step(self): """Advance the model by one step.""" print("IN SnetSim step, time " + str(self.schedule.time)) self.print_logs() # self.visualize() after learning agents are implemented self.schedule.step() def go(self): for i in range(self.parameters['max_iterations']): print("iteration " + str(i)) self.step()
class FormationFlying(Model): # ========================================================================= # Create a new FormationFlying model. # # Args: # n_flights: Number of flights # width, height: Size of the space, in kilometers. # speed: cruise-speed of flights in m/s. # communication_range: How far around should each Boid look for its neighbors # separation: What's the minimum distance each Boid will attempt to # keep from any other the three drives. # ========================================================================= def __init__( self, n_flights=2, n_origin_airports=2, n_destination_airports=2, width=1500, # [km] height=1500, speed=0.220, #[km/second] max_speed=0.500, communication_range=1000, #[km] departure_window=3, origin_airport_x=[ 0.0, 0.3 ], # the origin airports are randomly generated within these boundaries origin_airport_y=[0.0, 0.3], destination_airport_x=[0.7, 0.9], # same for destination airports destination_airport_y=[0.7, 0.9], fuel_reduction=0.75, negotiation_method=1, joining_method=0, alliance_ratio=0.30, manager_ratio=0.40, offer_ratio=0.80, entrance_fee=50, bid_increase=10): # ===================================================================== # Initialize parameters, the exact values will be defined later on. # ===================================================================== self.n_flights = n_flights self.n_origin_airports = n_origin_airports self.n_destination_airports = n_destination_airports self.vision = communication_range self.speed = speed self.max_speed = max_speed self.height = height self.width = width # The agents are activated in random order at each step, in a space that # has a certain width and height and that is not toroidal # (which means that edges do not wrap around) self.schedule = StagedActivation(self, stage_list=["step", "advance"], shuffle=True) # This line has changed # in V9 on 13-oct. You could add additional methods to the "stage_list" if you want to do more substeps of a # negotiation within one agent step. self.space = ContinuousSpace(width, height, False) # These are values between [0,1] that limit the boundaries of the # position of the origin- and destination airports. self.origin_airport_x = origin_airport_x self.origin_airport_y = origin_airport_y self.destination_airport_x = destination_airport_x self.destination_airport_y = destination_airport_y self.destination_agent_list = [] self.departure_window = departure_window self.fuel_reduction = fuel_reduction self.negotiation_method = negotiation_method self.joining_method = joining_method self.alliance_ratio = alliance_ratio self.manager_ratio = manager_ratio self.offer_ratio = offer_ratio self.entrance_fee = entrance_fee self.bid_increase = bid_increase self.fuel_savings_closed_deals = 0 self.total_planned_fuel = 0 self.manager_counter = 0 self.new_formation_counter = 0 self.add_to_formation_counter = 0 self.formation_counter = 0 self.agents_in_formation = 0 self.total_fuel_consumption = 0 self.alliance_fuel_consumption = 0 self.alliance_planned_fuel = 0 self.total_flight_time = 0 self.total_delay = 0 self.origin_list = [] self.destination_list = [] self.make_airports() self.make_agents() self.running = True self.datacollector = DataCollector(model_reporter_parameters, agent_reporter_parameters) # ========================================================================= # Create all flights, the flights are not all initialized at the same time, # but within a departure window. # ========================================================================= def make_agents(self): for i in range(self.n_flights): departure_time = self.random.uniform(0, self.departure_window) pos = self.random.choice(self.origin_list) destination_agent = self.random.choice(self.destination_agent_list) destination_pos = destination_agent.pos flight = Flight( i, self, pos, destination_agent, destination_pos, departure_time, self.speed, self.max_speed, self.vision, ) self.space.place_agent(flight, pos) self.schedule.add(flight) # ============================================================================= # Create all airports. The option "inactive_airports" gives you the # opportunity to have airports close later on in the simulation. # ============================================================================= def make_airports(self): inactive_airports = 0 for i in range(self.n_origin_airports): x = self.random.uniform( self.origin_airport_x[0], self.origin_airport_x[1]) * self.space.x_max y = self.random.uniform( self.origin_airport_y[0], self.origin_airport_y[1]) * self.space.y_max closure_time = 0 pos = np.array((x, y)) airport = Airport(i + self.n_flights, self, pos, "Origin", closure_time) self.space.place_agent(airport, pos) self.schedule.add( airport ) # they are only plotted if they are part of the schedule for i in range(self.n_destination_airports): x = self.random.uniform( self.destination_airport_x[0], self.destination_airport_x[1]) * self.space.x_max y = self.random.uniform( self.destination_airport_y[0], self.destination_airport_y[1]) * self.space.y_max if inactive_airports: closure_time = 50 inactive_airports = 0 else: closure_time = 0 pos = np.array((x, y)) airport = Airport(i + self.n_flights + self.n_origin_airports, self, pos, "Destination", closure_time) self.space.place_agent(airport, pos) self.destination_agent_list.append(airport) self.schedule.add( airport ) # agents are only plotted if they are part of the schedule # ========================================================================= # Define what happens in the model in each step. # ========================================================================= def step(self): all_arrived = True total_deal_value = 0 for agent in self.schedule.agents: if type(agent) is Flight: total_deal_value += agent.deal_value if agent.state != "arrived": all_arrived = False if all_arrived: self.running = False # This is a verification that no deal value is created or lost (total deal value # must be 0, and 0.001 is chosen here to avoid any issues with rounded numbers) if abs(total_deal_value) > 0.001: raise Exception("Deal value is {}".format(total_deal_value)) self.schedule.step() self.datacollector.collect(self)
class OpinionModel(Model): ''' A model with some number of agents Keyword arguments: N -- Number of agents neighborhoods -- An NxX matrix. neighborhoods[a] is agent a\'s list of neighbors. The neighborhoods is not actually a matrix. Each inner list may be of different length. intial_opinions -- This is a list size N of opinions. Each inner list must have the same length, the opinions are then labeled Opinion0, Opinion1, ..., OpinionZ. potentials -- Potentials is a 1-D list of functions Each function describes how agents are influenced by innodes. coupling -- AxA matrix, where A = |opinions|. Describes how opinions affect each other. ''' def __init__(self, N, neighborhoods, weights, initial_opinions, potentials, coupling, schedule="simultaneous"): self.ALPHA = .001 self.num_agents = N self.neighborhoods = neighborhoods self.initial_opinions = initial_opinions self.potentials = potentials self.coupling = coupling if weights is None: self.weights = [None for i in range(self.num_agents)] else: self.weights = weights #Set schedule if schedule == 'simultaneous': self.schedule = StagedActivation( self, stage_list=["simultaneousStep", "simultaneousAdvance"], shuffle=False) elif schedule == 'pairwise': self.schedule = StagedActivation( self, stage_list=["reset", "pairwiseStep", "noise"], shuffle=True) #stage_list is where you add "coupling" and "noise". #Create agents for i in range(self.num_agents): a_params = OpinionAgentParameters(i, self, self.neighborhoods[i], self.weights[i], self.potentials[i], initial_opinions[i]) if schedule == 'simultaneous': a = OpinionAgent(a_params) elif schedule == 'pairwise': a = OpinionAgent(a_params) self.schedule.add(a) ag_reps = dict() for i in range(len(self.schedule.agents[0].opinions)): ag_reps["Opinion" + str(i)] = self.makeLam(i) self.datacollector = DataCollector(agent_reporters=ag_reps) def step(self): ''' Advance the model one step ''' self.datacollector.collect(self) self.schedule.step() def run(self, steps): for i in range(steps): self.step() def total_change(self): sum = 0 for j in range(len(self.schedule.agents[0].opinions)): for i in range(self.num_agents): sum += abs(self.schedule.agents[i].opinions[0] - self.schedule.agents[i].nextOpinion[0]) return sum def makeLam(self, i): ''' Don't use outside of the context of the OpinionModel's init method. This function is needed in order for the DataCollector to work properly, intializing the lambdas inside __init__ inside a for loop causes the last value of the iterator to be used for all of the functions, causing unwanted behavior. So that's why this function exists. ''' return lambda a: a.opinions[i]