예제 #1
0
파일: model.py 프로젝트: bangtree/mesa
class Schelling(Model):
    '''
    Model class for the Schelling segregation model.
    '''

    def __init__(self, height=20, width=20, density=0.8, minority_pc=0.2, homophily=3):
        '''
        '''

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophily = homophily

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=True)

        self.happy = 0
        self.datacollector = DataCollector(
            {"happy": "happy"},  # Model-level count of happy agents
            # For testing purposes, agent's individual x and y
            {"x": lambda a: a.pos[0], "y": lambda a: a.pos[1]})

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            if self.random.random() < self.density:
                if self.random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent = SchellingAgent((x, y), self, agent_type)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

        self.running = True
        self.datacollector.collect(self)

    def step(self):
        '''
        Run one step of the model. If All agents are happy, halt the model.
        '''
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False
예제 #2
0
class SchellingModel(Model):
    """
    Model class for the Schelling segregation model.
    """

    def __init__(self, height, width, density, minority_pc, homophily):
        """
        """

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophily = homophily

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=True)

        self.happy = 0
        self.total_agents = 0
        self.datacollector = DataCollector(
            {"unhappy": lambda m: m.total_agents - m.happy},
            # For testing purposes, agent's individual x and y
            {"x": lambda a: a.pos[X], "y": lambda a: a.pos[Y]},
        )

        self.running = True

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell, x, y in self.grid.coord_iter():
            if random.random() < self.density:
                if random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent = SchellingAgent(self.total_agents, agent_type)
                self.grid.position_agent(agent, x, y)
                self.schedule.add(agent)
                self.total_agents += 1

    def step(self):
        """
        Run one step of the model. If All agents are happy, halt the model.
        """
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        self.datacollector.collect(self)

        if self.happy == self.total_agents:
            self.running = False
예제 #3
0
class PartyModel(Model):
    def __init__(self,
                 height=20,
                 width=20,
                 number_introvert=30,
                 number_ambivert=40,
                 number_extrovert=30):
        '''
        '''

        self.height = height
        self.width = width

        self.number_attendees = 1.0 * \
            (number_introvert + number_ambivert + number_extrovert)

        self.number_introvert = number_introvert
        self.number_ambivert = number_ambivert
        self.number_extrovert = number_extrovert

        self.percent_introvert = number_introvert / self.number_attendees
        self.percent_ambivert = number_ambivert / self.number_attendees
        self.percent_extrovert = number_extrovert / self.number_attendees

        self.introvert_cutoff = self.percent_introvert
        self.ambivert_cutoff = self.percent_introvert + self.percent_ambivert

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(width, height, torus=True)

        self.happy = 0
        self.happy_introverts = 0
        self.happy_ambiverts = 0
        self.happy_extroverts = 0
        self.datacollector = DataCollector(
            {"happy": "happy"},  # Model-level count of happy agents
            # For testing purposes, agent's individual x and y
            {
                "x": lambda a: a.pos[0],
                "y": lambda a: a.pos[1]
            })

        count = 0

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            if count < self.number_attendees:
                extroversion = self.random.random()
                if extroversion < self.introvert_cutoff:
                    agent_type = "introvert"
                else:
                    if extroversion < self.ambivert_cutoff:
                        agent_type = "ambivert"
                    else:
                        agent_type = "extrovert"

                agent = PartyAgent((x, y), self, agent_type)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)
                count = count + 1
        self.running = True
        self.datacollector.collect(self)

    '''
    Run one step of the model. If all agents are happy, halt the model.
    '''

    def step(self):

        # Reset counters of happy agents
        self.happy = 0
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

        if self.happy > self.schedule.get_agent_count() * 0.95:
            self.running = False
예제 #4
0
class NaSchTraffic(Model):
    """
    Model class for the Nagel and Schreckenberg traffic model.
    """
    def __init__(self,
                 height=1,
                 width=60,
                 vehicle_quantity=5,
                 general_max_speed=4,
                 seed=None):
        """"""

        super().__init__(seed=seed)
        self.height = height
        self.width = width
        self.vehicle_quantity = vehicle_quantity
        self.general_max_speed = general_max_speed
        self.schedule = SimultaneousActivation(self)
        self.grid = SingleGrid(width, height, torus=True)

        self.average_speed = 0.0
        self.averages = []
        self.total_speed = 0

        self.datacollector = DataCollector(
            model_reporters={
                "Average_Speed": "average_speed"
            },  # Model-level count of average speed of all agents
            # For testing purposes, agent's individual x position and speed
            agent_reporters={
                "PosX": lambda x: x.pos[0],
                "Speed": lambda x: x.speed,
            },
        )

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        cells = list(self.grid.coord_iter())
        self.random.shuffle(cells)
        for vehicle_iter in range(0, self.vehicle_quantity):
            cell = cells[vehicle_iter]
            (content, x, y) = cell
            agent = VehicleAgent((x, y), self, general_max_speed)
            self.grid.position_agent(agent, (x, y))
            self.schedule.add(agent)

        self.running = True
        self.datacollector.collect(self)

    def step(self):
        """
        Run one step of the model. Calculate current average speed of all agents.
        """
        if self.schedule.steps == 100:
            self.running = False
        self.total_speed = 0
        # Step all agents, then advance all agents
        self.schedule.step()
        if self.schedule.get_agent_count() > 0:
            self.average_speed = self.total_speed / self.schedule.get_agent_count(
            )
        else:
            self.average_speed = 0
        self.averages.append(self.average_speed)
        # collect data
        self.datacollector.collect(self)
예제 #5
0
class Schelling(Model):
    """
    Model class for the Schelling segregation model.
    """

    def __init__(self, height=30, width=30, density=0.9, minority_pc=0.5, homophily=3):
        """
        """
        # Height and width of the Grid; 
        # Height and width also defines the maximum number of agents that could be in the environment
        self.height = height
        self.width = width
        
        # Define the population density; Float between 0 and 1
        self.density = density
        
        # Ratio between blue and red. 
        # Blue is minority, red is majority; Float between 0 and 1; if > 0.5, blue becomes majority
        # 1 에 가까워 질수록 파란색이 많아지고,
        # 0 에 가까워 질수록 빨간색이 많아진다.
        self.minority_pc = minority_pc
        
        # number of similar neighbors required for the agents to be happy
        # Takes integer value between 0 and 8 since you can only be surrounded by 8 neighbors
        self.homophily = homophily

        # Scheduler controls the order in which agents are activated
        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(width, height, torus=True)

        self.happy = 0
        # Obtain data after each step
        self.datacollector = DataCollector(
            {"happy": "happy"},  # Model-level count of happy agents
            # For testing purposes, agent's individual x and y
            {"x": lambda a: a.pos[0], "y": lambda a: a.pos[1]},
        )

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            if self.random.random() < self.density:
                if self.random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent = SchellingAgent((x, y), self, agent_type)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

        self.running = True
        self.datacollector.collect(self)

    # The class requires a step function that represent each run
    def step(self):
        """
        Run one step of the model. If All agents are happy, halt the model.
        """
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

        # 여기서 terminate 하는 것을 manage 한다.
        if self.happy == self.schedule.get_agent_count():
            self.running = False
