Exemplo n.º 1
0
 def move(self):
     '''
     The random move function for the fish schools.
     '''
     neighbourhood = MultiGrid.get_neighborhood(self.model.grid, self.pos, True, False, 1)
     new_pos = random.choice(neighbourhood)
     MultiGrid.move_agent(self.model.grid, self, new_pos)
Exemplo n.º 2
0
    def fisherman_move(self):
        '''
        The random move function for the fisherman.
        '''
    	neighbourhood = MultiGrid.get_neighborhood(self.model.grid, self.pos, True, False, 1)
    	new_pos = random.choice(neighbourhood)
    	while (new_pos[0] < self.model.no_fish_size) and (new_pos[1] < self.model.no_fish_size):
    		new_pos = random.choice(neighbourhood)

    	MultiGrid.move_agent(self.model.grid, self, new_pos)
Exemplo n.º 3
0
class Neighborhood(Model):
    """A model of a neighborhood with some number of agents."""

    def __init__(self, N=10, width=None, height=None):
        """ Neighborhood: a neighborhood containing people

            Parameters
            ----------
            N:
                number of people in the neighborhood
            width:
                width of the (rectangular) neighborhood area
            height:
                height of the (rectangular) neighborhood area
        """
        super().__init__()
        
        self.num_agents = N
        self.width = width or min(N, 100)
        self.height = height or min(N, 100)

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

        # Create agents
        for i in range(self.num_agents):
            rand = random.random()
            infection = rand >= (N-N**.5)/N
            print(i, rand, (N-N**.5)/N)

            a = Person(i, self, level_of_infection=int(infection))
            print(a, a.level_of_infection)
            self.schedule.add(a)

            # adding the agent to a random position in the neighborhood
            (x, y) = random.random() * self.width, random.random() * self.height
            self.grid.place_agent(a, (int(x), int(y)))

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

        self.schedule.step()

    def get_neighbors(self, person, radius=1):
        """ get neighbors of person """
        neighbor_objects = self.grid.get_cell_list_contents([person.pos])
        return [*filter(lambda x: type(x) is Person and x is not person, 
                        neighbor_objects)]

    def move_agent(self, *args, **kwargs):
        return self.grid.move_agent(*args, **kwargs)
