예제 #1
0
class SlimeModel(Model):
    def __init__(self, height, width, color, numAgents, gDense, kRate, dcDiffu,
                 dhRes, dtRes, secRate):
        # number of agents per tile
        self.n = numAgents
        # grid density
        self.gD = gDense
        # rate of cAMP decay
        self.k = kRate
        # diffusion constant of cAMP
        self.Dc = dcDiffu
        # spatial resolution for cAMP simulation
        self.Dh = dhRes
        # time resolution for cAMP simulation
        self.Dt = dtRes
        # rate of cAMP secretion by an agent
        self.f = secRate
        # number of rows/columns in spatial array
        self.w = masterHeight
        # agent color
        self.color = color

        # height of grid
        self.height = masterHeight
        # width of grid
        self.width = masterWidth

        # Counter for generating sequential unique id's
        self.j = 0
        # Counter for DataVis agents' unique id's
        self.dv = 0
        # Counter for NumDataVis agents' unique id's
        self.ndv = 0

        # Create randomly ordered scheduler
        self.schedule = SimultaneousActivation(self)
        # Create grid (of type MultiGrid to support multiple agents per cell
        self.grid = MultiGrid(self.width, self.height, torus=False)

        # Initialize list of cAMP molecules
        self.cAMPs = list()

        # Initialize dict for datacollector with total datacollector
        dc = {"Total Amount of cAMP": self.getAmts}

        # Initialize for iterating through columns (x) and rows (y)
        self.x = 0
        self.y = 0

        # Loop to fill datacollector dictionary with dict entries for each column and row
        for x in range(masterWidth):
            dc.update({("x: " + str(x)): self.getColAmts})
            dc.update({("y: " + str(x)): self.getRowAmts})

        # Create datacollector to retrieve total amounts of cAMP from dc dict created above
        self.datacollector = DataCollector(dc)

        # Variable for storing random numbers
        r = 0

        # Initial loop to create agents and fill agents list with them
        for (contents, x, y) in self.grid.coord_iter():
            # Create object of type cAMP
            cell = cAMP([x, y], self, self.j, 0)
            # Add random amoutn of cAMP to cell (<1)
            cell.add(random.random())
            # Place cAMP onto grid at coordinates x, y
            self.grid._place_agent((x, y), cell)
            # Add cAMP molecule to list
            self.cAMPs.append(cell)

            # print("x:", x, " y:", y)

            if x == 50:
                # Create DataVis agent
                ag = DataVis([x, y], self, self.dv)
                # Place DataVis agent
                self.grid.place_agent(ag, tuple([x, y]))

                # Increment unique id counter
                self.dv += 1
            elif x > 50:
                # Create NumDataVis agent with appropriate slice num
                ag = NumDataVis([x, y], self, self.ndv)
                # Place NumDataVis agent
                self.grid.place_agent(ag, tuple([x, y]))

                # Increment unique id counter
                self.ndv += 1
            else:
                # Loop to create SlimeAgents
                if self.gD % 1 != 0:
                    r = random.random()
                    if r <= self.gD:
                        for i in range(self.n):
                            # Create object of type SlimeAgent
                            ag = SlimeAgent([x, y], self, self.j, self.color)
                            # Place agent onto grid at coordinates x, y
                            self.grid.place_agent(ag, tuple([x, y]))
                            # Add agent to schedule
                            self.schedule.add(ag)
                            # Increment j (unique_id variable)
                            self.j += 1
                else:
                    for i in range(self.n):
                        # Create object of type SlimeAgent
                        ag = SlimeAgent([x, y], self, self.j, self.color)
                        # Place agent onto grid at coordinates x, y
                        self.grid.place_agent(ag, tuple([x, y]))
                        # Add agent to schedule
                        self.schedule.add(ag)
                        # Increment j (unique_id variable)
                        self.j += 1

        # Print out number of agents
        print("# of agents:", self.j)

        self.running = True

    # Method for getting total cAMP amount
    def getAmts(self):
        # Initialize empty total variable
        total = 0
        # Loop to get total amount of cAMP from cAMPs list
        for molecule in self.cAMPs:
            total += molecule.getAmt()

        return total

    def getRowAmts(self):
        total = 0
        for x in range(masterWidth):
            try:
                total += self.grid.get_cell_list_contents(
                    (x, self.y))[0].getAmt()
            except IndexError:
                continue

        if self.y == 49:
            self.y = 0
        else:
            self.y += 1

        return total

    def getRowAmt(self, y):
        total = 0
        for x in range(masterWidth - 1):
            try:
                total += self.grid.get_cell_list_contents((x, y))[0].getAmt()
            except IndexError:
                continue

        if self.y == 49:
            self.y = 0
        else:
            self.y += 1

        return total

    def getColAmts(self):
        total = 0
        for y in range(masterHeight):
            try:
                total += self.grid.get_cell_list_contents(
                    (self.x, y))[0].getAmt()
            except IndexError:
                continue

        if self.x == 49:
            self.x = 0
        else:
            self.x += 1

        return total

    def sweepForClusters():
        blacklist = list()
        neighbors = list()
        for (contents, x, y) in self.grid.coord_iter():
            for agent in contents[1::]:
                if type(agent) == SlimeAgent and agent not in blacklist:
                    neighbors = agent.getNeighbors()
                    for neighbor in neighbors:
                        blacklist.append(neighbor)
                '''
                density = blacklist.length / density_coefficent_based_on_area
                clusteredAgents = 
                '''

    # Step method
    def step(self):
        cNeighbors = list()
        neighbors = list()
        lap = 0
        amtSelf = 0
        cAMPobj = cAMP
        newDiag = 0
        oldDiag = 0
        nAgents = 0
        layer = 1
        secRate = 0
        ''' Perform cAMP decay and diffusion actions '''
        for (contents, x, y) in self.grid.coord_iter():

            # This block is a bit messy but it works for now
            cont = True
            for content in contents:
                # Set row amounts if an object is DataVis
                if type(content) is DataVis or type(content) is NumDataVis:
                    content.setRowAmt(self.getRowAmt(y))
                    cont = False

            if cont:
                # Initialize number of agents for layer coloring
                nAgents = len(contents) - 1
                # Reset lap to 0
                lap = 0

                # Set cAMPobj to current tile's cAMP agent
                cAMPobj = contents[0]
                # Set neighbors to cAMPobj's neighbors (Von Neumann)
                neighbors = cAMPobj.getNeighbors()
                # Add cAMP objects form neighbors to cNeighbors
                for neighbor in neighbors:
                    if type(neighbor) is cAMP:
                        cNeighbors.append(neighbor)

                # Add sum of neighbors to lap
                for mol in cNeighbors:
                    lap += mol.getAmt()

                amtSelf = cAMPobj.getAmt()
                # Reassign lap to the laplacian (using previous neighbor sum value)
                lap = (lap - 4 * amtSelf) / (self.Dh**2)
                # Add decay to current cAMP object
                cAMPobj.add(
                    (-cAMPobj.getDecayRate() * amtSelf + self.Dc * lap) *
                    self.Dt)

                # Wipe cNeighbors
                cNeighbors.clear()

                # Iterate through all contents of a grid cell
                for agent in contents[1::]:
                    # Get all neighbors (excuding self)
                    neighbors = agent.getNeighbors()
                    # Examine each neighbor
                    for neighbor in neighbors:
                        # Add cAMP neighbors to list
                        if type(neighbor) is cAMP:
                            cNeighbors.append(neighbor)

                    # Add cAMP secretion to the cell that the agent shares with a cAMP object
                    cAMPobj.add(agent.getSecRate() * self.Dt)
                    # Decide whether or not to move
                    newx = (x + random.randint(-1, 2)) % self.w
                    newy = (y + random.randint(-1, 2)) % self.w

                    # Calculate differences
                    newDiag = ((self.grid[newx - 1][newy - 1])[0]).getAmt()
                    diff = ((self.grid[x - 1][y - 1])[0]).getAmt()

                    # Fix if there are crazy values for diff
                    if diff > 10:
                        diff = 10
                    elif diff < 10:
                        diff = -10

                    # Decide to move
                    if random.random() < np.exp(diff) / (1 + np.exp(diff)):
                        agent.move(tuple([newx, newy]))

                    # Layers for coloring agents based on density
                    agent.addLayer()
                    layer = agent.getLayer()
                    # Only change color of agent that is on top of a stack
                    if layer >= nAgents:
                        self.pickColor(agent, nAgents)

                    # Wipe cNeighbors
                    cNeighbors.clear()

        # Add step to schedule
        self.schedule.step()
        # Collect new data
        self.datacollector.collect(self)

    # Method to select a color based on the topmost agent
    def pickColor(self, topAgent, nAgents):
        shade = topAgent.getShades()
        if nAgents <= 2:
            topAgent.setShade(shade[0])
        elif nAgents == 3:
            topAgent.setShade(shade[1])
        elif nAgents == 4:
            topAgent.setShade(shade[2])
        elif nAgents == 5:
            topAgent.setShade(shade[3])
        elif nAgents == 6:
            topAgent.setShade(shade[4])
        elif nAgents == 7:
            topAgent.setShade(shade[5])
        elif nAgents == 8:
            topAgent.setShade(shade[6])
        elif nAgents == 9:
            topAgent.setShade(shade[7])