예제 #6
0
class Schelling(Model):
    '''
    Model class for the Schelling segregation model.
    '''
    def __init__(self,
                 height=20,
                 width=20,
                 density=0.8,
                 minority_pc=0.2,
                 homophily=3):
        '''
        '''

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophily = homophily

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=True)

        self.happy = 0
        self.datacollector = DataCollector(
            {"happy": "happy"},  # Model-level count of happy agents
            # For testing purposes, agent's individual x and y
            {
                "x": lambda a: a.pos[0],
                "y": lambda a: a.pos[1]
            })

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            if self.random.random() < self.density:
                if self.random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent = SchellingAgent((x, y), self, agent_type)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

        self.running = True
        self.datacollector.collect(self)

    def step(self):
        '''
        Run one step of the model. If All agents are happy, halt the model.
        '''
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False
예제 #7
0
class Robot2D(Model):
    """
    Model class for the 2D robot model.
    """

    def __init__(self, height=75, width=75):
        self.height = height
        self.width = width
        self.schedule = BaseScheduler(self)
        self.grid = SingleGrid(width, height, torus=True)
        self.ready=0
        self.localizedRobots=0
        self.movingAgents=0
        self.seeds=[] # Seed robots
        
        self.datacollector = DataCollector(
            model_reporters={"Ready": "ready", "Localized": "localizedRobots"},
            agent_reporters={"x": lambda a: a.pos[0], "y": lambda a: a.pos[1], "Gradient": "gradient"}
        )
        
        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        margin1X=[i for i in range(15)]
        margin2X=[i for i in range(height-41, height)]
        margin1Y=[i for i in range(5)]
        margin2Y=[i for i in range(height-5, height)]
        nRobots=0
        
        for cell in self.grid.coord_iter():
            # Change coordinates order
            y = cell[1] 
            x = cell[2]
            
            if x in margin1X or x in margin2X or y in margin1Y or y in margin2Y:
                continue
                
            if nRobots < MAX_ROBOTS:
                agent = RobotAgent((x,y), self, 1, figure1)
                self.grid.place_agent(agent, (x, y))
                self.schedule.add(agent)
                nRobots+=1
            else: # SEED ROBOTS
                if x > 40:
                    x=37
                    y+=1
                    # SEED 1
                    agent = RobotAgent((x,y), self, 0, figure1, loc=[0,0], grad=0)
                    self.grid.place_agent(agent, (x, y))
                    self.seeds.append(agent)
                    self.schedule.add(agent)

                    # SEED 2
                    agent = RobotAgent((x+1,y), self, 0, figure1, loc=[1,0], grad=1)
                    self.grid.place_agent(agent, (x+1, y))
                    self.seeds.append(agent)
                    self.schedule.add(agent)

                    # SEED 3
                    agent = RobotAgent((x,y+1), self, 0, figure1, loc=[0,1], grad=1)
                    self.grid.place_agent(agent, (x, y+1))
                    self.seeds.append(agent)
                    self.schedule.add(agent)

                    # SEED 4
                    agent = RobotAgent((x+1,y+1), self, 0, figure1, loc=[1,1], grad=1)
                    self.grid.place_agent(agent, (x+1, y+1))
                    self.seeds.append(agent)
                    self.schedule.add(agent)
                else:
                    # SEED 1
                    x-=1
                    y+=1
                    agent = RobotAgent((x,y), self, 0, figure1, loc=[0,0], grad=0)
                    self.grid.place_agent(agent, (x, y))
                    self.seeds.append(agent)
                    self.schedule.add(agent)

                    # SEED 2
                    agent = RobotAgent((x+1,y), self, 0, figure1, loc=[1,0], grad=1)
                    self.grid.place_agent(agent, (x+1, y))
                    self.seeds.append(agent)
                    self.schedule.add(agent)

                    # SEED 3
                    agent = RobotAgent((x,y+1), self, 0, figure1, loc=[0,1], grad=1)
                    self.grid.place_agent(agent, (x, y+1))
                    self.seeds.append(agent)
                    self.schedule.add(agent)

                    # SEED 4
                    agent = RobotAgent((x+1,y+1), self, 0, figure1, loc=[1,1], grad=1)
                    self.grid.place_agent(agent, (x+1, y+1))
                    self.seeds.append(agent)
                    self.schedule.add(agent)
                
                break
        
        self.running = True

    def step(self):
        """
        Run one step of the model.
        """
        # collect data
        self.datacollector.collect(self)
        
        self.schedule.step()
예제 #8
0
class Model(Model):
    """
    Model class for the Schelling segregation model.
    """
    def __init__(self, height=30, width=30, density=0.1, oxy_den_count=1):
        """
        """

        self.height = height
        self.width = width
        self.density = density

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(width, height, torus=True)
        self.datacollector = DataCollector(
            {"happy": "happy"},  # Model-level count of happy agents
            # For testing purposes, agent's individual x and y
            {
                "x": lambda a: a.pos[0],
                "y": lambda a: a.pos[1]
            },
        )

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            if self.random.random() < self.density:
                agent = SchellingAgent((x, y), self)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

        self.running = True
        self.datacollector.collect(self)

    def get_height():
        return self.height

    def get_width():
        return self.width

    def get_oxygen(self, x, y):
        return -1 * pow((x / 5) - 5, 2) - pow((y / 5) - 5, 2) + 25

    def get_oxy_grad(self, x, y):
        a = -(((2 * x) / 25) - 2)
        b = -(((2 * y) / 25) - 2)
        if abs(b) != 0:
            b = b / abs(b)
        if abs(a) != 0:
            a = a / abs(a)

        total = -1 * a - b
        return a, b, total

    def step(self):
        """
        Run one step of the model. If All agents are happy, halt the model.
        """
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)
예제 #9
0
class MondoModel(Model):
    """Questo è il mondo fatto a griglia"""
    def __init__(self, popolazione, width, height):
        super().__init__()
        self.popolazione = popolazione
        self.grid = SingleGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.points = []
        # Create agents
        for i in range(self.popolazione):
            a = PersonAgent(i, self)
            self.schedule.add(a)
            emptyspace = self.grid.find_empty()
            if emptyspace is not None:
                self.grid.place_agent(a, emptyspace)

        paziente_zero = self.schedule.agents[0]
        paziente_zero.virus = Virus(mortalita=20,
                                    tempo_incubazione=3,
                                    infettivita=70)
        paziente_zero.ttl = paziente_zero.virus.tempo_incubazione

    def step(self):
        '''Advance the model by one step.'''
        self.schedule.step()
        suscettibili = 0
        infetti = 0
        morti = 0
        immuni = 0
        for persona in self.schedule.agents:
            if persona.isAlive is False:
                morti += 1
            elif persona.isImmune is True:
                immuni += 1
            elif persona.virus is not None:
                infetti += 1
            else:
                suscettibili += 1
        self.points.append([suscettibili, infetti, morti, immuni])

    def crea_grafico(self):
        global_health_status = np.zeros((self.grid.width, self.grid.height))
        for persona, x, y in self.grid.coord_iter(
        ):  # ctrl+click per spiegare meglio

            if persona is None:
                global_health_status[x][y] = StatoCella.vuoto
            elif persona.isAlive is False:
                global_health_status[x][y] = StatoCella.morto
            elif persona.isImmune is True:
                global_health_status[x][y] = StatoCella.guarito
            elif persona.virus is not None:
                global_health_status[x][y] = StatoCella.infetto
            else:
                global_health_status[x][y] = StatoCella.suscettibile

        cmap = matplotlib.colors.ListedColormap([(0, 0, 0), (1, 0, 0),
                                                 (1, 1, 0), (0, 0, 1),
                                                 (0, 1, 0)])
        img = plt.imshow(global_health_status,
                         interpolation='nearest',
                         vmin=0,
                         vmax=4,
                         cmap=cmap)
        plt.colorbar(img, ticks=[0, 1, 2, 3, 4])
        plt.show()

    def crea_grafico_2(self):
        matplotlib.pyplot.plot(self.points)
        matplotlib.pyplot.show()
