示例#1
0
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()
示例#2
0
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()
示例#3
0
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()
示例#4
0
文件: test_time.py 项目: septra/mesa
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()
示例#5
0
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()
示例#6
0
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)
示例#7
0
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()
示例#8
0
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()
示例#9
0
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)
示例#10
0
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()
示例#11
0
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)
示例#12
0
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()
示例#14
0
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
示例#15
0
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()
示例#16
0
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)
示例#17
0
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]