예제 #2
0
class ForestDisease(Model):
    """
    Simple Forest Fire model.
    """
    def __init__(self,
                 height=100,
                 width=100,
                 density=0.65,
                 mortality=1,
                 wind='N',
                 distance='1'):
        """
        Create a new forest fire model.

        Args:
            height, width: The size of the grid to model
            density: What fraction of grid cells have a tree in them.
        """
        # Initialize model parameters
        self.height = height
        self.width = width
        self.density = density
        self.mortality = mortality
        self.wind = wind
        self.distance = distance

        # Set up model objects
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(height, width, torus=False)

        self.datacollector = DataCollector({
            "Fine":
            lambda m: self.count_type(m, "Fine"),
            "Infected":
            lambda m: self.count_type(m, "Infected"),
            "Dead":
            lambda m: self.count_type(m, "Dead")
        })

        # Place a tree in each cell with Prob = density
        for (contents, x, y) in self.grid.coord_iter():
            if self.random.random() < self.density:
                # Create a tree
                new_tree = TreeCell((x, y), self)
                self.grid._place_agent((x, y), new_tree)
                self.schedule.add(new_tree)

        center = (int(width / 2), int(height / 2))
        movingAgent = MovingAgent(center, self)
        self.grid._place_agent(center, movingAgent)
        new_tree = TreeCell(center, self)
        self.grid._place_agent(center, new_tree)
        self.schedule.add(new_tree)
        self.schedule.add(movingAgent)

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

    def step(self):
        """
        Advance the model by one step.
        """
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

        # Halt if no more fire
        if self.count_type(self, "Fine") == 0:
            self.running = False

    @staticmethod
    def count_type(model, tree_condition):
        """
        Helper method to count trees in a given condition in a given model.
        """
        count = 0
        for tree in model.schedule.agents:
            if tree.condition == tree_condition:
                count += 1
        return count