예제 #10
0
class Anthill(Model):
    def __init__(self):

        self.grid = SingleGrid(WIDTH, HEIGHT, False)
        self.schedule = RandomActivation(self)
        self.running = True
        self.internalrate = 0.2
        self.ant_id = 1
        self.tau = np.zeros((WIDTH,HEIGHT))
        self.datacollector = DataCollector({"Total number of Ants": lambda m: self.get_total_ants_number(),
                                            "mean tau": lambda m: self.evaluation1(),
                                            "sigma": lambda m: self.evaluation2(),
                                            "sigma*" :  lambda m: self.evaluation3(),
                                            })

        # List containing all coordinates of the boundary, initial ants location and brood location
        self.bound_vals = []
        self.neigh_bound = []
        self.middle=[]
        self.datacollector.collect(self)
        self.passage_to_right = []
        self.passage_to_left = []

        # for i in range(WIDTH):
        #     for j in range(HEIGHT):
        #         if i == 0 or j == 0 or i == WIDTH-1 or j == HEIGHT-1:
        #             self.bound_vals.append((i,j))
        #         if i == 1 or i == WIDTH - 2 or j == 1 or j == HEIGHT-2:
        #             self.neigh_bound.append((i,j))
        ##

        for i in range(WIDTH):
            for j in range(HEIGHT):
                ##make boundary
                if i == 0 or j == 0 or i == WIDTH - 1 or j == HEIGHT - 1:
                    self.bound_vals.append((i,j))
                if i == MIDDLE and 0<j<WIDTH - 1:
                    self.bound_vals.append((i,j))
                    self.middle.append((i,j))

                ##save neighbor
                if j ==1 and 1<= i <= MIDDLE-2:
                    self.neigh_bound.append((i,j))
                if j ==1 and MIDDLE+2<=i<=WIDTH - 2:
                    self.neigh_bound.append((i,j))
                if j ==HEIGHT - 1 and 1<= i <= MIDDLE-2:
                    self.neigh_bound.append((i,j))
                if j ==HEIGHT - 1 and MIDDLE+2<=i<=WIDTH - 2:
                    self.neigh_bound.append((i,j))
                if i == 1 and 2<= j<= MIDDLE-3:
                    self.neigh_bound.append((i, j))
                if i == HEIGHT - 2 and 2<= j<= MIDDLE-3:
                    self.neigh_bound.append((i, j))

                ## we let the columns next to th middle become the entrance to next chamber
                if i == MIDDLE-1 and 0<j<WIDTH-1:
                    self.passage_to_left.append((i, j))
                if i == MIDDLE + 1 and 0 < j < WIDTH - 1:
                    self.passage_to_right.append((i, j))




        # Make a Fence boundary
        b = 0
        for h in self.bound_vals:
            br = Fence(b,self)

            self.grid.place_agent(br,(h[0],h[1]))
            b += 1



    def step(self):
        '''Advance the model by one step.'''

        # Add new ants into the internal area ont he boundary
        for xy in self.neigh_bound:
            # Add with probability internal rate and if the cell is empty
            if self.random.uniform(0, 1) < self.internalrate and self.grid.is_cell_empty(xy) == True:

                a = Ant(self.ant_id, self)

                self.schedule.add(a)
                self.grid.place_agent(a,xy)

                self.ant_id += 1

        # Move the ants
        self.schedule.step()
        self.datacollector.collect(self)

        # with open("data/p02_b0_tau.txt", "a") as myfile:
        #     myfile.write(str(self.mean_tau_ant) + '\n')
        # with open("data/p02_b0_sigma.txt", "a") as myfile:
        #     myfile.write(str(self.sigma) + '\n')
        # with open("data/p02_b0_sigmastar.txt","a") as myfile:
        #     myfile.write(str(self.sigmastar) + "\n")

    def get_total_ants_number(self):
        total_ants=0
        for (agents, _, _) in self.grid.coord_iter():
            if type(agents) is Ant:
                total_ants += 1
        return total_ants

    def evaluation1(self):
        ##creat a empty grid to store currently information
        total_ants = np.zeros((WIDTH,HEIGHT))

        ## count the number of currently information
        for (agents, i, j) in self.grid.coord_iter():
            if type(agents) is Ant:
                total_ants[i][j] = 1
            else:
                total_ants[i][j] = 0
        ##update the tau
        self.tau = self.tau + total_ants
        ##calcualte the mean tau
        self.mean_tau_ant = self.tau.sum()/((WIDTH-2)**2)
        return self.mean_tau_ant

    def evaluation2(self):


        ## we need to minus the mean tau so we need to ensure the result of boundary is zero
        ## so we let the bounday equal mean_tau_ant in this way the (tau-mean_tau_ant) is zero of boundary
        for site in self.bound_vals:
            self.tau[site[0]][site[1]] = self.mean_tau_ant


        ##calculate the sigmaa
        self.sigma = ((self.tau-self.mean_tau_ant)**2).sum()/((WIDTH-2)**2)

        ## rechange the boundaryy
        for site in self.bound_vals:
            self.tau[site[0]][site[1]] = 0

        return np.sqrt(self.sigma)

    def evaluation3(self):
        ##calculate the sigmastar
        self.sigmastar = np.sqrt(self.sigma)/self.mean_tau_ant

        return self.sigmastar