Exemplo n.º 4
0
class PitchModel(Model):
    def __init__(self, N, width, height):
        '''Initiate the model'''
        self.num_agents = 2 * N
        self.grid = MultiGrid(width, height, False)
        self.schedule = SimultaneousActivation(self)
        self.running = True
        self.justConceded = 0
        self.score1 = 0
        self.score2 = 0
        self.i = 0
        self.newPossession = -1

        #Initialise potential fields for each state
        self.movePotentialGK1 = np.zeros((width, height))
        self.movePotentialGK2 = np.zeros((width, height))
        self.movePotentialGKP1 = np.zeros((width, height))
        self.movePotentialGKP2 = np.zeros((width, height))
        self.movePotentialDF1 = np.zeros((width, height))
        self.movePotentialDF2 = np.zeros((width, height))
        self.movePotentialPO1 = np.zeros((width, height))
        self.movePotentialPO2 = np.zeros((width, height))
        self.movePotentialBP1 = np.zeros((width, height))
        self.movePotentialBP2 = np.zeros((width, height))

        #Set initial potential field due to goals
        self.goalPotentialGK1 = np.zeros((width, height))
        self.goalPotentialGK2 = np.zeros((width, height))
        self.goalPotentialGKP1 = np.zeros((width, height))
        self.goalPotentialGKP2 = np.zeros((width, height))
        self.goalPotentialDF1 = np.zeros((width, height))
        self.goalPotentialDF2 = np.zeros((width, height))
        self.goalPotentialPO1 = np.zeros((width, height))
        self.goalPotentialPO2 = np.zeros((width, height))
        self.goalPotentialBP1 = np.zeros((width, height))
        self.goalPotentialBP2 = np.zeros((width, height))

        for x in range(8):
            for y in range(height):
                widthVal = ((width / 2) - 4) + x
                self.goalPotentialGK1[int(widthVal)][
                    y] = self.goalPotentialGK1[int(widthVal)][y] + (y + 1)
                self.goalPotentialGK1[int(widthVal)][
                    height - (y + 1)] = self.goalPotentialGK1[int(widthVal)][
                        height - (y + 1)] - np.log2(height - (y + 1))

                self.goalPotentialGK2[int(
                    widthVal)][y] = self.goalPotentialGK2[int(
                        widthVal)][y] - np.log2(height - (y + 1))
                self.goalPotentialGK2[int(widthVal)][height - (
                    y + 1)] = self.goalPotentialGK2[int(widthVal)][height -
                                                                   (y + 1)] + (
                                                                       y + 1)

                self.goalPotentialGKP1[int(widthVal)][
                    y] = self.goalPotentialGKP1[int(widthVal)][y] + (y + 1)
                self.goalPotentialGKP1[int(widthVal)][
                    height - (y + 1)] = self.goalPotentialGKP1[int(widthVal)][
                        height - (y + 1)] - np.log2(height - (y + 1))

                self.goalPotentialGKP2[int(
                    widthVal)][y] = self.goalPotentialGKP2[int(
                        widthVal)][y] - np.log2(height - (y + 1))
                self.goalPotentialGKP2[int(widthVal)][height - (
                    y + 1
                )] = self.goalPotentialGKP2[int(widthVal)][height -
                                                           (y + 1)] + (y + 1)

                self.goalPotentialDF1[int(widthVal)][
                    y] = self.goalPotentialDF1[int(widthVal)][y] + (y + 1)
                self.goalPotentialDF1[int(widthVal)][
                    height - (y + 1)] = self.goalPotentialDF1[int(widthVal)][
                        height - (y + 1)] - np.log2(height - (y + 1))

                self.goalPotentialDF2[int(
                    widthVal)][y] = self.goalPotentialDF2[int(
                        widthVal)][y] - np.log2(height - (y + 1))
                self.goalPotentialDF2[int(widthVal)][height - (
                    y + 1)] = self.goalPotentialDF2[int(widthVal)][height -
                                                                   (y + 1)] + (
                                                                       y + 1)

                self.goalPotentialPO1[int(
                    widthVal)][y] = self.goalPotentialPO1[int(
                        widthVal)][y] - np.log2(height - (y + 1))
                self.goalPotentialPO1[int(widthVal)][height - (
                    y + 1)] = self.goalPotentialPO1[int(widthVal)][height -
                                                                   (y + 1)] + (
                                                                       y + 1)

                self.goalPotentialPO2[int(widthVal)][
                    y] = self.goalPotentialPO2[int(widthVal)][y] + (y + 1)
                self.goalPotentialPO2[int(widthVal)][
                    height - (y + 1)] = self.goalPotentialPO2[int(widthVal)][
                        height - (y + 1)] - np.log2(height - (y + 1))

                self.goalPotentialBP1[int(
                    widthVal)][y] = self.goalPotentialBP1[int(
                        widthVal)][y] - np.log2(height - (y + 1))
                self.goalPotentialBP1[int(widthVal)][height - (
                    y + 1)] = self.goalPotentialBP1[int(widthVal)][height -
                                                                   (y + 1)] + (
                                                                       y + 1)

                self.goalPotentialBP2[int(widthVal)][
                    y] = self.goalPotentialBP2[int(widthVal)][y] + (y + 1)
                self.goalPotentialBP2[int(widthVal)][
                    height - (y + 1)] = self.goalPotentialBP2[int(widthVal)][
                        height - (y + 1)] - np.log2(height - (y + 1))

        for x in range(int((width / 2) - 4)):
            for y in range(height):
                r1 = (((x + 1)**2) + ((y + 1)**2))**0.5
                r2 = (((x + 1)**2) + ((height - (y + 1))**2))**0.5
                goalStart = ((width / 2) - 5) - x
                goalEnd = ((width / 2) + 4) + x

                self.goalPotentialGK1[int(goalStart)][
                    y] = self.goalPotentialGK1[int(goalStart)][y] + (r1)
                self.goalPotentialGK1[int(goalEnd)][y] = self.goalPotentialGK1[
                    int(goalEnd)][y] + (r1)
                self.goalPotentialGK1[int(goalStart)][
                    height - (y + 1)] = self.goalPotentialGK1[int(goalStart)][
                        height - (y + 1)] - np.log2(r2)
                self.goalPotentialGK1[int(goalEnd)][height - (
                    y + 1
                )] = self.goalPotentialGK1[int(goalEnd)][height -
                                                         (y + 1)] - np.log2(r2)

                self.goalPotentialGK2[int(goalStart)][
                    y] = self.goalPotentialGK2[int(goalStart)][y] - np.log2(r2)
                self.goalPotentialGK2[int(goalEnd)][y] = self.goalPotentialGK2[
                    int(goalEnd)][y] - np.log2(r2)
                self.goalPotentialGK2[int(goalStart)][height - (
                    y +
                    1)] = self.goalPotentialGK2[int(goalStart)][height -
                                                                (y + 1)] + (r1)
                self.goalPotentialGK2[int(goalEnd)][height - (
                    y +
                    1)] = self.goalPotentialGK2[int(goalEnd)][height -
                                                              (y + 1)] + (r1)

                self.goalPotentialGKP1[int(goalStart)][
                    y] = self.goalPotentialGKP1[int(goalStart)][y] + (r1)
                self.goalPotentialGKP1[int(goalEnd)][
                    y] = self.goalPotentialGKP1[int(goalEnd)][y] + (r1)
                self.goalPotentialGKP1[int(goalStart)][
                    height - (y + 1)] = self.goalPotentialGKP1[int(goalStart)][
                        height - (y + 1)] - np.log2(r2)
                self.goalPotentialGKP1[int(goalEnd)][
                    height - (y + 1)] = self.goalPotentialGKP1[int(goalEnd)][
                        height - (y + 1)] - np.log2(r2)

                self.goalPotentialGKP2[int(
                    goalStart
                )][y] = self.goalPotentialGKP2[int(goalStart)][y] - np.log2(r2)
                self.goalPotentialGKP2[int(goalEnd)][
                    y] = self.goalPotentialGKP2[int(goalEnd)][y] - np.log2(r2)
                self.goalPotentialGKP2[int(goalStart)][height - (
                    y + 1
                )] = self.goalPotentialGKP2[int(goalStart)][height -
                                                            (y + 1)] + (r1)
                self.goalPotentialGKP2[int(goalEnd)][height - (
                    y +
                    1)] = self.goalPotentialGKP2[int(goalEnd)][height -
                                                               (y + 1)] + (r1)

                self.goalPotentialDF1[int(goalStart)][
                    y] = self.goalPotentialDF1[int(goalStart)][y] + (r1)
                self.goalPotentialDF1[int(goalEnd)][y] = self.goalPotentialDF1[
                    int(goalEnd)][y] + (r1)
                self.goalPotentialDF1[int(goalStart)][
                    height - (y + 1)] = self.goalPotentialDF1[int(goalStart)][
                        height - (y + 1)] - np.log2(r2)
                self.goalPotentialDF1[int(goalEnd)][height - (
                    y + 1
                )] = self.goalPotentialDF1[int(goalEnd)][height -
                                                         (y + 1)] - np.log2(r2)

                self.goalPotentialDF2[int(goalStart)][
                    y] = self.goalPotentialDF2[int(goalStart)][y] - np.log2(r2)
                self.goalPotentialDF2[int(goalEnd)][y] = self.goalPotentialDF2[
                    int(goalEnd)][y] - np.log2(r2)
                self.goalPotentialDF2[int(goalStart)][height - (
                    y +
                    1)] = self.goalPotentialDF2[int(goalStart)][height -
                                                                (y + 1)] + (r1)
                self.goalPotentialDF2[int(goalEnd)][height - (
                    y +
                    1)] = self.goalPotentialDF2[int(goalEnd)][height -
                                                              (y + 1)] + (r1)

                self.goalPotentialPO1[int(goalStart)][
                    y] = self.goalPotentialPO1[int(goalStart)][y] - np.log2(r2)
                self.goalPotentialPO1[int(goalEnd)][y] = self.goalPotentialPO1[
                    int(goalEnd)][y] - np.log2(r2)
                self.goalPotentialPO1[int(goalStart)][height - (
                    y +
                    1)] = self.goalPotentialPO1[int(goalStart)][height -
                                                                (y + 1)] + (r1)
                self.goalPotentialPO1[int(goalEnd)][height - (
                    y +
                    1)] = self.goalPotentialPO1[int(goalEnd)][height -
                                                              (y + 1)] + (r1)

                self.goalPotentialPO2[int(goalStart)][
                    y] = self.goalPotentialPO2[int(goalStart)][y] + (r1)
                self.goalPotentialPO2[int(goalEnd)][y] = self.goalPotentialPO2[
                    int(goalEnd)][y] + (r1)
                self.goalPotentialPO2[int(goalStart)][
                    height - (y + 1)] = self.goalPotentialPO2[int(goalStart)][
                        height - (y + 1)] - np.log2(r2)
                self.goalPotentialPO2[int(goalEnd)][height - (
                    y + 1
                )] = self.goalPotentialPO2[int(goalEnd)][height -
                                                         (y + 1)] - np.log2(r2)

                self.goalPotentialBP1[int(goalStart)][
                    y] = self.goalPotentialBP1[int(goalStart)][y] - np.log2(r2)
                self.goalPotentialBP1[int(goalEnd)][y] = self.goalPotentialBP1[
                    int(goalEnd)][y] - np.log2(r2)
                self.goalPotentialBP1[int(goalStart)][height - (
                    y +
                    1)] = self.goalPotentialBP1[int(goalStart)][height -
                                                                (y + 1)] + (r1)
                self.goalPotentialBP1[int(goalEnd)][height - (
                    y +
                    1)] = self.goalPotentialBP1[int(goalEnd)][height -
                                                              (y + 1)] + (r1)

                self.goalPotentialBP2[int(goalStart)][
                    y] = self.goalPotentialBP2[int(goalStart)][y] + (r1)
                self.goalPotentialBP2[int(goalEnd)][y] = self.goalPotentialBP2[
                    int(goalEnd)][y] + (r1)
                self.goalPotentialBP2[int(goalStart)][
                    height - (y + 1)] = self.goalPotentialBP2[int(goalStart)][
                        height - (y + 1)] - np.log2(r2)
                self.goalPotentialBP2[int(goalEnd)][height - (
                    y + 1
                )] = self.goalPotentialBP2[int(goalEnd)][height -
                                                         (y + 1)] - np.log2(r2)

        #Create Agents
        for i in range(self.num_agents):
            if i > ((2 * N) - 3):
                a = PlayerAgent(i, self, True)
            else:
                a = PlayerAgent(i, self)
            self.schedule.add(a)

            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))

        #Set Up Kickoff
        self.kickoff()

        #Set Up DataCollector
        self.datacollector = DataCollector(model_reporters={
            "Score 1": "score1",
            "Score 2": "score2"
        },
                                           agent_reporters={
                                               "Avg. Displacement": "avgDisp",
                                               "Max Displacement": "maxDisp"
                                           })

    def kickoff(self):
        posBoy = -1
        newPositions = {}
        if self.justConceded == 0:
            posTeam = self.random.randint(1, 2)
        else:
            posTeam = self.justConceded
        for cellContents, x, y in self.grid.coord_iter():
            if len(cellContents) == 0:
                pass
            else:
                for i in cellContents:
                    if posBoy == -1:
                        if i.teamID == posTeam:
                            if i.goalkeeper == True:
                                pass
                            else:
                                i.possession = True
                                posBoy = i.unique_id
                                newPositions[i] = ((self.grid.width / 2) - 1,
                                                   (self.grid.height / 2) - 1)
                    if i.unique_id != posBoy:
                        if i.teamID == 1:
                            if i.goalkeeper == True:
                                x = self.random.randint(
                                    (self.grid.width / 2) - 5,
                                    (self.grid.width / 2) + 3)
                                y = self.random.randint(0, 17)
                                newPositions[i] = (x, y)
                            else:
                                x = self.random.randrange(self.grid.width)
                                y = self.random.randint(
                                    0, (self.grid.height / 2) - 1)
                                newPositions[i] = (x, y)
                        else:
                            if i.goalkeeper == True:
                                x = self.random.randint(
                                    (self.grid.width / 2) - 5,
                                    (self.grid.width / 2) + 3)
                                y = self.random.randint(
                                    self.grid.height - 18,
                                    self.grid.height - 1)
                                newPositions[i] = (x, y)
                            else:
                                x = self.random.randrange(self.grid.width)
                                y = self.random.randint(
                                    (self.grid.height / 2) - 1,
                                    self.grid.height - 1)
                                newPositions[i] = (x, y)
        for key in newPositions.keys():
            (x, y) = newPositions[key]
            x = int(x)
            y = int(y)
            self.grid.move_agent(key, (x, y))
        self.justConceded = 0

    def calcPotential(self):
        for x in range(self.grid.width):
            for y in range(self.grid.height):
                self.movePotentialGK1[x][y] = self.goalPotentialGK1[x][y]
                self.movePotentialGK2[x][y] = self.goalPotentialGK2[x][y]

                self.movePotentialGKP1[x][y] = self.goalPotentialGKP1[x][y]
                self.movePotentialGKP2[x][y] = self.goalPotentialGKP2[x][y]

                self.movePotentialDF1[x][y] = self.goalPotentialDF1[x][y]
                self.movePotentialDF2[x][y] = self.goalPotentialDF2[x][y]

                self.movePotentialPO1[x][y] = self.goalPotentialPO1[x][y]
                self.movePotentialPO2[x][y] = self.goalPotentialPO2[x][y]

                self.movePotentialBP1[x][y] = self.goalPotentialBP1[x][y]
                self.movePotentialBP2[x][y] = self.goalPotentialBP2[x][y]

        playerPos = {}
        for agent, x, y in self.grid.coord_iter():
            if len(agent) == 0:
                pass
            else:
                for i in agent:
                    playerPos[i.unique_id] = {"x": x, "y": y, "state": i.state}
                    if i.state == "":
                        i.checkState()
                        playerPos[i.unique_id]['state'] = i.state
        for key in playerPos.keys():
            agent = playerPos[key]

            for i in range(self.grid.width):
                for j in range(self.grid.height):
                    r = ((agent['x'] - i)**2 + (agent['y'] - j)**2)**(0.5)
                    if r != 0:
                        if agent['state'] == "GK":
                            self.movePotentialGK1[i][
                                j] = self.movePotentialGK1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialGK2[i][
                                j] = self.movePotentialGK2[i][j] + (20 /
                                                                    (r**2))

                            self.movePotentialGKP1[i][
                                j] = self.movePotentialGKP1[i][j] + (20 /
                                                                     (r**2))
                            self.movePotentialGKP2[i][
                                j] = self.movePotentialGKP2[i][j] + (20 /
                                                                     (r**2))

                            self.movePotentialDF1[i][
                                j] = self.movePotentialDF1[i][j] + 40 * (
                                    (5 * (2**(-1 / 6)) / r)**12 -
                                    (5 * (2**(-1 / 6)) / r)**6)
                            self.movePotentialDF2[i][
                                j] = self.movePotentialDF2[i][j] + 40 * (
                                    (5 * (2**(-1 / 6)) / r)**12 -
                                    (5 * (2**(-1 / 6)) / r)**6)

                            self.movePotentialPO1[i][
                                j] = self.movePotentialPO1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialPO2[i][
                                j] = self.movePotentialPO2[i][j] + (20 /
                                                                    (r**2))

                            self.movePotentialBP1[i][
                                j] = self.movePotentialBP1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialBP2[i][
                                j] = self.movePotentialBP2[i][j] + (20 /
                                                                    (r**2))

                        elif agent['state'] == "GKP":
                            self.movePotentialGK1[i][
                                j] = self.movePotentialGK1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialGK2[i][
                                j] = self.movePotentialGK2[i][j] + (20 /
                                                                    (r**2))

                            self.movePotentialGKP1[i][
                                j] = self.movePotentialGKP1[i][j]
                            self.movePotentialGKP2[i][
                                j] = self.movePotentialGKP2[i][j]

                            self.movePotentialDF1[i][
                                j] = self.movePotentialDF1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialDF2[i][
                                j] = self.movePotentialDF2[i][j] + (20 /
                                                                    (r**2))

                            self.movePotentialPO1[i][
                                j] = self.movePotentialPO1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialPO2[i][
                                j] = self.movePotentialPO2[i][j] + (20 /
                                                                    (r**2))

                            self.movePotentialBP1[i][
                                j] = self.movePotentialBP1[i][j]
                            self.movePotentialBP2[i][
                                j] = self.movePotentialBP2[i][j]

                        elif agent['state'] == "DF":
                            self.movePotentialGK1[i][
                                j] = self.movePotentialGK1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialGK2[i][
                                j] = self.movePotentialGK2[i][j] + (20 /
                                                                    (r**2))

                            self.movePotentialGKP1[i][
                                j] = self.movePotentialGKP1[i][j] + (20 /
                                                                     (r**2))
                            self.movePotentialGKP2[i][
                                j] = self.movePotentialGKP2[i][j] + (20 /
                                                                     (r**2))

                            self.movePotentialDF1[i][
                                j] = self.movePotentialDF1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialDF2[i][
                                j] = self.movePotentialDF2[i][j] + (20 /
                                                                    (r**2))

                            self.movePotentialPO1[i][
                                j] = self.movePotentialPO1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialPO2[i][
                                j] = self.movePotentialPO2[i][j] + (20 /
                                                                    (r**2))

                            self.movePotentialBP1[i][
                                j] = self.movePotentialBP1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialBP2[i][
                                j] = self.movePotentialBP2[i][j] + (20 /
                                                                    (r**2))

                        elif agent['state'] == "PO":
                            self.movePotentialGK1[i][
                                j] = self.movePotentialGK1[i][j] - (20 /
                                                                    (r**2))
                            self.movePotentialGK2[i][
                                j] = self.movePotentialGK2[i][j] - (20 /
                                                                    (r**2))

                            self.movePotentialGKP1[i][
                                j] = self.movePotentialGKP1[i][j] - (20 /
                                                                     (r**2))
                            self.movePotentialGKP2[i][
                                j] = self.movePotentialGKP2[i][j] - (20 /
                                                                     (r**2))

                            self.movePotentialDF1[i][
                                j] = self.movePotentialDF1[i][j] + 40 * (
                                    (2.5 * (2**(-1 / 6)) / r)**12 -
                                    (2.5 * (2**(-1 / 6)) / r)**6)
                            self.movePotentialDF2[i][
                                j] = self.movePotentialDF2[i][j] + 40 * (
                                    (2.5 * (2**(-1 / 6)) / r)**12 -
                                    (2.5 * (2**(-1 / 6)) / r)**6)

                            self.movePotentialPO1[i][
                                j] = self.movePotentialPO1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialPO2[i][
                                j] = self.movePotentialPO2[i][j] + (20 /
                                                                    (r**2))

                            self.movePotentialBP1[i][
                                j] = self.movePotentialBP1[i][j] + (20 /
                                                                    (r**2))
                            self.movePotentialBP2[i][
                                j] = self.movePotentialBP2[i][j] + (20 /
                                                                    (r**2))

                        elif agent['state'] == "BP":
                            self.movePotentialGK1[i][
                                j] = self.movePotentialGK1[i][j] - (20 /
                                                                    (r**2))
                            self.movePotentialGK2[i][
                                j] = self.movePotentialGK2[i][j] - (20 /
                                                                    (r**2))

                            self.movePotentialGKP1[i][
                                j] = self.movePotentialGKP1[i][j]
                            self.movePotentialGKP2[i][
                                j] = self.movePotentialGKP2[i][j]

                            self.movePotentialDF1[i][
                                j] = self.movePotentialDF1[i][j] - (20 /
                                                                    (r**2))
                            self.movePotentialDF2[i][
                                j] = self.movePotentialDF2[i][j] - (20 /
                                                                    (r**2))

                            self.movePotentialPO1[i][
                                j] = self.movePotentialPO1[i][j] + 40 * (
                                    (5 * (2**(-1 / 6)) / r)**12 -
                                    (5 * (2**(-1 / 6)) / r)**6)
                            self.movePotentialPO2[i][
                                j] = self.movePotentialPO2[i][j] + 40 * (
                                    (5 * (2**(-1 / 6)) / r)**12 -
                                    (5 * (2**(-1 / 6)) / r)**6)

                            self.movePotentialBP1[i][
                                j] = self.movePotentialBP1[i][j]
                            self.movePotentialBP2[i][
                                j] = self.movePotentialBP2[i][j]

                        else:
                            print(
                                "Error in CalcPotential: Player has no state")

    def scoreCheck(self):
        '''Checks if any player agent has successfully scored and increments the team's score by 1'''
        if self.justConceded == 0:
            pass
        else:
            if self.justConceded == 1:
                self.score2 = self.score2 + 1
                self.kickoff()
            else:
                self.score1 = self.score1 + 1
                self.kickoff()

    def gridVisual(self):
        grid = np.zeros((self.grid.width, self.grid.height))
        for agent, x, y in self.grid.coord_iter():
            if len(agent) != 0:
                for k in agent:
                    grid[x][y] = k.teamID
        name = "Visualisation\Latest Test\Figure_" + str(self.i) + ".jpg"
        plt.imsave(name, grid)

    def bugTest(self):
        self.calcPotential()
        plt.figure(1)
        plt.clf()
        plt.imshow(self.movePotentialBP1, interpolation="nearest")

        plt.figure(2)
        plt.clf()
        plt.imshow(self.movePotentialBP2, interpolation="nearest")

        plt.figure(3)
        plt.clf()
        plt.imshow(self.movePotentialDF1, interpolation="nearest")

        plt.figure(4)
        plt.clf()
        plt.imshow(self.movePotentialDF2, interpolation="nearest")

        plt.figure(5)
        plt.clf()
        plt.imshow(self.movePotentialGK1, interpolation="nearest")

        plt.figure(6)
        plt.clf()
        plt.imshow(self.movePotentialGK2, interpolation="nearest")

        plt.figure(7)
        plt.clf()
        plt.imshow(self.movePotentialGKP1, interpolation="nearest")

        plt.figure(8)
        plt.clf()
        plt.imshow(self.movePotentialGKP2, interpolation="nearest")

        plt.figure(9)
        plt.clf()
        plt.imshow(self.movePotentialPO1, interpolation="nearest")

        plt.figure(10)
        plt.clf()
        plt.imshow(self.movePotentialPO2, interpolation="nearest")

    def step(self):
        '''Advance the model by one step.'''
        self.calcPotential()
        self.scoreCheck()
        self.datacollector.collect(self)
        self.schedule.step()
        self.i = self.i + 1
        self.gridVisual()

        print("Step: " + str(self.i))
        print(str(self.score1) + " - " + str(self.score2))