예제 #3
0
class ForestFire(Model):
    """
    Simple Forest Fire model.
    """
    def __init__(self, height, width, density, catch_chance, burnout_chance,
                 bird_density):
        """
        Create a new forest fire model.

        Args:
            height, width: The size of the grid to model
            density: What fraction of grid cells have a tree in them.
        """
        # Initialize model parameters
        self.height = height
        self.width = width
        self.density = density
        self.catch_chance = catch_chance
        self.burnout_chance = burnout_chance

        # Set up model objects
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(height, width, torus=False)

        self.datacollector = DataCollector({
            "Fine":
            lambda m: self.count_type(m, "Fine"),
            "On Fire":
            lambda m: self.count_type(m, "On Fire"),
            "Burned Out":
            lambda m: self.count_type(m, "Burned Out")
        })

        # Place a tree in each cell with Prob = density
        for (contents, x, y) in self.grid.coord_iter():
            if random.random() < self.density:
                # Create a tree
                new_tree = TreeCell((x, y), self, self.catch_chance,
                                    self.burnout_chance)
                # Set all trees in the first column on fire.
                if x == 0:
                    new_tree.condition = "On Fire"
                self.grid._place_agent((x, y), new_tree)
                self.schedule.add(new_tree)

        for (contents, x, y) in self.grid.coord_iter():
            if random.random() < (bird_density):
                new_bird = Bird((x, y), self)
                self.grid._place_agent((x, y), new_bird)
                self.schedule.add(new_bird)

        for (contents, x, y) in self.grid.coord_iter():
            new_empty = Empty((x, y), self)
            self.grid._place_agent((x, y), new_empty)
            self.schedule.add(new_empty)

        self.running = True

        # Place a bird in every 10th tree

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

        # Halt if no more fire
        if self.count_type(self, "On Fire") == 0:
            self.running = False

    @staticmethod
    def count_type(model, tree_condition):
        """
        Helper method to count trees in a given condition in a given model.
        """
        count = 0
        for tree in model.schedule.agents:
            if tree.condition == tree_condition:
                count += 1
        return count