예제 #11
0
class VirtuousEmotivistModel(Model):
    '''
    Model class for the "Virtuous-Emotivist segregating opinion transfer model".
    '''

    def __init__(self, init_seed, height, width, density, minority_pc, homophily, virtuous_homophily, nudge_amount, num_to_argue, num_to_convert, convert_prob, convinced_threshold \
            , random_move_prob, traditionless_life_decrease, vir_a, vir_b, vir_c, emo_a, emo_b \
            , emo_c , emo_bias_a, emo_bias_b, emo_bias_c , strongest_belief_weight, count_extra_pow, count_extra_det \
            , count_extra_det_pow, extra_pow, extra_det , belief_of_extra_pow, belief_of_extra_det, belief_of_extra_det_pow):

        # uncomment to make runs reproducible
        super().__init__(seed=init_seed)

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        # segregation logic taken from the Schelling segregation model example
        self.homophily = homophily
        self.virtuous_homophily = virtuous_homophily
        self.convert_prob = convert_prob
        self.num_to_convert = num_to_convert
        self.traditionless_life_decrease = traditionless_life_decrease
        self.steps_since = 0

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=True)

        self.happy = 0
        self.convinced = 0
        self.virtuous_count = 0
        self.emotivist_count = 0
        self.virtuous_death_count = 0
        self.datacollector = DataCollector( # Model-level variables for graphs
            {"happy": "happy", "convinced": "convinced", "emotivist_count": "emotivist_count" \
                , "virtuous_count": "virtuous_count", "virtuous_death_count": "virtuous_death_count"},
            {"x": lambda a: a.pos[0], "y": lambda a: a.pos[1], "happy": lambda a: a.happy, # Agent-level variables
            "convinced": lambda a: a.convinced, "strongest_belief": lambda a: a.strongest_belief()
            , "beliefs": lambda a: a.beliefs_string(), "type": lambda a: 0 if isinstance(a, EmotivistAgent) else 1})

        self.nudge_amount = nudge_amount
        self.num_to_argue = num_to_argue
        self.convinced_threshold = convinced_threshold
        self.random_move_prob = random_move_prob

        population = [
            "A", "B", "C"
        ]  # defined here because of dependencies on the visualization side (emo_bias in server.py)
        self.population = population
        probs_emotivist = np.array([emo_a, emo_b, emo_c])
        probs_emotivist = probs_emotivist / np.sum(
            probs_emotivist)  # normalize probs to 1.0
        probs_virtuous = np.array([vir_a, vir_b, vir_c])
        probs_virtuous = probs_virtuous / np.sum(probs_virtuous)
        initial_bias_emotivist = {
            "A": emo_bias_a,
            "B": emo_bias_b,
            "C": emo_bias_c
        }
        self.strongest_belief_weight = strongest_belief_weight

        # Set up agents
        # We get a list of cells in order from the grid iterator
        # and randomize the list
        cell_list = list(self.grid.coord_iter())
        random.shuffle(cell_list)
        total_num_agents = self.density * self.width * self.height

        det_emotivists_added = 0
        pow_emotivists_added = 0
        det_pow_emotivists_added = 0

        # pregenerate a list of strongest_beliefs in random order according to distribution
        # currently only works with a population of 3 beliefs
        list_emotivist_choices = []
        emo_length = ceil((1.0 - self.minority_pc) * total_num_agents)
        for i in range(0, emo_length):
            if (float(i) / emo_length < probs_emotivist[0]):
                list_emotivist_choices.append(population[0])
            elif (float(i) / emo_length <
                  probs_emotivist[0] + probs_emotivist[1]):
                list_emotivist_choices.append(population[1])
            else:
                list_emotivist_choices.append(population[2])

        random.shuffle(list_emotivist_choices)

        list_virtuous_choices = []
        vir_length = ceil(self.minority_pc * total_num_agents)
        for i in range(0, vir_length):
            if (float(i) / vir_length < probs_virtuous[0]):
                list_virtuous_choices.append(population[0])
            elif (float(i) / vir_length <
                  probs_virtuous[0] + probs_virtuous[1]):
                list_virtuous_choices.append(population[1])
            else:
                list_virtuous_choices.append(population[2])

        random.shuffle(list_virtuous_choices)

        # create agents and add to grid
        i = 0
        for cell in cell_list:
            x = cell[1]
            y = cell[2]
            if i < total_num_agents:
                if i < self.minority_pc * total_num_agents:
                    #initial_strongestbelief_virtuous = random.choices(population, weights=probs_virtuous, k=1)[0]
                    initial_strongestbelief_virtuous = list_virtuous_choices.pop(
                    )
                    initial_beliefs_virtuous = {}
                    for belief in population:
                        if (belief == initial_strongestbelief_virtuous):
                            initial_beliefs_virtuous[
                                belief] = strongest_belief_weight
                        else:
                            initial_beliefs_virtuous[belief] = (
                                1 - strongest_belief_weight) / (
                                    len(population) - 1)
                    agent = VirtuousAgent(i, (x, y), self,
                                          initial_beliefs_virtuous)
                    self.virtuous_count += 1
                else:
                    #agent_type = 0
                    #initial_strongestbelief_emotivist = random.choices(population, weights=probs_emotivist, k=1)[0]
                    initial_strongestbelief_emotivist = list_emotivist_choices.pop(
                    )
                    initial_beliefs_emotivist = {}
                    det = 0.0
                    pow = 1.0
                    if (initial_strongestbelief_emotivist
                            == belief_of_extra_det
                            and det_emotivists_added < count_extra_det):
                        det = extra_det
                        det_emotivists_added += 1
                    elif (initial_strongestbelief_emotivist
                          == belief_of_extra_pow
                          and pow_emotivists_added < count_extra_pow):
                        pow = extra_pow
                        pow_emotivists_added += 1
                    elif (initial_strongestbelief_emotivist
                          == belief_of_extra_det_pow
                          and det_pow_emotivists_added < count_extra_det_pow):
                        pow = extra_pow
                        det_pow_emotivists_added += 1

                    for belief in population:
                        if (belief == initial_strongestbelief_emotivist):
                            initial_beliefs_emotivist[
                                belief] = strongest_belief_weight
                        else:
                            initial_beliefs_emotivist[belief] = (
                                1 - strongest_belief_weight) / (
                                    len(population) - 1)

                    agent = EmotivistAgent(i, (x, y), self,
                                           initial_beliefs_emotivist,
                                           initial_bias_emotivist, pow, det)
                    self.emotivist_count += 1

                i += 1
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

        self.last_agent_id = i
        # update message with starting probs
        self.message = "Emotivist probs: " + str(list(map(lambda x: "{:.2f}".format(x), probs_emotivist.tolist()))) \
                + ", Virtuous probs: " + str(list(map(lambda x: "{:.2f}".format(x), probs_virtuous.tolist())))
        self.running = True
        self.datacollector.collect(self)

    def update_emo_vir_count(self):
        emotivist_count = 0
        virtuous_count = 0
        for agent_type in self.datacollector.agent_vars["type"][-1]:
            if (agent_type[1] == 0):
                emotivist_count += 1
            else:
                virtuous_count += 1

        self.emotivist_count = emotivist_count
        self.virtuous_count = virtuous_count

    def update_happy_convinced_count(self):
        tmphappy = 0
        for agent_happy in self.datacollector.agent_vars["happy"][-1]:
            if (agent_happy[1]):
                tmphappy += 1
        tmpconvinced = 0
        for agent_convinced in self.datacollector.agent_vars["convinced"][-1]:
            if (agent_convinced[1]):
                tmpconvinced += 1

        self.happy = tmphappy
        self.convinced = tmpconvinced

    def step(self):
        '''
        Run one step of the model. Uncomment "self.running = False" to enable auto-stopping after the
        model has run for 200 steps with almost all agents happy and convinced
        '''
        # Reset counter of happy agents
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

        # update model-level counts
        self.update_happy_convinced_count()
        self.update_emo_vir_count()

        # optional auto-stopping
        if self.happy > self.schedule.get_agent_count(
        ) - 3 and self.convinced == self.schedule.get_agent_count() - 3:
            self.steps_since += 1
            if (self.steps_since > 200):
                #self.running = False
                pass