Exemplo n.º 5
0
Arquivo: model.py Projeto: Fije/MC-ACO
class Environment(Model):
    """ A model which contains a number of ant colonies. """
    def __init__(self, width, height, n_colonies, n_ants, n_obstacles, decay=0.2, sigma=0.1, moore=False, birth=True, death=True):
        """
        :param width: int, width of the system
        :param height: int, height of the system
        :param n_colonies: int, number of colonies
        :param n_ants: int, number of ants per colony
        :param decay: float, the rate in which the pheromone decays
        :param sigma: float, sigma of the Gaussian convolution
        :param moore: boolean, True/False whether Moore/vonNeumann is used
        """
        super().__init__()

        # Agent variables
        self.birth = birth
        self.death = death

        self.pheromone_level = 1

        # Environment variables
        self.width = width
        self.height = height
        self.grid = MultiGrid(width, height, False)

        self.moore = moore

        self.sigma = sigma
        self.decay = decay

        # Environment attributes
        self.schedule = RandomActivation(self)

        self.colonies = [Colony(self, i, (width // 2, height // 2), n_ants, birth=self.birth, death=self.death) for i in range(n_colonies)]

        self.pheromones = np.zeros((width, height), dtype=np.float)
        self.pheromone_updates = []

        self.food = FoodGrid(self)
        self.food.add_food()

        self.obstacles = []
        for _ in range(n_obstacles):
            self.obstacles.append(Obstacle(self))

        # Metric + data collection
        self.min_distance = distance.cityblock(self.colonies[0].pos, self.food.get_food_pos())
        self.datacollector = DataCollector(
            model_reporters={"Minimum path length": metrics.min_path_length,
                             "Mean minimum path length": metrics.mean_min_path_length},
            agent_reporters={"Agent minimum path length": lambda x: min(x.path_lengths),
                            "Encounters": Ant.count_encounters})

        # Animation attributes
        self.pheromone_im = None
        self.ax = None

    def step(self):
        """
        Do a single time-step using freeze-dry states, colonies are updated each time-step in random orders, and ants
        are updated per colony in random order.
        """
        self.food.step()
        self.datacollector.collect(self)

        # Update all colonies
        for col in random.sample(self.colonies, len(self.colonies)):
            col.step()

        self.schedule.step()
        self.update_pheromones()

    def move_agent(self, ant, pos):
        """
        Move an agent across the map.
        :param ant: class Ant
        :param pos: tuple (x, y)
        """
        if self.moore:
            assert np.sum(np.subtract(pos, ant.pos) ** 2) in [1, 2], \
                "the ant can't move from its original position {} to the new position {}, because the distance " \
                "is too large".format(ant.pos, pos)
        else:
            assert np.sum(np.subtract(pos, ant.pos) ** 2) == 1, \
                "the ant can't move from its original position {} to the new position {}, because the distance " \
                "is too large, loc_food {}".format(ant.pos, pos, self.food.get_food_pos())

        self.grid.move_agent(ant, pos)

    def get_random_position(self):
        return (np.random.randint(0, self.width), np.random.randint(0, self.height))

    def position_taken(self, pos):
        if pos in self.food.get_food_pos():
            return True

        for colony in self.colonies:
            if colony.on_colony(pos):
                return True

        for obstacle in self.obstacles:
            if obstacle.on_obstacle(pos):
                return True

        return False

    def add_food(self):
        """
        Add food somewhere on the map, which is not occupied by a colony yet
        """
        self.food.add_food()

    def place_pheromones(self, pos):
        """
        Add pheromone somewhere on the map
        :param pos: tuple (x, y)
        """
        self.pheromone_updates.append((pos, self.pheromone_level))

    def get_neighbor_pheromones(self, pos, id):
        """
        Get the passable neighboring positions and their respective pheromone levels for the pheromone id
        :param pos:
        :param id:
        :return:
        """
        indices = self.grid.get_neighborhood(pos, self.moore)
        indices = [x for x in indices if not any([isinstance(x, Obstacle) for x in self.grid[x[0]][x[1]]])]

        pheromones = [self.pheromones[x, y] for x, y in indices]

        return indices, pheromones

    def update_pheromones(self):
        """
        Place the pheromones at the end of a timestep on the grid. This is necessary for freeze-dry time-steps
        """
        for (pos, level) in self.pheromone_updates:
            # self.pheromones[pos] += level
            self.pheromones[pos] += 1

        self.pheromone_updates = []

        # gaussian convolution using self.sigma
        self.pheromones = gaussian_filter(self.pheromones, self.sigma) * self.decay


    def animate(self, ax):
        """

        :param ax:
        :return:
        """
        self.ax = ax
        self.animate_pheromones()
        self.animate_colonies()
        self.animate_ants()
        self.animate_food()
        self.animate_obstacles()

    def animate_pheromones(self):
        """
        Update the visualization part of the Pheromones.
        :param ax:
        """

        pheromones = np.rot90(self.pheromones.astype(np.float64).reshape(self.width, self.height))
        if not self.pheromone_im:
            self.pheromone_im = self.ax.imshow(pheromones,
                                               vmin=0, vmax=50,
                                               interpolation='None', cmap="Purples")
        else:
            self.pheromone_im.set_array(pheromones)

    def animate_colonies(self):
        """
        Update the visualization part of the Colonies.
        :return:
        """
        for colony in self.colonies:
            colony.update_vis()

    def animate_food(self):
        """
        Update the visualization part of the FoodGrid.
        :return:
        """
        self.food.update_vis()

    def animate_ants(self):
        """
        Update the visualization part of the Ants.
        """
        for ant in self.schedule.agents:
            ant.update_vis()

    def animate_obstacles(self):
        """
        Update the visualization part of the Obstacles.
        :return:
        """
        for obstacle in self.obstacles:
            obstacle.update_vis()

    def grid_to_array(self, pos):
        """
        Convert the position/indices on self.grid to imshow array.
        :param pos: tuple (int: x, int: y)
        :return: tuple (float: x, float: y)
        """
        return pos[0] - 0.5, self.height - pos[1] - 1.5

    def pheromone_threshold(self, threshold):
        """ Returns an array of the positions in the grid in which
        the pheromone levels are above the given threshold"""
        pher_above_thres = np.where(self.pheromones >= threshold)

        return list(zip(pher_above_thres[0],pher_above_thres[1]))

    def find_path(self, pher_above_thres):
        """ Returns the shortest paths from all the colonies to all the food sources.
        A path can only use the positions in the given array. Therefore, this function
        checks whether there is a possible path for a certain pheremone level.
        Essentially a breadth first search"""
        space_searched = False
        all_paths = []
        food_sources = self.food.get_food_pos()

        # Search the paths for a colony to all food sources
        for colony in self.colonies:
            colony_paths = []
            pos_list = {colony.pos} # Prooning
            possible_paths = [[colony.pos]]

            # Continue expanding search area until all food sources found
            # or until the entire space is searched
            while food_sources != [] and not space_searched:
                space_searched = True
                temp = []

                for path in possible_paths:
                    for neighbor in self.grid.get_neighborhood(include_center=False, radius=1, pos=path[-1], moore=self.moore):
                        if neighbor in food_sources:
                            food_path = copy(path)
                            food_path.append(neighbor)
                            colony_paths.append(food_path)
                            food_sources.remove(neighbor)

                        # Add epanded paths to the possible paths
                        if neighbor in pher_above_thres and neighbor not in pos_list:
                            space_searched = False
                            temp_path = copy(path)
                            temp_path.append(neighbor)
                            temp.append(temp_path)
                            pos_list.add(neighbor)

                    possible_paths.remove(path)

                possible_paths += temp

        all_paths.append(colony_paths)

        return all_paths
Exemplo n.º 6
0
class SamplePSO(PSO):
    def __init__(self, population: int, dimension: int,
                 attraction_best_global: float,
                 attraction_best_personal: float, lim_vel_particles: float,
                 inertia_particle: float, max_iterations: int, width: int,
                 height: int, num_max_locales: int, suavizar_espacio: int):
        super().__init__(population, dimension, attraction_best_global,
                         attraction_best_personal, lim_vel_particles,
                         inertia_particle, max_iterations)

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

        # Variables para el espacio de busqueda
        self.num_max_locales = num_max_locales
        self.suavizar_espacio = suavizar_espacio

        # Crear espacio de busqueda
        self.setup_search_space()

        # Crear particulas
        # Lo hace la clase padre

        # Colocar particulas
        # Hay que adaptar pos interno al espacio de busqueda
        self.place_particles(True)

        # Captura de datos para grafica
        self.datacollector = DataCollector({
            "Best": lambda m: m.global_best_value,
            "Average": lambda m: m.average()
        })

    def average(self):
        sum = 0
        for agent in self.schedule.agents:
            if isinstance(agent, Particle):
                sum += agent.personal_best_value
        return sum / self.population

    # Se modifica step del padre para añadir el collector

    def step(self):
        super().step()
        # Collect data
        self.datacollector.collect(self)
        # Stop si llega al máximo
        if self.global_best_value == 1:
            self.running = False

    def place_particles(self, initial=False):
        for particle in self.particles:
            pos = self.pos_particle_to_pos(particle)

            if initial:
                self.grid.place_agent(particle, pos)
            else:
                self.grid.move_agent(particle, pos)

    def pos_particle_to_pos(self, particle: Particle):
        # Convierte posiciones de particula [0 1] en posiciones de grid 2D
        min_xcor = 0
        max_xcor = self.width - 1
        min_ycor = 0
        max_ycor = self.height - 1
        x_cor = self.convert(particle.pos_particle[0], min_xcor, max_xcor)
        y_cor = self.convert(particle.pos_particle[1], min_ycor, max_ycor)
        return (x_cor, y_cor)

    @staticmethod
    def convert(x: float, a: float, b: float) -> int:
        # Bijection from [0, 1] to [a, b]
        return int(a + x * (b - a))

    def setup_search_space(self):
        # Preparar un espacio de busqueda con colinas y valles

        if self.num_max_locales == 0:
            for agent, x, y in self.grid.coord_iter():
                val = random.random()
                patch = Patch(self.unique_id, self, (x, y), val)
                self.unique_id += 1
                self.grid.place_agent(patch, (x, y))
        else:
            n_elements = (self.width - 1) * (self.height - 1)
            selected_elements = random.sample(range(n_elements),
                                              self.num_max_locales)
            element = 0
            for (agentSet, x, y) in self.grid.coord_iter():
                val = 10 * random.random(
                ) if element in selected_elements else 0
                patch = Patch(self.unique_id, self, (x, y), val)
                self.unique_id += 1
                self.grid.place_agent(patch, (x, y))
                element += 1

        # Suavizado del espacio
        for _ in range(self.suavizar_espacio):
            for (agentSet, x, y) in self.grid.coord_iter():
                for agent in agentSet:
                    if isinstance(agent, Patch):
                        agent.diffuse_val(1)

        # Normalizacion del espacio 0 y 0.99999
        min_val = 0
        max_val = 0
        for (agentSet, x, y) in self.grid.coord_iter():
            for agent in agentSet:
                if isinstance(agent, Patch):
                    if agent.val < min_val:
                        min_val = agent.val
                    if agent.val > max_val:
                        max_val = agent.val
        for (agentSet, x, y) in self.grid.coord_iter():
            for agent in agentSet:
                if isinstance(agent, Patch):
                    agent.val = 0.99999 * (agent.val - min_val) / (max_val -
                                                                   min_val)

        # Marcar a 1 el máximo
        max_val = 0
        max_patch = None
        for (agentSet, x, y) in self.grid.coord_iter():
            for agent in agentSet:
                if isinstance(agent, Patch):
                    if agent.val > max_val:
                        max_patch = agent
        if isinstance(max_patch, Particle):
            max_patch.val = 1

        # Colorear patches
        for (agentSet, x, y) in self.grid.coord_iter():
            for agent in agentSet:
                if isinstance(agent, Patch):
                    agent.set_color()

    # Se han de definir los métodos evaluation y psoexternalUpdate

    def evaluation(self, particle: Particle):
        # Se podría usar particle.pos si se ejecutara primero pso_external_update
        # Pero se ejecuta despues

        # Hay que revisar la primera evaluación al crear particulas
        if self.grid is not None:

            pos = self.pos_particle_to_pos(particle)
            for patch in self.grid.get_cell_list_contents(pos):
                if isinstance(patch, Patch):
                    return patch.val
        else:
            return 0

    def pso_external_update(self):
        self.place_particles()
Exemplo n.º 7
0
class Kmedias(Model):
    def __init__(self, height, width, initial_topics, agrupados,
                 dispersion, tam_dispersion, num_cluster, tolerancia,
                 representar_areas):
        super().__init__()
        self.height = height
        self.width = width

        # Numero de topics a clasificar
        self.initial_topics = initial_topics
        self.agrupados = agrupados
        self.dispersion = dispersion
        self.tam_dispersion = tam_dispersion
        self.num_cluster = num_cluster
        self.tolerancia = tolerancia
        self.representar_areas = representar_areas

        self.unique_id=0

        # Creación del planificador y del grid
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(self.width, self.height, torus=False)

        self.topics = []
        self.clusters = []

        self.colors = {0: "lime",
                       1: "yellow",
                       2: "green",
                       3: "blue",
                       4: "fuchsia",
                       5: "brown"}

        self.setup()

        self.running = True

    def setup(self):
        if self.agrupados==True:
            self.setup_topics2()
        else:
            self.setup_topics()
        self.setup_cluster()

    def setup_topics(self):
        self.setup_patches("grey0")
        for _ in range(self.initial_topics):
            pos = [random.randint(0, self.width-1), random.randint(0, random.randint(0, self.height-1))]
            topic = Topic(self.unique_id, self, pos, "black")
            self.unique_id +=1
            self.grid.place_agent(topic, pos)
            self.topics.append(topic)

    def setup_topics2(self):
        self.setup_patches("grey0")
        bolsas = random.randint(1, self.dispersion)
        for _ in range(bolsas):
            pos = [random.randint(0, self.width - 1), random.randint(0, random.randint(0, self.height - 1))]
            topic = Topic(self.unique_id, self, pos, "black")
            self.unique_id += 1
            self.grid.place_agent(topic, pos)
            self.topics.append(topic)

        for _ in range(self.initial_topics - bolsas):
            # Clonar uno de los topics darle orientacion random (ya la tienen)
            # y hacer que avance 0-5 posiciones posiciones
            ram = random.randint(0, len(self.topics)-1)
            topic_father = self.topics[ram]
            pos = topic_father.pos
            topic = Topic(self.unique_id, self, pos, "black", random.randint(0, 359))
            self.unique_id += 1
            self.grid.place_agent(topic, pos)
            self.topics.append(topic)
            for _ in range(random.randint(0, self.tam_dispersion)):
                if topic.can_move():
                    topic.forward()

    def setup_patches(self, color):
        for agent, x, y in self.grid.coord_iter():
            pos = [x,y]
            cell = Cell(self.unique_id,self,pos,color)
            self.unique_id +=1
            self.grid.place_agent(cell,pos)

    def setup_cluster(self):
        # 1. Generar centros aleatorios
        for i in range(self.num_cluster):
            topic = self.topics[random.randint(0, len(self.topics)-1)]
            pos = topic.pos
            color = "red"
            cluster = Cluster(self.unique_id, self, pos, color)
            self.unique_id += 1
            self.grid.place_agent(cluster, pos)
            self.clusters.append(cluster)
            cluster.clase_color = self.colors[i]

    def step(self):
        # print("step turulu")
        # 4. Mientras algún centro de mueva
        if self.any_cluster_movido():
            # 2. Asignar un grupo a cada elemento
            for topic in self.topics:
                topic.clase = self.get_clase(topic)
                topic.color = self.colors[topic.clase]
            # Contar los elementos asignados a cada cluster
            i = 0
            for cluster in self.clusters:
                topicClase = []
                for topic in self.topics:
                    if topic.clase == i:
                        topicClase.append(topic)
                if len(topicClase) > 0:
                    centroide = self.calcular_centroide(topicClase)
                    if self.distance(centroide, cluster.pos) > 0.01:
                        cluster.movido = True
                    else:
                        cluster.movido = False
                    self.grid.move_agent(cluster, centroide)
                else:
                    x_pos = random.randint(0, self.width-1)
                    y_pos = random.randint(0, self.height-1)
                    self.grid.move_agent(cluster, [x_pos, y_pos])
                    cluster.movido = True
                i += 1

        else:
            # No se moveran más los cluster
            if self.representar_areas:
                self.areas()
                self.representar_areas = False
            else:
                self.running = False

    def areas(self):

        # Poner todos los topics en negro
        for topic in self.topics:
            topic.color = "black"

        # Colorear con color al centroide más cercano
        for (agentset, x, y) in self.grid.coord_iter():
            for agent in agentset:
                if isinstance(agent, Cell):
                    clase = self.get_clase(agent)
                    agent.color = self.colors[clase]

    def calcular_centroide(self, topicClase):
        sum_x = 0
        sum_y = 0
        for topic in topicClase:
            sum_x += topic.pos[0]
            sum_y += topic.pos[1]
        x = int(sum_x / len(topicClase))
        y = int(sum_y / len(topicClase))
        return [x,y]

    def any_cluster_movido(self):
        for c in self.clusters:
            if c.movido == True:
                return True
        return False

    def get_clase(self, topic):
        clase = 0
        distance = self.distance(topic.pos, self.clusters[0].pos)
        for i in range(1,len(self.clusters)):
            new_distance = self.distance(topic.pos, self.clusters[i].pos)
            if new_distance < distance:
                distance = new_distance
                clase = i
        return clase

    @staticmethod
    def distance(pos1, pos2):
        return math.sqrt((pos1[0]-pos2[0])**2+(pos1[1]-pos2[1])**2)
Exemplo n.º 8
0
class MarketModel(Model):
    def __init__(self,
                 buff,
                 plot_buff,
                 max_agents_number,
                 market,
                 checkout_slider,
                 width=50,
                 height=50,
                 steps=3000):
        self.steps = steps
        self.plot_buff = plot_buff
        self.running = True
        self.market = market
        self.checkout_slider = checkout_slider
        self.num_agents = max_agents_number
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(width, height, True)
        self.grid_mutex = Lock()
        self.agents_number = 1
        self.regal_agents = []
        self.checkout_agents = []
        self.opened_checkouts = []
        self.closed_checkouts = []
        self.space_graph = np.zeros((width, height))
        self.place_checkouts()
        self.place_regals()
        self.thread_pool = ThreadPool(20)
        self.customer_list = buff
        self.total_income = 0.0
        self.agent_counts = [[0 for x in range(self.grid.width)]
                             for y in range(self.grid.height)]
        self.plot_buff.append(self.agent_counts)
        self.plot_buff.append(self.grid.width)
        self.plot_buff.append(self.grid.height)
        self.income_data_collector = DataCollector(
            model_reporters={"total_income": get_income})

        self.queue_length_data_collector = DataCollector(
            model_reporters={
                "average_queue_length": compute_average_queue_size
            })

        self.open_checkouts()

    def add_agent(self):
        i = random.randint(0, 1)
        if i == 0:
            a = CommonCustomer(self.agents_number, self, self.market.articles)
        else:
            a = LazyCustomer(self.agents_number, self, self.market.articles)
        # a = CommonCustomer(self.agents_number, self, self.market.articles)
        self.agents_number += 1
        self.schedule.add(a)
        self.grid.place_agent(a, (a.x, a.y))
        self.customer_list.append(a)

    def place_checkouts(self):
        for checkout_location in self.market.cashRegisters:
            checkout_agent = Checkout(self.agents_number, self,
                                      checkout_location)
            self.agents_number += 1
            self.grid.place_agent(checkout_agent, checkout_location)
            self.checkout_agents.append(checkout_agent)
            self.space_graph[checkout_location[0], checkout_location[1]] = 1
        self.closed_checkouts = self.checkout_agents

    def place_regals(self):
        for regal in self.market.regals:
            self.place_regal(regal)

    def place_regal(self, regal):
        for shelf in regal.shelf_list:
            self.place_shelf(shelf)

    def place_shelf(self, shelf):
        shelf_agent = ShelfAgent(self.agents_number, self, shelf)
        pos = shelf_agent.get_location()
        self.agents_number += 1
        self.grid.place_agent(shelf_agent, pos)
        self.regal_agents.append(shelf_agent)
        self.space_graph[pos[0], pos[1]] = 1

    def open_checkouts(self):
        for i in range(0, len(self.checkout_agents),
                       len(self.checkout_agents) // self.checkout_slider):
            checkout = self.closed_checkouts.pop(
                random.randint(0,
                               len(self.closed_checkouts) - 1))
            checkout.open()
            self.opened_checkouts.append(checkout)
            self.schedule.add(checkout)

    def open_random_checkout(self):
        if len(self.closed_checkouts) != 0:
            checkout = self.closed_checkouts.pop(
                random.randint(0,
                               len(self.closed_checkouts) - 1))
            checkout.open()
            self.opened_checkouts.append(checkout)
            self.schedule.add(checkout)

    def close_random_checkout(self):
        if len(self.opened_checkouts) > 1:
            checkout = self.opened_checkouts.pop(
                random.randint(0,
                               len(self.opened_checkouts) - 1))
            checkout.close()
            self.closed_checkouts.append(checkout)
            # self.schedule.add(checkout)

    def find_nearest_checkouts(self, location, n):
        new_list = self.opened_checkouts.copy()
        ordered_list = sorted(new_list,
                              key=(lambda x:
                                   ((x.location[0] - location[0])**2) + (
                                       (x.location[1] - location[1])**2)))
        return ordered_list[0:]

    def generate_random_starting_pos(self):
        pos_list = [(self.grid.width // 2 + 1, 0), (self.grid.width - 1, 1),
                    (self.grid.width - 1, self.grid.height - 2)]
        i = random.randint(0, len(pos_list) - 1)
        pos = pos_list[i]

        if i == 0:
            pos = (pos_list[0][0] + random.randint(-2, 2), pos_list[0][1])

        return pos

    def step(self):
        print(self.checkout_slider)
        self.income_data_collector.collect(self)
        self.queue_length_data_collector.collect(self)

        if compute_average_queue_size(self) > 3:
            self.open_random_checkout()

        if compute_average_queue_size(self) < 3:
            self.close_random_checkout()

        sigma = 1
        cycle_steps = 1500
        n = self.schedule.steps // cycle_steps + 1
        gauss = gaussian(
            self.schedule.steps * (6 * sigma / cycle_steps) - 3 * n * sigma, 0,
            sigma) * self.num_agents
        print(gauss)
        while len(self.schedule.agents) - len(
                self.checkout_agents) < np.ceil(gauss):
            self.add_agent()

        self.schedule.step()

    def move_agent(self, agent, new_pos):
        # self.grid_mutex.acquire()
        self.agent_counts[new_pos[0]][new_pos[1]] += 1
        self.plot_buff[0] = self.agent_counts
        self.grid.move_agent(agent, new_pos)
        # self.grid_mutex.release()

    def remove_agent(self, agent):
        # self.grid_mutex.acquire()
        self.grid.remove_agent(agent)
        self.schedule.remove(agent)
        if type(agent) is CommonCustomer:
            self.customer_list.remove(agent)
        # self.grid_mutex.release()

    def get_customers(self):
        return self.customer_list
Exemplo n.º 9
0
class HumanitarianLogistics(Model):
    """A model with: number of azc
        rate of newcomer arrival
        dimensions width and height"""
    def __init__(self, shock_period, shock_duration, shock_rate, N_cities, N_a,
                 nc_rate, width, height):

        #canvas info
        self.width = width
        self.height = height

        #sim boilerplate
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True

        self.num_nc = 0  #counts number of applicants
        self.num_azc = N_a  #number of AZC in sim
        self.nc_rate = nc_rate  #rate of inflow of newcomers
        self.num_cities = N_cities  #number of cities in sim
        self.num_buildings = 3

        self.num_activity_centers = 2
        self.num_activities_per_center = 2
        self.num_per_step = 10

        self.num_activity_centers = 2
        self.num_activities_per_center = 2

        #initialize shock values
        self.shock_period = shock_period  #how often does shock occur
        self.shock_duration = shock_duration  #how long does shock last
        self._shock_duration = shock_duration  #current position in shock
        self.shock_rate = shock_rate  #amt of increase during shock
        self.shock = False  #shock flag
        self.number_added = 1  #base rate of influx
        self.number_shocks = 4
        self.shock_growth = 2

        #dict of probabilities of first/second decision success rates by country
        self.specs = {}
        # list of multinomial probabilities for countries
        self.country_multinomial = []
        # list of shock distributions for countries related to adding newcomers
        self.country_shock_dist = []
        # list of countries
        self.country_list = []
        with open("country-input.csv") as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                decisionList = []
                decisionList.append(float(row['DecisionA']))
                decisionList.append(float(row['DecisionB']))
                self.specs[row['Country']] = decisionList
                self.country_shock_dist.append(row['ShockDist'])
                self.country_list.append(row['Country'])
                self.country_multinomial.append(row['Multinomial'])

        self.country_count = np.zeros(
            len(self.country_list
                ))  #keeps track of how many applicants from each country
        self.country_success = np.zeros(len(self.country_list))
        self.current_country_index = -1

        #records capacitiy of each AZC type
        self.datacollector = DataCollector(model_reporters={
            'Cap - Extended-AS': calc_extended_as,
            'Cap - AS': calc_as
        })

        #records success rates of each country of origin using current_country_index
        #which is manipulated in sr_country
        sr_functions = {}
        for i in range(0, len(self.country_list)):
            self.current_country_index = i
            sr_functions[self.country_list[
                self.current_country_index]] = sr_country

        self.sr = DataCollector(model_reporters=sr_functions)

        self.capacity_dc = DataCollector(model_reporters={
            'Current Capacity': coa_occ,
            'Projected Capacity': coa_proj
        })

        #Ter apel
        ta_pos = (int(self.width / 2), int(self.height / 6 * 5))
        ta_id = self.num_cities + 1
        ter_apel = City(self.num_cities + 1, self, ta_pos)
        ta_coa = COA(ta_id, self, ter_apel)
        ta_coa.ta = True
        self.schedule.add(ta_coa)
        ta_ind = IND(ta_id, self, ter_apel)
        self.schedule.add(ta_ind)
        ta_azc = AZC(ta_id, self, 'edp', ta_pos, ta_coa)
        ta_azc.ta = True
        ta_coa.azcs.add(ta_azc)
        ta_coa.capacities[ta_azc] = ta_azc.occupancy
        self.schedule.add(ta_azc)
        self.grid.place_agent(ta_azc, ta_pos)
        self.ter_apel = ta_azc

        #add activities
        self.test_activity = Football(0, self, 5)
        self.schedule.add(self.test_activity)

        #generate cities

        for city in range(self.num_cities):
            space_per_city = int(self.width / self.num_cities)

            orientation_x = int(
                space_per_city / 2 + city * space_per_city +
                int(space_per_city / self.num_azc / 2))  #center point for city
            pos = (orientation_x, int(self.height / 2))  #placeholder position
            city_size = np.random.uniform(low=0, high=1)
            city_is_big = False
            if city_size > 0.70:
                city_is_big = True
            current_city = City(city, self, pos,
                                city_is_big)  #instantiates city
            #add COA
            current_coa = COA(city, self, current_city)
            current_city.coa = current_coa
            self.schedule.add(current_coa)
            self.grid.place_agent(current_coa,
                                  (pos[0], int(self.height / 3 * 2)))
            current_ind = IND(city, self, current_city)
            self.schedule.add(current_ind)
            current_coa.IND = current_ind
            current_ind.coa = current_coa
            #adds city to schedule n grid
            self.schedule.add(current_city)
            self.grid.place_agent(current_city, (current_city.pos))

            #azc location essentials
            space_per_azc = int(space_per_city / self.num_azc)
            azc_starting_point = orientation_x - (.5 * space_per_city)
            num_activity_centers_added = 0
            # Create AZCs
            for i in range(self.num_azc):
                '''
                if i == 0:
                    occupant_type = 'edp'   # ter apel
                '''
                if i < self.num_azc - 2:
                    occupant_type = 'as'  # standard AZC
                elif i == self.num_azc - 2:
                    occupant_type = 'as_ext'  # extended procedure AZC
                else:
                    occupant_type = 'tr'  # 'Housing' for those with

                #place evenly
                x = int(azc_starting_point + i * space_per_azc)
                y = int(self.height * .5)

                a = AZC(i, self, occupant_type, (x, y),
                        current_coa)  #instantiate
                self.schedule.add(a)  #add in time
                self.grid.place_agent(a, (x, y))  #add in spaace
                current_city.buildings.add(a)
                if a.occupant_type != 'tr':
                    current_coa.azcs.add(a)
                    current_coa.capacities[a] = a.occupancy

                if a.occupant_type == 'tr':
                    current_city.social_housing = a

                #add viz
                v = AZC_Viz(self, a)
                self.schedule.add(v)
                self.grid.place_agent(v, v.pos)

            #create civilian buildings

            y = int(self.height / 5)
            space_per_building = space_per_city / self.num_buildings
            row_size = 15

            if city == 0:
                x = int(azc_starting_point + .5 * space_per_building)
                current = Hotel(self.num_buildings + 1, self, (x, y), 1000)
                current_city.buildings.add(current)
                current.city = current_city
                self.grid.place_agent(current, (x, y))
                self.schedule.add(current)

                empty = Empty(self.num_buildings + 1, self,
                              (int(x + space_per_building), y), 100)
                current_city.buildings.add(empty)
                empty.city = current_city
                self.grid.place_agent(empty, (int(x + space_per_building), y))
                self.schedule.add(empty)

            for bdg in range(city * self.num_buildings):

                x = int(azc_starting_point + (bdg % 3) * space_per_building)

                if bdg == 0:

                    current = Hotel(bdg, self, (x, y), 1000)
                    current_city.buildings.add(current)
                    current.city = current_city
                    self.grid.place_agent(current, (x, y))
                    self.schedule.add(current)
                else:
                    empty = Empty(bdg, self, (x, y - row_size * int(bdg / 3)),
                                  100 * bdg)
                    current_city.buildings.add(empty)
                    empty.city = current_city
                    self.grid.place_agent(empty,
                                          (x, y - row_size * int(bdg / 3)))
                    self.schedule.add(empty)

    def house(self, newcomer):

        #find building for newcomers legal status
        eligible_buildings = [
            x for x in self.schedule.agents
            if type(x) is AZC and x.occupant_type == newcomer.ls
        ]

        #take first one, in future, evaluate buildings on some criteria
        destination = eligible_buildings[0]
        house_loc = destination.pos  #where is it

        if newcomer.ls is not 'edp':
            newcomer.loc.occupancy -= 1  #reduce occupance of prev building

        #add noise so agents don't overlap
        x = house_loc[0] + np.random.randint(-20, 20)
        y = house_loc[1] + np.random.randint(-20, 20)

        self.grid.move_agent(newcomer, (x, y))  #place

        destination.occupants.add(newcomer)  #add agent to building roster
        newcomer.loc = destination  #update agent location

        destination.occupancy += 1  #update occupancy

    def Remove(self, agent):

        agent.loc.occupancy -= 1  #reduce occupancy of building
        agent.loc.occupants.remove(agent)

        #remove from time n space
        self.schedule.remove(agent)
        self.grid.remove_agent(agent)

    def shock_distribution(self):
        #draws a random discrete number from multinomial distribution
        country = np.random.multinomial(1, self.country_shock_dist, size=1)

        # turns that distribution into a number
        country = np.where(country == 1)[1][0]

        # assigns that number to a country
        country_of_origin = self.country_list[country]
        return country_of_origin

    def country_distribution(self):
        #draws a random discrete number from multinomial distribution
        country = np.random.multinomial(1, self.country_multinomial, size=1)

        # turns that distribution into a number
        country = np.where(country == 1)[1][0]

        # updates country count
        self.country_count[country] += 1

        # assigns that number to a country
        country_of_origin = self.country_list[country]
        return country_of_origin

    def addNewcomer(self, shock, country_of_origin):

        #increase count
        self.num_nc += 1

        if not shock:

            country_of_origin = self.country_distribution()

        else:

            self.country_count[self.country_list.index(country_of_origin)] += 1

        x = np.random.randint(0, 10, dtype='int')
        y = np.random.randint(0, 10, dtype='int')
        #define newcomer
        r = Newcomer(self.num_nc, self, country_of_origin, (x, y))
        self.schedule.add(r)
        self.grid.place_agent(r, r.pos)

        #find coa
        coa = [x for x in self.schedule.agents if type(x) is COA][0]

        coa.intake(r)  #place n ter apel
        coa.newcomers.add(r)  #adds NC to coa's list of residents
        r.coa = coa  #likewise for the newcomer

    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)  #collects occupancy data
        self.sr.collect(self)  #collects success rate data
        self.capacity_dc.collect(self)

        if self.schedule.steps % self.shock_period == 0:
            self.shock = True
            self.shock_counter = 0

        if self.shock:

            #if self._shock_duration > (self._shock_duration / 2):
            #    self.number_added += self.shock_rate
            #else:
            #    self.number_added -= self.shock_rate
            self.number_added += self.shock_rate
            for i in range(int(self.number_added)):

                shock_country = self.shock_distribution()

                self.addNewcomer(
                    True, shock_country
                )  # currently in data file all shocks come from Syria
                self.shock_counter += 1
            self._shock_duration -= 1

            if self._shock_duration == 0:

                self.shock = False
                self._shock_duration = self.shock_duration
                self.number_added = 1

                self.shock_counter = 0
                self.shock_rate = self.shock_rate * self.shock_growth
        else:

            #adds newcomers to simuluation at a given rate
            if uniform(0, 1) < self.nc_rate:
                for i in range(self.num_per_step):

                    self.addNewcomer(False, None)
Exemplo n.º 10
0
class Environment(Model):
    """ A model which contains ants with specified roles. """
    def __init__(self,
                 N=10,
                 g=1,
                 size=10,
                 p_uf=0.5,
                 p_pu=0.1,
                 p_up=0.5,
                 p_fl=0.8,
                 p_lu=0.05,
                 ratio=0.5,
                 moore=False,
                 grow=False):
        """
        Args:
            N (int): number of ants
            g (float): the max group size of an Ant relative to N
            size(int): the size of the system (size X size)
            p_uf (float): the probability that Unassigned changes to Follower
            p_pu (float): the probability that Pheromone changes to Unassigned
            p_up (float): the probability that Unassigned changes to Pheromone
            p_fl (float): the probability that Follower changes to Leader
            p_lu (float): the probability that Leader changes to Unassigned
            ratio (float): the start ratio of leaders (1 - ratio is the start nr of pheromone)
            moore (bool): True/False whether Moore/vonNeumann is used
            grow (bool): True/False whether the system grows over time or not
        """
        super().__init__()

        # Environment variables
        size = int(size)
        self.width = size
        self.height = size
        self.moore = moore
        self.grow = grow
        self.grid = MultiGrid(size, size, torus=True)
        self.interaction_probs = {
            Unassigned: (-1, None),
            Follower: (-1, None),
            Leader: (p_uf, Follower),
            Pheromone: (p_up, Pheromone),
            "success": (p_fl, Leader),
            "failure": (p_lu, Unassigned),
            "scent_lost": (p_pu, Unassigned)
        }
        self.ant_counter = 0

        # Environment attributes
        self.schedule = RandomActivation(self)

        # Ant variables
        N = int(N)
        self.N = N
        self.g = g
        self.max_group_size = np.round(g * N) if np.round(g * N) >= 1 else 1
        role_division = {
            Unassigned: np.round(N // 2),
            Follower: 0,
            Leader: int((N // 2) * ratio),
            Pheromone: N - np.round(N // 2) - int((N // 2) * ratio)
        }
        self.role_division = role_division

        for role, number in role_division.items():
            self.add_ants(number, role)

        model_reporters = {
            "unassigned":
            lambda m: sum(
                [1 if a.role == Unassigned else 0 for a in m.schedule.agents]),
            "followers":
            lambda m: sum(
                [1 if a.role == Follower else 0 for a in m.schedule.agents]),
            "leaders":
            lambda m: sum(
                [1 if a.role == Leader else 0 for a in m.schedule.agents]),
            "pheromone":
            lambda m: sum(
                [1 if a.role == Pheromone else 0 for a in m.schedule.agents])
        }
        self.dc = DataCollector(model_reporters=model_reporters)

    def get_torus_coordinates(self, x, y):
        """
        Gives correct coordinates if the coordinates are out of bounds.

        Args:
            x (int): current x position
            y (int): current y position

        Returns:
            Tuple of (x, y) that is in ([0, width], [0, height])
        """
        return x % self.width, y % self.height

    def get_torus_neighborhood(self,
                               pos,
                               moore,
                               radius=1,
                               include_center=False):
        """
        Faster alternative to the mesa built-in grid.get_neighbourhood().

        Args:
            pos (tuple): tuple of position (int x, int y)
            moore (bool): if True, uses Moore's neighborhood
                   if False, uses Neumann's neighborhood
            radius (int): decides the radius of the neighborhood (default 1)
            include_center (bool): if True, include the center
                            if False, do not include the center
                            (default False)

        Returns:
            An iterator that gives all coordinates that are connected to pos
            through the given neighborhood
        """
        x, y = pos

        coordinates = set()

        # Loop over Moore's neighborhood
        for dy in range(-radius, radius + 1):
            for dx in range(-radius, radius + 1):
                if dx == 0 and dy == 0 and not include_center:
                    continue

                # Skip anything outside the manhattan distance for Neumann
                if not moore and abs(dx) + abs(dy) > radius:
                    continue

                px, py = x + dx, y + dy

                px, py = self.get_torus_coordinates(px, py)

                coords = (px, py)

                if coords not in coordinates:
                    coordinates.add(coords)
                    yield coords

    def get_random_position(self):
        """
        Gets a random position in the grid, samples from a uniform distribution.

        Returns:
            Tuple position (int x, int y)
        """
        return (np.random.randint(0, self.width),
                np.random.randint(0, self.height))

    def add_ants(self, N, role):
        """
        Adds N ants of with role role to this colony.

        Args:
            N (int): integer value which specifies the nr of ants to add
            role (Role): one of {Unassigned, Follower, Leader, Pheromone}
        """

        for _ in range(N):
            a = Ant(self.ant_counter, model=self, pos=None, role=role)

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

            self.ant_counter += 1

    def move_agent(self, ant, pos):
        """
        Move an agent across the map.

        Args:
            ant (Ant): what agent to move
            pos (tuple): (int x, int y) to move the agent to
        """
        self.grid.move_agent(ant, pos)

    def step(self):
        """
        Do a single time-step using freeze-dry states, colonies are updated each time-step in random orders, and ants
        are updated per colony in random order.
        """
        self.schedule.step()
        self.dc.collect(self)

        if self.grow:
            self.add_ants(1, Unassigned)
            self.N += 1

    def animate(self, ax):
        """
        Update the visualization part of the Ants.

        Args:
            ax (Axes): axes binding of matplotlib to animate on
        """
        self.ax = ax
        self.animate_ants()

    def animate_ants(self):
        """ Ask the ants to update themselfs in the animation. """
        for ant in self.schedule.agents:
            ant.update_vis()

    def grid_to_array(self, pos):
        """
        Convert the position/indices on self.grid to imshow array.

        Args:
            pos (tuple): (int x, int y)
        Returns:
            tuple (int: x, int: y), that contains the converted position
        """
        return pos[0], self.height - pos[1] - 1
Exemplo n.º 11
0
class GeneticNQueens(Genetic):
    def __init__(self, population, num_iters, crossover_ratio, mutation_ratio,
                 n_queens):
        self.n_queens = n_queens

        super().__init__(population, num_iters, crossover_ratio,
                         mutation_ratio)
        self.grid = MultiGrid(self.n_queens, self.n_queens, False)
        self.queens = []

        self.best: Individual = None
        self.create_board()

        self.running = True

        # Captura de datos para grafica
        self.datacollector = DataCollector({
            "Best": lambda m: m.best.fitness,
            "Average": lambda m: m.average(),
            "Worst": lambda m: m.worst(),
            "Diversity": lambda m: m.diversity()
        })

    def average(self):
        sum = 0
        for individual in self.individuals:
            sum += individual.fitness
        return sum / len(self.individuals)

    def worst(self):
        worst = self.individuals[0].fitness
        for individual in self.individuals[1:len(self.individuals)]:
            if worst > individual.fitness:
                worst = individual.fitness
        return worst

    def create_board(self):
        for i in range(self.n_queens):
            cell_queen = CellQueen(self.unique_id, self, (i, 0))
            self.unique_id += 1
            self.grid.place_agent(cell_queen, (i, 0))
            self.queens.append(cell_queen)
            for j in range(self.n_queens):
                color = "white" if divmod(i + j, 2)[1] == 1 else "black"
                cell = Cell(self.unique_id, self, (i, j), color)
                self.unique_id += 1
                self.grid.place_agent(cell, (i, j))
        self.update_best()

    def update_board(self):
        i = 0
        for queen in self.queens:
            self.grid.move_agent(queen, (i, self.best.content[i]))
            i += 1

    def update_best(self):
        best = self.individuals[0]
        for individual in self.individuals[1:len(self.individuals)]:
            if individual.fitness > best.fitness:
                best = individual
        self.best = best

    # Metodos de la clase padre
    def initial_population(self):
        for _ in range(self.population):
            content = [
                random.randint(0, self.n_queens - 1)
                for _ in range(self.n_queens)
            ]
            individual = Individual(self.unique_id, self, 0, content)
            self.unique_id += 1
            self.compute_fitness(individual)
            self.individuals.append(individual)

    def compute_fitness(self, individual):
        res = 0
        lis = [i for i in range(len(individual.content))]
        for i in lis:
            for j in lis[i:len(lis)]:
                if j > i:
                    res += self.threat(i, j, individual.content)
        individual.fitness = self.n_queens - res

    def threat(self, i, j, content):
        eli = content[i]
        elj = content[j]
        if (eli == elj) or\
                ((elj - eli) == (j - i)) or\
                ((elj - eli) == (i - j)):
            return 1
        return 0

    def crossover(self, content1, content2):
        cut_point = 1 + random.randint(0, len(content1) - 1)
        c1 = content1[0:cut_point] + content2[cut_point:len(content2)]
        c2 = content2[0:cut_point] + content1[cut_point:len(content1)]
        return [c1, c2]

    def mutate(self, individual):
        for i in range(len(individual.content)):
            if random.random() * 100 < self.mutation_ratio:
                individual.content[i] = random.randint(0, self.n_queens - 1)

    def external_update(self):
        self.update_best()

        self.update_board()

        # Recoger datos para plot
        self.datacollector.collect(self)

        # Parada de simulacion si se encuentra solucion
        # O si se acaban las iteraciones
        if self.best.fitness == self.n_queens:
            self.running = False