예제 #4
0
class SquashBee(Model):
    def __init__(self,
                 height=50,
                 width=50,
                 time=0,
                 density_bee=50,
                 density_gender_bee=50,
                 gain_polline_raccolto=40,
                 density_zucca=50,
                 prob_accoppiamento=50,
                 offsetX=5,
                 offsetY=5):

        self.height = height
        self.width = width
        self.time = 200
        self.density_bee = density_bee
        self.density_gender_bee = density_gender_bee
        self.gain_polline_raccolto = gain_polline_raccolto
        self.density_zucca = density_zucca
        self.prob_accoppiamento = prob_accoppiamento
        self.offsetX = offsetX
        self.offsetY = offsetY
        self.anno = 1

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

        self.datacollector = DataCollector({
            "Zucche_fiori":
            lambda m: self.count_type(m, "Flower"),
            "Zucche":
            lambda m: self.count_type(m, "Zucca"),
            "Seed":
            lambda m: self.count_type(m, "Seed"),
            "Api":
            lambda m: self.count_type(m, "Bee"),
            "Larve":
            lambda m: self.count_type(m, "Bee_son")
        })

        # metto le api nella griglia
        for i in range(self.density_bee):
            x = self.random.randrange(2, 33)
            y = self.random.randrange(2, 33)
            new_bee = Bee((x, y), self, self.density_gender_bee,
                          self.gain_polline_raccolto, 120)
            self.grid.place_agent(new_bee, (x, y))
            self.schedule.add(new_bee)

        # metto i fiori delle zucche nella griglia
        for i in range(self.density_zucca):
            x = self.random.randrange(5, 30)
            y = self.random.randrange(5, 30)
            new_zucca = Zucca_flower((x, y), self, self.prob_accoppiamento, 45)
            self.grid._place_agent((x, y), new_zucca)
            self.schedule.add(new_zucca)

        # metto i fiori nella griglia
        for i in range(150):
            x = self.random.randrange(self.height)
            y = self.random.randrange(self.width)
            new_f = flower((x, y), self)
            self.grid._place_agent((x, y), new_f)
            self.schedule.add(new_f)

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

    def step(self):
        self.time += 1

        #fioritura primaverile
        if self.time == 90:
            # metto i fiori nella griglia
            for i in range(150):
                x = self.random.randrange(self.height)
                y = self.random.randrange(self.width)
                if (self.grid.is_cell_empty((x, y))):
                    new_f = flower((x, y), self)
                    self.grid._place_agent((x, y), new_f)
                    self.schedule.add(new_f)

        # semina ogni anno
        if self.time == 160:
            # metto i semi delle zucche nella griglia
            if self.anno % 2 == 0:
                for i in range(self.density_zucca):
                    x = self.random.randrange(5 + self.offsetX,
                                              30 + self.offsetX)
                    y = self.random.randrange(5 + self.offsetY,
                                              30 + self.offsetY)
                    if (self.grid.is_cell_empty((x, y))):
                        new_seme = Zucca_seed((x, y), self)
                        self.grid._place_agent((x, y), new_seme)
                        self.schedule.add(new_seme)
            if self.anno % 2 == 1:
                for i in range(self.density_zucca):
                    x = self.random.randrange(5, 30)
                    y = self.random.randrange(5, 30)
                    if (self.grid.is_cell_empty((x, y))):
                        new_seme = Zucca_seed((x, y), self)
                        self.grid._place_agent((x, y), new_seme)
                        self.schedule.add(new_seme)

        # reset anno
        if self.time == 360:
            self.time = 0
            self.anno += 1

        self.schedule.step()
        # collect data
        self.datacollector.collect(self)

    @staticmethod
    def count_type(model, agent_type):
        """
        Helper method to count trees in a given condition in a given model.
        """
        count = 0
        for agent in model.schedule.agents:
            if agent.type_agent == agent_type:
                count += 1
        return count