예제 #12
0
class Anthill(Model):
    def __init__(self):

        self.grid = SingleGrid(WIDTH, HEIGHT, False)
        self.schedule = RandomActivation(self)
        self.running = True
        self.internalrate = 0.2
        self.ant_id = 1
        self.tau = np.zeros((WIDTH, HEIGHT))
        self.datacollector = DataCollector({
            "Total number of Ants":
            lambda m: self.get_total_ants_number(),
            "mean tau":
            lambda m: self.evaluation1(),
            "sigma":
            lambda m: self.evaluation2(),
            "sigma*":
            lambda m: self.evaluation3(),
        })

        # List containing all coordinates of the boundary, initial ants location and brood location
        self.bound_vals = []
        self.neigh_bound = []
        self.datacollector.collect(self)

        # Make the bound_vals and neigh_bound lists by one of the following:
        # self.nowalls()
        self.onewall()
        # self.twowalls()
        # self.threewalls()

        # Make a Fence boundary
        b = 0
        for h in self.bound_vals:
            br = Fence(b, self)

            self.grid.place_agent(br, (h[0], h[1]))
            b += 1

    def step(self):
        '''Advance the model by one step.'''
        # Add new ants into the internal area ont he boundary

        for xy in self.neigh_bound:

            # Add with probability internal rate and if the cell is empty
            if self.random.uniform(
                    0, 1) < self.internalrate and self.grid.is_cell_empty(
                        xy) == True:

                a = Ant(self.ant_id, self)

                self.schedule.add(a)
                self.grid.place_agent(a, xy)

                self.ant_id += 1

        # Move the ants
        self.schedule.step()
        self.datacollector.collect(self)

        # Remove all ants in neigh_bound

        for (agents, i, j) in self.grid.coord_iter():
            if (i, j) in self.neigh_bound and type(agents) is Ant:

                self.grid.remove_agent(agents)
                self.schedule.remove(agents)

        data_tau.append(self.mean_tau_ant)
        data_sigma.append(np.sqrt(self.sigma))
        data_sigmastar.append(self.sigmastar)

        if len(data_sigmastar) > 2000:
            if abs(data_sigmastar[-2] - data_sigmastar[-1]) < 0.0000001:
                try:
                    # TAU
                    with open("results/m1_tau_inf.pkl", 'rb') as f:
                        tau_old = pickle.load(f)
                        tau_old[int(len(tau_old) + 1)] = data_tau
                        f.close()
                    pickle.dump(tau_old, open("results/m1_tau_inf.pkl", 'wb'))

                except:
                    pickle.dump({1: data_tau},
                                open("results/m1_tau_inf.pkl", 'wb'))

                try:
                    # SIGMA
                    with open("results/m1_sigma_inf.pkl", 'rb') as f:
                        sigma_old = pickle.load(f)
                        sigma_old[int(len(sigma_old) + 1)] = data_sigma
                        f.close()
                    pickle.dump(sigma_old,
                                open("results/m1_sigma_inf.pkl", 'wb'))

                except:
                    pickle.dump({1: data_sigma},
                                open("results/m1_sigma_inf.pkl", 'wb'))

                try:
                    # SIGMASTAR
                    with open("results/m1_sigmastar_inf.pkl", 'rb') as f:
                        sigmastar_old = pickle.load(f)
                        sigmastar_old[int(len(sigmastar_old) +
                                          1)] = data_sigmastar
                        f.close()
                    pickle.dump(sigmastar_old,
                                open("results/m1_sigmastar_inf.pkl", 'wb'))

                except:
                    pickle.dump({1: data_sigmastar},
                                open("results/m1_sigmastar_inf.pkl", 'wb'))

                try:
                    # MATRIX
                    with open("results/m1_matrix_inf.pkl", 'rb') as f:
                        matrix_old = pickle.load(f)
                        matrix_old[int(len(matrix_old) + 1)] = self.tau
                        f.close()
                    pickle.dump(matrix_old,
                                open("results/m1_matrix_inf.pkl", 'wb'))

                except:
                    pickle.dump({1: self.tau},
                                open("results/m1_matrix_inf.pkl", 'wb'))

                self.running = False

        # with open("tau2_new.txt", "a") as myfile:
        #     myfile.write(str(self.mean_tau_ant) + '\n')
        # with open("sigma2_new.txt", "a") as myfile:
        #     myfile.write(str(np.sqrt(self.sigma)) + '\n')
        # with open("datasigmastar2_new.txt","a") as myfile:
        #     myfile.write(str(self.sigmastar) + "\n")

    def nowalls(self):
        # For model without walls:
        for i in range(WIDTH):
            for j in range(HEIGHT):
                if i == 0 or j == 0 or i == WIDTH - 1 or j == HEIGHT - 1:
                    self.bound_vals.append((i, j))
                if i == 1 or i == WIDTH - 2 or j == 1 or j == HEIGHT - 2:
                    self.neigh_bound.append((i, j))

    def onewall(self):
        # For model with ONE wall:
        for i in range(WIDTH):
            for j in range(HEIGHT):
                if i == 0 or j == 0 or i == WIDTH - 1 or j == HEIGHT - 1:
                    self.bound_vals.append((i, j))
                if i == WIDTH - 2 or j == 1 or j == HEIGHT - 2:
                    self.neigh_bound.append((i, j))

    def twowalls(self):
        # For model with TWO walls:
        for i in range(WIDTH):
            for j in range(HEIGHT):
                if i == 0 or j == 0 or i == WIDTH - 1 or j == HEIGHT - 1:
                    self.bound_vals.append((i, j))
                if j == 1 or j == HEIGHT - 2:
                    self.neigh_bound.append((i, j))

    def threewalls(self):
        # For model with THREE walls:
        for i in range(WIDTH):
            for j in range(HEIGHT):
                if i == 0 or j == 0 or i == WIDTH - 1 or j == HEIGHT - 1:
                    self.bound_vals.append((i, j))
                if j == HEIGHT - 2:
                    self.neigh_bound.append((i, j))

    def get_total_ants_number(self):
        total_ants = 0
        for (agents, _, _) in self.grid.coord_iter():
            if type(agents) is Ant:
                total_ants += 1
        return total_ants

    def evaluation1(self):

        ##creat a empty grid to store currently information
        total_ants = np.zeros((WIDTH, HEIGHT))

        ## count the number of currently information
        for (agents, i, j) in self.grid.coord_iter():

            if type(agents) is Ant:
                total_ants[i][j] = 1
            else:
                total_ants[i][j] = 0

        ##update the tau
        self.tau = self.tau + total_ants

        ##calcualte the mean tau
        self.mean_tau_ant = self.tau.sum() / ((WIDTH - 2)**2)

        return self.mean_tau_ant

    def evaluation2(self):

        ## we need to minus the mean tau so we need to ensure the result of boundary is zero
        ## so we let the bounday equal mean_tau_ant in this way the (tau-mean_tau_ant) is zero of boundary
        for site in self.bound_vals:
            self.tau[site[0]][site[1]] = self.mean_tau_ant

        ## calculate the sigmaa
        self.sigma = ((self.tau - self.mean_tau_ant)**2).sum() / (
            (WIDTH - 2)**2)

        ## rechange the boundaryy
        for site in self.bound_vals:
            self.tau[site[0]][site[1]] = 0

        return np.sqrt(self.sigma)

    def evaluation3(self):
        ## calculate the sigmastar
        self.sigmastar = np.sqrt(self.sigma) / self.mean_tau_ant

        return self.sigmastar
예제 #13
0
파일: model.py 프로젝트: zykls/whynot
class Schelling(Model):
    """Model class for the Schelling segregation model."""
    def __init__(
        self,
        height=20,
        width=20,
        density=0.8,
        minority_pc=0.2,
        homophily=3,
        education_boost=0,
        education_pc=0.2,
        seed=None,
    ):
        """Seed is used to set randomness in the __new__ function of the Model superclass."""
        # pylint: disable-msg=unused-argument,super-init-not-called

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophily = homophily
        self.education_boost = education_boost
        self.education_pc = education_pc

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=True)

        self.happy = 0
        self.datacollector = DataCollector(
            {"happy": "happy"},  # Model-level count of happy agents
            # For testing purposes, agent's individual x and y
            {
                "x": lambda a: a.pos[0],
                "y": lambda a: a.pos[1]
            },
        )

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell in self.grid.coord_iter():
            x_coord = cell[1]
            y_coord = cell[2]
            if self.random.random() < self.density:
                if self.random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent_homophily = homophily
                if self.random.random() < self.education_pc:
                    agent_homophily += self.education_boost

                agent = SchellingAgent((x_coord, y_coord), self, agent_type,
                                       agent_homophily)
                self.grid.position_agent(agent, (x_coord, y_coord))
                self.schedule.add(agent)

        self.running = True
        self.datacollector.collect(self)

    def step(self):
        """Run one step of the model. If All agents are happy, halt the model."""
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False
예제 #14
0
class SeparationBarrierModel(Model):
    def __init__(self, height, width, palestinian_density, settlement_density,
                 settlers_violence_rate, settlers_growth_rate, suicide_rate, greed_level,
                 settler_vision=1, palestinian_vision=1, 
                 movement=True, max_iters=1000):

        super(SeparationBarrierModel, self).__init__()
        self.height = height
        self.width = width
        self.palestinian_density = palestinian_density
        self.settler_vision = settler_vision
        self.palestinian_vision = palestinian_vision
        self.settlement_density = settlement_density
        self.movement = movement
        self.running = True
        self.max_iters = max_iters
        self.iteration = 0
        self.schedule = RandomActivation(self)
        self.settlers_violence_rate = settlers_violence_rate
        self.settlers_growth_rate = settlers_growth_rate
        self.suicide_rate = suicide_rate
        self.greed_level = greed_level

        self.total_violence = 0

        self.grid = SingleGrid(height, width, torus=False)

        model_reporters = {
        }
        agent_reporters = {
#           "x": lambda a: a.pos[0],
#           "y": lambda a: a.pos[1],
        }
        self.dc = DataCollector(model_reporters=model_reporters,
                                agent_reporters=agent_reporters)
        self.unique_id = 0

        # Israelis and palestinans split the region in half
        for (contents, x, y) in self.grid.coord_iter():
            if random.random() < self.palestinian_density:
                palestinian = Palestinian(self.unique_id, (x, y), vision=self.palestinian_vision, breed="Palestinian",
                          model=self)
                self.unique_id += 1
                self.grid.position_agent(palestinian, x,y)
                self.schedule.add(palestinian)
            elif ((y > (self.grid.height) * (1-self.settlement_density)) and random.random() < self.settlement_density):
                settler = Settler(self.unique_id, (x, y),
                                  vision=self.settler_vision, model=self, breed="Settler")
                self.unique_id += 1
                self.grid.position_agent(settler, x,y)
                self.schedule.add(settler)

    def add_settler(self, pos):
        settler = Settler(self.unique_id, pos,
                          vision=self.settler_vision, model=self, breed="Settler")
        self.unique_id += 1
        self.grid.position_agent(settler, pos[0], pos[1])
        self.schedule.add(settler)

    def set_barrier(self,victim_pos, violent_pos):
        #print("Set barrier - Greed level", self.greed_level)
        visible_spots = self.grid.get_neighborhood(victim_pos,
                                                        moore=True, radius=self.greed_level + 1)
        furthest_empty  = self.find_furthest_empty_or_palestinian(victim_pos, visible_spots)
        x,y = furthest_empty
        current = self.grid[y][x]
        #print ("Set barrier!!", pos, current)
        free = True
        if (current is not None and current.breed == "Palestinian"):
            #print ("Relocating Palestinian")
           free =  self.relocate_palestinian(current, current.pos)

        if (free):
            barrier = Barrier(-1, furthest_empty, model=self)
            self.grid.position_agent(barrier, x,y)
        
        # Relocate the violent palestinian
        #violent_x, violent_y = violent_pos
        #if violent_pos != furthest_empty:
        #    violent_palestinian = self.grid[violent_y][violent_x]
        #    self.relocate_palestinian(violent_palestinian, furthest_empty)

    def relocate_palestinian(self, palestinian, destination):
        #print ("Relocating Palestinian in ", palestinian.pos, "To somehwhere near ", destination)
        visible_spots = self.grid.get_neighborhood(destination,
                                                        moore=True, radius=palestinian.vision)
        nearest_empty = self.find_nearest_empty(destination, visible_spots)
        #print("First Nearest empty to ", palestinian.pos, " Is ", nearest_empty)
        if (nearest_empty):
            self.grid.move_agent(palestinian, nearest_empty)
        else:
            #print ("Moveing to random empty")
            if (self.grid.exists_empty_cells()):
                self.grid.move_to_empty(palestinian)
            else:
                return False

        return True

    def find_nearest_empty(self, pos, neighborhood):
        nearest_empty = None
        sorted_spots = self.sort_neighborhood_by_distance(pos, neighborhood)
        index = 0
        while (nearest_empty is None and index < len(sorted_spots)):
            if self.grid.is_cell_empty(sorted_spots[index]):
                nearest_empty = sorted_spots[index]
            index += 1

        return nearest_empty

    def find_furthest_empty_or_palestinian(self, pos, neighborhood):
        furthest_empty = None
        sorted_spots = self.sort_neighborhood_by_distance(pos, neighborhood)
        sorted_spots.reverse()
        index = 0
        while (furthest_empty is None and index < len(sorted_spots)):
            spot = sorted_spots[index]
            if self.grid.is_cell_empty(spot) or self.grid[spot[1]][spot[0]].breed == "Palestinian" :
                furthest_empty = sorted_spots[index]
            index += 1

        return furthest_empty



    def sort_neighborhood_by_distance(self, from_pos, neighbor_spots):
        from_x, from_y = from_pos
        return sorted(neighbor_spots, key = lambda spot: self.eucledean_distance(from_x, spot[0], from_y, spot[1], self.grid.width, self.grid.height))


    def eucledean_distance(self, x1,x2,y1,y2,w,h):
        # http://stackoverflow.com/questions/2123947/calculate-distance-between-two-x-y-coordinates
        return math.sqrt(min(abs(x1 - x2), w - abs(x1 - x2)) ** 2 + min(abs(y1 - y2), h - abs(y1-y2)) ** 2)
        

    def step(self):
        """
        Advance the model by one step and collect data.
        """
        self.violence_count = 0
      #  for i in range(100):
        self.schedule.step()
        self.total_violence += self.violence_count
      #  average = self.violence_count / 100
        #print("Violence average %f " % average)
        print("Total Violence: ", self.total_violence)
예제 #15
0
class EconomicSystemModel(Model):
    """ A simple model of an economic system.

    All agents begin with certain revenue, each time step the agents
    execute its expenditures and sell its production. If they retain a
    healthy revenue, they can choose to hire and grow;
    otherwise they can choose to shrink;
    if too much debt is acquired the agent goes bankrupt.
    Let's see what happens to the system.
    """
    def __init__(self,
                 width=10,
                 height=10,
                 industry_pc=0.8,
                 services_pc=0.6,
                 tax_industry=0.1,
                 tax_services=0.2,
                 nsteps=60):
        """ Initialization method of economic system model class

        Parameters
        ----------
        width : int
            Grid width
        height : int
            Grid height
        industry_pc : float
            Industry percentage in the system
        services_pc : float
            Services percentage in the industry
        tax_industry : float
            Tax rate for industry sector
        tax_services : float
            Tax rate for services sector
        nsteps : int
            Number of time steps in months
        """

        # Model input attributes
        self.width = width
        self.height = height
        self.industry_pc = industry_pc
        self.services_pc = services_pc
        self.nsteps = nsteps

        # Order in which agents perform their steps,
        # random activation means no particular preference
        self.schedule = RandomActivation(self)

        # Grid initialization
        self.grid = SingleGrid(width, height, torus=True)

        # Data to be located per time step
        self.datacollector = DataCollector(model_reporters={
            "GDP": compute_gdp,
            "Employment": compute_employment
        },
                                           agent_reporters={
                                               "Employees": "employees",
                                               "Value": "value",
                                               "Industry": "type"
                                           })

        # Set up agents using a grid iterator that returns
        # the coordinates of a cell as well as its contents
        for cell in self.grid.coord_iter():

            # Cell coordinates
            x = cell[1]
            y = cell[2]

            # Assign industry type
            if self.random.random() < self.industry_pc:
                if self.random.random() < self.services_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                # Initialize agent
                tax_rates = [tax_industry, tax_services]
                agent = IndustryAgent((x, y), self, agent_type, tax_rates)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

        # Running set to true and collect initial conditions
        self.running = True
        self.datacollector.collect(self)

        # Computed initial conditions of the model
        self.gdp = compute_gdp(self)
        self.employment = compute_employment(self)
        self.max_size_services = max_size_industry(self, 1)
        self.max_size_industry = max_size_industry(self, 0)
        self.max_size_industries = max_size_industry(self, -2)

    def step(self):
        '''
        Method to run one time step of the model
        '''

        # Run time step
        self.schedule.step()

        # Collect data
        self.datacollector.collect(self)

        # Computed metrics
        self.gdp = compute_gdp(self)
        self.employment = compute_employment(self)
        self.max_size_services = max_size_industry(self, 1)
        self.max_size_industry = max_size_industry(self, 0)
        self.max_size_industries = max_size_industry(self, -2)

        # Halt model after maximum number of time steps
        if self.schedule.steps == self.nsteps:
            self.running = False
예제 #16
0
파일: model.py 프로젝트: TomBener/abm-mesa
class Schelling(Model):
    '''
    Define the Model
    The other core class
    '''
    '''
    mesa/space.py/Grid has 3 properties:
        - width
        - height
        - torus
    So `minority_pc` and `homophily` are customized properties here.
    '''
    def __init__(self,
                 height=20,
                 width=20,
                 density=0.8,
                 minority_pc=0.2,
                 homophily=3):
        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophily = homophily

        # Scheduler is used `RandomActivation`, which is defined in mesa/time.py/RandomActivation.
        # Specify *time* of the model.
        self.schedule = RandomActivation(self)
        # `SingleGrid` is defined in mesa/space.py/SingleGrid.
        # Grid which strictly enforces one object per cell.
        # Specify *space* of the model.
        # width, height, torus are the native properties.
        self.grid = SingleGrid(width, height, torus=True)

        # Without happy agents initially
        self.happy = 0
        # DataCollector collects 3 types of data:
        # model-level data, agent-level data, and tables
        # A DataCollector is instantiated with 2 dictionaries of reporter names and associated variable names or functions for each, one for model-level data and one for agent-level data; a third dictionary provides table names and columns. Variable names are converted into functions which retrieve attributes of that name.
        self.datacollector = DataCollector(
            {
                'happy': 'happy'
            },  # Model-level count of happy agents, only one agent-level reporter
            # For testing purposes, agent’s individual x and y
            # lambda function, it is like:
            # lambda x, y: x ** y
            {
                'x': lambda a: a.pos[0],
                'y': lambda a: a.pos[1]
            },
        )

        # Set up agents
        # We use grid iterator that returns
        # the coordinates of a cell as well
        # as its contents. (coord_iter)
        # coord_iter is defined in mesa/space.py, which, which returns coordinates as well as cell contents.
        for cell in self.grid.coord_iter():
            # Grid cells are indexed by [x][y] (tuple), where [0][0] is assumed to be the bottom-left and [width-1][height-1] is the top-right. If a grid is toroidal, the top and bottom, and left and right, edges wrap to each other.
            x = cell[1]
            y = cell[2]
            if self.random.random() < self.density:
                if self.random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent = SchellingAgent((x, y), self, agent_type)
                # position_agent is defined in mesa/space.py. Position an agent on the grid. This is used when first placing agents!
                self.grid.position_agent(agent, (x, y))
                # schedule.add() method is defined in mesa/time.py.
                # Add an Agent object to the schedule.
                #
                # Aggs:
                #   agent: An Agent to be added to the schedule. Note: the agent must have a step() method.
                self.schedule.add(agent)

        self.running = True
        # datacollector.collect() method is defined in mesa/datacollection.py. When the collect(…) method is called, it collects these attributes and executes these functions one by one and store the results.
        self.datacollector.collect(self)

    # Oh, I did’t understand step(…) method previously. Now I know as a consequential method, it executes all stages for all agents.
    def step(self):
        '''
        Run one step of the model. If all agents are happy, halt the model.
        '''
        self.happy = 0  # Reset counter of happy agents
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

        # Method get_agent_count is defined in mesa/time.py. It returns the current number agents in the queue.
        if self.happy == self.schedule.get_agent_count():
            self.running = False
예제 #17
0
class SIRModel(Model):
    '''Description of the model'''
    
    def __init__(self, width, height, infectivity=2.0, infection_duration = 10, immunity_duration = 15, mutation_probability=0, mutation_strength=10, visualise_each_x_timesteps=-1):
        # Set the model parameters
        self.infectivity = infectivity       # Infection strength per infected individual
        self.infection_duration = infection_duration # Duration of infection
        self.immunity_duration = immunity_duration  # Duration of infection
        
        #mutations
        self.mutation_probability = mutation_probability 
        self.mutation_strength = mutation_strength
        #self.mean_inf_duration_list = []

        percentage_starting_infected = 0.01
        percentage_starting_recovered = 0.01
       
        self.visualise_each_x_timesteps = visualise_each_x_timesteps
        self.grid = SingleGrid(width, height, torus=False)
        self.schedule = SimultaneousActivation(self)
        for (contents, x, y) in self.grid.coord_iter():
            # Place randomly generated individuals
            rand = random.random()
            cell = Cell((x,y), self)

            # place random infected cells with a chance
            if rand < percentage_starting_infected:
                cell.initialise_as_infected()

            # place random infected cells with a chance
            elif rand < percentage_starting_infected + percentage_starting_recovered:
                cell.initialise_as_recovered()

            self.grid.place_agent(cell, (x,y))
            self.schedule.add(cell)

        # Add data collector, to plot the number of individuals of different types
        self.datacollector_cells = DataCollector(model_reporters={
            "Infected": fracI,
            "Susceptible": fracS,
            "Recovered": fracR,
        })

        # Add data collector, to plot the mean infection duration
        self.datacollector_meaninfectionduration = DataCollector(model_reporters={"Mean_inf_duration": compute_mean_infduration})

        # collects grids per amount of time steps
        self.grids_saved = []
        
        self.running = True

    def get_grid_cells(self):
        return np.array([cell.state for cell in self.schedule.agents])

    def step(self):
        # collect grids for running without browser
        if self.visualise_each_x_timesteps != -1:
            if self.schedule.time % self.visualise_each_x_timesteps == 0:
                print(f'timestep: {self.schedule.time}, saved grid.')
                self.grids_saved.append(self.get_grid_cells())

        self.datacollector_cells.collect(self)
        self.datacollector_meaninfectionduration.collect(self)

        self.schedule.step()
예제 #18
0
class Schelling(Model):
    '''
    Model class for the Schelling segregation model.
    This class has been modified from the original model of mesa. Complexity has been added such that the model be used with a model of the policy making process.
    '''
    def __init__(self,
                 height=20,
                 width=20,
                 density=0.8,
                 minority_pc=0.2,
                 homophilyType0=0.5,
                 homophilyType1=0.5,
                 movementQuota=0.30,
                 happyCheckRadius=5,
                 moveCheckRadius=5):
        '''
        '''

        self.height = height
        self.width = width
        self.density = density
        self.minority_pc = minority_pc
        self.homophilyType0 = homophilyType0
        self.homophilyType1 = homophilyType1
        self.movementQuota = movementQuota
        self.happyCheckRadius = happyCheckRadius
        self.moveCheckRadius = moveCheckRadius

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=True)

        self.happy = 0
        self.stepCount = 0
        self.evenness = 0
        self.empty = 0
        self.type0agents = 0
        self.type1agents = 0
        self.movementQuotaCount = 0
        self.numberOfAgents = 0
        self.datacollector = DataCollector(
            # Model-level count of happy agents
            {
                "step": "stepCount",
                "happy": "happy",
                "evenness": "evenness",
                "numberOfAgents": "numberOfAgents"
            },
            # For testing purposes, agent's individual x and y
            {
                "x": lambda a: a.pos[0],
                "y": lambda a: a.pos[1]
            })

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            if self.random.random() < self.density:
                if self.random.random() < self.minority_pc:
                    agent_type = 1
                else:
                    agent_type = 0

                agent = SchellingAgent((x, y), self, agent_type)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)
        print("Schedule", len(self.schedule.agents))

        self.running = True
        self.numberOfAgents = self.schedule.get_agent_count()
        self.datacollector.collect(self)

    def step(self):
        '''
        Run one step of the model. If All agents are happy, halt the model.
        Note on the eveness paramater calculation:
            It cannot be performed in the step function of the agents as then it would not take consider periods of time during which the agents are still moving, making the parameter calculation inaccurate. 
        '''
        self.happy = 0  # Reset counter of happy agents
        self.empty = 0  # Reset counter of empty cells
        self.type0agents = 0  # Reset count of type 0 agents
        self.type1agents = 0  # Reset count of type 1 agents
        self.movementQuotaCount = 0  # Reset count of the movement quota

        # run the step for the agents
        self.schedule.step()
        print(self.movementQuotaCount, " agents moved.")
        print(round(self.happy / self.schedule.get_agent_count() * 100, 2),
              "percent are happy agents.")

        # calculating empty counter
        self.empty = (self.height *
                      self.width) - self.schedule.get_agent_count()
        # calculating type 0 and type 1 agent numbers
        for agent in self.schedule.agent_buffer(shuffled=True):
            if agent.type == 0:
                self.type0agents += 1
            if agent.type == 1:
                self.type1agents += 1

        # calculation of evenness (segregation parameter) using Haw (2015).
        self.evenness_calculation()

        # iterate the steps counter
        self.stepCount += 1

        # collect data
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False
            print("All agents are happy, the simulation ends!")

    def evenness_calculation(self):
        '''
        To calculate the evenness parameter, one needs to first subdivide the grid into areas of more than one square each. The evenness will be then calculated based on the distribution of type 0 and type 1 agents in each of these areas.
        The division into area needs to be done carefully as it depends on the inputs within the model (width and height of the grid).
        '''

        # check for a square grid
        if self.height != self.width:
            self.running = False
            print(
                "WARNING - The grid is not a square, please insert the same width and height"
            )

        # reset the evenness parameter
        self.evenness = 0

        # algorithm to calculate evenness
        n = 4  # number of big areas considered in width and height
        if self.height % n == 0:
            # consider all big areas
            for big_dy in range(n):
                for big_dx in range(n):
                    # looking within one big areas, going through all cells
                    listAgents = []
                    for small_dy in range(int(self.height / n)):
                        for small_dx in range(int(self.height / n)):
                            for agents in self.schedule.agent_buffer(
                                    shuffled=True):
                                if agents.pos == (self.height / n * big_dx +
                                                  small_dx,
                                                  self.height / n * big_dy +
                                                  small_dy):
                                    listAgents.append(agents)
                    # calculating evenness for each big area
                    countType0agents = 0  # Reset of the type counter for type 0 agents
                    countType1agents = 0  # Reset of the type counter for type 1 agents
                    # checking the type of agents in the big area
                    for agents in listAgents:
                        if agents.type == 0:
                            countType0agents += 1
                        if agents.type == 1:
                            countType1agents += 1
                    self.evenness += 0.5 * abs(
                        (countType0agents / self.type0agents) -
                        (countType1agents / self.type1agents))
        print("evenness :", round(self.evenness, 2))
예제 #19
0
class EconMod(Model):
    '''
    Model class for arming model.
    '''

    def __init__(self, height, width, density, 
    domestic_min, domestic_max, 
    domestic_mean, domestic_sd,
    num_adversaries, expenditures):
        '''
        '''

        self.height = height
        self.width = width
        self.density = density
        self.domestic_min = domestic_min
        self.domestic_max = domestic_max
        self.domestic_mean = domestic_mean
        self.domestic_sd = domestic_sd
        self.num_adversaries = num_adversaries
        self.expenditures = expenditures

        self.schedule = RandomActivation(self)  # All agents act at once
        self.grid = SingleGrid(height, width, torus=True)
        self.datacollector = DataCollector(
            # Collect data on each agent's arms levels
            agent_reporters = {
                "Arms": "arms",
                "Military_Burden": "mil_burden",
                "Econ": "econ",
                "Domestic": "domestic"
                })

        # Set up agents
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            if random.random() < self.density:
                ## Set starting economy for all
                ##econ_start = 10
                # Draw from pareto -- parameter set to 3, arbitrary
                econ_start = pareto.rvs(3,1)
                econ_growth = 0.03
                # domestic need -- determines econ variation
                #domestic_need = np.random.uniform(
                #    self.domestic_min,
                #    self.domestic_max
                #    )
                #https://stackoverflow.com/questions/18441779/how-to-specify-upper-and-lower-limits-when-using-numpy-random-normal
                lower, upper = self.domestic_min, self.domestic_max
                mu, sigma = self.domestic_mean, self.domestic_sd
                X = truncnorm(
                    (lower - mu) / sigma, (upper - mu) / sigma, loc=mu, scale=sigma)
                domestic_need = X.rvs(1)

                
                expenditures = self.expenditures
                # starting percent of wealth spent on weapons
                arms_start_perc = np.random.uniform(0, 0.06) 
                arms = arms_start_perc * econ_start

                # create agent
                agent = state((x, y), self, econ_start = econ_start,
                            econ_growth = econ_growth, arms = arms,
                            domestic_need = domestic_need,
                            num_adversaries = num_adversaries,
                            expenditures = expenditures)

                # place agent in grid
                self.grid.position_agent(agent, (x, y))
                # add schedule
                self.schedule.add(agent)

        self.running = True
        self.datacollector.collect(self)

    def step(self):
        '''
        Run one step of the model.
        '''
        # Collect data
        self.datacollector.collect(self)
        self.schedule.step()       
예제 #20
0
파일: schelling.py 프로젝트: pcjmeerman/Tpm
class Schelling(Model):
    """
    Model class for the Schelling segregation model.
    
    Parameters
    ----------
    height : int
             height of grid
    width : int
            height of width
    density : float
            fraction of grid cells occupied
    minority_fraction : float
            fraction of agent of minority color
    tolerance_threshold : int
    
    Attributes
    ----------
    height : int
    width : int
    density : float
    minority_fraction : float
    schedule : RandomActivation instance
    grid : SingleGrid instance
    
    """
    def __init__(self,
                 height=20,
                 width=20,
                 density=0.8,
                 minority_fraction=0.2,
                 tolerance_threshold=4,
                 seed=None):
        super().__init__(seed=seed)
        self.height = height
        self.width = width
        self.density = density
        self.minority_fraction = minority_fraction

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(width, height, torus=True)
        self.datacollector = DataCollector(
            model_reporters={'happy': count_happy})

        # Set up agents
        # We use a grid iterator that returns
        # the coordinates of a cell as well as
        # its contents. (coord_iter)
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            if self.random.random() < self.density:
                if self.random.random() < self.minority_fraction:
                    agent_color = Color.RED
                else:
                    agent_color = Color.BLUE

                agent = SchellingAgent((x, y), self, agent_color,
                                       tolerance_threshold)
                self.grid.position_agent(agent, (x, y))
                self.schedule.add(agent)

    def step(self):
        """
        Run one step of the model.
        """
        self.schedule.step()
        self.datacollector.collect(self)
예제 #21
0
class SchellingModel(Model):
    '''Model class for Schelling segregation model'''

    def __init__(self, height=20, width=20, density=.8, group_ratio=.66, minority_ratio=.5, homophily=3):
        self.height = height
        self.width = width
        self.density = density
        self.group_ratio = group_ratio
        self.minority_ratio = minority_ratio
        self.homophily = homophily
        self.happy = 0
        self.segregated = 0

        self.schedule = RandomActivation(self)
        self.grid = SingleGrid(height, width, torus=False)

        self.place_agents()
        self.datacollector = DataCollector( {'happy': (lambda m: m.happy), 'segregated': (lambda m: m.segregated)})
        self.running = True


    def step(self):
        '''Run one step of model'''
        self.schedule.step()
        self.calculate_stats()
        self.datacollector.collect(self)

        if self.happy == self.schedule.get_agent_count():
            self.running = False


    def place_agents(self):
        for cell in self.grid.coord_iter():
            x, y = cell[1:3]
            if random.random() < self.density:
                if random.random() < self.group_ratio:
                    if random.random() < self.minority_ratio:
                        group = 0
                    else:
                        group = 1
                else:
                    group = 2

                agent = SchellingAgent((x,y), group)
                self.grid.position_agent(agent, (x,y))
                self.schedule.add(agent)

        for agent in self.schedule.agents:
            count = 0
            for neighbour in self.grid.iter_neighbors(agent.pos, moore=False):
                if neighbour.group == agent.group:
                    count += 1
            agent.similar = count


    def calculate_stats(self):
        happy_count = 0
        avg_seg = 0
        for agent in self.schedule.agents:
            avg_seg += agent.similar
            if agent.similar >= self.homophily:
                happy_count += 1

        self.happy = happy_count
        self.segregated = avg_seg/self.schedule.get_agent_count()