Exemplo n.º 1
0
class bacServerModel(Model):
    ################
    ###Deprecated###
    ################
    def __init__(self, width, height, beginRad):
            self.running = True
            self.num_agents = width * height
            self.schedule = RandomActivation(self)
            self.grid = MultiGrid(width, height, IS_TOROIDAL) #True for toroidal
            #self.datacollector = DataCollector(
            #    model_reporters = {"Identifier": function_name}, #note no parentheses, just function name
            #    agent_reporter = {"Identifier2": function_name2})

            for x in range(self.grid.width):
                for y in range(self.grid.height):
                    a = bacServerAgent(self.num_agents, self)
                    self.num_agents += 1
                    self.schedule.add(a)
                    self.grid.place_agent(a, (x,y))

            x = self.grid.width // 2
            y = self.grid.height // 2

            #create subsequent agents
            positions = self.grid.get_neighborhood((x,y), moore=False, radius=beginRad, include_center=True)
            for coord in positions:
                ag = self.grid.get_cell_list_contents([coord])[0]
                ag.activate()


    def step(self):
        #self.datacollector.collect(self)
        self.schedule.step()
Exemplo n.º 2
0
class Kvecinos(Model):
    def __init__(self, height, width, initial_population, n_clases, k):
        super().__init__()
        self.height = height
        self.width = width
        self.initial_population = initial_population
        # N_class será el número de colores
        self.n_clases = n_clases
        self.k = k
        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.colors = {
            0: "red",
            1: "blue",
            2: "green0",
            3: "violet",
            4: "cyan",
            5: "orange"
        }

        self.clases = []

        self.setup()

        self.running = True

    def setup(self):
        for agent, x, y in self.grid.coord_iter():
            patch = Cell(self.unique_id, self, (x, y), "black")
            self.unique_id += 1
            self.grid.place_agent(patch, (x, y))
            self.schedule.add(patch)

        for i in range(self.initial_population):
            x = random.randint(0, self.width - 1)
            y = random.randint(0, self.height - 1)
            pos = (x, y)
            color = random.randint(0, self.n_clases - 1)

            cell = self.grid.get_cell_list_contents(pos)[0]
            self.clases.append(cell)
            self.clases[i].color = self.colors[color]

            individual = Individual(self.unique_id, self, pos,
                                    self.colors[color])
            self.unique_id += 1
            self.grid.place_agent(individual, pos)

    def step(self):
        self.schedule.step()
Exemplo n.º 3
0
class ConveyModel(Model):
    """A model with some number of agents."""

    def __init__(self, N, width, height):
        super().__init__()
        self.num_agents = N
        self.grid = MultiGrid(width, height, True)
        self.schedule = BaseScheduler(self)

        # Create agents
        for i in range(self.num_agents):
            a = ConwayAgent(i, self)
            # Add the agent to a random grid cell
            x = random.randrange(self.grid.width)
            y = random.randrange(self.grid.height)
            while(len(self.grid.get_cell_list_contents((x,y)))):
                x = random.randrange(self.grid.width)
                y = random.randrange(self.grid.height)
            self.grid.place_agent(a, (x, y))
            self.schedule.add(a)
        self.i = i

        self.datacollector = DataCollector(
            agent_reporters={"State": lambda a: a.die})

    def step(self):
        self.datacollector.collect(self)
        new_agents = []
        for (x, y) in product(range(self.grid.width), range(self.grid.height)):
            ns = self.grid.iter_neighbors((x,y), True)
            neighbors = 0
            for n in ns:
                if(n):
                    neighbors += 1
            if(self.grid[x][y]):  # live cell
                if(neighbors < 2):  # underpopulation
                    list(self.grid[x][y])[0].die = 1
                elif(neighbors > 3):  # overpopulation
                    list(self.grid[x][y])[0].die = 1
            else:  # dead cell
                if(neighbors == 3):
                    new_agents.append((x, y))
        for (x, y) in product(range(self.grid.width), range(self.grid.height)):
            if self.grid[x][y]:
                a = list(self.grid[x][y])[0]
                if a.die:
                    self.grid.remove_agent(a)
                    self.schedule.remove(a)
        for na in new_agents:
            self.i += 1
            a = ConwayAgent(self.i, self)
            self.grid.place_agent(a, na)
            self.schedule.add(a)
Exemplo n.º 4
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)
class ExplorationArea(Model):
    def __init__(
            self,
            nrobots,
            wifi_range,
            radar_radius=6,
            alpha=8.175,
            gamma=0.65,
            inj_pri=0,
            ninjured=None,
            ncells=None,
            obstacles_dist=None,
            load_file=None,
            dump_datas=True,  # enable data collection
            alpha_variation=False,  # record datas for alpha variation studies
            alpha_csv=alpha_csv,  # aggregate datas
            alpha_step_csv=alpha_step_csv,  # single step datas
            gamma_variation=False,  # record datas for gamma variation studies
            gamma_csv=gamma_csv,
            optimization_task=False,  # enable a small part of data collection for optimization task
            time_csv=number_of_steps_csv,
            robot_status_csv=robot_status_csv):

        # checking params consistency
        if not load_file and (not ncells or not obstacles_dist
                              or not ninjured):
            print("Invalid params")
            sys.exit(-1)

        # used in server start
        self.running = True
        self.nrobots = nrobots
        self.radar_radius = radar_radius
        self.ncells = ncells
        self.obstacles_dist = obstacles_dist
        self.wifi_range = wifi_range
        self.alpha = alpha
        self.gamma = gamma
        self.ninjured = ninjured
        self.inj_pri = inj_pri
        self.dump_datas = dump_datas
        self.optimization_task = optimization_task
        self.frontier = set()
        self.broken_beans = 0
        # Data collection tools
        if self.dump_datas:
            # it represents the sum of the difficulties of every cell
            self.total_difficulty = 0

            self.dc_robot_status = DataCollector({
                "idling":
                lambda m: self.get_number_robots_status(m, "idling"),
                "travelling":
                lambda m: self.get_number_robots_status(m, "travelling"),
                "exploring":
                lambda m: self.get_number_robots_status(m, "exploring"),
                "deploying_bean":
                lambda m: self.get_number_robots_status(m, "deploying_bean"),
                "step":
                lambda m: self.get_step(m)
            })
            self.time_csv = time_csv
            self.robot_status_csv = robot_status_csv

        if self.optimization_task:
            self.total_idling_time = 0

        self.alpha_variation = alpha_variation
        self.gamma_variation = gamma_variation
        if self.alpha_variation:
            self.costs_each_path = list()
            self.alpha_csv = alpha_csv
            self.alpha_step = dict()
            self.alpha_step_csv = alpha_step_csv
        if self.gamma_variation:
            self.gamma_df = pd.DataFrame(columns=["step", "mean", "std"])
            self.gamma_csv = gamma_csv

        self.schedule = RandomActivation(self)
        # unique counter for agents
        self.agent_counter = 1
        self.nobstacle = 0
        # graph of seen cells
        self.seen_graph = nx.DiGraph()

        rnd.seed()

        # place a cell agent for store data and visualization on each cell of the grid
        # if map is not taken from file, create it
        if load_file == None:
            self.grid = MultiGrid(ncells + 2, ncells + 2, torus=False)
            for i in self.grid.coord_iter():
                if i[1] != 0 and i[2] != 0 and i[1] != self.ncells + 1 and i[
                        2] != self.ncells + 1:
                    rand = np.random.random_sample()
                    obstacle = True if rand < self.obstacles_dist else False
                    # if obstacle
                    if obstacle:
                        self.nobstacle += 1
                        difficulty = math.inf
                        explored = -1
                        priority = 0
                        utility = -math.inf
                    # if free
                    else:
                        difficulty = np.random.randint(low=1, high=13)
                        if self.dump_datas:
                            self.total_difficulty += difficulty
                        explored = 0
                        priority = 0
                        utility = 1.0
                # if contour cell
                else:
                    difficulty = np.random.randint(low=1, high=13)
                    explored = -2
                    priority = -math.inf
                    utility = -math.inf
                # place the agent in the grid
                a = Cell(self.agent_counter, self, i[1:], difficulty, explored,
                         priority, utility)
                self.grid.place_agent(a, i[1:])
                self.agent_counter += 1

            # create injured agents
            valid_coord = []
            for i in self.grid.coord_iter():
                cell = [
                    e for e in self.grid.get_cell_list_contents(i[1:])
                    if isinstance(e, Cell)
                ][0]
                if cell.explored == 0:
                    valid_coord.append(cell.pos)
            for i in range(0, ninjured):
                inj_index = rnd.choice(valid_coord)
                a = Injured(self.agent_counter, self, inj_index)
                self.schedule.add(a)
                self.grid.place_agent(a, inj_index)
                self.agent_counter += 1
        else:
            # load map from file
            try:
                with open(load_file, 'r') as f:
                    file = f.read()
            except:
                print("file not found")
                sys.exit(-1)
            exported_map = literal_eval(file)
            self.ncells = int(math.sqrt(len(exported_map["Cell"].keys()))) - 2
            self.grid = MultiGrid(self.ncells + 2,
                                  self.ncells + 2,
                                  torus=False)
            for index in exported_map["Cell"].keys():
                cell = exported_map["Cell"][index]
                difficulty = cell[2]
                explored = cell[3]
                priority = cell[4]
                utility = cell[5]
                if difficulty == "inf":
                    difficulty = math.inf
                if priority == "-inf":
                    priority = -math.inf
                if utility == "-inf":
                    utility = -math.inf
                if explored == -1:
                    self.nobstacle += 1
                if self.dump_datas and utility == 1:
                    self.total_difficulty += difficulty
                a = Cell(self.agent_counter, self, index, difficulty, explored,
                         priority, utility)
                self.grid.place_agent(a, index)
                self.agent_counter += 1

            for index in exported_map["Injured"].keys():
                a = Injured(self.agent_counter, self, index)
                self.schedule.add(a)
                self.grid.place_agent(a, index)
                self.agent_counter += 1

        # create robotic agents
        row = 0
        starting_coord = []
        # data collection number of beans requested
        if self.dump_datas:
            self.deployed_beans_at_start = 0
        # generating the list for the starting position of robots
        for c in range(self.grid.width):
            # take the agent cell
            cell = [
                e for e in self.grid.get_cell_list_contents(tuple([c, row]))
                if isinstance(e, Cell)
            ][0]
            if cell.explored != -1:
                starting_coord.append(c)
        for i in range(0, self.nrobots):
            column = rnd.choice(starting_coord)
            a = Robot(self.agent_counter, self, tuple([column, row]),
                      self.radar_radius)
            self.schedule.add(a)
            self.grid.place_agent(a, (column, row))
            self.agent_counter += 1
            # create initial frontier: add cell in front of the robot if valid and not obstacles
            cell = [
                e for e in self.grid.get_cell_list_contents(
                    tuple([column, row + 1])) if isinstance(e, Cell)
            ][0]
            if cell.explored == 0:
                self.frontier.add(tuple([column, row + 1]))
            try:
                cell = [
                    e for e in self.grid.get_cell_list_contents(
                        tuple([column + 1, row + 1])) if isinstance(e, Cell)
                ][0]
                if cell.explored == 0:
                    self.frontier.add(tuple([column + 1, row + 1]))
            except:
                pass
            try:
                cell = [
                    e for e in self.grid.get_cell_list_contents(
                        tuple([column - 1, row + 1])) if isinstance(e, Cell)
                ][0]
                if cell.explored == 0:
                    self.frontier.add(tuple([column - 1, row + 1]))
            except:
                pass

            cell = [
                e
                for e in self.grid.get_cell_list_contents(tuple([column, row]))
                if isinstance(e, Cell)
            ][0]
            # in the cell where some robots are deployed, only one bean is deployed
            if not cell.wifi_bean:
                cell.wifi_bean = True
                for index in self.grid.get_neighborhood(
                        cell.pos,
                        "moore",
                        include_center=False,
                        radius=self.wifi_range):
                    cell = [
                        e for e in self.grid.get_cell_list_contents(index)
                        if isinstance(e, Cell)
                    ][0]
                    cell.wifi_covered = True
                if self.dump_datas:
                    self.deployed_beans_at_start += 1

    # what the model does at each time step
    def step(self):

        # data collection for alpha variation
        if self.alpha_variation:
            sim_step = self.get_step(self)
            self.alpha_step[sim_step] = list()

        # call step function for all of the robots in random order
        self.schedule.step()

        if self.dump_datas:
            self.dc_robot_status.collect(self)
        if self.optimization_task:
            self.total_idling_time += self.get_number_robots_status(
                self, "idling")
        if self.gamma_variation:
            distances = self.compute_robot_distances(self)
            self.gamma_df = self.gamma_df.append(
                {
                    "step": self.get_step(self),
                    "mean": distances[0],
                    "std": distances[1]
                },
                ignore_index=True,
                sort=False)
        # if all seen cells have benn explored, stop the simulation
        # we do this so if there are unreachable cells, the cannot be seen, so the simulation stops anyway
        stop_exploration_done = True
        for node in self.seen_graph.nodes():
            cell = [
                obj for obj in self.grid.get_cell_list_contents(node)
                if isinstance(obj, Cell)
            ][0]
            if cell.explored == 0 or cell.explored == 1:
                stop_exploration_done = False
        stop_no_robots = False
        if len([x for x in self.schedule.agents if isinstance(x, Robot)]) == 0:
            stop_no_robots = True
        stop = stop_exploration_done or stop_no_robots

        if stop:
            print("Simultation ended")
            # Data collection
            if self.dump_datas:
                df = pd.read_csv(self.time_csv)
                df = df.append(
                    {
                        "nrobots": self.nrobots,
                        "ncells": self.ncells,
                        "steps": self.schedule.steps,
                        "total_difficulty": self.total_difficulty,
                        "beans_deployed": self.get_number_bean_deployed(self)
                    },
                    ignore_index=True)
                df.to_csv(self.time_csv, index=False)

                df_robots_status = self.dc_robot_status.get_model_vars_dataframe(
                )
                df = pd.read_csv(self.robot_status_csv)
                if len(df["sim_id"]) == 0:
                    df_robots_status["sim_id"] = 0
                else:
                    df_robots_status["sim_id"] = df["sim_id"][df.index[-1]] + 1
                df = df.append(df_robots_status, ignore_index=True, sort=False)
                df.to_csv(self.robot_status_csv, index=False)

            if self.alpha_variation:
                mean = round(np.mean(self.costs_each_path), 3)
                std = round(np.std(self.costs_each_path), 3)
                df = pd.read_csv(self.alpha_csv)
                df = df.append(
                    {
                        "nrobots": self.nrobots,
                        "radar_radius": self.radar_radius,
                        "alpha": self.alpha,
                        "gamma": self.gamma,
                        "mean": mean,
                        "std": std
                    },
                    ignore_index=True)
                df.to_csv(self.alpha_csv, index=False)

                tmp_df = pd.DataFrame(columns=["step", "cost"])
                for s, costs in zip(self.alpha_step.keys(),
                                    self.alpha_step.values()):
                    if not costs:
                        tmp_df = tmp_df.append({
                            "step": s,
                            "cost": -1
                        },
                                               ignore_index=True,
                                               sort=False)
                        continue
                    for c in costs:
                        tmp_df = tmp_df.append({
                            "step": s,
                            "cost": c
                        },
                                               ignore_index=True,
                                               sort=False)
                df = pd.read_csv(self.alpha_step_csv)
                if len(df["sim_id"]) == 0:
                    tmp_df["sim_id"] = 0
                else:
                    tmp_df["sim_id"] = df["sim_id"][df.index[-1]] + 1
                tmp_df["nrobots"] = self.nrobots
                tmp_df["radar_radius"] = self.radar_radius
                tmp_df["alpha"] = self.alpha
                tmp_df["gamma"] = self.gamma
                df = df.append(tmp_df, ignore_index=True, sort=False)
                df.to_csv(self.alpha_step_csv, index=False)

            if self.gamma_variation:
                df = pd.read_csv(self.gamma_csv)
                if len(df["sim_id"]) == 0:
                    self.gamma_df["sim_id"] = 0
                else:
                    self.gamma_df["sim_id"] = df["sim_id"][df.index[-1]] + 1
                self.gamma_df["nrobots"] = self.nrobots
                self.gamma_df["radar_radius"] = self.radar_radius
                self.gamma_df["alpha"] = self.alpha
                self.gamma_df["gamma"] = self.gamma
                df = df.append(self.gamma_df, ignore_index=True, sort=False)
                df.to_csv(self.gamma_csv, index=False)

            self.running = False

    def run_model(self):
        while (True):
            # search for unexplored cells
            stop = True
            for node in self.seen_graph.nodes():
                cell = [
                    obj for obj in self.grid.get_cell_list_contents(node)
                    if isinstance(obj, Cell)
                ][0]
                if cell.explored == 0 or cell.explored == 1:
                    stop = False
            # if all seen cells have benn explored, stop the simulation
            # we do this so if there are unreachable cells, the cannot be seen, so the simulation stops anyway
            if stop:
                self.running = False
                break
            else:
                self.step()

    # Data collection utilities
    @staticmethod
    def get_step(m):
        return m.schedule.steps

    # these two should go faster since cells are not in the scheduler anymore
    @staticmethod
    def get_number_robots_status(m, status):
        status_value = {
            "idling": 0,
            "travelling": 1,
            "exploring": 2,
            "deploying_bean": 3
        }
        return len([
            x for x in m.schedule.agents
            if isinstance(x, Robot) and x.status == status_value[status]
        ])

    @staticmethod
    def get_number_bean_deployed(m):
        return sum([
            x.number_bean_deployed
            for x in m.schedule.agents if isinstance(x, Robot)
        ]) + m.deployed_beans_at_start

    # function for gamma variation
    @staticmethod
    def compute_robot_distances(m):
        nrobots = m.nrobots
        T_up = np.full(
            (nrobots, nrobots),
            0.0)  # if it's only zero, numpy represents only integers
        # didn't dig deep in numpy doc but it looks like it handles triangualr matrices as "normal" matrices, so
        # i just initilize a full matrix and then i'll use it as a triangular.
        robots = [x for x in m.schedule.agents if isinstance(x, Robot)]
        # the order of the robots in robots can change from step to step (due to the random scheduler),
        # This shouldn't create any type of problem, but to avoid a lot of problems with indexes later on
        # we sort them basing on the unique_id
        robots.sort(key=lambda x: x.unique_id)
        # I need the lowest id to shift back the ids to fit the matrices coordinations
        lowest_id = robots[0].unique_id
        for r in robots:
            matrix_id_row = r.unique_id - lowest_id
            # the distance of a robot to itself is zero by definition
            y1, x1 = r.pos
            for i in range(matrix_id_row + 1, nrobots):
                r2 = robots[i]  # i can do this because they are sorted
                y2, x2 = r2.pos
                T_up[matrix_id_row][i] = distance.euclidean([x1, y1], [x2, y2])
        mean_dist_robots = list()
        # the robot 0 has only the rows
        mean_robot_zero = sum(T_up[0, 1:nrobots])
        mean_dist_robots.append(mean_robot_zero)
        for i in range(1, nrobots -
                       1):  # the last row has no values, i iters the rows
            mean_robot = (sum(T_up[0:i, i]) +
                          sum(T_up[i, i + 1:nrobots])) / (nrobots - 1)
            mean_dist_robots.append(mean_robot)
        # last robot has only the columns
        mean_last_robot = sum(T_up[0:nrobots - 1, nrobots - 1])
        mean_dist_robots.append(mean_last_robot)
        return tuple([
            round(np.mean(mean_dist_robots), 3),
            round(np.std(mean_dist_robots), 3)
        ])
Exemplo n.º 6
0
class PandemicsModel(Model):
    def __init__(self, config=default_config, disease=dis.covid_disease):
        self.agents_count = config.citizens_count + config.policemen_count
        self.disease = disease
        self.deceased = []
        self.buried = []
        self.deceased_counter = 0
        self.infected_counter = 0
        self.grid = MultiGrid(config.width, config.height, True)
        self.safety_per_cell = np.ones((config.height, config.width))
        self.buildings_map = np.zeros((config.height, config.width))
        self.buildings_id_map = np.zeros((config.height, config.width))
        self.schedule = SimultaneousActivation(self)
        self.datacollector = DataCollector(
            model_reporters={
                "deceased": "deceased_counter",
                "infected": "infected_counter"},
            agent_reporters={
                "hp": lambda a: a.profile["hp"],
                "mask_protection": "mask_protection",
                "infection_day": lambda a: a.profile["infection_day"],
                "obedience": lambda a: a.profile["obedience"],
                "fear": lambda a: a.profile["fear"]}
        )
        self.config = config
        self.buildings = {b["id"] : b for b in self.config.buildings}
        self.houses = [x for x in self.buildings.values() if x['type'] == 'house']
        self.workplaces = [x for x in self.buildings.values() if x['type'] == 'workplace']
        self.shops = [x for x in self.buildings.values() if x['type'] == 'shop']

        self.add_buildings_to_map(self.buildings)

        self.street_positions = []
        for x in range(self.config.width):
            for y in range(self.config.height):
                if self.buildings_map[y][x] == 0:
                    self.street_positions.append((x, y))

        self.house_to_agents = defaultdict(list)
        self.workplace_to_agents = defaultdict(list)

        self.current_location_type = None

        # Create agents
        for i in range(self.agents_count):
            if i < config.policemen_count:
                a = agent.create_distribution_policeman_agent(
                        i, self, config.policemen_mental_features_distribution)
                a.assign_house(self, self.houses)
            elif i < config.policemen_count + config.citizens_count:
                a = agent.create_distribution_citizen_agent(
                        i, self, config.citizens_mental_features_distribution)
                a.assign_house(self, self.houses)
                a.assign_workplace(self, self.workplaces)
            self.add_agent(a)

        for i in self.random.choices(self.schedule.agents, k=config.infected_count):
            i.start_infection()
        self.running = True
        self.steps_count = 0
        self.datacollector.collect(self)

    # Returns (type, id) of the building where agent a is currently located
    def where_is_agent(self, a):
        (x, y) = a.pos
        return (self.buildings_map[y][x], self.buildings_id_map[y][x])

    def compute_time_of_day(self):
        return self.steps_count % self.config.steps_per_day / (self.config.steps_per_day / HOURS_PER_DAY)

    def compute_current_location_type(self):
        t = self.compute_time_of_day()
        return self.config.day_plan[t] if t in self.config.day_plan else \
                self.config.day_plan[min(self.config.day_plan.keys(), key=lambda k: k-t)]

    # Updates current location type based on time of day and the config schedule
    # Returns true if there is a change in current_location_type
    def update_current_location_type(self):
        t = self.compute_time_of_day()
        if t in self.config.day_plan:
            self.current_location_type = self.config.day_plan[t]
            return True
        return False

    def add_buildings_to_map(self, buildings):
        for b in buildings.values():
            (x, y) = b["bottom-left"]
            for i in range(x, x+b["width"]):
                for j in range(y, y+b["height"]):
                    self.buildings_map[j][i] = self.config.building_tags[b['type']]
                    self.buildings_id_map[j][i] = b['id']

    def add_agent(self, a):
        self.schedule.add(a)
        # Add the agent to a random grid cell
        x = self.random.randrange(self.grid.width)
        y = self.random.randrange(self.grid.height)
        self.grid.place_agent(a, (x, y))

    def bury_agent(self, a):
        self.schedule.remove(a)
        self.grid.remove_agent(a)
        self.deceased_counter += 1
        self.buried.append(a)

    def risk_from_agents(self, agents, weight):
        risk = 0
        for a in agents:
            risk += 1 - a.mask_protection
        return risk*weight

    def evaluate_safety_per_cell(self):
        """ 1.0 is a perfectly safe cell - empty, with all neighbours
        and neighbours-of-neighbours empty as well """
        for content, x, y in model.grid.coord_iter():
            self.safety_per_cell[y][x] = 1 # initial value
            # Compute risk from (x,y) cell
            ring0_risk = self.risk_from_agents(content, weight=0.5)
            considered_cells = {(x,y)}

            # Compute risk coming from the neighbours of (x,y) cell
            neighbours = self.grid.get_neighborhood(
                (x,y), moore=True, include_center=False)
            neighbours_content = self.grid.get_cell_list_contents(neighbours)
            ring1_risk = self.risk_from_agents(neighbours_content, 0.25)
            considered_cells | set(neighbours)

            # Compute risk coming from
            # the neighbours of the neighbours of (x,y) cell
            neighbours_of_neighbours = set()
            for c in neighbours:
                neighbours_of_neighbours | set(
                    self.grid.get_neighborhood(
                        (x,y),moore=True, include_center=False))
            neighbours_of_neighbours -= considered_cells
            ring2_risk = self.risk_from_agents(
                self.grid.get_cell_list_contents(neighbours_of_neighbours), 0.125)
            self.safety_per_cell[y][x] -= ring0_risk + ring1_risk + ring2_risk

    def step(self):
        if (self.update_current_location_type()):
            for a in self.schedule.agents:
                if (self.current_location_type is not None):
                    b = a.select_building(self.current_location_type)
                    a.teleport_to_building(b)
                else:
                    a.teleport_to_street()

        self.evaluate_safety_per_cell()
        self.schedule.step()
        self.steps_count += 1
        # collect data
        self.datacollector.collect(self)
        for d in self.deceased:
            self.bury_agent(d)
        self.deceased = []

    def run_model(self, n):
        for i in range(n):
            self.step()
Exemplo n.º 7
0
class WolfSheep(Model):
    """
    Wolf-Sheep Predation Model
    """

    height = 20
    width = 20

    initial_sheep = 2
    initial_wolves = 5
    sheep_reproduce = 0.04
    wolf_reproduce = 0.05

    wolf_gain_from_food = 20

    grass = False
    grass_regrowth_time = 5
    sheep_gain_from_food = 4

    verbose = False  # Print-monitoring

    description = (
        "A model for simulating wolf and sheep (predator-prey) ecosystem modelling."
    )

    def __init__(self,
                 height=20,
                 width=20,
                 initial_sheep=100,
                 initial_wolves=50,
                 sheep_reproduce=0.04,
                 wolf_reproduce=0.05,
                 wolf_gain_from_food=20,
                 grass=False,
                 grass_regrowth_time=30,
                 sheep_gain_from_food=4):
        """
        Create a new Wolf-Sheep model with the given parameters.

        Args:
            initial_sheep: Number of sheep to start with
            initial_wolves: Number of wolves to start with
            sheep_reproduce: Probability of each sheep reproducing each step
            wolf_reproduce: Probability of each wolf reproducing each step
            wolf_gain_from_food: Energy a wolf gains from eating a sheep
            grass: Whether to have the sheep eat grass for energy
            grass_regrowth_time: How long it takes for a grass patch to regrow
                                 once it is eaten
            sheep_gain_from_food: Energy sheep gain from grass, if enabled.
        """
        super().__init__()
        # Set parameters
        self.height = height
        self.width = width
        self.initial_sheep = initial_sheep
        self.initial_wolves = initial_wolves
        self.sheep_reproduce = sheep_reproduce
        self.wolf_reproduce = wolf_reproduce
        self.wolf_gain_from_food = wolf_gain_from_food
        self.grass = grass
        self.grass_regrowth_time = grass_regrowth_time
        self.sheep_gain_from_food = sheep_gain_from_food
        self.schedule = RandomActivationByBreed(self)
        self.grid = MultiGrid(self.height, self.width, torus=True)
        self.datacollector = DataCollector({
            "Wolves":
            lambda m: m.schedule.get_breed_count(Wolf),
            "Sheep":
            lambda m: m.schedule.get_breed_count(Sheep),
        })
        # Create Shed
        x = self.random.randrange(self.width)
        y = self.random.randrange(self.height)
        shed = Shed(self.next_id(), (x, y), self)
        self.grid.place_agent(shed, (x, y))
        self.schedule.add(shed)

        # Create water source
        while True:
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            this_cell = self.grid.get_cell_list_contents([(x, y)])
            cell = [obj for obj in this_cell if isinstance(obj, Shed)]
            if len(cell) == 0:
                break
        ws1 = WaterSource(self.next_id(), (x, y), self)
        self.grid.place_agent(ws1, (x, y))
        self.schedule.add(ws1)
        while True:
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            this_cell = self.grid.get_cell_list_contents([(x, y)])
            cell = [obj for obj in this_cell if isinstance(obj, Shed)]
            if len(cell) == 0:
                break
            cell = [obj for obj in this_cell if isinstance(obj, WaterSource)]
            if len(cell) == 0:
                break
        ws2 = WaterSource(self.next_id(), (x, y), self)
        self.grid.place_agent(ws2, (x, y))
        self.schedule.add(ws2)

        # Create grass patches
        if self.grass:
            for agent, x, y in self.grid.coord_iter():
                this_cell = self.grid.get_cell_list_contents([(x, y)])
                is_water = [
                    obj for obj in this_cell if isinstance(obj, WaterSource)
                ]
                is_shed = [obj for obj in this_cell if isinstance(obj, Shed)]
                if len(is_water) > 0 or len(is_shed) > 0:
                    continue
                fully_grown = self.random.choice([True, False])
                if fully_grown:
                    countdown = self.grass_regrowth_time
                else:
                    countdown = self.random.randrange(self.grass_regrowth_time)

                patch = GrassPatch(self.next_id(), (x, y), self, fully_grown,
                                   countdown)
                self.grid.place_agent(patch, (x, y))
                self.schedule.add(patch)

        # Create sheep:
        for i in range(self.initial_sheep):
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            energy = self.random.randrange(2 * self.sheep_gain_from_food)
            sheep = Sheep(self.next_id(), (x, y), self, True, energy)
            sheep.target = shed
            self.grid.place_agent(sheep, (x, y))
            self.schedule.add(sheep)

        # Create wolves
        for i in range(self.initial_wolves):
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            energy = self.random.randrange(2 * self.wolf_gain_from_food)
            wolf = Wolf(self.next_id(), (x, y), self, True, energy)
            if abs(ws1.pos[0] - x) + abs(ws1.pos[1] - y) < abs(
                    ws2.pos[0] - x) + abs(ws2.pos[1] - y):
                wolf.target = ws1
            else:
                wolf.target = ws2
            self.grid.place_agent(wolf, (x, y))
            self.schedule.add(wolf)

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

    def step(self):
        self.schedule.step()
        # collect data
        self.datacollector.collect(self)
        if self.verbose:
            print([
                self.schedule.time,
                self.schedule.get_breed_count(Wolf),
                self.schedule.get_breed_count(Sheep),
            ])

    def run_model(self, step_count=200):

        if self.verbose:
            print("Initial number wolves: ",
                  self.schedule.get_breed_count(Wolf))
            print("Initial number sheep: ",
                  self.schedule.get_breed_count(Sheep))

        for i in range(step_count):
            self.step()

        if self.verbose:
            print("")
            print("Final number wolves: ", self.schedule.get_breed_count(Wolf))
            print("Final number sheep: ", self.schedule.get_breed_count(Sheep))
Exemplo n.º 8
0
class HoominWorld(Model):

    LEFT = 0
    RIGHT = 1
    STRAIGHT = 2

    FRIENDNODELOGNAME = "friendnodes"
    TOTALMESSAGELOGNAME = "totalmessages"
    STEPSTOCOMPLETIONLOGNAME = "stepstocompletion"

    verbose = False
    description = "A model of foot traffic and radio communication in an urban environment"

    def __init__(self,
                 height=50,
                 width=50,
                 initial_hoomins=10,
                 logtag="default"):
        super().__init__()

        print("initializing ", settings.width, settings.height)
        #map height and width
        self.height = settings.height
        self.width = settings.width

        #logging framework
        self.logger = Logging("logs", logtag)
        self.logtag = logtag
        self.G = nx.Graph()

        #graph visualization
        if not settings.runheadless:
            plt.ion()
            plt.show()

        #ignore this. it does nothing
        self.hoomin_level = 0

        #road generation tuning
        self.straightweight = settings.straightweight
        self.leftweight = settings.leftweight
        self.rightweight = settings.rightweight
        self.initial_roads = settings.initial_roads
        self.initial_road_seeds = settings.initial_road_seeds
        self.gridspacing = settings.gridspacing
        self.roadcurrentcoord = np.array((0, 0))
        self.roaddir = np.array((1, 0))
        self.roadset = set()

        #home tuning options
        self.homes_per_hoomins = 1
        self.initial_homes = self.homes_per_hoomins * initial_hoomins
        self.homeset = set()

        #scatterbrain metrics
        self.total_scattermessages = 0
        self.global_scattermessages = 0
        self.hoominzero_nodecount = 0

        #hoomin tuning values
        self.initial_hoomins = settings.initial_hoomins
        self.schedule = RandomHoominActivation(self)
        self.grid = MultiGrid(self.height, self.width, torus=True)
        self.datacollector = DataCollector({
            "Messages Exchanged":
            lambda m: m.total_scattermessages,
            "FriendGraph Node Count":
            lambda m: m.hoominzero_nodecount
        })

        #initialize roads
        for i in range(self.initial_road_seeds):
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)

            self.singleroad((x, y))

        homelist = []

        #initialize homes
        for i in range(self.initial_homes):
            road = self.random.sample(self.roadset, 1)
            if len(road) > 0 and road[0] is not None:
                neighbors = self.grid.get_neighborhood(road[0].pos, False,
                                                       True)
                for neighbor in neighbors:
                    n = []
                    if len(self.grid.get_cell_list_contents(neighbor)) is 0:
                        n.append(neighbor)
                    if len(n) > 0:
                        homeblock = self.random.sample(n, 1)
                        home = Home(self.next_id(), homeblock[0], self)
                        homelist.append(home)
                        self.grid.place_agent(home, homeblock[0])
            else:
                print(
                    "systemic oppression under capitalism forclosed on one hoomin's home."
                )

        self.homeset = self.homeset.union(set(homelist))

        #initialize hoomins
        for i in range(self.initial_hoomins):
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)
            hoomin = SocialHoomin(self.next_id(), (x, y), self)
            if i == 1:
                for x in range(settings.initial_scattermessages):
                    hoomin.store_scattermessage("hoomin!")
                hoomin.pos = (0, 0)
                x = 0
                y = 0
                self.hoomin_zero_id = hoomin.unique_id

            if i == self.initial_hoomins - 1:
                self.final_hoomin_id = hoomin.unique_id
                hoomin.pos = (self.width - 1, self.height - 1)
                x = self.width - 1
                y = self.height - 1

            possiblehomes = self.homeset.difference(Home.claimedhomes)
            if len(possiblehomes) > 0:
                myhome = self.random.sample(possiblehomes, 1)
            if len(myhome) > 0:
                myhome[0].claim(hoomin)
            self.grid.place_agent(hoomin, (x, y))
            self.schedule.add(hoomin)
            self.G.add_node(hoomin, agent=[hoomin])

        #initialize hoomin friends
        friendlist = set(self.schedule._agents)
        for i in self.schedule._agents:
            fren = self.random.sample(friendlist.difference(set([i])),
                                      settings.friendsperhoomin)
            for x in fren:
                self.schedule._agents[i].addfriend(x)
                self.G.add_edge(self.schedule._agents[i],
                                self.schedule._agents[x])

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

    def roadplace_grid(self):
        for h in range(self.height):
            if h % self.gridspacing is 0:
                for w in range(self.width):
                    road = Road(self.next_id(), (w, h), self)
                    self.grid.place_agent(road, (w, h))

        for w in range(self.width):
            if w % self.gridspacing is 0:
                for h in range(self.height):
                    road = Road(self.next_id(), (w, h), self)
                    self.grid.place_agent(road, (w, h))

    def roadplace_random(self, direction=0):

        if direction is HoominWorld.STRAIGHT:
            True
        elif direction is HoominWorld.LEFT:
            self.roaddir = np.array((-1 * self.roaddir[1], self.roaddir[0]))
        elif direction is HoominWorld.RIGHT:
            self.roaddir = np.array((self.roaddir[1], -1 * self.roaddir[0]))
        else:
            self.roaddir = np.array((0, 0))
            print("bad bad bad")
#        print("placing road, direction ", direction, " coord: ", self.roadcurrentcoord)

        newcoord = self.roadcurrentcoord + self.roaddir
        if newcoord[0] >= self.width or newcoord[0] < 0:
            return None
        if newcoord[1] >= self.height or newcoord[1] < 0:
            return None

        self.roadcurrentcoord += self.roaddir

        road = Road(self.next_id(), tuple(self.roadcurrentcoord), self)
        self.grid.place_agent(road, tuple(self.roadcurrentcoord))

        return road

    def singleroad(self, initialcoord=(0, 0)):
        #initialize roads
        #print("placing road seed: ", initialcoord)
        roaddir = self.random.randrange(4)
        roadseedx = self.random.randrange(self.width)
        roadseedy = self.random.randrange(self.height)
        road = Road(self.next_id(), (roadseedx, roadseedy), self)
        self.roadcurrentcoord = (roadseedx, roadseedy)
        self.grid.place_agent(road, (roadseedx, roadseedy))

        #note: roads are not scheduled because they do nothing
        road = None
        counter = 0
        roadlist = []
        for i in range(self.initial_roads):
            while road is None:
                val = self.random.random()
                #print("val: " , val)
                if val <= self.straightweight:
                    road = self.roadplace_random(HoominWorld.STRAIGHT)
                elif val > self.straightweight and val <= self.leftweight + self.straightweight:
                    road = self.roadplace_random(HoominWorld.LEFT)
                elif val > self.leftweight + self.straightweight:
                    road = self.roadplace_random(HoominWorld.RIGHT)
                if road is None:
                    #print("err: road is none")
                    True

                roadlist.append(road)
            road = None
            counter += 1
        #print("initialized ", counter, " road tiles")
        self.roadset = self.roadset.union(set(roadlist))
        del roadlist

    def get_hoomin_level(self):
        return self.hoomin_level

    def logstep(self):
        if not self.logger.isopen(HoominWorld.FRIENDNODELOGNAME):
            self.logger.open(HoominWorld.FRIENDNODELOGNAME, overwrite=True)
        if not self.logger.isopen(HoominWorld.TOTALMESSAGELOGNAME):
            self.logger.open(HoominWorld.TOTALMESSAGELOGNAME, overwrite=True)

        self.logger.write(
            HoominWorld.TOTALMESSAGELOGNAME,
            str(self.hoomin_level) + " " + str(self.global_scattermessages))

        st = "STEP: " + str(self.hoomin_level) + " hoominzero: " + str(
            self.schedule._agents[self.hoomin_zero_id].friendgraph.
            number_of_nodes()) + " finalhoomin: " + str(self.schedule._agents[
                self.final_hoomin_id].friendgraph.number_of_nodes())
        self.logger.write(HoominWorld.FRIENDNODELOGNAME, st)

    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)
        self.hoomin_level += 1
        if self.hoomin_level % settings.graphrefreshfreq == 0 and settings.displayfriendgraph and not settings.runheadless:
            plt.cla()
            plt.clf()
            nx.draw(self.schedule._agents[self.hoomin_zero_id].friendgraph)
            plt.draw()
            plt.pause(0.001)
        if self.verbose:
            print([self.schedule.time, "nothing yet"])

        if len(self.schedule._agents[self.final_hoomin_id].scatterbuffer
               ) >= settings.initial_scattermessages:
            print("model completed")
            self.running = False
            if not self.logger.isopen(HoominWorld.STEPSTOCOMPLETIONLOGNAME):
                self.logger.open(HoominWorld.STEPSTOCOMPLETIONLOGNAME,
                                 overwrite=True)
            self.logger.write(HoominWorld.STEPSTOCOMPLETIONLOGNAME,
                              self.hoomin_level)
            self.logger.close(HoominWorld.STEPSTOCOMPLETIONLOGNAME)

        self.logstep()

    def run_model(self, step_count=200):
        if self.verbose:
            print("Initializing hoomins",
                  self.schedule.get_hoomin_count(Hoomin))
        while self.running:
            self.step()
Exemplo n.º 9
0
class CovidModel(Model):
    def size(filename):
        return Image.open(filename).size

    def __init__(self,
                 filename,
                 num_infec_agents=20,
                 num_uninfec_agents=20,
                 num_rec_agents=20,
                 mask_efficacy=95,
                 passing=True,
                 steps_per_hour_slow=12,
                 steps_per_hour_fast=1,
                 hours_per_day=3,
                 days=1,
                 cleans_per_day=1):
        im = Image.open(filename)  # open image file
        self.surfaces = []
        self.surface_pos = []
        self.entrances = []
        self.entrance_pos = []
        self.humans = []
        self.filename = filename
        self.width, self.height = im.size  # Get the width and height of the image to iterate over
        self.schedule = RandomActivation(self)
        self.grid = MultiGrid(width=self.width,
                              height=self.height,
                              torus=False)
        self.mask_efficacy = mask_efficacy / 100
        self.passing = passing
        self.steps_per_hour_slow = steps_per_hour_slow
        self.steps_per_hour_fast = steps_per_hour_fast
        self.steps_per_hour = self.steps_per_hour_fast
        self.hours_per_day = hours_per_day
        self.cleans_per_day = cleans_per_day
        self.hours = 0
        self.days = days
        self.datacollector = DataCollector(
            model_reporters={
                "Uninfected": get_uninfected_agents,
                "Recovered": get_recovered_agents,
                "Infected": get_infected_agents,
                "Quarantined of Infected": get_quarantined_agents,
                "Average Distance": get_average_distance,
                "Average Nearest Distance": get_avg_min_distance,
                "Days": get_days,
                "Hours": get_hours,
                "Average R_0": get_average_r0
            },
            agent_reporters={
                #	"Uninfected": lambda x: x.infected == False and x.recovered == False,
                #	"Infected": lambda x: x.infected == True,
                #	"Recovered": (add later)
            })

        convert(filename, self, self.surfaces,
                self.entrances)  # convert environment, create position lists

        for surface in self.surfaces:
            self.surface_pos.append(surface.pos)
        for entrance in self.entrances:
            self.entrance_pos.append(entrance.pos)

        # THIS SHOULD BE NOTED THAT THIS WILL ADD ONE TO THE TOTAL NUMBER OF HUMANS
        # create professor
        prof_seat = self.surfaces[0]
        pos = prof_seat.pos
        self.surfaces.remove(prof_seat)
        prof = Faculty(new_id(),
                       self,
                       pos=pos,
                       next_pos=pos,
                       seat=prof_seat,
                       infected=False,
                       recovered=False,
                       masked=True,
                       arrived=True)
        self.grid.place_agent(prof, pos)
        self.schedule.add(prof)
        self.humans.append(prof)

        #
        # setup_agnet(ag_type)
        # Find random starting postion and seat for agent. Create new agent with these parameters. Update
        # agent's infection status based off of ag_type. Give agent random caution level and update agent accordingly
        # Place agent on grid and add to scheduler and list of humans.
        def setup_agent(ag_type):
            pos = random.choice(self.entrance_pos)  # start agents at entrance
            seat = random.choice(
                self.surfaces)  # get random goal postion for agent
            self.surfaces.remove(seat)  # make goal position unique
            next_pos = seat.pos
            new_human = Student(new_id(),
                                self,
                                pos=pos,
                                next_pos=next_pos,
                                seat=seat)  # create new Student agent
            if ag_type == "uninfec":
                new_human.infected, new_human.recovered = False, False  # set state of agent
            elif ag_type == "infec":
                new_human.init_infect()  # needs deliberate setup
            elif ag_type == "rec":
                new_human.infected, new_human.recovered = False, True
            new_human.caution_level = random.randint(
                0,
                max_caution_level)  # create agents of different caution levels
            if new_human.caution_level == 0:
                new_human.masked = False
            elif new_human.caution_level == 1:
                new_human.masked = True
            elif new_human.caution_level == 2:
                new_human.masked = True
            if random.random(
            ) < percent_immunocompromised:  # create immunocomprimised agents
                new_human.immunocompromised = True
            else:
                new_human.immunocompromised = False
            self.grid.place_agent(new_human, pos)  # place agent on grid
            self.schedule.add(new_human)  # add agent to schedule
            self.humans.append(new_human)

        for agents in range(num_uninfec_agents):
            setup_agent("uninfec", )
        for agents in range(num_infec_agents):
            setup_agent("infec", )
        for agents in range(num_rec_agents):
            setup_agent("rec", )

        self.running = True

    #
    # self.check_arrival(destination)
    # Check arrival of nonquarantined agents at given destination.
    def check_arrival(self, destination):
        for human in self.humans:
            if not human.quarantined:  # only check agents at class
                if destination == "seats":
                    if not human.arrived or human.pos not in self.surface_pos:
                        return False
                elif destination == "exit":
                    if not human.arrived or human.pos not in self.entrance_pos:
                        return False
        return True

    #
    # self.check_agents()
    # Cautious agents check selves for symptoms and self quarantine if necessary.
    def check_agents(self):
        for human in self.humans:
            if human.infected and human.symptomatic and human.caution_level > 0 and not human.quarantined:  # if cautious person and symptomatic quarantine
                human.quarantine()
                #print("quarantined " + str(human.unique_id) + " on step" + str(self.schedule.steps))

    #
    # self.leave()
    # Update agent's next position to be exit.
    def leave(self):
        for human in self.humans:
            human.next_pos = random.choice(self.entrance_pos)

    #
    # self.clean_grid()
    # Iterate over surface and door cells and clean cells of virus.
    def clean_grid(self):
        for pos in self.surface_pos:
            for x in self.grid.get_cell_list_contents(pos):
                if isinstance(x, BaseEnvironment):
                    x.clean()
        for pos in self.entrance_pos:
            for x in self.grid.get_cell_list_contents(pos):
                if isinstance(x, BaseEnvironment):
                    x.clean()
        #print("cleaned")

    #
    # self.reset
    # Reset next postion of all agents to their seat.
    def reset(self):
        for human in self.humans:
            human.next_pos = human.seat.pos

    #
    # self.step()
    # Update steps_per_hour based off of agent arrival. Complete one class day. Move agents off grid,
    # clean grid, and self-quarantine agents if necessary. Stop simulation if all agents are recovered or uninfected.
    def step(self):
        # can we stop?
        if get_recovered_agents(self) + get_uninfected_agents(self) == len(
                self.humans):
            self.running = False

        if self.check_arrival(
                "seats"):  # if all agents have arrived class has "started"
            self.passing = False
        if self.passing:
            self.steps_per_hour = self.steps_per_hour_slow
        else:
            self.steps_per_hour = self.steps_per_hour_fast
        if not self.passing:
            self.hours += 1 / self.steps_per_hour  # add time to class hours
            if self.hours % self.hours_per_day < 0.001:  # after a 3 hour class
                self.leave()  # move agents off grid
                self.passing = True  # passing period begins again
            if self.hours % (self.hours_per_day / self.cleans_per_day) < 0.001:
                self.clean_grid()
        if self.check_arrival("exit"):  # if all agents have left
            self.check_agents()  # agents check selves for symptoms
            self.clean_grid()  # clean grid
            self.hours = 0
            self.days += 1  # number of days of class increases
            self.reset()  # update scheduled position
        #print("a(s): " + str(self.check_arrival("seats")) + " a(e): " + str(self.check_arrival("exit")) + ", s_p_h: " + str(self.steps_per_hour) + ", h: " + str(self.hours) + ", d: " + str(self.days) + ", s: " + str(self.schedule.steps))
        self.schedule.step()
        self.datacollector.collect(self)

    def run_model(self):
        #print("Rt: " + self.run_time)
        for i in range(self.run_time):
            self.step()
Exemplo n.º 10
0
class Intersection(Model):
    """
    Here the model is initialized. The Generatedmap.txt is read in order to locate traffic lights and car spawns.
    Cars and traffic lights are spawned here.
    """

    def __init__(self, spawnrate, tactic, offset, cycletime):
        # Variable parameters
        self.tactic = tactic  # [ Offset, Proportional, Lookahead, GreenWave]
        self.spawnrate = spawnrate
        self.offset = offset
        self.slowmotionrate = 0.2
        self.cycletime = cycletime

        # Value initializations
        self.emission = [0, 0, 0]  # emission per step
        self.traveltime = []
        self.averagetraveltime = 0
        self.carID = 0
        self.averageemission = []

        # Reading roadmap and emission values
        self.emissionvalues = reademissionvalues()
        [
            self.roadmap,
            self.spawns,
            self.lights,
            self.height,
            self.cellsperlane,
            self.intersections,
            self.streetlength,
            self.gridsize,
        ] = readroadmap()

        # Model and visualization parameters
        self.schedule = RandomActivation(self)
        self.width = self.height
        self.grid = MultiGrid(self.width, self.height, True)
        self.running = True

        # Initializing matrix which shows what cars in front of traffic lights go to what over traffic lights.
        self.tlightmatrix = np.empty((len(self.lights), len(self.lights)))
        self.tlightmatrix[:] = np.nan
        self.trafficlightlist = []
        self.lightcombinations = [
            ["SR", "SD", "SL", "WR"],
            ["ER", "ED", "EL", "SR"],
            ["NR", "ND", "NL", "ER"],
            ["WR", "WD", "WL", "NR"],
        ]

        # Data collection
        self.datacollector = DataCollector(
            model_reporters={
                "tactic": "tactic",
                "Spawnrate": "spawnrate",
                "Offset": "offset",
                "Cycletime": "cycletime",
                "AverageTraveltime": "averagetraveltime",
                "Totalcars": lambda m: self.numberofcars(),
                "CO2": lambda m: self.getco2(),
                "NOx": lambda m: self.getnox(),
                "PM10": lambda m: self.getpm(),
                "AverageCO2": lambda m: self.getaverageco2(),
                "AverageNOx": lambda m: self.getaveragenox(),
                "AveragePM": lambda m: self.getaveragepm(),
            },
        )

        # Needed for green wave tactic
        self.mostcars = []
        self.goesto = []
        self.firstgreenintersection = -1
        self.secondgreenintersection = -1
        self.firstcombination = None
        self.secondcombination = None
        self.firstcycledone = 0

        # Needed for lookahead tactic
        self.mostexpectedcars = [0, 0, 0]  # cars,intersection,combination

        # results in list of lists with intersectionnumbers in the right place, e.g.: [[0, 1],[2,3]]
        # Needed for the offset tactic to know which lights to offset
        self.intersectionmatrix = []
        lastnumber = 0
        for i in range(int(math.sqrt(self.intersections))):
            tempmaptrix = []
            for j in range(int(math.sqrt(self.intersections))):
                tempmaptrix.append(j + lastnumber)
            lastnumber = tempmaptrix[-1] + 1
            self.intersectionmatrix.append(tempmaptrix)
        self.intersectionmatrix = np.array(self.intersectionmatrix)

        # Initialize information dictionary (which lights are suppesed to be green and how long they have been green for
        self.trafficlightinfo = {}
        for i in range(self.intersections):
            self.trafficlightinfo.update(
                {f"intersection{i}": {"Trafficlightinfo": {}, "Timeinfo": {}}}
            )

        # Initializes traffic lights
        for i, light in enumerate(self.lights):
            self.trafficlightinfo[f"intersection{light[1][3]}"]["Trafficlightinfo"][
                f"{light[1][1:3]}"
            ] = i
            self.trafficlightinfo[f"intersection{light[1][3]}"]["Timeinfo"].update(
                {
                    "Currentgreen": -1,
                    "Currenttimegreen": 0,
                    "Maxtimegreen": 0,
                    "Allred": 1,
                }
            )
            intersectionnumber = int(light[1][3])
            intersectiony = np.where(self.intersectionmatrix == intersectionnumber)[0]
            intersectionx = np.where(self.intersectionmatrix == intersectionnumber)[1]
            direction = light[1][1]
            lane = light[1][2]
            location = light[0]
            xlocation = int(location[0])
            ylocation = self.height - 1 - int(location[1])
            trafficlight = TrafficLightAgent(
                f"{xlocation},{ylocation},{light[1][1:3]}",
                self,
                "red",
                direction,
                lane,
                i,
                intersectionnumber,
                self.tactic,
                self.offset,
                [intersectionx, intersectiony],
                self.cycletime,
            )
            self.trafficlightlist.append([light[1], i])
            self.schedule.add(trafficlight)
            self.grid.place_agent(trafficlight, (xlocation, ylocation))
        self.tlightmatrix = lightconnection(
            self.tlightmatrix, self.trafficlightlist, self.intersections
        )

        # Place legend
        self.grid.place_agent(LegendCarIcon("Caricon", self), (65, 68))
        self.grid.place_agent(LegendGreenTlightIcon("GreenTlighticon", self), (65, 69))
        self.grid.place_agent(LegendRedTlightIcon("RedTlighticon", self), (65, 70))

    # Get emission values
    def getco2(self):

        return self.emission[0]

    def getnox(self):

        return self.emission[1]

    def getpm(self):

        return self.emission[2]

    def getaveragetraveltime(self):

        return self.averagetraveltime

    def getaverageco2(self):
        totalco2 = 0
        if len(self.averageemission) > 0:
            for i, emissions in enumerate(self.averageemission):
                totalco2 += emissions[0]
            return totalco2 / len(self.averageemission)
        else:
            return 0

    def getaveragenox(self):
        totalnox = 0
        if len(self.averageemission) > 0:
            for i, emissions in enumerate(self.averageemission):
                totalnox += emissions[1]
            return totalnox / len(self.averageemission)
        else:
            return 0

    def getaveragepm(self):
        totalpm = 0
        if len(self.averageemission) > 0:
            for i, emissions in enumerate(self.averageemission):
                totalpm += emissions[2]
            return totalpm / len(self.averageemission)
        else:
            return 0

    def numberofcars(self):
        return len(self.schedule.agents) - 12 * self.intersections

    def step(self):
        """
        Step function that will randomly place cars based on the spawn chance
        and will visit all the agents to perform their step function.
        """
        # Spawn cars
        for spawn in self.spawns:
            location = spawn[0]
            cell_contents = self.grid.get_cell_list_contents([location])

            if (
                not cell_contents
                and random.randint(0, int(100 / self.slowmotionrate)) < self.spawnrate
            ):
                location = spawn[0]
                xlocation = int(location[0])
                ylocation = self.height - 1 - int(location[1])
                direction = spawn[1][1]
                lane = spawn[1][2]
                car = CarAgent(
                    f"car{self.carID}",
                    self,
                    direction,
                    lane,
                    [xlocation, ylocation]
                )
                self.carID += 1
                self.schedule.add(car)
                self.grid.place_agent(car, (xlocation, ylocation))

        # Clear all previous step's emission and travel time
        if len(self.traveltime) > 0:
            self.averagetraveltime = sum(self.traveltime) / len(self.traveltime)

        # For the greenwave tactic
        if (
            self.tactic == "GreenWave"
            and len(self.schedule.agents) > 12 * self.intersections
            and ((self.schedule.steps % (self.cycletime * 2)) == 0)
        ):

            self.firstcycledone = 0
            self.mostcars = np.argmax(np.nansum(self.tlightmatrix, axis=1))
            if self.mostcars:
                self.goesto = np.where(~np.isnan(self.tlightmatrix[self.mostcars]))
                self.firstgreenintersection = self.lights[self.mostcars][1][3]
                self.secondgreenintersection = self.lights[self.goesto[0][0]][1][3]

                # Determines the direction of traffic lights
                firstdirection = self.schedule.agents[int(self.mostcars)].direction
                seconddirection = self.schedule.agents[self.goesto[0][0]].direction

                # Determines combinations of traffic lights that can stay green
                for i, combination in enumerate(self.lightcombinations):
                    if firstdirection + "D" in combination:
                        self.firstcombination = self.lightcombinations[i]
                    if seconddirection + "D" in combination:
                        self.secondcombination = self.lightcombinations[i]
                # If 1st part of green wave is over (so 1 cycle has been done)
                if not ((self.schedule.steps % (self.cycletime * 2)) == 0):
                    self.firstcycledone = 1

        # For the proportional tactic
        if (
            self.tactic == "Proportional"
            and len(self.schedule.agents) > 12 * self.intersections
        ):
            for i in range(self.intersections):
                currenttimegreen = self.trafficlightinfo[f"intersection{i}"][
                    "Timeinfo"
                ]["Currenttimegreen"]
                maxgreentime = self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                    "Maxtimegreen"
                ]
                self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                    "Currenttimegreen"
                ] = (currenttimegreen + 1)
                if currenttimegreen > maxgreentime + 6:
                    carsinfront = np.nansum(self.tlightmatrix, axis=1)
                    totalcars = [0, 0, 0, 0]
                    for key in self.trafficlightinfo[f"intersection{i}"][
                        "Trafficlightinfo"
                    ].keys():
                        trafficlight = int(
                            self.trafficlightinfo[f"intersection{i}"][
                                "Trafficlightinfo"
                            ][key]
                        )
                        cars = carsinfront[trafficlight]
                        for j, combi in enumerate(self.lightcombinations):
                            if key in combi:
                                totalcars[j] = totalcars[j] + cars
                    # No cars? pick regular timeschedule
                    if sum(totalcars) == 0:
                        totalcars = [1, 1, 1, 1]
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currentgreen"
                    ] = totalcars.index(max(totalcars))
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Maxtimegreen"
                    ] = (max(totalcars) / (sum(totalcars) / 4) * self.cycletime)
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currenttimegreen"
                    ] = 0
                if currenttimegreen == maxgreentime:
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currentgreen"
                    ] = -1

        # For the lookahead tactic
        if (
            self.tactic == "Lookahead"
            and len(self.schedule.agents) > 12 * self.intersections
        ):
            self.mostexpectedcars = [0, 0, 0]
            for i in range(self.intersections):
                currenttimegreen = self.trafficlightinfo[f"intersection{i}"][
                    "Timeinfo"
                ]["Currenttimegreen"]
                maxgreentime = self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                    "Maxtimegreen"
                ]
                self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                    "Currenttimegreen"
                ] = (currenttimegreen + 1)
                if currenttimegreen > maxgreentime + 6:
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"]["Allred"] = 0
                    carsexpected = np.nansum(self.tlightmatrix, axis=0)
                    carsinfront = np.nansum(self.tlightmatrix, axis=1)
                    totalcars = [0, 0, 0, 0]
                    # For every direction + lane in intersection
                    for key in self.trafficlightinfo[f"intersection{i}"][
                        "Trafficlightinfo"
                    ].keys():
                        trafficlight = int(
                            self.trafficlightinfo[f"intersection{i}"][
                                "Trafficlightinfo"
                            ][key]
                        )
                        cars = carsinfront[trafficlight]
                        # For every lightcombination
                        for j, combi in enumerate(self.lightcombinations):
                            if key in combi:
                                totalcars[j] = (
                                    totalcars[j] + cars + carsexpected[trafficlight]
                                )
                                if totalcars[j] > self.mostexpectedcars[0]:
                                    self.mostexpectedcars[0] = totalcars[j]
                                    self.mostexpectedcars[1] = i
                                    self.mostexpectedcars[2] = j
                    # Reset timers
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currentgreen"
                    ] = (
                        self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                            "Currentgreen"
                        ]
                        + 1
                    ) % 4
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Maxtimegreen"
                    ] = self.cycletime
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"][
                        "Currenttimegreen"
                    ] = 0
                if currenttimegreen == maxgreentime:
                    self.trafficlightinfo[f"intersection{i}"]["Timeinfo"]["Allred"] = 1
            if self.mostexpectedcars[0] != 0:
                # Change green light information of intersection with most expected cars
                self.trafficlightinfo[f"intersection{self.mostexpectedcars[1]}"][
                    "Timeinfo"
                ]["Currentgreen"] = self.mostexpectedcars[2]

                # Get trafficlightnumbers of ligths where most cars are expected
                mostcars = 0
                mostcarslight = None
                comingfrom = np.nansum(self.tlightmatrix, axis=1)
                for direction in self.lightcombinations[self.mostexpectedcars[2]]:
                    greenlight = int(
                        self.trafficlightinfo[
                            f"intersection{self.mostexpectedcars[1]}"
                        ]["Trafficlightinfo"][direction]
                    )
                    # Where the cars to those lights come from.
                    lightscomingfrom = np.argwhere(
                        ~np.isnan(self.tlightmatrix[:, greenlight])
                    )
                    for light in lightscomingfrom:
                        if light:
                            light = light[0]
                            carsinfront = np.sum(comingfrom[light])
                            if carsinfront > mostcars:
                                mostcars = int(carsinfront)
                                mostcarslight = light

                # Find intersection + directon of this light and change this intersection's green light information
                if mostcars != 0:
                    intersection = int(self.lights[mostcarslight][1][3])
                    direction = self.lights[mostcarslight][1][1:3]
                    for k, directs in enumerate(self.lightcombinations):
                        if direction in directs[0:3]:
                            self.trafficlightinfo[f"intersection{intersection}"][
                                "Timeinfo"
                            ]["Currentgreen"] = k
                            pass

        self.datacollector.collect(self)
        self.emission = [0, 0, 0]
        self.schedule.step()
Exemplo n.º 11
0
class AntModel(Model):
    def __init__(self, num_ln, num_fj, num_mk_col, num_ft_col, width, height):
        """
        :param num_ln: Number of L. Niger agents
        :param num_fj: Number of F. Japonica agents
        :param num_mk_col: Number of M. Kuricola colonies
        :param num_ft_col: Number of F. Tropicalis colonies
        :param width: Width of the model grid
        :param height: Height of the model grid
        """
        super().__init__()
        self.num_ln = num_ln
        self.num_fj = num_fj
        self.num_mk_col = num_mk_col
        self.num_ft_col = num_ft_col
        self.grid = MultiGrid(width, height, True)
        self.schedule = RandomActivation(self)
        self.running = True

        for h in range(self.num_fj):
            ant = FJaponica(uuid4(), self)
            self.schedule.add(ant)
            self.grid.place_agent(ant, self.grid.find_empty())

        for j in range(self.num_mk_col):
            colony = MKuricolaColony(uuid4(), self)
            self.schedule.add(colony)
            self.grid.place_agent(colony, self.grid.find_empty())

        for k in range(self.num_ft_col):
            colony = FTropicalisColony(uuid4(), self)
            self.schedule.add(colony)
            self.grid.place_agent(colony, self.grid.find_empty())

        for i in range(self.num_ln):
            ant = LNiger(uuid4(), self)
            self.schedule.add(ant)
            self.grid.place_agent(ant, self.grid.find_empty())
            ant._init_post_place()

        self.data_collector = DataCollector(
            model_reporters={},
            agent_reporters={"states": ant_state_collector})
        self.weights_dict = json.load(open("newout.json", "r"))

    def drop_pheromone(self, location):
        """
        Drops a LNPheromone object at the given location if one does not already exist. If one does already exist,
        1 is added to the existing object's 'tracks' field.
        :param location: An (x, y) tuple detailing the location to drop the pheromone.
        :return: None
        """
        if not self.is_pheromone_in_cell(location):
            self.grid.place_agent(LNPheromone(uuid4(), self), location)
        else:
            self.get_pheromone_in_cell(location).tracks += 1

    def is_pheromone_in_cell(self, location):
        """
        Determines if a pheromone already exists in a given cell.
        :param location: The location to check.
        :return: boolean
        """
        return True in [
            type(x) == LNPheromone
            for x in self.grid.get_cell_list_contents(location)
        ]

    def is_ant_in_cell(self, location):
        """
        Determines whether an ant exists in a given cell.
        :param location: The location to check.
        :return: boolean
        """
        return True in [
            isinstance(x, Ant)
            for x in self.grid.get_cell_list_contents(location)
        ]

    def is_colony_in_cell(self, location):
        """
        Determines whether an aphid colony exists in a given cell.
        :param location: The location to check.
        :return: boolean
        """
        return True in [
            type(x) == MKuricolaColony or type(x) == FTropicalisColony
            for x in self.grid.get_cell_list_contents(location)
        ]

    def get_pheromone_in_cell(self, location):
        """
        Returns a LNPheromone object from a cell. ASsumes the cell has already been proven to have a pheromone object
        in it.
        :param location: The cell location to check.
        :return: The LNPheromone object within the cell.
        """
        in_cell_pheromone = None
        for i in self.grid.get_cell_list_contents(location):
            if type(i) == LNPheromone:
                in_cell_pheromone = i
        return in_cell_pheromone

    def get_closest_agent_of_type(self, agent, agent_type):
        """
        Gets the closest agent (besides self) of type agent_type. Returns -1 if it cannot find one.
        :param agent: The agent to find the closest agent_type to.
        :param agent_type: The type of the agent we are looking for.
        :return:
        """
        for radius in range(1, self.grid.width):
            for neighbor in self.grid.get_neighbors(pos=agent.pos,
                                                    moore=True,
                                                    include_center=False,
                                                    radius=radius):
                if isinstance(neighbor, agent_type):
                    return neighbor
        return -1

    def get_closest_colony(self, agent):
        """
        Gets the closest colony to an agent. If an agent is of type colony, it returns itself.
        :param agent: The agent to find the closest colony to.
        :return: The closest colony or -1 if not found.
        """
        return self.get_closest_agent_of_type(agent, Colony)

    @staticmethod
    def distance_between_cells(location_a, location_b):
        """
        Calculates the distance between two cells on the grid.
        :param location_a: First cell location.
        :param location_b: Second cell location.
        :return:
        """
        return np.sqrt((location_a[0] - location_b[0])**2 +
                       (location_a[1] - location_a[1])**2)

    def get_nearest_cell_to_goal(self, goal_cell, possible_cells):
        """
        Returns the cell from a list of possible cells which is closest to the end location.
        :param goal_cell: The goal cell of the agent
        :param possible_cells: Candidate cells.
        :return: The location of the closest cell to the goal cell.
        """
        closest_neighbor_index = -1
        closest_neighbor_distance = np.inf
        for i in range(0, len(possible_cells)):
            dist = self.distance_between_cells(possible_cells[i], goal_cell)
            if dist < closest_neighbor_distance:
                closest_neighbor_index = i
                closest_neighbor_distance = dist
        return possible_cells[closest_neighbor_index]

    def get_number_of_agents_in_radius(self, location, radius, agent_type):
        """
        Returns the number of agents of type agent_type within a radius (not including center) of location.
        :param location: Location to search around.
        :param radius: Radius to search.
        :param agent_type: Type of agent to search for.
        :return: int
        """
        total_agents = 0
        for neighbor in self.grid.get_neighbors(pos=location,
                                                moore=True,
                                                include_center=False,
                                                radius=radius):
            if isinstance(neighbor, agent_type):
                total_agents += 1
        return total_agents

    def get_all_of_agent_type(self, agent_type):
        """
        Returns all instances of agents of type agent_type in the Grid.
        :param agent_type: The type of agent to find.
        :return: A list of agent objects.
        """
        return [
            x for x in self.grid.get_neighbors(pos=(0, 0),
                                               moore=True,
                                               include_center=True,
                                               radius=self.grid.width)
            if isinstance(x, agent_type)
        ]

    def step(self):
        """
        A method called every step that occurs
        :return: None
        """
        self.data_collector.collect(self)
        self.schedule.step()
Exemplo n.º 12
0
class SOMENModel(Model):
    def __init__(self, width, height):

        # Model attributes initialization
        self.workers_number = 10
        self.agents = []
        self.workers = []
        self.average_stress = 0
        self.running = True

        #SOBA
        configuration.settings.init()
        configuration.defineOccupancy.init()
        configuration.defineMap.init()

        self.clock = Time()

        #Vars of control
        self.num_occupants = 0
        self.day = self.clock.day
        self.NStep = 0
        self.placeByStateByTypeAgent = {}
        self.agentsWorkingByStep = []
        self.agentsIn = 0

        # Schedule
        self.schedule = BaseScheduler(self)
        self.grid = MultiGrid(width, height, False)

        #Create the map
        self.createRooms()
        self.setMap(width, height)
        self.createDoors()
        self.createWalls()
        #Create agents
        self.setAgents()

        # Create timer agent
        self.timer = TimeAgent(len(self.agents), self)
        self.schedule.add(self.timer)
        self.agents.append(self.timer)

        # Create sensor agent
        self.sensor = SensorAgent(len(self.agents), self)
        self.schedule.add(self.sensor)
        self.agents.append(self.sensor)
        '''
        # Create workers agents
        for i in range(self.workers_number):
            worker = WorkerAgent(i+len(self.agents), self)
            self.schedule.add(worker)
            self.workers.append(worker)
        '''

        # Create data collectors
        self.model_collector = DataCollector(
            model_reporters={"Average Stress": lambda a: a.average_stress})
        self.worker_collector = WorkerCollector(
            agent_reporters={
                "Stress": lambda a: a.stress,
                "Event Stress": lambda a: a.event_stress,
                "Time Pressure": lambda a: a.time_pressure,
                "Effective Fatigue": lambda a: a.effective_fatigue,
                "Productivity": lambda a: a.productivity,
                'Emails read': lambda a: a.emails_read,
                'Pending tasks': lambda a: len(a.tasks),
                'Overtime hours': lambda a: a.overtime_hours,
                'Rest at work hours': lambda a: a.rest_at_work_hours,
                'Tasks completed': lambda a: a.tasks_completed
            })
        self.sensor_collector = SensorCollector(
            agent_reporters={
                "Temperature": lambda a: a.wbgt,
                "Noise": lambda a: a.noise,
                "Luminosity": lambda a: a.luminosity
            })
        self.time_collector = TimeCollector(agent_reporters={
            "Day": lambda a: a.days,
            "Time": lambda a: a.clock
        })

    #SOBA
    def setAgents(self):

        self.lights = []
        id_light = 0
        for room in self.rooms:
            if room.typeRoom != 'out' and room.light == False:
                light = Light(id_light, self, room)
                self.lights.append(light)
                id_light = id_light + 1
                room.light = light
                for room2 in self.rooms:
                    if room.name.split(r".")[0] == room2.name.split(r".")[0]:
                        room2.light = light

        # Height and Width
        height = self.grid.height
        width = self.grid.width

        # CREATE AGENTS

        self.agents = []
        # Create occupants
        for n_type_occupants in configuration.defineOccupancy.occupancy_json:
            self.placeByStateByTypeAgent[
                n_type_occupants['type']] = n_type_occupants['states']
            n_agents = n_type_occupants['N']
            for i in range(0, n_agents):
                a = WorkerAgent(i + len(self.agents) + 1000, self,
                                n_type_occupants)
                self.workers.append(a)
                self.schedule.add(a)
                self.grid.place_agent(a, self.outBuilding.pos)
                self.pushAgentRoom(a, self.outBuilding.pos)
                self.num_occupants = self.num_occupants + 1

        self.schedule.add(self.clock)
        for light in self.lights:
            self.schedule.add(light)

    def isConected(self, pos):
        nextRoom = False
        for room in self.rooms:
            if room.pos == pos:
                nextRoom = room
        if nextRoom == False:
            return False
        for x in range(0, width):
            for y in range(0, height):
                self.pos_out_of_map.append(x, y)
        for room in self.rooms:
            self.pos_out_of_map.remove(room.pos)

    def createRooms(self):
        rooms = configuration.defineMap.rooms_json
        self.rooms = []
        for room in rooms:
            newRoom = 0
            name = room['name']
            typeRoom = room['type']
            if typeRoom != 'out':
                conectedTo = room.get('conectedTo')
                entrance = room.get('entrance')
                measures = room['measures']
                dx = measures['dx']
                dy = measures['dy']
                newRoom = Room(name, typeRoom, conectedTo, dx, dy)
                newRoom.entrance = entrance
            else:
                newRoom = Room(
                    name,
                    typeRoom,
                    None,
                    0,
                    0,
                )
                self.outBuilding = newRoom
            self.rooms.append(newRoom)
        for room1 in self.rooms:
            if room1.conectedTo is not None:
                for otherRooms in list(room1.conectedTo.values()):
                    for room2 in self.rooms:
                        if room2.name == otherRooms:
                            room1.roomsConected.append(room2)
                            room2.roomsConected.append(room1)
        for room in self.rooms:
            room.roomsConected = list(set(room.roomsConected))
        sameRoom = {}
        for room in self.rooms:
            if sameRoom.get(room.name.split(r".")[0]) is None:
                sameRoom[room.name.split(r".")[0]] = 1
            else:
                sameRoom[room.name.split(r".")
                         [0]] = sameRoom[room.name.split(r".")[0]] + 1

    def setMap(self, width, height):
        rooms_noPos = self.rooms
        rooms_using = []
        rooms_used = []
        for room in self.rooms:
            if room.entrance is not None:
                room.pos = (int(1), 1)
                rooms_using.append(room)
                rooms_used.append(room)
                rooms_noPos.remove(room)
                break
        while len(rooms_noPos) > 0:
            for roomC in rooms_using:
                xc, yc = roomC.pos
                rooms_conected = roomC.conectedTo
                rooms_using.remove(roomC)
                if rooms_conected is not None:
                    orientations = list(rooms_conected.keys())
                    for orientation in orientations:
                        if orientation == 'R':
                            for room in rooms_noPos:
                                if room.name == rooms_conected['R']:
                                    room.pos = (int(xc + 1), yc)
                                    rooms_noPos.remove(room)
                                    rooms_used.append(room)
                                    rooms_using.append(room)
                        elif orientation == 'U':
                            for room in rooms_noPos:
                                if room.name == rooms_conected['U']:
                                    room.pos = (xc, int(yc + 1))
                                    rooms_noPos.remove(room)
                                    rooms_used.append(room)
                                    rooms_using.append(room)
                        elif orientation == 'D':
                            for room in rooms_noPos:
                                if room.name == rooms_conected['D']:
                                    room.pos = (xc, int(yc - 1))
                                    rooms_noPos.remove(room)
                                    rooms_used.append(room)
                                    rooms_using.append(room)
                        elif orientation == 'L':
                            for room in rooms_noPos:
                                if room.name == rooms_conected['L']:
                                    room.pos = (int(xc - 1), yc)
                                    rooms_noPos.remove(room)
                                    rooms_used.append(room)
                                    rooms_using.append(room)
                else:
                    pass
        self.rooms = rooms_used

    def createDoors(self):
        self.doors = []
        for roomC in self.rooms:
            roomsConected = roomC.roomsConected
            for room in roomsConected:
                door_created = False
                same_corridor = False
                if room.name != roomC.name:
                    for door in self.doors:
                        if (door.room1.name == roomC.name
                                and door.room2.name == room.name) or (
                                    door.room2.name == roomC.name
                                    and door.room1.name == room.name):
                            door_created = True
                        if room.name.split(r".")[0] == roomC.name.split(
                                r".")[0]:
                            same_corridor = True
                    if door_created == False and same_corridor == False:
                        d = Door(roomC, room)
                        self.doors.append(d)
                        room.doors.append(d)
                        roomC.doors.append(d)

    def createWalls(self):
        for room in self.rooms:
            if room.typeRoom != 'out':
                walls = []
                xr, yr = room.pos
                roomA = self.getRoom((xr, yr + 1))
                if roomA != False:
                    if roomA.name.split(r".")[0] == room.name.split(r".")[0]:
                        pass
                    else:
                        wall = Wall(room, roomA)
                        walls.append(wall)
                else:
                    wall = Wall(room)
                    walls.append(wall)
                roomB = self.getRoom((xr, yr - 1))
                if roomB != False:
                    if roomB.name.split(r".")[0] == room.name.split(r".")[0]:
                        pass
                    else:
                        wall = Wall(room, roomB)
                        walls.append(wall)
                else:
                    wall = Wall(room)
                    walls.append(wall)
                roomC = self.getRoom((xr + 1, yr))
                if roomC != False:
                    if roomC.name.split(r".")[0] == room.name.split(r".")[0]:
                        pass
                    else:
                        wall = Wall(room, roomC)
                        walls.append(wall)
                else:
                    wall = Wall(room)
                    walls.append(wall)
                roomD = self.getRoom((xr - 1, yr))
                if roomD != False:
                    if roomD.name.split(r".")[0] == room.name.split(r".")[0]:
                        pass
                    else:
                        wall = Wall(room, roomD)
                        walls.append(wall)
                else:
                    wall = Wall(room)
                    walls.append(wall)

                room.walls = walls

    def getPosState(self, name, typeA):
        placeByStateByTypeAgent = self.placeByStateByTypeAgent
        n = 0
        for state in self.placeByStateByTypeAgent[typeA]:
            if state.get('name') == name:
                pos1 = state.get('position')
                if isinstance(pos1, dict):
                    for k, v in pos1.items():
                        if v > 0:
                            placeByStateByTypeAgent[typeA][n]['position'][
                                k] = v - 1
                            self.placeByStateByTypeAgent = placeByStateByTypeAgent
                            return k
                    return list(pos1.keys())[-1]
                else:
                    return pos1
            n = n + 1

    def thereIsClosedDoor(self, beforePos, nextPos):
        oldRoom = False
        newRoom = False
        for room in rooms:
            if room.pos == beforePos:
                oldRoom = room
            if room.pos == nextPos:
                newRoom = room
        for door in self.doors:
            if (door.room1.name == oldRoom.name and door.room2.name
                    == newRoom.name) or (door.room2.name == oldRoom.name
                                         and door.room1.name == newRoom.name):
                if door.state == False:
                    return True
        return False

    def thereIsOccupant(self, pos):
        possible_occupant = self.grid.get_cell_list_contents([pos])
        if (len(possible_occupant) > 0):
            for occupant in possible_occupant:
                if isinstance(occupant, WorkerAgent):
                    return True
        return False

    def ThereIsOtherOccupantInRoom(self, room, agent):
        for roomAux in self.rooms:
            possible_occupant = []
            if roomAux.name.split(r".")[0] == room.name.split(r".")[0]:
                possible_occupant = self.grid.get_cell_list_contents(
                    roomAux.pos)
            for occupant in possible_occupant:
                if isinstance(occupant, WorkerAgent) and occupant != agent:
                    return True
        return False

    def ThereIsSomeOccupantInRoom(self, room):
        for roomAux in self.rooms:
            possible_occupant = []
            if roomAux.name.split(r".")[0] == room.name.split(r".")[0]:
                possible_occupant = self.grid.get_cell_list_contents(
                    roomAux.pos)
            for occupant in possible_occupant:
                if isinstance(occupant, WorkerAgent):
                    return True
        return False

    def thereIsOccupantInRoom(self, room, agent):
        for roomAux in self.rooms:
            possible_occupant = []
            if roomAux.name.split(r".")[0] == room.name.split(r".")[0]:
                possible_occupant = self.grid.get_cell_list_contents(
                    roomAux.pos)
            for occupant in possible_occupant:
                if isinstance(occupant, WorkerAgent) and occupant == agent:
                    return True
        return False

    def getRoom(self, pos):
        for room in self.rooms:
            if room.pos == pos:
                return room
        return False

    def pushAgentRoom(self, agent, pos):
        room = self.getRoom(pos)
        room.agentsInRoom.append(agent)

    def popAgentRoom(self, agent, pos):
        room = self.getRoom(pos)
        room.agentsInRoom.remove(agent)

    def openDoor(self, agent, room1, room2):
        for door in self.doors:
            if ((door.room1 == room1 and door.room2 == room2)
                    or (door.room1 == room2 and door.room2 == room1)):
                door.state = False

    def closeDoor(self, agent, room1, room2):
        numb = random.randint(0, 10)
        for door in self.doors:
            if ((door.room1 == room1 and door.room2 == room2)
                    or (door.room1 == room2 and door.room2 == room1)):
                if 7 >= numb:
                    door.state = False
                else:
                    door.state = True

    def getMatrix(self, agent):
        new_matrix = configuration.defineOccupancy.returnMatrix(
            agent, self.clock.clock)
        agent.markov_matrix = new_matrix

    def getTimeInState(self, agent):
        matrix_time_in_state = configuration.defineOccupancy.getTimeInState(
            agent, self.clock.clock)
        return matrix_time_in_state

    def sobaStep(self):
        aw = 0
        for agent in self.agents:
            if agent.state == 'working in my workplace':
                aw = aw + 1
        self.agentsWorkingByStep.append(aw)
        self.schedule.step()

        if (self.clock.day > self.day):
            self.day = self.day + 1
        self.NStep = self.NStep + 1

        if self.clock.clock > 17:
            model.ramenScript.generateJSON()
            while (True):
                pass

    def step(self):

        self.sobaStep()

        if self.timer.new_day:
            self.addTasks()
            self.createEmailsDistribution()

        self.average_stress = sum(
            worker.stress for worker in self.workers) / len(self.workers)

        if self.timer.new_hour:
            self.worker_collector.collect(self)
            self.sensor_collector.collect(self)
            self.time_collector.collect(self)
            self.model_collector.collect(self)

    def addTasks(self):
        ''' Add tasks to workers '''

        # Get task distribution params
        mu, sigma = workload_settings.tasks_arriving_distribution_params
        tasks_arriving_distribution = np.random.normal(
            mu, sigma, self.workers_number * 10)

        for worker in self.workers:

            # Get number of tasks to add
            tasks_number = math.floor(
                abs(tasks_arriving_distribution[random.randint(
                    0, 10 * self.workers_number - 1)]))
            worker.tasks_completed = 0

            # Add tasks
            for i in range(tasks_number):
                worker.addTask(Task())

            worker.calculateAverageDailyTasks(self.timer.days)
            worker.calculateEventStress(tasks_number)

            # worker.printTasksNumber()
            # worker.printAverageDailyTasks()
            # worker.printEventStress()

    def createEmailsDistribution(self):
        '''Create emails distribution'''
        # Get emails distribution
        mu, sigma = email_settings.emails_read_distribution_params
        emails_read_distribution = np.random.normal(mu, sigma,
                                                    self.workers_number * 10)

        for worker in self.workers:

            emails_received = math.floor(
                abs(emails_read_distribution[random.randint(
                    0, 10 * self.workers_number - 1)]))
            emails_distribution_over_time = np.random.choice(
                [0, 1],
                size=(480, ),
                p=[(480 - emails_received) / 480, emails_received / 480])
            worker.emails_read = 0
            worker.email_read_distribution_over_time = emails_distribution_over_time
Exemplo n.º 13
0
class Map(Model):
	def __init__(self, ncells, obstacles_dist, ninjured):
		# used in server start
		self.running = True
		self.ncells = ncells
		self.obstacles_dist = obstacles_dist
		self.ninjured = ninjured

		# grid and schedule representation
		self.grid = MultiGrid(ncells + 2, ncells + 2, torus = False)
		self.schedule = RandomActivation(self)
		# unique counter for agents 
		self.agent_counter = 1
		out_grid = {}
		out_grid["Cell"] = {}
		out_grid["Injured"] = {}
		# place a cell agent for store data and visualization on each cell of the grid
		for i in self.grid.coord_iter():
			if i[1] != 0 and i[2] != 0 and i[1] != self.ncells + 1 and i[2] != self.ncells + 1:
				rand = np.random.random_sample()
				obstacle = True if rand < self.obstacles_dist else False
				if obstacle:
					difficulty = "inf"
					explored = -1
					priority = 0
					utility = "-inf"
				else:
					difficulty = np.random.randint(low = 1, high = 13)
					explored = 0
					priority = 0
					utility = 1.0
			else:
				difficulty = np.random.randint(low = 1, high = 13)
				explored = -2
				priority = "-inf"
				utility = "-inf"

			# generate big wall all across the map
			'''
			_, y, x = i
			if x == 200 or x == 199:
				difficulty = "inf"
				explored = -1
				priority = 0
				utility = "-inf"
			if (x == 200 or x ==199) and (y == 150 or y == 50 or y == 250):
				difficulty = np.random.randint(low = 1, high = 13)
				explored = 0
				priority = 0
				utility = 1.0	
			'''	
			# place the agent in the grid
			out_grid["Cell"][i[1:]]= [self.agent_counter, i[1:], difficulty, explored, priority, utility]
			a = Cell(self.agent_counter, self, i[1:], difficulty, explored, priority, utility)
			self.schedule.add(a)
			self.grid.place_agent(a, i[1:])
			self.agent_counter += 1

		# generate buildings structure	
		'''
		for i in range(0, 50):
			x = rnd.randint(20,300)
			y = rnd.randint(20,300)
			for j in range(0,rnd.randint(0,3)):
				for k in range(0, rnd.randint(0,10)):
					cell = [e for e in self.grid.get_cell_list_contents(tuple([x+j, y+k])) if isinstance(e, Cell)][0]
					cell.difficulty = "inf"
					cell.explored = -1
					cell.priority = 0
					cell.utility = "-inf"
					ag_count = out_grid["Cell"][tuple([x+j,y+k])][0]
					out_grid["Cell"][tuple([x+j,y+k])]= [ag_count, cell.pos, cell.difficulty, cell.explored, cell.priority, cell.utility]
		for i in range(0, 50):
			x = rnd.randint(20,300)
			y = rnd.randint(20,300)
			for j in range(0,rnd.randint(0,3)):
				for k in range(0, rnd.randint(0,10)):
					cell = [e for e in self.grid.get_cell_list_contents(tuple([x+k, y+j])) if isinstance(e, Cell)][0]
					cell.difficulty = "inf"
					cell.explored = -1
					cell.priority = 0
					cell.utility = "-inf"
					ag_count = out_grid["Cell"][tuple([x+k,y+j])][0]
					out_grid["Cell"][tuple([x+k,y+j])]= [ag_count, cell.pos, cell.difficulty, cell.explored, cell.priority, cell.utility]
		'''

		# create injured agents
		valid_coord = []
		for i in self.grid.coord_iter():
			cell = [e for e in self.grid.get_cell_list_contents(i[1:]) if isinstance(e, Cell)][0]
			if cell.explored == 0:
				valid_coord.append(cell.pos)
		for i in range(self.agent_counter, + self.agent_counter + self.ninjured):
			inj_index = rnd.choice(valid_coord)
			out_grid["Injured"][inj_index] = [i, inj_index]
			a = Injured(i, self, inj_index)
			self.schedule.add(a)
			self.grid.place_agent(a, inj_index)	
		with open('robot_exploration/maps/mymap.py', 'w') as f:
			f.writelines([str(out_grid), '\n'])

	def step(self):
		pass
Exemplo n.º 14
0
class Forest (Model): 
    def __init__ (self,  
                endophytism = True, ## allow endophyte life style in model run
                ws = 30, ## initial num of wood
                endodisp=2.0, ## dispersal of endos
                decompdisp=10.0, ## dispersal of decomps
                leafdisp = 4.0, ## how well do leaves disperse
                leaffall = 1, ## how frequently do leaves disperse
                numdecomp=1, ## initial number of decomposers
                numendo=1,   ## initial number of endos
                endoloss=0.05,   ## rate of loss of endophyte infect per step
                newwood = 15, ## total energy added in new logs each step
                woodfreq = 1, ## how often to put new logs onto the landscape 
                width = 100, ## grid dimensions, only one (squares only)
                kappa = 0.03, ## average rate of parent tree clusters per unit distance 
                sigma = 3.0, ## variance of child tree clusters, +/- spread of child clusters
                mu = 2.2, ## average rate of child tree clusters per unit distance 
                nuke = False, ## make landscape, but no agents
                ): 

        self.endophytism = endophytism 
        self.nwood = ws 
        self.endodisp = endodisp 
        self.decompdisp = decompdisp 
        self.leafdisp = leafdisp
        self.leaffall = leaffall 
        self.numdecomp = numdecomp 
        self.numendo = numendo 
        self.endoloss = endoloss 
        self.newwood = newwood 
        self.woodfreq = woodfreq
        self.schedule = RandomActivation(self) 
        self.grid = MultiGrid(width, width, torus = True)
        self.running = True
        self.width = width 
        self.kappa = kappa
        self.sigma = sigma
        self.mu = mu
        self.decompspor = 0 ## sporulation events this turn
        self.endospor = 0 ## sporulation events this turn
        self.datacollector = DataCollector(
            model_reporters={
                "Endophytes": sumendos,
                "Endo_subs": Endo_subs,
                "Decomposers": sumdecomps,
                "Decomp_subs": Decomp_subs,
                "Infected_trees": bluetrees,
                "decompspor_count": decompspor_count,
                "endospor_count": endospor_count,
                "Trees": tracktrees,
                })

        ## make initial agents:
        if not nuke: ## if not a nuclear holocaust where life is devoid
            self.make_trees()
            for i in range(self.nwood): self.add_wood() ## no make_woods method
            self.make_fungi()

    def make_trees(self):
        ## let's use our thomas process module
        tname = 1

        positions = tp.makepos(tp.ThomasPP(kappa = self.kappa, 
                                sigma=self.sigma, 
                                mu=self.mu, 
                                Dx=self.grid.width-1))
        for i in positions:
                try:
                    tree = Tree(tname, self, i, 
                                disp = self.leafdisp, 
                                leaffall = self.leaffall,
                                endoloss = self.endoloss,
                                infection = False)
                    self.schedule.add(tree) 
                    self.grid.place_agent(tree, i)
                    tname += 1
                except IndexError:
                    print ("Tree out-of-bounds, ipos=",i,"grid dim=", self.grid.width, self.grid.height)

    ## add initial wood to landscape
    def add_wood(self): 
        wname = len(self.getall(Wood)) + 1 
        x = random.randrange(self.grid.width)
        y = random.randrange(self.grid.height)
        pos = (x, y)
        ## wood already present? then just add to the pile
        if any([ type(i)==Wood for i in self.grid.get_cell_list_contents(pos) ]):
            for i in self.grid.get_cell_list_contents(pos):
                if type(i)==Wood: 
                    i.energy += random.randrange(self.newwood) ## 
        else:
            wood = Wood(wname, self, pos, energy = random.randrange(self.newwood)+1) ## 
            self.grid.place_agent(wood, (x,y))
            self.schedule.add(wood)
            wname += 1 

    ## non-initial, step addition of wood
    def cwd(self): 
        cwdlist = [round(random.randrange(self.newwood))+1] ## our first log of the step, at least 1 
        while sum(cwdlist) < round(self.newwood*.9)-1 : ## until we get at 90% of our assigned cwd...
            newlog=round(random.randrange(self.newwood-sum(cwdlist)))+1 ## new log, at least 1 kg
            cwdlist.append(newlog) ## put newlog on the list, until newwood reached)
        wname = len(self.getall(Wood)) + 1 
        for i in cwdlist:
            self.add_wood()

    def make_fungi(self):
        fname = len(self.getall(Fungus)) + 1 

        ## decomposers first:
        decomps=0
        while decomps < self.numdecomp:
            pos = self.findsubstrate(Wood)
            if any([ type(i)==Fungus for i in self.grid.get_cell_list_contents(pos) ]):
                pass 
            else:
                fungus = Fungus(fname, self, pos, energy=10, endocomp=False, disp = self.decompdisp)
                self.schedule.add(fungus) 
                self.grid.place_agent(fungus, pos)
                fname += 1; decomps += 1

        ## then endophytes:
        endos=0
        while endos < self.numendo:
            pos = self.findsubstrate(Wood)
            if any([ type(i)==Fungus for i in self.grid.get_cell_list_contents(pos) ]):
                pass
            else:
                fungus = Fungus(fname, self, pos, energy=10, endocomp=True, disp = self.endodisp)
                self.schedule.add(fungus) 
                self.grid.place_agent(fungus, pos)
                fname += 1; endos += 1


    def findsubstrate (self, substrate):
        Subs = self.getall(substrate)
        try:
            somestick = (random.choice(Subs).pos) ## pick from these, return position
            return(somestick) ## pick from these, return position
        except IndexError:
            print("no substrates")
            pass

    def selthin(self, intensity):
        ## intensity should be in the form of a percentage
        aa=self.getall(Tree)
        if intensity > 1 or intensity < 0:
                print("too intense! (or not intense enough)")
                pass
        else:
            bb=random.sample(aa, int(len(aa)*intensity))
            [ i.die() for i in bb ]




    def getall(self, typeof):
        if not any([ type(i)==typeof for i in self.schedule.agents ]):
            return([])
        else:
            istype = np.array([ type(i)==typeof for i in self.schedule.agents ])
            ags = np.array(self.schedule.agents)
            return list(ags[istype])


############### deforestation functions ###########

## forest fragmentation:

    def fragcenters(self,cens):
    ## cens=number of forest fragments
        centers=[]
        for i in range(cens):
            x=int(random.random()*self.width) ## self.width instead
            y=int(random.random()*self.width) ## self.width instead
            z=(x,y)
            centers.append(z)
        return(centers)


    def onefrag(self, center, ags, rad=10):
    ## center=center of fragment
    ## ags = list of trees
    ## rad = radius of fragment to be protected
        survivors = []
        for i in ags:
            distf=((center[0]-i.pos[0])**2 + (center[1]-i.pos[1])**2)**(1/2)
            if distf <= rad: survivors.append(i)
        return(survivors)

    def fragup(self, centers, rad):
        ## 1 - get trees
        alltrees = self.getall(Tree)
        ## 2 - get centers
        fcenters = self.fragcenters(centers)
        ## 3 - designate survivors
        remnants = []
        for i in fcenters:
            surv=self.onefrag(i, alltrees, rad)
            remnants.extend(surv)
        ## kill everything else
        cuttrees = set(alltrees) - set(remnants)
        for i in cuttrees: i.die()
        ## maybe useful for plotting, return the objects
        return({"alltrees":alltrees,
                "centers":fcenters,
                "remnants":remnants,
                "cuttrees":cuttrees,
                })

## Selective thinning:

    def selthin(self, intensity):
        ## intensity should be in the form of a percentage
        aa=self.getall(Tree)
        if intensity > 1:
                print("too intense!")
                pass
        else:
            bb=random.sample(aa, int(len(aa)*intensity))
        for i in bb: i.die() ## kill em
    ## plot data:
        return({"alltrees":aa,
                "centers":None,
                "remnants":self.getall(Tree),
                "cuttrees":bb,
                })

############################################################# 
## step


    def step(self): 
        if self.schedule.time % self.woodfreq ==  self.woodfreq - 1: ##  = delay from start
            self.cwd() ## add wood
        self.schedule.step() ## agents do their thing
        self.datacollector.collect(self) ## collect data
        self.decompspor = 0 ## reset sporulation event tally
        self.endospor = 0 ## reset sporulation event tally
Exemplo n.º 15
0
class SpeedModel(Model):
    """
    Model of the game "Spe_ed". This class controls the execution of the simulation.
    """
    def __init__(self,
                 width,
                 height,
                 nb_agents,
                 agent_classes,
                 initial_agents_params=None,
                 cells=None,
                 data_collector=None,
                 save=False):
        """
        Model-Initialization.
        :param width: Width of the field
        :param height: Height of the field
        :param nb_agents: Number of Agents
        :param agent_classes: List of classes of the agents that should be players in the game. The length has to be
        equal or greater than nb_agents
        :param initial_agents_params: A list of dictionaries containing initialization parameters for agents that should
        be initialized at the start of the simulation
        :param cells: A Spe_ed-cells like 2D-Array that initializes the field
        :param data_collector: Mesa data collector function
        :param save: whether or not track the games history
        """
        super().__init__()
        self.data_collector = data_collector
        self.width = width
        self.height = height
        self.nb_agents = nb_agents
        self.save = save
        if self.save:
            self.history = []
        if initial_agents_params is None:
            initial_agents_params = [{} for i in range(nb_agents)]
        else:
            initial_agents_params = copy.deepcopy(initial_agents_params)

        self.schedule = SimultaneousActivation(self)

        self.grid = MultiGrid(width, height, True)
        # width and height are swapped since height is rows and width is columns
        # an alternative to this representation would be to transpose cells everytime it is exposed
        # but that could be inefficient
        self.cells = np.zeros((height, width), dtype="int")

        # Init initial agents
        self.speed_agents = []
        self.active_speed_agents = []
        for i in range(nb_agents):
            agent_params = initial_agents_params[i]
            agent_params["model"] = self
            # set to random position/direction if no position/direction is given
            if "pos" not in agent_params:
                agent_params["pos"] = self.random.choice(
                    list(self.grid.empties))
            if "direction" not in agent_params:
                agent_params["direction"] = self.random.choice(list(Direction))

            agent = agent_classes[i](**agent_params)

            # don't add agent to grid/cells if its out of bounds. But add it to the scheduler.
            if self.grid.out_of_bounds(agent_params["pos"]):
                self.schedule.add(agent)
                self.speed_agents.append(agent)
            else:
                self.add_agent(agent)
                self.speed_agents.append(agent)
                self.active_speed_agents.append(agent)

        if cells is not None:
            self.init_cells_and_grid(cells)

    def init_cells_and_grid(self, cells):
        """
        Initializes Mesas Grid and the Model-cells the field with the information given in cells.
        :param cells: A Spe_ed-cells like 2D-Array that initializes the field
        :return: None
        """
        self.cells = np.array(cells)
        # add traces to grid
        for y in range(self.cells.shape[0]):
            for x in range(self.cells.shape[1]):
                # cell is occupied by a collision
                if self.cells[y, x] == -1:
                    agent = AgentTraceCollision(self, (x, y))
                    self.add_agent(agent)
                # cell is occupied by head or trace
                elif self.cells[y, x] != 0:
                    # head of the agent is not already a entry in self.grid
                    if len(self.grid.get_cell_list_contents((x, y))) == 0:
                        # add trace
                        agent = AgentTrace(
                            self, (x, y),
                            self.speed_agents[self.cells[y, x] -
                                              1])  # get agent based on id
                        self.add_agent(agent)

    def step(self):
        """
        Computes one iteration of the model.
        :return: None
        """
        if self.data_collector:
            self.data_collector.collect(self)
        if self.save:
            self.history.append(copy.deepcopy(model_to_json(self)))
        self.schedule.step()
        self.check_collisions()
        self.check_game_finished()

    def step_specific_agent(self, agent):
        """
        Only steps one specific agent. This is only for specific applications (e.g. Multi-Minimax).
        Don't use this method if not necessary since it doesn't increment all model parts (e.g. time).
        :param cells: The agent to step
        :return: None
        """
        agent.step()
        agent.advance()
        self.check_collisions()
        self.check_game_finished()

    def check_collisions(self):
        """
        Checks every active agent for collisions with traces or other agents. Colliding agents are eliminated.
        :return: None
        """
        agents_to_set_inactive = []
        for agent in self.speed_agents:
            for t in agent.trace:
                cell_contents = self.grid.get_cell_list_contents(t)
                if len(cell_contents) > 1:
                    if agent not in agents_to_set_inactive:
                        agents_to_set_inactive.append(agent)
                    self.add_agent(AgentTraceCollision(self, t))

        for agent in agents_to_set_inactive:
            agent.set_inactive()

    def check_game_finished(self):
        """
        Checks whether or not the game has finished (every agent is eliminated) and prints the result if finished.
        :return: None
        """
        if len(self.active_speed_agents) <= 1:
            self.running = False
            if self.save:
                self.history.append(copy.deepcopy(model_to_json(self)))
                path = os.path.abspath("") + "/res/simulatedGames/"
                for entry in self.history:
                    entry["cells"] = entry["cells"].tolist()
                with open(
                        path + datetime.datetime.now().strftime(
                            "%d-%m-%y__%H-%M-%S-%f") + ".json", "w") as f:
                    json.dump(self.history, f, indent=4)

    def add_agent(self, agent):
        """
        Adds an agent to the model.
        :param agent: The agent to add to the model
        :return: None
        """
        self.schedule.add(agent)
        self.grid.place_agent(agent, agent.pos)
        # swapped position args since cells has the format (height, width)
        pos = (agent.pos[1], agent.pos[0])
        if isinstance(agent, SpeedAgent):
            self.cells[pos] = agent.unique_id
        elif type(agent) is AgentTraceCollision:
            self.cells[pos] = -1
        elif type(agent) is AgentTrace:
            self.cells[pos] = agent.origin.unique_id

    def remove_agent(self, agent):
        """
        Removes an agent from the model.
        :param agent: The agent to remove from the model
        :return: None
        """
        if agent in self.schedule.agents:
            self.schedule.remove(agent)
            self.grid.remove_agent(agent)

    def get_agent_by_id(self, unique_id):
        """
        Returns an agent-object by its unique_id.
        :param unique_id: The agent id to search for
        :return: Agent or None if no match
        """
        for agent in self.speed_agents:
            if agent.unique_id == unique_id:
                return agent
        return None
Exemplo n.º 16
0
class SOBAModel(Model):
    def __init__(self,
                 width,
                 height,
                 modelWay=None,
                 seed=int(time()),
                 nothing=1,
                 voting_method=False):
        super().__init__(seed)
        #Init configurations and defines
        configuration.settings.init()
        configuration.defineOccupancy.init()
        configuration.defineMap.init()

        #Way of working
        if modelWay is None:
            self.modelWay = configuration.settings.model
        else:
            self.modelWay = modelWay

        #Mesa
        self.schedule = BaseScheduler(self)
        self.grid = MultiGrid(width, height, False)
        self.running = True

        #Control of time and energy
        self.energy = Energy()
        self.clock = Time()

        self.voting_method = voting_method
        self.sc = SocialChoice()

        #Log
        self.log = Log()
        if self.voting_method:
            self.log = Logsc()
        self.roomsSchedule = []
        self.agentSatisfationByStep = []
        self.fangerSatisfationByStep = []
        self.agentsActivityByTime = []
        self.averageSatisfationByTime = []
        self.totalSatisfationByTime = []
        self.occupantsValues = False
        if self.modelWay != 0 and os.path.isfile('../log/tmp/occupants.txt'):
            self.occupantsValues = self.log.getOccupantsValues()

        #Vars of control
        self.complete = False
        self.num_occupants = 0
        self.day = self.clock.day
        self.NStep = 0
        self.timeToSampling = 'init'  # Temperature ThermalLoads
        self.placeByStateByTypeAgent = {}
        self.lightsOn = []

        #Create the map
        self.createRooms()
        self.createThermalzones()
        self.setMap(width, height)
        self.createDoors()
        self.createWindows()
        self.createWalls()

        #Create agents
        self.setAgents()

    def consumeEnergy(self, appliance):
        if isinstance(appliance, PC):
            if appliance.state == 'on':
                self.energy.consumeEnergyAppliance('PC', appliance.consumeOn)
            elif appliance.state == 'standby':
                self.energy.consumeEnergyAppliance('PC',
                                                   appliance.consumeStandby)
            else:
                self.energy.consumeEnergyAppliance('PC', 0)

        elif isinstance(appliance, Light):
            if appliance.state == 'on':
                self.energy.consumeEnergyAppliance('Light', appliance.consume)
            else:
                self.energy.consumeEnergyAppliance('Light', 0)

        elif isinstance(appliance, HVAC):
            if appliance.state == 'on':
                self.energy.consumeEnergyAppliance('HVAC', appliance.consumeOn)
            else:
                self.energy.consumeEnergyAppliance('HVAC', 0)
        else:
            pass

    def isConected(self, pos):
        nextRoom = False
        for room in self.rooms:
            if room.pos == pos:
                nextRoom = room
        if nextRoom == False:
            return False
        for x in range(0, width):
            for y in range(0, height):
                self.pos_out_of_map.append(x, y)
        for room in self.rooms:
            self.pos_out_of_map.remove(room.pos)

    def createRooms(self):
        rooms = configuration.defineMap.rooms_json
        self.rooms = []
        #occupantsByTypeRoom = configuration.defineMap.NumberOccupancyByTypeRoom
        for room in rooms:
            newRoom = 0
            name = room['name']
            typeRoom = room['type']
            if typeRoom != 'out':
                conectedTo = room.get('conectedTo')
                nameThermalZone = room.get('thermalZone')
                entrance = room.get('entrance')
                measures = room['measures']
                dx = measures['dx']
                dy = measures['dy']
                dh = measures['dh']
                jsonWindows = room.get('windows')
                newRoom = Room(name, typeRoom, conectedTo, nameThermalZone, dx,
                               dy, dh, jsonWindows)
                newRoom.entrance = entrance
            else:
                newRoom = Room(name, typeRoom, None, False, 0, 0, 0, {})
                self.outBuilding = newRoom
            self.rooms.append(newRoom)
        for room1 in self.rooms:
            if room1.conectedTo is not None:
                for otherRooms in list(room1.conectedTo.values()):
                    for room2 in self.rooms:
                        if room2.name == otherRooms:
                            room1.roomsConected.append(room2)
                            room2.roomsConected.append(room1)
        for room in self.rooms:
            room.roomsConected = list(set(room.roomsConected))
        sameRoom = {}
        for room in self.rooms:
            if sameRoom.get(room.name.split(r".")[0]) is None:
                sameRoom[room.name.split(r".")[0]] = 1
            else:
                sameRoom[room.name.split(r".")
                         [0]] = sameRoom[room.name.split(r".")[0]] + 1

    def createThermalzones(self):
        self.thermalZones = []
        namesThermalZonesCreated = []
        for room1 in self.rooms:
            posibleThermalZone = room1.nameThermalZone
            if posibleThermalZone not in namesThermalZonesCreated and posibleThermalZone != False and posibleThermalZone is not None:
                namesThermalZonesCreated.append(posibleThermalZone)
                rooms = []
                for room2 in self.rooms:
                    if room2.nameThermalZone == posibleThermalZone:
                        rooms.append(room2)
                TZ = ThermalZone(self, posibleThermalZone, rooms)
                for room3 in TZ.rooms:
                    room3.thermalZone = TZ
                self.thermalZones.append(TZ)

        if self.modelWay == 2:
            hoursRoomsOnOffByDay = {}
            hoursRoomsOnStrings = self.log.getScheduleRooms()
            hoursRoomsOn = []
            for row in hoursRoomsOnStrings:
                hoursRoomsOn.append([row[0], float(row[1]), float(row[2])])
            for room in self.rooms:
                count = 0
                if room.typeRoom != 'out' and room.typeRoom != 'restroom':
                    hoursOneRoomOn = []
                    for row in hoursRoomsOn:
                        if row[0] == room.name:
                            hoursOneRoomOn.append([row[1], row[2]])
                    hoursOneRoomOnByDay = []
                    for i in range(0, 5):
                        hoursOneDay = []
                        for hour in hoursOneRoomOn:
                            if int(hour[0]) == i:
                                hoursOneDay.append(hour[1])
                        hoursOneRoomOnByDay.append(hoursOneDay)
                    hoursOnOffOneRoomByDay = []
                    for i in range(0, 5):
                        hoursOnOffOneRoomOneDay = []
                        hourOn = hoursOneRoomOnByDay[i]
                        if len(hourOn) > 0:
                            auxHour = hourOn[0]
                            hourOnAux = hourOn[0]
                            for hour in hourOn:
                                if (auxHour != hour):
                                    if (hour >
                                        (auxHour +
                                         configuration.settings.setOffWorthIt)
                                        ):
                                        hourOff = auxHour - 0.01
                                        pairOnOff = [
                                            int(hourOnAux * 100) / 100,
                                            int(hourOff * 100) / 100
                                        ]
                                        hoursOnOffOneRoomOneDay.append(
                                            pairOnOff)
                                        auxHour = hour + 0.01
                                        hourOnAux = hour
                                    else:
                                        auxHour = hour + 0.01
                                else:
                                    auxHour = auxHour + 0.01
                            pairOnOffObligatory = [hourOnAux, hourOn.pop()]
                            hoursOnOffOneRoomOneDay.append(pairOnOffObligatory)
                            hoursOnOffOneRoomByDay.append(
                                hoursOnOffOneRoomOneDay)
                        else:
                            hoursOnOffOneRoomByDay.append(False)
                    hoursRoomsOnOffByDay[room.name] = hoursOnOffOneRoomByDay
                    count = count + 1

            for tz in self.thermalZones:
                schedule = []
                for i in range(0, 5):
                    scheduleByDay = []
                    for room in tz.rooms:
                        hoursByDay = hoursRoomsOnOffByDay.get(room.name)
                        if hoursByDay is not None and hoursByDay != False:
                            hoursOneDay = hoursByDay[i]
                            if hoursOneDay is not None and hoursOneDay != False:
                                for hours in hoursOneDay:
                                    hourOn = hours[0]
                                    hourOff = hours[1]
                                    for pairHours in scheduleByDay:
                                        if hourOn > pairHours[0] and pairHours[
                                                1] > hourOn:
                                            scheduleByDay.remove(
                                                [pairHours[0], pairHours[1]])
                                            hourOn = pairHours[0]
                                            if (hourOff < pairHours[1]):
                                                hourOff = pairHours[1]
                                            else:
                                                pass
                                        elif hourOff > pairHours[
                                                0] and pairHours[1] > hourOff:
                                            scheduleByDay.remove(
                                                [pairHours[0], pairHours[1]])
                                            hourOff = pairHours[1]
                                            if (hourOn > pairHours[0]):
                                                hourOn = pairHours[0]
                                            else:
                                                pass
                                        elif hourOff > pairHours[
                                                1] and pairHours[0] > hourOn:
                                            scheduleByDay.remove(
                                                [pairHours[0], pairHours[1]])
                                    scheduleByDay.append([hourOn, hourOff])
                    if len(scheduleByDay) == 0:
                        scheduleByDay.append([False])
                    schedule.append(scheduleByDay)
                scheduleJoined = []
                for day in schedule:
                    if day != False:
                        scheduleJoined.append(sorted(day))

                for day in scheduleJoined:
                    i = 0
                    if day != False:
                        while (len(day) > (i + 1)):
                            if (day[i][1] +
                                    configuration.settings.setOffWorthIt
                                ) > day[i + 1][0]:
                                day[i][1] = day[i + 1][1]
                                day.pop(i + 1)
                            else:
                                i = i + 1
                tz.schedule = scheduleJoined

    def setMap(self, width, height):
        rooms_noPos = self.rooms
        rooms_using = []
        rooms_used = []
        for room in self.rooms:
            if room.entrance is not None:
                room.pos = (int(1), 2)
                rooms_using.append(room)
                rooms_used.append(room)
                rooms_noPos.remove(room)
                break
        while len(rooms_noPos) > 0:
            for roomC in rooms_using:
                xc, yc = roomC.pos
                rooms_conected = roomC.conectedTo
                rooms_using.remove(roomC)
                if rooms_conected is not None:
                    orientations = list(rooms_conected.keys())
                    for orientation in orientations:
                        if orientation == 'R':
                            for room in rooms_noPos:
                                if room.name == rooms_conected['R']:
                                    room.pos = (int(xc + 1), yc)
                                    rooms_noPos.remove(room)
                                    rooms_used.append(room)
                                    rooms_using.append(room)
                        elif orientation == 'U':
                            for room in rooms_noPos:
                                if room.name == rooms_conected['U']:
                                    room.pos = (xc, int(yc + 1))
                                    rooms_noPos.remove(room)
                                    rooms_used.append(room)
                                    rooms_using.append(room)
                        elif orientation == 'D':
                            for room in rooms_noPos:
                                if room.name == rooms_conected['D']:
                                    room.pos = (xc, int(yc - 1))
                                    rooms_noPos.remove(room)
                                    rooms_used.append(room)
                                    rooms_using.append(room)
                        elif orientation == 'L':
                            for room in rooms_noPos:
                                if room.name == rooms_conected['L']:
                                    room.pos = (int(xc - 1), yc)
                                    rooms_noPos.remove(room)
                                    rooms_used.append(room)
                                    rooms_using.append(room)
                else:
                    pass
        self.rooms = rooms_used

    def createDoors(self):
        self.doors = []
        for roomC in self.rooms:
            roomsConected = roomC.roomsConected
            for room in roomsConected:
                door_created = False
                same_corridor = False
                if room.name != roomC.name:
                    for door in self.doors:
                        if (door.room1.name == roomC.name
                                and door.room2.name == room.name) or (
                                    door.room2.name == roomC.name
                                    and door.room1.name == room.name):
                            door_created = True
                        if room.name.split(r".")[0] == roomC.name.split(
                                r".")[0]:
                            same_corridor = True
                    if door_created == False and same_corridor == False:
                        d = Door(roomC, room)
                        self.doors.append(d)
                        room.doors.append(d)
                        roomC.doors.append(d)

    def createWindows(self):
        for room in self.rooms:
            windows = []
            json = room.jsonWindows
            if json is None:
                pass
            else:
                for k in json:
                    window = Window(k, json[k]['l1'], json[k]['l2'])
                    windows.append(window)
            room.windows = windows

    def createWalls(self):
        for room in self.rooms:
            if room.typeRoom != 'out':
                walls = []
                innerWalls = []
                adjRooms = []
                xr, yr = room.pos
                roomA = self.getRoom((xr, yr + 1))
                if roomA != False:
                    if roomA.typeRoom != 'out':
                        if roomA.name.split(r".")[0] == room.name.split(
                                r".")[0]:
                            pass
                        else:
                            wall = Wall(room.dx, room.dh, room, roomA)
                            innerWalls.append(wall)
                            adjRooms.append(roomA)
                    else:
                        wall = Wall(room.dx, room.dh, orientation='N')
                        walls.append(wall)
                else:
                    wall = Wall(room.dx, room.dh, orientation='N')
                    walls.append(wall)
                roomB = self.getRoom((xr, yr - 1))
                if roomB != False:
                    if roomB.typeRoom != 'out':
                        if roomB.name.split(r".")[0] == room.name.split(
                                r".")[0]:
                            pass
                        else:
                            wall = Wall(room.dx, room.dh, room, roomB)
                            innerWalls.append(wall)
                            adjRooms.append(roomB)
                    else:
                        wall = Wall(room.dx, room.dh, orientation='S')
                        walls.append(wall)
                else:
                    wall = Wall(room.dx, room.dh, orientation='S')
                    walls.append(wall)
                roomC = self.getRoom((xr + 1, yr))
                if roomC != False:
                    if roomC.typeRoom != 'out':
                        if roomC.name.split(r".")[0] == room.name.split(
                                r".")[0]:
                            pass
                        else:
                            wall = Wall(room.dy, room.dh, room, roomC)
                            innerWalls.append(wall)
                            adjRooms.append(roomC)
                    else:
                        wall = Wall(room.dy, room.dh, orientation='E')
                        walls.append(wall)
                else:
                    wall = Wall(room.dy, room.dh, orientation='E')
                    walls.append(wall)
                roomD = self.getRoom((xr - 1, yr))
                if roomD != False:
                    if roomD.typeRoom != 'out':
                        if roomD.name.split(r".")[0] == room.name.split(
                                r".")[0]:
                            pass
                        else:
                            wall = Wall(room.dy, room.dh, room, roomD)
                            innerWalls.append(wall)
                            adjRooms.append(roomD)
                    else:
                        wall = Wall(room.dy, room.dh, orientation='W')
                        walls.append(wall)
                else:
                    wall = Wall(room.dy, room.dh, orientation='W')
                    walls.append(wall)
                room.walls = walls
                room.innerWalls = innerWalls
                room.roomsAdj = adjRooms

    def setAgents(self):
        # Identifications
        id_offset = 1000

        # Height and Width
        height = self.grid.height
        width = self.grid.width

        # CREATE AGENTS

        #Create Lightlights
        self.lights = []
        id_light = 0
        for room in self.rooms:
            if room.typeRoom != 'out' and room.light == False:
                light = Light(id_light, self, room)
                self.lights.append(light)
                id_light = id_light + 1
                room.light = light
                for room2 in self.rooms:
                    if room.name.split(r".")[0] == room2.name.split(r".")[0]:
                        room2.light = light

        id_hvac = id_light + id_offset
        #Create HVAC
        self.HVACs = []
        for thermalZone in self.thermalZones:
            restroom = False
            for room in thermalZone.rooms:
                if room.typeRoom == 'restroom':
                    restroom = True
            if restroom == False:
                hvac = HVAC(id_hvac, self, thermalZone)
                thermalZone.hvac = hvac
                self.HVACs.append(hvac)
                id_hvac = id_hvac + 1
            else:
                thermalZone.hvac = False

        #Create PC
        '''
		self.workplaces = []
		id_aux = 0
		for room in self.rooms:
			#for i in range(0, room.PCs):
			pc = PC(id_pc + id_aux, self, room)
			room.PCs.append(pc)
			self.workplaces.append(pc)
			id_aux = id_aux + 1
		'''
        id_occupant = id_hvac + id_offset
        id_pc = id_occupant + id_offset
        self.workplaces = []
        self.agents = []
        # Create occupants
        if self.modelWay == 0:
            countPC = 0
            print('Número de ocupantes: ',
                  configuration.defineOccupancy.occupancy_json[0]['N'])
            for n_type_occupants in configuration.defineOccupancy.occupancy_json:
                self.placeByStateByTypeAgent[
                    n_type_occupants['type']] = n_type_occupants['states']
                n_agents_perfect = int(
                    (n_type_occupants['N'] *
                     n_type_occupants['environment'][0]) / 100)
                for i in range(0, n_agents_perfect):
                    rooms_with_already_pc = []
                    a = Occupant(id_occupant, self, n_type_occupants, 1)
                    self.agents.append(a)
                    id_occupant = 1 + id_occupant
                    for state_use_PCs in n_type_occupants['PCs']:
                        roomPC = False
                        name_room_with_pc = a.positionByState[state_use_PCs]
                        for room in self.rooms:
                            if room.name.split(r".")[0] == name_room_with_pc:
                                roomPC = room
                        if roomPC != False and roomPC.typeRoom != 'out':
                            if roomPC not in rooms_with_already_pc:
                                pc = PC(id_pc, self, roomPC)
                                id_pc = id_pc + 1
                                pc.owner = a
                                self.workplaces.append(pc)
                                a.PCs[state_use_PCs] = pc
                                pc.states_when_is_used.append(state_use_PCs)
                                roomPC.PCs.append(pc)
                            else:
                                for pcaux in roomPC.PCs:
                                    if pcaux.owner == a:
                                        a.PCs[state_use_PCs] = pcaux
                                        pc.states_when_is_used.append(
                                            state_use_PCs)
                    self.schedule.add(a)
                    self.grid.place_agent(a, self.outBuilding.pos)
                    self.pushAgentRoom(a, self.outBuilding.pos)
                    self.num_occupants = self.num_occupants + 1
                n_agents_good = int((n_type_occupants['N'] *
                                     n_type_occupants['environment'][1]) / 100)
                for i in range(0, n_agents_good):
                    rooms_with_already_pc = []
                    a = Occupant(id_occupant, self, n_type_occupants, 2)
                    self.agents.append(a)
                    id_occupant = 1 + id_occupant
                    for state_use_PCs in n_type_occupants['PCs']:
                        roomPC = False
                        name_room_with_pc = a.positionByState[state_use_PCs]
                        for room in self.rooms:
                            if room.name.split(r".")[0] == name_room_with_pc:
                                roomPC = room
                        if roomPC != False and roomPC.typeRoom != 'out':
                            if roomPC not in rooms_with_already_pc:
                                pc = PC(id_pc, self, roomPC)
                                id_pc = id_pc + 1
                                pc.owner = a
                                self.workplaces.append(pc)
                                a.PCs[state_use_PCs] = pc
                                pc.states_when_is_used.append(state_use_PCs)
                                roomPC.PCs.append(pc)
                            else:
                                for pcaux in roomPC.PCs:
                                    if pcaux.owner == a:
                                        a.PCs[state_use_PCs] = pcaux
                                        pc.states_when_is_used.append(
                                            state_use_PCs)
                    self.schedule.add(a)
                    self.grid.place_agent(a, self.outBuilding.pos)
                    self.pushAgentRoom(a, self.outBuilding.pos)
                    self.num_occupants = self.num_occupants + 1
                n_agents_bad = int(n_type_occupants['N'] *
                                   n_type_occupants['environment'][2] / 100)
                allAgents = n_agents_perfect + n_agents_good + n_agents_bad
                if allAgents < n_type_occupants['N']:
                    n_agents_bad = n_type_occupants['N'] - (n_agents_perfect +
                                                            n_agents_good)
                for i in range(0, n_agents_bad):
                    rooms_with_already_pc = []
                    a = Occupant(id_occupant, self, n_type_occupants, 3)
                    self.agents.append(a)
                    id_occupant = 1 + id_occupant
                    for state_use_PCs in n_type_occupants['PCs']:
                        roomPC = False
                        name_room_with_pc = a.positionByState[state_use_PCs]
                        for room in self.rooms:
                            if room.name.split(r".")[0] == name_room_with_pc:
                                roomPC = room
                        if roomPC != False and roomPC.typeRoom != 'out':
                            if roomPC not in rooms_with_already_pc:
                                pc = PC(id_pc, self, roomPC)
                                id_pc = id_pc + 1
                                pc.owner = a
                                self.workplaces.append(pc)
                                a.PCs[state_use_PCs] = pc
                                pc.states_when_is_used.append(state_use_PCs)
                                roomPC.PCs.append(pc)
                            else:
                                for pcaux in roomPC.PCs:
                                    if pcaux.owner == a:
                                        a.PCs[state_use_PCs] = pcaux
                                        pc.states_when_is_used.append(
                                            state_use_PCs)
                    self.schedule.add(a)
                    self.grid.place_agent(a, self.outBuilding.pos)
                    self.pushAgentRoom(a, self.outBuilding.pos)
                    self.num_occupants = self.num_occupants + 1
        else:
            for n_type_occupants in configuration.defineOccupancy.occupancy_json:
                self.placeByStateByTypeAgent[
                    n_type_occupants['type']] = n_type_occupants['states']
                n_agents = n_type_occupants['N']
                for i in range(0, n_agents):
                    rooms_with_already_pc = []
                    a = Occupant(id_occupant, self, n_type_occupants, '')
                    self.agents.append(a)
                    id_occupant = 1 + id_occupant
                    for state_use_PCs in n_type_occupants['PCs']:
                        roomPC = False
                        name_room_with_pc = a.positionByState[state_use_PCs]
                        for room in self.rooms:
                            if room.name.split(r".")[0] == name_room_with_pc:
                                roomPC = room
                        if roomPC != False and roomPC.typeRoom != 'out':
                            if roomPC not in rooms_with_already_pc:
                                pc = PC(id_pc, self, roomPC)
                                id_pc = id_pc + 1
                                pc.owner = a
                                self.workplaces.append(pc)
                                a.PCs[state_use_PCs] = pc
                                pc.states_when_is_used.append(state_use_PCs)
                                roomPC.PCs.append(pc)
                            else:
                                for pcaux in roomPC.PCs:
                                    if pcaux.owner == a:
                                        a.PCs[state_use_PCs] = pcaux
                                        pc.states_when_is_used.append(
                                            state_use_PCs)
                    self.schedule.add(a)
                    self.grid.place_agent(a, self.outBuilding.pos)
                    self.pushAgentRoom(a, self.outBuilding.pos)
                    self.num_occupants = self.num_occupants + 1

        #Add to schedule
        for pc in self.workplaces:
            self.schedule.add(pc)
        for light in self.lights:
            self.schedule.add(light)
        for hvac in self.HVACs:
            self.schedule.add(hvac)

        self.schedule.add(self.clock)

    def getPosState(self, name, typeA):
        placeByStateByTypeAgent = self.placeByStateByTypeAgent
        n = 0
        for state in self.placeByStateByTypeAgent[typeA]:
            if state.get('name') == name:
                pos1 = state.get('position')
                if isinstance(pos1, dict):
                    for k, v in pos1.items():
                        if v > 0:
                            placeByStateByTypeAgent[typeA][n]['position'][
                                k] = v - 1
                            self.placeByStateByTypeAgent = placeByStateByTypeAgent
                            return k
                    return list(pos1.keys())[-1]
                else:
                    return pos1
            n = n + 1

    def thereIsClosedDoor(self, beforePos, nextPos):
        oldRoom = False
        newRoom = False
        for room in rooms:
            if room.pos == beforePos:
                oldRoom = room
            if room.pos == nextPos:
                newRoom = room
        for door in self.doors:
            if (door.room1.name == oldRoom.name and door.room2.name
                    == newRoom.name) or (door.room2.name == oldRoom.name
                                         and door.room1.name == newRoom.name):
                if door.state == False:
                    return True
        return False

    def thereIsPC(self, pos):
        x, y = pos
        for pc in self.workplaces:
            if pc.x == x and pc.y == y:
                return True
        return False

    def thereIsOccupant(self, pos):
        possible_occupant = self.grid.get_cell_list_contents([pos])
        if (len(possible_occupant) > 0):
            for occupant in possible_occupant:
                if isinstance(occupant, Occupant):
                    return True
        return False

    def ThereIsOtherOccupantInRoom(self, room, agent):
        for roomAux in self.rooms:
            possible_occupant = []
            if roomAux.name.split(r".")[0] == room.name.split(r".")[0]:
                possible_occupant = self.grid.get_cell_list_contents(
                    roomAux.pos)
            for occupant in possible_occupant:
                if isinstance(occupant, Occupant) and occupant != agent:
                    return True
        return False

    def ThereIsSomeOccupantInRoom(self, room):
        for roomAux in self.rooms:
            possible_occupant = []
            if roomAux.name.split(r".")[0] == room.name.split(r".")[0]:
                possible_occupant = self.grid.get_cell_list_contents(
                    roomAux.pos)
            for occupant in possible_occupant:
                if isinstance(occupant, Occupant):
                    return True
        return False

    def thereIsOccupantInRoom(self, room, agent):
        for roomAux in self.rooms:
            possible_occupant = []
            if roomAux.name.split(r".")[0] == room.name.split(r".")[0]:
                possible_occupant = self.grid.get_cell_list_contents(
                    roomAux.pos)
            for occupant in possible_occupant:
                if isinstance(occupant, Occupant) and occupant == agent:
                    return True
        return False

    def getRoom(self, pos):
        for room in self.rooms:
            if room.pos == pos:
                return room
        return False

    def pushAgentRoom(self, agent, pos):
        room = self.getRoom(pos)
        room.agentsInRoom.append(agent)

    def popAgentRoom(self, agent, pos):
        room = self.getRoom(pos)
        room.agentsInRoom.remove(agent)

    def getLightWithRoom(self, room):
        for light in self.lights:
            if light.room == room:
                return light
        return False

    def crossDoor(self, agent, room1, room2):
        numb = random.randint(0, 10)
        for door in self.doors:
            if ((door.room1 == room1 and door.room2 == room2)
                    or (door.room1 == room2 and door.room2 == room1)):
                if agent.leftClosedDoor >= numb:
                    door.state = False
                else:
                    door.state = True

    def getMatrix(self, agent):
        new_matrix = configuration.defineOccupancy.returnMatrix(
            agent, self.clock.clock)
        agent.markov_matrix = new_matrix

    def getTimeInState(self, agent):
        matrix_time_in_state = configuration.defineOccupancy.getTimeInState(
            agent, self.clock.clock)
        return matrix_time_in_state

    def end_work(self, agent, pc):
        change = configuration.defineOccupancy.environmentBehaviour(
            agent, self.clock.clock, 'pc')[int(agent.environment) - 1]
        print(change)
        if change == 'off':
            pc.turn_off()
        elif change == 'standby':
            pc.turn_standby()
        else:
            pass

    def switchLights(self, agent, currentRoom, nextRoom):
        change = configuration.defineOccupancy.environmentBehaviour(
            agent, self.clock.clock, 'light')[int(agent.environment) - 1]
        light_switch_on = nextRoom.light
        if light_switch_on != False and light_switch_on.state == 'off':
            light_switch_on.switch_on()
        if change == 'off':
            light_switch_off = currentRoom.light
            if self.ThereIsOtherOccupantInRoom(currentRoom, agent) == False:
                if light_switch_off != False:
                    light_switch_off.switch_off()
        else:
            pass

    def step(self):
        if (self.running == False):
            os.system("kill -9 %d" % (os.getppid()))
            os.killpg(os.getpgid(os.getppid()), signal.SIGTERM)

        if (self.clock.day == 5):
            self.energy.finalDay(self.NStep)
            self.energy.finalWeek()
            self.running = False
            if self.voting_method:
                self.log.collectEnergyValues(
                    self, self.energy.energyByDayTotal,
                    self.energy.energyByDayHVAC, self.energy.energyByDayLPC,
                    configuration.settings.time_by_step,
                    self.energy.energyByStepTotal,
                    self.energy.energyByStepHVACsTotal,
                    self.energy.energyByStepLPCTotal)
                self.log.collectComfortValues(
                    self, configuration.settings.time_by_step,
                    self.agentSatisfationByStep, self.fangerSatisfationByStep)
                self.log.collectScheduleValues(
                    self, configuration.settings.time_by_step,
                    self.agentsActivityByTime)
                self.log.collectSatisfactionValues(
                    self, configuration.settings.time_by_step,
                    self.totalSatisfationByTime, self.averageSatisfationByTime)
            else:
                self.log.collectEnergyValues(
                    self.modelWay, self.energy.energyByDayTotal,
                    self.energy.energyByDayHVAC, self.energy.energyByDayLPC,
                    configuration.settings.time_by_step,
                    self.energy.energyByStepTotal,
                    self.energy.energyByStepHVACsTotal,
                    self.energy.energyByStepLPCTotal)
                self.log.collectComfortValues(
                    self.modelWay, configuration.settings.time_by_step,
                    self.agentSatisfationByStep, self.fangerSatisfationByStep)
                self.log.collectScheduleValues(
                    self.modelWay, configuration.settings.time_by_step,
                    self.agentsActivityByTime)
                self.log.collectSatisfactionValues(
                    self.modelWay, configuration.settings.time_by_step,
                    self.totalSatisfationByTime, self.averageSatisfationByTime)
            if self.modelWay == 0:
                self.log.saveScheduleRooms(self.roomsSchedule)
                dictAgents = {}
                for agent in self.agents:
                    agent.scheduleLog.append(
                        [self.day, agent.arrive, agent.leave])
                    scheduleByDay = {}
                    for e in agent.scheduleLog:
                        d = 'day' + str(e[0])
                        scheduleByDay[d] = {'arrive': e[1], 'leave': e[2]}
                    posByState = {}
                    for k, v in agent.positionByState.items():
                        posByState[k] = v
                    dictAgents[str(agent.unique_id)] = {
                        'TComfort': agent.TComfort,
                        'posByState': posByState,
                        'schedule': scheduleByDay
                    }
                self.log.saveOccupantsValues(dictAgents)
            return

        if self.modelWay == 0 or self.modelWay == 1:
            for hvac in self.HVACs:
                if ((self.clock.clock >
                     (configuration.defineMap.ScheduleByTypeRoom.get(
                         hvac.thermalZone.rooms[0].typeRoom)[0]))
                        and (configuration.defineMap.ScheduleByTypeRoom.get(
                            hvac.thermalZone.rooms[0].typeRoom)[1] >
                             self.clock.clock)):
                    hvac.working = True
                else:
                    hvac.working = False
        elif self.modelWay == 2:
            for hvac in self.HVACs:
                for hours in hvac.thermalZone.schedule[self.clock.day]:
                    if hours != [False]:
                        if ((self.clock.getCorrectHour(
                                self.clock.clock +
                                configuration.settings.timeSetOnHVACBeforeGetT)
                             ) > hours[0]) and ((self.clock.getDownCorrectHour(
                                 hours[1] - configuration.settings.
                                 timeSetOffHVACBeforeloseT)) >
                                                self.clock.clock):
                            hvac.working = True
                        elif ((hvac.thermalZone.rooms[0].typeRoom == 'class')
                              and ((self.clock.getCorrectHour(
                                  self.clock.clock + configuration.settings.
                                  timeSetOnHVACBeforeGetTClass)) > hours[0])
                              and ((self.clock.getDownCorrectHour(
                                  hours[1] - configuration.settings.
                                  timeSetOffHVACBeforeloseT)) >
                                   self.clock.clock)):
                            hvac.working = True
                        else:
                            usr = False
                            if self.clock.getDownCorrectHour(
                                    hours[1]) > self.clock.clock:
                                for room in hvac.thermalZone.rooms:
                                    if self.ThereIsSomeOccupantInRoom(
                                            room) == True:
                                        usr = True
                            if usr == True:
                                hvac.working = True
                            else:
                                hvac.working = False
                    else:
                        hvac.working = False

        #Temperature in TZ
        if (self.timeToSampling == 'init'):
            for tz in self.thermalZones:
                tz.getQ(self, configuration.settings.timeToSampling)
            self.timeToSampling = configuration.settings.timeToSampling * (
                1 / configuration.settings.time_by_step)
        elif (self.timeToSampling > 1):
            self.timeToSampling = self.timeToSampling - 1
        else:
            for tz in self.thermalZones:
                tz.step()
                tz.getQ(self, configuration.settings.timeToSampling)
            self.timeToSampling = configuration.settings.timeToSampling * (
                1 / configuration.settings.time_by_step)

        self.schedule.step()

        #Rooms occupancy
        time = self.clock.clock
        day = self.clock.day
        for room in self.rooms:
            if len(
                    room.agentsInRoom
            ) > 0 and room.typeRoom != 'out' and room.typeRoom != 'restRoom':
                self.roomsSchedule.append([room.name, day, time])

        #Satisfation collection
        time = configuration.settings.time_by_step * self.NStep
        sumat = 0
        number = 0
        for agent in self.agents:
            if self.getRoom(agent.pos).typeRoom != 'out' and self.getRoom(
                    agent.pos).typeRoom != 'restroom' and self.getRoom(
                        agent.pos).typeRoom != 'hall' and self.getRoom(
                            agent.pos).typeRoom != 'corridor':
                sumat = sumat + agent.comfort
                number = number + 1
        if number > 0:
            self.agentSatisfationByStep.append(sumat / number)
        else:
            self.agentSatisfationByStep.append(0)

        sumat = 0
        number = 0
        for hvac in self.HVACs:
            varaux = False
            for room in hvac.thermalZone.rooms:
                if self.ThereIsSomeOccupantInRoom(
                        room
                ) and room.typeRoom != 'out' and room.typeRoom != 'restroom' and room.typeRoom != 'corridor' and room.typeRoom != 'hall':
                    varaux = True
            if varaux == True:
                sumat = sumat + hvac.fangerValue
                number = number + 1
        if number > 0:
            self.fangerSatisfationByStep.append(sumat / number)
        else:
            self.fangerSatisfationByStep.append(0)

        # Satisfaction SC
        if self.voting_method:
            time = configuration.settings.time_by_step * self.NStep
            sumat = 0
            number = 0
            for agent in self.agents:
                if self.getRoom(agent.pos).typeRoom != 'out' and self.getRoom(
                        agent.pos).typeRoom != 'restroom' and self.getRoom(
                            agent.pos).typeRoom != 'hall' and self.getRoom(
                                agent.pos).typeRoom != 'corridor':
                    sumat += agent.preference['{:.1f}'.format(
                        self.getRoom(
                            agent.pos).thermalZone.hvac.desiredTemperature)]
                    number += 1

            self.totalSatisfationByTime.append(sumat)

            if number > 0:
                self.averageSatisfationByTime.append(sumat / number)
            else:
                self.averageSatisfationByTime.append(0)

        #Ocupancy activity collection
        time = configuration.settings.time_by_step * self.NStep
        sumat = 0
        number = 0
        for agent in self.agents:
            if (agent.state == 'working in my office') or (
                    agent.state == 'in a meeting') or (
                        agent.state
                        == 'working in my laboratory') or (agent.state
                                                           == 'giving class'):
                sumat = sumat + 1
        self.agentsActivityByTime.append(sumat)

        if len(self.lightsOn) > 0 and (self.clock.clock >
                                       configuration.settings.offLights):
            for light in self.lightsOn:
                light.switch_off()

        self.energy.finalStep()
        if (self.clock.day > self.day):
            self.energy.finalDay(self.NStep)
            if self.modelWay == 0:
                for agent in self.agents:
                    timeA = self.clock.getDownCorrectHour(agent.arrive - 0.10)
                    timeB = self.clock.getDownCorrectHour(agent.leave - 0.10)
                    agent.scheduleLog.append([self.day, timeA, timeB])
                    agent.arrive = False
                    agent.leave = False
            if self.occupantsValues != False:
                for agent in self.agents:
                    day = 'day' + str(self.day + 1)
                    agent.behaviour['arriveTime'] = self.occupantsValues[str(
                        agent.unique_id)]['schedule'][day]['arrive']
                    agent.behaviour['leaveWorkTime'] = self.occupantsValues[
                        str(agent.unique_id)]['schedule'][day]['leave']
            self.day = self.day + 1
        self.NStep = self.NStep + 1
Exemplo n.º 17
0
class MesaTraitsModel(Model):
    '''
    TODO: add new description here
    '''

    height = 20
    width = 20

    no_of_species = 4
    no_of_seeds = 1

    verbose = False  # Print-monitoring

    description = 'A model for creating patch expansion out of a few patches.'

    def __init__(self,
                 height=60,
                 width=60,
                 no_of_species=4,
                 no_of_seeds=2,
                 no_of_agents=20):
        '''
        Create a new MesaTraitsModel.

        Args:

        '''
        super().__init__()
        # Set parameters
        self.height = height
        self.width = width
        self.no_of_agents = no_of_agents

        self.schedule = RandomActivationByBreed(self)
        self.grid = MultiGrid(self.height, self.width, torus=True)
        self.no_of_species = no_of_species
        self.no_of_seeds = no_of_seeds
        self.patch_manager = PatchManager()

        self.datacollector = DataCollector(
            {"Organisms": lambda m: m.schedule.get_breed_count(Organism)})
        # Create patches
        for agent, x, y in self.grid.coord_iter():
            #print("new patch added")
            grown = False

            patch = Patch(self.next_id(), (x, y), self, 0.04, None, grown)
            self.grid.place_agent(patch, (x, y))
            self.schedule.add(patch)
            self.patch_manager.add_patch(patch)

        list_of_cells = []
        #select some random patches (without substitution)
        total_seeds = no_of_species * no_of_seeds
        for i in range(self.width):
            for j in range(self.height):
                list_of_cells.append((i, j))

        cords = random.sample(list_of_cells, total_seeds)

        #choose agents at those patches to be assigned the species
        _ = 0
        for i in range(no_of_species):
            for j in range(no_of_seeds):
                patch = self.grid.get_cell_list_contents(cords[_])
                patch[0].grown = True
                patch[0].species = i
                self.patch_manager.remove_patch(patch[0])
                _ += 1

        #make the patch grow
        self.patch_manager.grow_patches()

        # make moving agents
        for i in range(20):  #20 agents
            x = random.choice(range(self.width))
            y = random.choice(range(self.height))
            agent = Organism(self.next_id(), (x, y),
                             self,
                             energy_tank=100,
                             current_energy=50,
                             metabolic_cost=1,
                             energy_gain_per_patch=5,
                             age=5,
                             sexual=False,
                             maturity_age=20,
                             max_longevity=1000,
                             patch_affinity=[1, 1, 0, 0],
                             climatic_affinity=0.6,
                             climatic_affinity_sd=0.05,
                             line_of_sight=1,
                             dispersal_speed=2,
                             reproductive_delay=0,
                             offspring_number=1,
                             moore=True)
            self.grid.place_agent(agent, (x, y))
            self.schedule.add(agent)

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

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

    def run_model(self, step_count=200):

        if self.verbose:
            pass

        for i in range(step_count):
            self.step()

        if self.verbose:
            pass
Exemplo n.º 18
0
class TumorModel(Model):
    def __init__(self, width, height,
            initial_tumor_size=2,
            first_cycle_offset=80,
            treatment_cycles=30,
            treatment_cycle_interval=4,
            param_scale=1.0,
            kde=0.02, 
            proliferative_growth_rate=0.121,
            proliferative_to_quiescent_rate=0.03,
            proliferative_elimination_rate=0.7,
            quiescent_to_damaged_rate=0.7,
            damaged_to_proliferative_rate=0.003,
            damaged_elimination_rate=0.008):
        self.initial_tumor_size = initial_tumor_size
        self.first_cycle_offset = first_cycle_offset
        self.treatment_cycles = treatment_cycles
        self.treatment_cycle_interval = treatment_cycle_interval
        self.dissolve_rate = (1 - kde)
        self.proliferative_growth_rate = proliferative_growth_rate * param_scale
        self.proliferative_elimination_rate = proliferative_elimination_rate * param_scale
        self.proliferative_to_quiescent_rate = proliferative_to_quiescent_rate * param_scale
        self.quiescent_to_damaged_rate = quiescent_to_damaged_rate * param_scale
        self.damaged_to_proliferative_rate = damaged_to_proliferative_rate * param_scale
        self.damaged_elimination_rate = damaged_elimination_rate * param_scale
        super().__init__()
        self.grid = MultiGrid(width, height, torus=False)
        self.schedule = RandomActivation(self)
        self.running = True
        self.step_number = 0
        self.tumor_cells_count = initial_tumor_size ** 2

        # Calculate tumor area coordinates
        x1 = self.grid.width // 2 - self.initial_tumor_size // 2
        x2 = x1 + self.initial_tumor_size - 1
        y1 = self.grid.height // 2 - self.initial_tumor_size // 2
        y2 = y1 + self.initial_tumor_size - 1

        # Create agents
        for x in range(self.grid.width):
            for y in range(self.grid.height):
                # uncomment to place a proliferative cell on the center
                if x in range(x1, x2 + 1) and y in range(y1, y2 + 1):
                    if x == x1 or x == x2 or y == y1 or y == y2:
                        a = ProliferativeCellAgent(y * width + x, self, 0)
                    else:
                        a = QuiescentCellAgent(y * width + x, self, 0)
                else:
                    a = CellAgent(y * width + x, self, 0)
                self.schedule.add(a)
                self.grid.place_agent(a, (x, y))

        self.datacollector = DataCollector(
            agent_reporters={"C": "C"},
            model_reporters={"MTD": compute_MTD})

    def step(self):
        if self.step_number >= self.first_cycle_offset and \
                self.treatment_cycles > 0 and \
                (self.step_number - self.first_cycle_offset) % \
                self.treatment_cycle_interval == 0:
            self.treatment_cycles -= 1
            for x in range(self.grid.width):
                for y in range(self.grid.height):
                    cell = self.grid.get_cell_list_contents([(x,y)])[0]
                    if cell.pos[0] == 0 or \
                       cell.pos[1] == 0 or \
                       cell.pos[0] == self.grid.width - 1 or \
                       cell.pos[1] == self.grid.height - 1:
                            cell.C = 1
        self.tumor_cells_count = tumor_cells_count(self)
        self.datacollector.collect(self)
        self.schedule.step()
        self.step_number += 1
Exemplo n.º 19
0
class Model(Model):
    """A model with a number of agents.
    It represents a space where you can experiment by varying parameters"""

    def __init__(self, n_victims, n_offenders, n_criminal_generators, r_criminal_generators, max_cp,
                 pop_count, width, height):

        self.grid = MultiGrid(width, height, torus=False)
        self.schedule = RandomActivation(self)
        self.datacollector = DataCollector(
            model_reporters={"Average Perception of Safety": average_perception_of_safety,
                             "Crime-rate": crime_rate_single_run},
        )
        self.width = width
        self.height = height
        self.running = True

        # Number of crimes committed per time step.
        self.crime_number = 0.0


        # User settable parameters
        self.num_victims = n_victims
        self.num_offenders = n_offenders
        self.num_crime_areas = n_criminal_generators
        self.crime_area_rad = r_criminal_generators
        self.hotspot_rad = 1
        self.max_criminal_preference = max_cp
        self.pop_count = pop_count

        # add light agents to the grid
        self.light_layer()

        # add possible victims to the grid
        self.add_victims()

        # add possible offenders to the grid
        self.add_offenders()

        # add crime areas
        self.add_criminal_areas()

        self.datacollector.collect(self)

    def light_layer(self):
        """Add the light layer to the model. """
        for i in range(self.width):
            for j in range(self.height):
                l = Light(uuid.uuid4(), i + j, self)
                self.schedule.add(l)
                # light is ordered from darkest to lightest from the
                # bottom left corner to the top right corner.
                self.grid.place_agent(l, (i, j))

                # light is randomised, so long as the
                # luminance difference of surrounding cells is within a limit
                # self.grid.place_agent(l, self.r_pos(l))

    def r_pos(self, new_l):
        """Randomises the positions of the light realistically by considering the difference
        between the illuminance in one position and another"""

        # Position precisely one light agent per position.
        valid = False

        while not valid:
            x = self.random.randrange(self.width)
            y = self.random.randrange(self.height)

            # Check if there is already a light agent in this spot
            if not (any(isinstance(agent, Light)
                        for agent in self.grid.get_cell_list_contents((x, y)))):
                # Check whether given the difference in the influencing factors between the agent
                # and surrounding agents, the new agent can be placed in this position.
                # Returns True or False
                if self.valid_pos((x, y), new_l, 1):
                    valid = True
                    return x, y

    def valid_pos(self, n_pos, new_a, delta):
        """Check whether this position is a valid position given the difference in
        the inlfueincing factors between the new agent and the surrounding agents"""

        # Get the surrounding positions
        neighborhood = self.grid.get_neighborhood(n_pos, moore=True,
                                                  include_center=False)


        # Get the surrounding positions containing light agents.
        cell_contents = []
        for pos in neighborhood:
            cell_contents.append(self.grid.get_cell_list_contents([pos]))

        f_cell_contents = [val for sublist in cell_contents for val in sublist]

        surr_light = [a for a in f_cell_contents if isinstance(a, Light)]

        # If the surrounding light list is empty, return the position
        if len(surr_light) == 0:
            return True
        else:
            # Check whether the difference in illuminance is within the valid scope
            for l in surr_light:

                if abs(l.illuminance - new_a.illuminance) >= delta:
                    return False

        return True

    def get_random_pos(self):
        x = self.random.randrange(self.grid.width)
        y = self.random.randrange(self.grid.height)
        return (x, y)

    def add_victims(self):
        for i in range(self.num_victims):
            # Generate a safe location for this agent.
            s = SafeLocation(uuid.uuid4(), self)
            self.schedule.add(s)
            self.grid.place_agent(s, self.get_random_pos())

            # Generate the agent given its safe location.
            p = PossibleVictim(uuid.uuid4(), self, s)
            self.schedule.add(p)
            self.grid.place_agent(p, self.get_random_pos())

    def add_offenders(self):
        for i in range(self.num_offenders):
            c = PossibleOffender(uuid.uuid4(), self, self.max_criminal_preference)
            self.schedule.add(c)
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            self.grid.place_agent(c, (x, y))

    def generate_criminal_areas(self):
        """ Return a list of criminal areas with specified centroids and radius.
            If criminal areas overlap, update the criminal areas.

            DOES NOT ADD THE AREAS TO THE MODEL, AS IT IS ONLY THE POSITIONS
            WITHIN THE AREAS THAT ARE ADDED TO THE MODEL. """

        # ----- HELPER FUNCTION -----

        def generate_centroid_list(n):
            """ If no centroids have been passed,
            generate random centroids for the criminal areas. """
            centroids = []
            for i in range(n):
                x = self.random.randrange(self.grid.width)
                y = self.random.randrange(self.grid.height)
                centroids.append((x, y))
            return centroids

        def get_surr_pos(pos, r=3):
            return self.grid.get_neighborhood(pos, moore=True, include_center=True, radius=r)

        # ---------------------------
        centroids = self.num_crime_areas
        radius = self.crime_area_rad

        # If the parameter passed as the centroid is an int, generate this number of centroids.
        if isinstance(centroids, int):
            centroids = generate_centroid_list(centroids)

        criminal_area = []
        # For every centroid in the list, create either a hotspot or a criminal area depending
        # on the type.
        for c in centroids:
            criminal_area.append(CrimeGenerator(uuid.uuid4(), self, c, radius))

        # Return a list of criminal areas.
        return criminal_area

    def add_criminal_areas(self, criminal_area=None):
        """Add crime areas to the model. """
        # If no criminal area has been passed, generate random criminal area.
        if criminal_area is None:
            criminal_area = self.generate_criminal_areas()

    def increment_crimes(self):
        self.crime_number += 1
        global crime_number
        crime_number += 1

    def check_victim_agents(self):
        if not [agent for agent in self.schedule.agents if
                isinstance(agent, PossibleVictim)]:
            self.running = False

    def step(self):
        """Advance the model by one step."""
        self.schedule.step()
        self.datacollector.collect(self)
        self.check_victim_agents()
        self.crime_number = 0
Exemplo n.º 20
0
class Modelo(Model):
    """
    A model with some number of ants and data.
    """
    m = 5
    ants = 1
    data = pd.DataFrame()
    grid_clusters = {}
    lista_bordas = list()

    def __init__(self, ants=1000, grid_size=5, data=pd.DataFrame()):
        super().__init__()
        #self.running = True
        self.ants = ants
        self.m = grid_size
        self.v = False
        self.grid = MultiGrid(int(self.m), int(self.m), True)
        self.schedule = RandomActivation(self)
        self.verbose = False  # Print-monitoring
        self.data = data

        # Create ants
        for i in range(self.ants):
            # Add the agent ant to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            while len(self.grid.get_cell_list_contents((x, y))) != 0:
                x = self.random.randrange(self.grid.width)
                y = self.random.randrange(self.grid.height)
                print("re-posicionando")
            a = AntAgent("ant_" + str(i), (x, y), self)
            self.schedule.add(a)
            self.grid.place_agent(a, (x, y))

        # Create data
        for i in self.data.index:
            # Add the agent ant to a random grid cell
            x = self.random.randrange(self.grid.width)
            y = self.random.randrange(self.grid.height)
            while len(self.grid.get_cell_list_contents((x, y))) != 0:
                x = self.random.randrange(self.grid.width)
                y = self.random.randrange(self.grid.height)
                print("re-posicionando")
            d = DataAgent(i, (x, y), self)
            self.schedule.add(d)
            self.grid.place_agent(d, (x, y))

    def step(self):
        #print(self.data)
        if (self.schedule.steps == 500 or self.schedule.steps == 1000
                or self.schedule.steps == 1500 or self.schedule.steps == 2000
                or self.schedule.steps == 2500 or self.schedule.steps == 3000
                or self.schedule.steps == 3500 or self.schedule.steps == 4000
                or self.schedule.steps == 4500 or self.schedule.steps == 5000):
            self.validar_clusters()
        if (self.schedule.steps == 510 or self.schedule.steps == 1010
                or self.schedule.steps == 1510 or self.schedule.steps == 2010
                or self.schedule.steps == 2510 or self.schedule.steps == 3010
                or self.schedule.steps == 3510 or self.schedule.steps == 4010
                or self.schedule.steps == 4510 or self.schedule.steps == 5010):
            self.remover_bordas()
        self.schedule.step()

    def validar_clusters(self):
        #print(self.grid.grid)
        x = list()
        y = list()
        ids = list()
        #classes= list()

        for l in self.grid.grid:
            for c in l:
                for agent in c:
                    #print ("{} - {}".format(agent.unique_id, agent.pos))
                    if "data_" in agent.unique_id:
                        #coloca o dado no data frame
                        x_pos, y_pos = agent.pos
                        ids.append(agent)
                        x.append(x_pos)
                        y.append(y_pos)

        positions = np.column_stack((x, y))
        clustering = DBSCAN(eps=2, min_samples=3).fit(positions)

        self.grid_clusters = {}
        self.avaliar_clusters(clustering.labels_, ids)
        self.apresentar_clusters()
        self.definir_bordas()

    def avaliar_clusters(self, indicacoes, agentes):
        for i in range(len(indicacoes)):
            #print("{} - {}".format(agentes[i], indicacoes[i]))
            if indicacoes[i] == -1:
                continue
            if indicacoes[i] in self.grid_clusters.keys():
                cluster = self.grid_clusters.get(indicacoes[i])
                cluster.append(agentes[i])
                self.grid_clusters.update({indicacoes[i]: cluster})
            else:
                cluster = list()
                cluster.append(agentes[i])
                self.grid_clusters.update({indicacoes[i]: cluster})

        classes = list(self.data['class'].unique())

        for numero_cluster in self.grid_clusters.keys():
            cluster = self.grid_clusters.get(numero_cluster)
            indices = list()
            for a in self.grid_clusters.get(numero_cluster):
                indices.append(a.index_df)

            dados = self.data.loc[indices, :]
            gini = self.gini_index(dados, classes)
            self.grid_clusters.update(
                {numero_cluster: {
                    'agentes': cluster,
                    'gini': gini
                }})

    def definir_bordas(self):
        for k in self.grid_clusters.keys():
            #print("Cluster {}:".format(k))
            #indices = list()
            for a in self.grid_clusters.get(k)['agentes']:
                #print(self.grid.get_neighbors(a.pos, True))
                x, y = a.pos

                if (x + 1 >= self.grid.width):
                    xp1 = 0
                else:
                    xp1 = x + 1

                if (x - 1 < 0):
                    xm1 = self.grid.width - 1
                else:
                    xm1 = x - 1

                if (y + 1 >= self.grid.width):
                    yp1 = 0
                else:
                    yp1 = y + 1

                if (y - 1 < 0):
                    ym1 = self.grid.width - 1
                else:
                    ym1 = y - 1

                # x + 1
                if (not self.tem_dado((xp1, y))):
                    self.add_borda((xp1, y))
                # x - 1
                if (not self.tem_dado((xm1, y))):
                    self.add_borda((xm1, y))
                # y + 1
                if (not self.tem_dado((x, yp1))):
                    self.add_borda((x, yp1))
                # y - 1
                if (not self.tem_dado((x, ym1))):
                    self.add_borda((x, ym1))
                # x - 1 y - 1
                if (not self.tem_dado((xm1, ym1))):
                    self.add_borda((xm1, ym1))
                # x - 1 y + 1
                if (not self.tem_dado((xm1, yp1))):
                    self.add_borda((xm1, yp1))
                # x + 1 y - 1
                if (not self.tem_dado((xp1, ym1))):
                    self.add_borda((xp1, ym1))
                # x + 1 y + 1
                if (not self.tem_dado((xp1, yp1))):
                    self.add_borda((xp1, yp1))

    def gini_index(self, dados, classes):
        # quantidade de elementos no cluster
        n_instances = len(dados)
        # calculo do indice de gini
        gini = 0.0
        score = 0.0
        # indice do grupo, analisando o indice para cada classe
        for classe in classes:
            saida = dados['class'].value_counts()
            if hasattr(saida, classe):
                p = saida.loc[classe] / n_instances
            else:
                p = 0
            score += p * p
        # ponderando o indice pelo tamenho do grupo
        gini += (1.0 - score)
        return gini

    def apresentar_clusters(self):
        with open('log_aca.txt', 'a') as f:
            print("Step: {}".format(self.schedule.steps), file=f)
            for k in self.grid_clusters.keys():
                print("Cluster {}:".format(k), file=f)
                indices = list()
                for a in self.grid_clusters.get(k)['agentes']:
                    indices.append(a.index_df)
                dados = self.data.loc[indices, :]
                print("Dados no cluster:", file=f)
                print(dados['class'].value_counts(), file=f)
                print("Gini index: {}".format(
                    self.grid_clusters.get(k)['gini']),
                      file=f)
                print("", file=f)

    def tem_dado(self, posicao):
        ocupantes = self.grid.get_cell_list_contents(posicao)
        for o in ocupantes:
            if (isinstance(o, DataAgent) or isinstance(o, BordaAgent)):
                return True
        return False

    def add_borda(self, posicao):
        a = BordaAgent("borda", posicao, self)
        self.schedule.add(a)
        self.lista_bordas.append(a)
        self.grid.place_agent(a, (posicao))

    def remover_bordas(self):
        print("removendo")
        for o in self.lista_bordas:
            if (isinstance(o, BordaAgent)):
                print("borda")
                self.grid.remove_agent(o)
        self.lista_bordas = list()
Exemplo n.º 21
0
class WolfSheep(Model):
    """
    Wolf-Sheep Predation Model
    """
    height = 20
    width = 20

    initial_sheep = 100
    initial_wolves = 50

    sheep_reproduce = 0.04
    wolf_reproduce = 0.05

    wolf_gain_from_food = 20

    grass = False
    grass_regrowth_time = 30
    sheep_gain_from_food = 4

    grass_presence_probability = 1.0

    moore = True

    description = (
        "A model for simulating wolf and sheep (predator-prey) ecosystem modelling."
    )

    def __init__(
            self,
            height=20,
            width=20,
            initial_sheep=100,
            initial_wolves=50,
            sheep_reproduce=0.04,
            wolf_reproduce=0.05,
            wolf_gain_from_food=20,
            grass=False,
            grass_regrowth_time=30,
            sheep_gain_from_food=4,
            initial_energy=10,
            moore=True,
    ):
        """
        Create a new Wolf-Sheep model with the given parameters.

        Args:
            initial_sheep: Number of sheep to start with
            initial_wolves: Number of wolves to start with
            sheep_reproduce: Probability of each sheep reproducing each step
            wolf_reproduce: Probability of each wolf reproducing each step
            wolf_gain_from_food: Energy a wolf gains from eating a sheep
            grass: Whether to have the sheep eat grass for energy
            grass_regrowth_time: How long it takes for a grass patch to regrow
                                 once it is eaten
            sheep_gain_from_food: Energy sheep gain from grass, if enabled.
        """
        super().__init__()
        # Set parameters
        self.height = height
        self.width = width
        self.initial_sheep = initial_sheep
        self.initial_wolves = initial_wolves
        self.sheep_reproduce = sheep_reproduce
        self.wolf_reproduce = wolf_reproduce
        self.wolf_gain_from_food = wolf_gain_from_food
        self.grass = grass
        self.grass_regrowth_time = grass_regrowth_time
        self.sheep_gain_from_food = sheep_gain_from_food
        self.initial_energy = initial_energy

        self.schedule = RandomActivationByBreed(self)
        self.grid = MultiGrid(self.height, self.width, torus=True)
        self.counter = 0
        self.moore = moore
        self.datacollector = DataCollector(
            {
                "Wolves": lambda m: m.schedule.get_breed_count(Wolf),
                "Sheep": lambda m: m.schedule.get_breed_count(Sheep),
            }
        )

        # Create sheep:
        for _ in range(initial_sheep):
            initial_position = (random.randint(0, height - 1), random.randint(0, width - 1))

            # Incrementing counter
            self.counter += 1

            # Creating sheep agent
            sheep_agent = Sheep(self.counter, initial_position, self, moore, initial_energy)

            # Adding sheep agent
            self.schedule.add(sheep_agent)

            # Placing agent
            self.grid.place_agent(sheep_agent, initial_position)

        # Create wolves
        for _ in range(initial_wolves):
            # Defining initial position
            initial_position = (random.randint(0, height - 1), random.randint(0, width - 1))

            # Incrementing counter
            self.counter += 1

            # Creating wolf agent
            wolf_agent = Wolf(self.counter, initial_position, self, moore, initial_energy)

            # Adding agent
            self.schedule.add(wolf_agent)

            # Placing agent
            self.grid.place_agent(wolf_agent, initial_position)

        # Create grass patches
        for grid_height in range(height):
            for grid_width in range(width):
                # Incrementing counter
                self.counter += 1

                # Creating GrassPatch agent
                grass_patch_agent = GrassPatch(
                    self.counter,
                    self,
                    True,
                    self.grass_regrowth_time
                )

                # Adding agent
                self.schedule.add(grass_patch_agent)

                # Placing agent
                self.grid.place_agent(grass_patch_agent, (grid_height, grid_width))

    def get_agents_at_position(self, position: tuple):
        """
        Returns all the agents located at a specific location
        """
        return self.grid.get_cell_list_contents([position])

    def get_grass_patch_to_eat_at_position(self, position: tuple) -> Union[GrassPatch, None]:
        """
        This function returns a GrassPatch agent if and only if this agent is eatable
        """
        grass_patch = None
        agents = self.get_agents_at_position(position)

        for agent in agents:
            if type(agent) == GrassPatch:
                grass_patch = agent
                break

        return grass_patch if grass_patch.is_eatable() else None

    def get_sheep_to_eat_at_position(self, position: tuple) -> Union[Sheep, None]:
        """
        This function returns a sheep agent to be eaten by a wolf agent if the wolf agents calling this function shares
        its tile with a sheep agent. If there are several sheep agents on the same tile, one of them will be chosen randomly.
        """
        sheep_agent = None
        agents = self.get_agents_at_position(position)

        for agent in agents:
            if type(agent) == Sheep:
                sheep_agent = agent
                break

        return sheep_agent

    def add_new_agent(self, agent_type: str, pos: tuple):
        agent = None

        # Increasing counter
        self.counter += 1

        if agent_type == Wolf:
            agent = Wolf(self.counter, pos, self, self.moore, self.initial_energy)
        elif agent_type == Sheep:
            agent = Sheep(self.counter, pos, self, self.moore, self.initial_energy)

        # Adding agent in schedule's agents array
        self.schedule.add(agent)

        # Placing agent in the grid
        self.grid.place_agent(agent, pos)

    def remove_agent(self, agent: Agent):
        """
        This function is to be called when an agent dies
        """
        # Removing agent from the grid
        self.grid.remove_agent(agent)

        # Removing agent from schedule
        self.schedule.remove(agent)

    def step(self):
        self.schedule.step()

        # Collect data
        self.datacollector.collect(self)

        # ... to be completed

    def run_model(self, step_count=200):
        # Iterating
        for step in range(step_count):
            self.schedule.step()

            # Collect data
            self.datacollector.collect()
Exemplo n.º 22
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])
Exemplo n.º 23
0
class LabModel(Model):

    def __init__(self, width, height):

        defineAgents.init()

        self.num_Users = 0
        self.schedule = BaseScheduler(self)
        self.running = True
        self.grid = MultiGrid(width, height, False)

        self.agents_json = []

        self.clock = Time()
        self.day = self.clock.day

        self.NStep = 0
        self.createWalls(width, height)
        self.createDoors(width, height)
        self.savePosOutOfMap()
        self.setRooms()
        self.setAgents()

        self.getRules()


    def getRules(self):
        listdata1 = post.getEvents(0)
        self.actionsNear = listdata1[0]
        print('Near actions: ', self.actionsNear)
        listdata2 = post.getEvents(2)
        self.actionsFar = listdata2[0]
        print('Far actions: ', self.actionsFar)
        
    def createWalls(self, width, height):
        self.Walls = []
        for y in range(int(height*0.2),height):
            x = width
            wall = Wall(x, y)
            self.Walls.append(wall)
        for x in range(0,int(width/2)):
            y = 0
            wall = Wall(x,y)
            self.Walls.append(wall)
        for x in range(0,width):
            y = height*0.2
            wall = Wall(x,y)
            self.Walls.append(wall)
        for y in range(0,height+1):
            x = 0
            wall = Wall(x,y)
            self.Walls.append(wall)
        for y in range(0, height+1):
            x = width/2
            wall = Wall(x,y)
            self.Walls.append(wall)
        for x in range(int(width/2), width):
            y = height* 0.6
            wall = Wall(x,y)
            self.Walls.append(wall)
        for x in range(0, width):
            y = height
            wall = Wall(x,y)
            self.Walls.append(wall)

    def createDoors(self, width, height):
        door1 = Door(0,2,False, True)
        door2 = Door(4,3, True)
        door3 = Door(7,8)
        door4 = Door(7,12)
        self.doors = [door1, door2, door3, door4]
        # Clean positions of doors
        for wall in self.Walls:
            for door in self.doors:
                if ((wall.x == door.x) and (wall.y == door.y )):
                    self.Walls.remove(wall)

    def savePosOutOfMap(self):
        self.pos_out_of_map = []
        for x in range(8,15):
            for y in range(0,3):
                pos = (x,y)
                self.pos_out_of_map.append(pos)

    def setRooms(self):
        positions_room_out = []
        positions_room_out.append((self.doors[0].x, self.doors[0].y)) #I understand that door 1 is out of the laboratory
        self.roomOut = Room(positions_room_out)
        positions_room1 = []
        for x in range(1,7):
            for y in range(1,3):
                pos = (x, y)
                positions_room1.append(pos)
        room1 = Room(positions_room1)
        positions_room2 = []
        for x in range(1,7):
            for y in range(4,17):
                pos = (x, y)
                positions_room2.append(pos)
        positions_room2.append((self.doors[1].x, self.doors[1].y))
        room2 = Room(positions_room2)
        positions_room3 = []
        for x in range(8,14):
            for y in range(4,10):
                pos = (x, y)
                positions_room3.append(pos)
        positions_room2.append((self.doors[2].x, self.doors[2].y))
        room3 = Room(positions_room3)
        positions_room4 = []
        for x in range(8,14):
            for y in range(11,17):
                pos = (x, y)
                positions_room4.append(pos)
        positions_room2.append((self.doors[3].x, self.doors[3].y))
        room4 = Room(positions_room4)
        self.rooms = [room1, room2, room3, room4, self.roomOut]

    def isInMap(self, possible_steps_out_of_map):
        possible_step = possible_steps_out_of_map
        for each_pos in self.pos_out_of_map:
            xp, yp = each_pos
            xu, yu = possible_step
            if ((xp == xu) and (yp == yu)):
                return False
        return True

    def thereIsPC(self, pos):
        x,y = pos
        for pc in self.workplaces:
            if pc.x == x and pc.y == y:
                return True
        return False        

    def thereIsWall(self, possible_steps_before_walls):
        possible_step = possible_steps_before_walls
        for each_wall in self.Walls:
            xw = each_wall.x
            yw = each_wall.y
            xu, yu = possible_step
            if ((xw == xu) and (yw == yu)):
                return True
        return False

    def thereIsClosedDoor(self, possible_steps_before_doors):
        xu,yu = possible_steps_before_doors
        for door in self.doors:
            if ((xu == door.x) and (yu == door.y)):
                if door.state == False:
                    return True
        return False

    def ThereIsUserInRoom(self, room):
        for pos in room.pos_room:
            possible_user = self.grid.get_cell_list_contents([pos])
            if (len(possible_user) > 0):
                for user in possible_user:
                    if isinstance(user,UserAgent):
                        return True
        return False

    def setAgents(self):
        # Identifications
        id_offset = 100

        id_sensorCoffe = self.num_Users + id_offset
        id_sensorTV = id_sensorCoffe + id_offset
        id_sensorAccess = id_sensorTV + id_offset
        id_bulb = id_sensorAccess + id_offset
        id_pc = id_sensorAccess + id_bulb

        # Height and Width
        height = self.grid.height
        width = self.grid.width

        # CREATE AGENT 

        # Create Coffe Maker
        capacity_coffeMaker = 30
        self.cm = CoffeMakerAgent(id_sensorCoffe, self, capacity_coffeMaker)
        self.grid.place_agent(self.cm, (1, height-1))
        # Create TV
        self.tv = TVAgent(id_sensorTV, self)
        self.grid.place_agent(self.tv, (4,height-1))
        # Create Control Access
        self.ca = AccessAgent(id_sensorAccess, self, self.doors[1])
        self.grid.place_agent(self.ca, (2, 3))
        # Create LightBulbs
        self.bulbs = []
        LB1 = Bulb(id_bulb, self, self.rooms[0])
        self.bulbs.append(LB1)
        LB2 = Bulb(id_bulb+1, self, self.rooms[1])
        self.bulbs.append(LB2)
        LB3 = Bulb(id_bulb+2, self, self.rooms[2])
        self.bulbs.append(LB3)
        LB4 = Bulb(id_bulb+3, self, self.rooms[3])
        self.bulbs.append(LB4)
        # Create PC
        self.workplaces = []
        PC1 = PC(id_pc, self, 9, 6, 'd')
        self.grid.place_agent(PC1, (9, 6))
        self.workplaces.append(PC1)
        PC2 = PC(id_pc+1, self, 11, 6, 'd')
        self.grid.place_agent(PC2, (11, 6))
        self.workplaces.append(PC2)
        PC3 = PC(id_pc+2, self, 12, 6, 'd')
        self.grid.place_agent(PC3, (12, 6))
        self.workplaces.append(PC3)
        PC4 = PC(id_pc+3, self, 11, 7, 'u')
        self.grid.place_agent(PC4, (11, 7))
        self.workplaces.append(PC4)
        PC5 = PC(id_pc+4, self, 12, 7, 'u')
        self.grid.place_agent(PC5, (12, 7))
        self.workplaces.append(PC5)
        PC6 = PC(id_pc+5, self, 9, 14, 'd')
        self.grid.place_agent(PC6, (9, 14))
        self.workplaces.append(PC6)
        PC7 = PC(id_pc+6, self, 11, 14, 'u')
        self.grid.place_agent(PC7, (11, 14))
        self.workplaces.append(PC7)
        PC8 = PC(id_pc+7, self, 12, 14, 'u')
        self.grid.place_agent(PC8, (12, 14))
        self.workplaces.append(PC8)
        PC9 = PC(id_pc+8, self, 11, 13, 'd')
        self.grid.place_agent(PC9, (11, 13))
        self.workplaces.append(PC9)
        PC10 = PC(id_pc+9, self, 12, 13, 'd')
        self.grid.place_agent(PC10, (12, 13))
        self.workplaces.append(PC10)

        def getFreePlace():
            x = random.randrange(self.grid.width)
            y = random.randrange(self.grid.height)
            position = (x,y)
            possible_free_place = self.grid.get_cell_list_contents([position])
            if len(possible_free_place) == 0:
                there_is_wall = self.thereIsWall(position)
                if there_is_wall == False:
                    place_in_map = self.isInMap(position)
                    if place_in_map == True:
                        return position
            return getFreePlace()

         # Create users
        countPC = 0
        for n_type_users in defineAgents.agents_json:
            n_agents = n_type_users['N']
            for i in range(0, n_agents):
                a = UserAgent(i, self, self.workplaces[countPC], n_type_users)
                self.schedule.add(a)
                self.grid.place_agent(a, (0, 2))
                countPC = countPC + 1

        #Add to schedule
        for pc in self.workplaces:
            self.schedule.add(pc)
        for bulb in self.bulbs:
            self.schedule.add(bulb)
        self.schedule.add(self.cm)
        self.schedule.add(self.tv)
        self.schedule.add(self.ca)
        self.schedule.add(self.clock)

    def createAgent(self, pos):
        if self.thereIsUser((0,2)) == False:
            self.num_Users = self.num_Users + 1
            a = UserAgent(self.num_Users - 1, self, self.workplaces[self.num_Users - 1])
            self.schedule.add(a)
            #x, y = getFreePlace()
            self.grid.place_agent(a, (0, 2))

    def ThereIsUserNear(self, pos):
        xa, ya = pos
        round_pos = []
        round_pos.append((xa-1,ya-1))
        round_pos.append((xa-1,ya))
        round_pos.append((xa-1,ya+1)) 
        round_pos.append((xa+1,ya+1))
        round_pos.append((xa,ya+1))
        round_pos.append((xa,ya-1))
        round_pos.append((xa+1,ya))
        round_pos.append((xa+1,ya-1))
        for pos in round_pos:
            xp, yp = pos
            if (xp>=0 and yp>=0 and yp < self.grid.height and xp < self.grid.width):
                possible_user = self.grid.get_cell_list_contents([pos])
                if (len(possible_user) > 0):
                    for user in possible_user:
                        if isinstance(user,UserAgent):
                            return True
                        else:
                            continue
            else:
                continue
        return False

    def ThereIsUserUp(self, pos, id_pc):
        xa, ya = pos
        possible_user = self.grid.get_cell_list_contents([(xa,ya+1)])
        if (len(possible_user) > 0):
                for user in possible_user:
                    if isinstance(user,UserAgent) and user.pc.unique_id == id_pc:
                        return True
        return False

    def ThereIsUserDown(self, pos, id_pc):
        xa, ya = pos
        possible_user = self.grid.get_cell_list_contents([(xa,ya-1)])
        if (len(possible_user) > 0):
            for user in possible_user:
                if isinstance(user,UserAgent) and user.pc.unique_id == id_pc:
                    return True
        return False

    def ThereIsUserDownCM(self, pos):
        xa, ya = pos
        agents = []
        possible_user = self.grid.get_cell_list_contents([(xa,ya-1)])
        if (len(possible_user) > 0):
            for user in possible_user:
                if isinstance(user,UserAgent):
                    agents.append(user)
        return agents

    def thereIsUser(self,pos):
        possible_user = self.grid.get_cell_list_contents([pos])
        if (len(possible_user) > 0):
            for user in possible_user:
                if isinstance(user,UserAgent):
                    return True
        return False

    def ThereIsOtherUserInRoom(self, room, agent):
        for pos in room.pos_room:
            possible_user = self.grid.get_cell_list_contents([pos])
            if (len(possible_user) > 0):
                for user in possible_user:
                    if isinstance(user,UserAgent) and user != agent:
                        return True
        return False

    def getRoom(self, pos):
        for room in self.rooms:
            if pos in room.pos_room:
                return room
        return False

    def getLightWithRoom(self, room):
        for light in self.bulbs:
            if light.room == room:
                return light
        return False
        
    def openDoor(self,pos,agent = 0):
        x_pos, y_pos = pos
        doors = self.doors
        for door in doors:
            x = door.x
            y = door.y
            if ((x == x_pos) and (y == y_pos)):
                if isinstance(agent, AccessAgent):
                    door.open(True)
                else:
                    door.open()

    def closeDoor(self,pos):
        x_pos, y_pos = pos
        doors = self.doors
        for door in doors:
            x = door.x
            y = door.y
            if ((x == x_pos) and (y == y_pos)):
                door.close()

    def getMatrix(self,agent):
        new_matrix = defineAgents.returnMatrix(agent, self.clock.clock)
        agent.markov_matrix = new_matrix
    
    def getTimeInState(self, agent):
        matrix_time_in_state = defineAgents.getTimeInState(agent, self.clock.clock)
        return matrix_time_in_state

    def step(self):
        self.schedule.step()
        self.NStep = self.NStep + 1
class PlaneModel(Model):
    """ A model representing simple plane consisting of 16 rows of 6 seats (2 x 3) using a given boarding method """

    method_types = {
        'Random': methods.random,
        'Front-to-back': methods.front_to_back,
        'Front-to-back (4 groups)': methods.front_to_back_gr,
        'Back-to-front': methods.back_to_front,
        'Back-to-front (4 groups)': methods.back_to_front_gr,
        'Window-Middle-Aisle': methods.win_mid_ais,
        'Steffen Perfect': methods.steffen_perfect,
        'Steffen Modified': methods.steffen_modified
    }

    def __init__(self, method, shuffle_enable=True, common_bags='normal'):
        self.grid = MultiGrid(21, 7, False)
        self.running = True
        self.schedule = queue_method.QueueActivation(self)
        self.method = self.method_types[method]
        self.entry_free = True
        self.shuffle_enable = shuffle_enable
        self.common_bags = common_bags
        # Create agents and splitting them into separate boarding groups accordingly to a given method
        self.boarding_queue = []
        self.method(self)

        # Create patches representing corridor, seats and walls
        id = 97
        for row in (0, 1, 2, 4, 5, 6):
            for col in (0, 1, 2):
                patch = PatchAgent(id, self, 'WALL')
                self.grid.place_agent(patch, (col, row))
                id += 1
            for col in range(3, 19):
                patch = PatchAgent(id, self, 'SEAT')
                self.grid.place_agent(patch, (col, row))
                id += 1
            for col in (19, 20):
                patch = PatchAgent(id, self, 'WALL')
                self.grid.place_agent(patch, (col, row))
                id += 1
        for col in range(21):
            patch = PatchAgent(id, self, 'CORRIDOR', 'FREE')
            self.grid.place_agent(patch, (col, 3))
            id += 1

    def step(self):
        self.schedule.step()

        if len(self.grid.get_cell_list_contents((0, 3))) == 1:
            self.get_patch((0, 3)).state = 'FREE'

        if self.get_patch((0, 3)).state == 'FREE' and len(self.boarding_queue) > 0:
            a = self.boarding_queue.pop()
            a.state = 'GOING'
            self.schedule.add(a)
            self.grid.place_agent(a, (0, 3))
            self.get_patch((0, 3)).state = 'TAKEN'

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

    def get_patch(self, pos):
        agents = self.grid.get_cell_list_contents(pos)
        for agent in agents:
            if isinstance(agent, PatchAgent):
                return agent
        return None

    def get_passenger(self, pos):
        agents = self.grid.get_cell_list_contents(pos)
        for agent in agents:
            if isinstance(agent, PassengerAgent):
                return agent
        return None
Exemplo n.º 25
0
class EgyptSim(Model):
    """
    Simulation Model for wealth distribution represented by grain in ancient Egypt
    """

    # Variable declarations for non python programmer sanity
    # Map variables
    height = 30
    width = 30

    # Simulation Variables
    timeSpan = 500
    currentTime = 0
    startingSettlements = 14
    startingHouseholds = 7
    startingHouseholdSize = 5
    startingGrain = 3000
    minAmbition = 0.1
    minCompetency = 0.5
    generationalVariation = 0.9
    knowledgeRadius = 20
    distanceCost = 10
    fallowLimit = 4
    popGrowthRate = 0.1
    fission = False
    fissionChance = 0.7
    rental = True
    rentalRate = 0.5
    totalPopulation = startingSettlements * startingHouseholds * startingHouseholdSize
    totalGrain = startingGrain * startingHouseholds
    startingPopulation = totalPopulation
    projectedHistoricalPopulation = totalPopulation
    maxHouseholdGrain = startingGrain

    # Step variables
    mu = 0
    sigma = 0
    alpha = 0
    beta = 0

    # Visualisation
    description = "A model simulating wealth growth and distribution in Ancient Egypt.\n\nThe model allows one to see how variables such as the flooding of the Nile, human character traits and random chance effect the acquisition and distribution of wealth."

    # List of identifiers and colors for settlements
    SETDICT = {"s1": "#FF0000",
               "s2": "#FF4500",
               "s3": "#BC8F8F",
               "s4": "#00FF00",
               "s5": "#00FFFF",
               "s6": "#0000FF",
               "s7": "#FF00FF",
               "s8": "#FF1493",
               "s9": "#708090",
               "s10": "#DC143C",
               "s11": "#FF8C00",
               "s12": "#FF69B4",
               "s13": "#800000",
               "s14": "#7CFC00",
               "s15": "#008B8B",
               "s16": "#483D8B",
               "s17": "#4B0082",
               "s18": "#FF69B4",
               "s19": "#000000",
               "s20": "#8B4513"}

    def __init__(self, height: int = 30, width: int = 30, timeSpan: int = 500,
                 startingSettlements: int = 14, startingHouseholds: int = 7,
                 startingHouseholdSize: int = 5, startingGrain: int = 3000,
                 minAmbition: float = 0.1, minCompetency: float = 0.5,
                 generationalVariation: float = 0.9, knowledgeRadius: int = 20,
                 distanceCost: int = 10, fallowLimit: int = 4, popGrowthRate: float = 0.1,
                 fission: bool = False, fissionChance: float = 0.7, rental: bool = True,
                 rentalRate: float = 0.5):
        """
        Create a new EgyptSim model
        Args:
            height: The height of the simulation grid
            width: The width of the simulation grid
            timeSpan: The number of years over which the model is to run
            startingSettlements: The starting number of Settlements
            startingHouseholds: The starting number of Households per Settlement
            startingHouseholdSize: The starting number of workers in a Household
            startingGrain: The starting amount of grain for each Household
            minAmbition: The minimum ambition value for a Household
            minCompetency: The minimum competency value for a Household
            generationalVariation: The difference between generations of a Household
            knowledgeRadius: How far outside ther Settlement a Household can "see"
            distanceCost: The cost to move grain per cell away from a settlemnt
            fallowLimit: The number of years a field can lay fallow before it is harvested
            popGrowthRate: The rate at which the population grows
            fission: If Household fission (Moving between settlements) is allowed
            fissionChance: The chance fission occuring
            rental: If land rental is allowed
            rentalRate: The rate at which households will rent land
        """
        super().__init__()
        # Set Parameters
        # Map size
        self.height = height
        self.width = width

        # If the number of starting settlements is greater than the maximum reasonable number of households considering territory and farming area
        # Considers that each household needs at least two field to survive at a minimum number of members, a Settlment needs 9 (territory) + 2 * households
        # Tiles to survive
        if startingSettlements > ((width - 1) * height) // (9 + (startingHouseholds * 2)):
            if startingSettlements > 20:
                self.startingSettlements = 20
            else:
                self.startingSettlements = ((height - 1) * width) // (9 + (startingHouseholds * 2))
            print("Too many starting settlements to support the settlements and household, truncating to: ", self.startingSettlements)
        else:
            self.startingSettlements = startingSettlements
        # Simulation Variables
        self.timeSpan = timeSpan
        self.currentTime = 0
        self.startingHouseholds = startingHouseholds
        self.startingHouseholdSize = startingHouseholdSize
        self.startingGrain = startingGrain
        self.minAmbition = minAmbition
        self.minCompetency = minCompetency
        self.generationalVariation = generationalVariation
        self.knowledgeRadius = knowledgeRadius
        self.distanceCost = distanceCost
        self.fallowLimit = fallowLimit
        self.popGrowthRate = popGrowthRate
        self.fission = fission
        self.fissionChance = fissionChance
        self.rental = rental
        self.rentalRate = rentalRate
        self.totalGrain = startingGrain * startingHouseholds * startingSettlements
        self.totalPopulation = startingSettlements * startingHouseholds * startingHouseholdSize
        self.startingPopulation = self.totalPopulation
        self.projectedHistoricalPopulation = self.startingPopulation
        self.maxHouseholdGrain = startingGrain

        # Scheduler and Grid
        self.schedule = EgyptSchedule(self)
        self.grid = MultiGrid(height = self.height, width = self.width, torus=False)

        # Define specific tables for data collection purposes
        setlist = []
        for i in range(self.startingSettlements):
            setlist.append("s" + str(i + 1) + "_Population")
        tables = {"Settlement Population": setlist}

        # Data collection
        self.datacollector = DataCollector(model_reporters = 
            {"Households": lambda m: m.schedule.get_breed_count(Household),
             "Settlements": lambda m: m.schedule.get_breed_count(Settlement),
             "Total Grain": lambda m: m.totalGrain,
             "Total Population": lambda m: m.totalPopulation,
             "Projected Hisorical Poulation (0.1% Growth)": lambda m: m.projectedHistoricalPopulation,
             "Gini-Index": gini,
             "Maximum Settlement Population": maxSetPop,
             "Minimum Settlement Population": minSetPop,
             "Mean Settlement Poulation" : meanSetPop,
             "Maximum Household Wealth": maxHWealth,
             "Minimum Household Wealth": minHWealth,
             "Mean Household Wealth" : meanHWealth,
             "Number of households with < 33% of wealthiest grain holding": lowerThirdGrainHoldings,
             "Number of households with 33 - 66%  of wealthiest grain holding": middleThirdGrainHoldings,
             "Number of households with > 66% of wealthiest grain holding": upperThirdGrainHoldings 
            },
            tables = tables)

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

    def collectTableData(self):
        setPops = {}
        for s in self.schedule.get_breed(Settlement):
            setPops[s.unique_id + "_Population"] = s.population
        self.datacollector.add_table_row("Settlement Population", setPops, True)

    def setupMapBase(self):
        """
        Create the grid as field and river
        """
        for agent, x, y in self.grid.coord_iter():
            # If on left edge, make a river
            if x == 0:
                uid = "r" + str(x) + "|" + str(y)
                river = River(uid, self, (x, y))
                self.grid.place_agent(river, (x, y))
            # Otherwise make a field
            else:
                uid = "f" + str(x) + "|" + str(y)
                field = Field(uid, self, (x, y), 0.0)
                self.grid.place_agent(field, (x, y))
                self.schedule.add(field)

    def setupSettlementsHouseholds(self):
        """
        Add settlements and households to the simulation
        """
        h = 1
        for i in range(self.startingSettlements):
            # Loop untill a suitable location is found
            while True:
                x = self.random.randrange(1, self.width)
                y = self.random.randrange(self.height)

                flag = False
                cell = self.grid.get_cell_list_contents((x, y))
                # Check that tile is available
                for agent in cell:
                    if agent.settlementTerritory:
                        break
                    else:
                        flag = True
                        break

                if flag:
                    break

            # Add settlement to the grid
            population = self.startingHouseholds * self.startingHouseholdSize
            uid = "s" + str(i + 1) # Use a custom id for the datacollector
            settlement = Settlement(uid, self, (x, y), population, self.startingHouseholds, uid, self.SETDICT[uid])
            self.grid.place_agent(settlement, (x, y))

            # Set the surrounding fields as territory
            local = self.grid.get_neighbors((x, y), moore=True, include_center=True, radius=1)
            for a in local:
                a.settlementTerritory = True

            # Add households for the settlement to the scheduler
            for j in range(self.startingHouseholds):
                huid = "h" + str(h) # Use a custom id for the datacollector
                ambition =  np.random.uniform(self.minAmbition, 1)
                competency = np.random.uniform(self.minCompetency, 1)
                genCount = self.random.randrange(5) + 10
                household = Household(huid, self, settlement, (x, y), self.startingGrain,
                                      self.startingHouseholdSize, ambition, competency, genCount)
                # ! Dont add household to grid, is redundant
                self.schedule.add(household)
                h += 1
            # Add settlement to the scheduler
            self.schedule.add(settlement)

    def setup(self):
        """
        Setup model parameters
        """
        self.setupMapBase()
        self.setupSettlementsHouseholds()

    def step(self):
        self.currentTime += 1
        self.maxHouseholdGrain = 0
        self.setupFlood()
        self.schedule.step()
        self.projectedHistoricalPopulation = round(self.startingPopulation * ((1.001) ** self.currentTime))
        self.datacollector.collect(self)
        # Add settlement data to table 
        self.collectTableData()
        # Cease running once time limit is reached or everyone is dead
        if self.currentTime >= self.timeSpan or self.totalPopulation == 0: 
            self.running = False
 
    def setupFlood(self):
        """
        Sets up common variables used for the flood method in Fields
        """
        self.mu = random.randint(0, 10) + 5
        self.sigma = random.randint(0, 5) + 5
        self.alpha = (2 * self.sigma ** 2)
        self.beta = 1 / (self.sigma * math.sqrt(2 * math.pi))
Exemplo n.º 26
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.º 27
0
class GentrifiedNeighbourhood(Model):
  def from_dict(self, d):
    self.__dict__.update(d)

  def __init__(self, people_inside, people_outside, outside_person_econ_dist_mean, share_threshold,
      property_value_dist_mean, num_residential, num_commercial, num_streets, width, height):
    super().__init__()

    self.people_inside = int(people_inside)
    self.people_outside = int(people_outside)
    self.num_people = people_inside + people_outside
    self.outside_person_econ_dist_mean = outside_person_econ_dist_mean
    self.share_threshold = share_threshold
    self.property_value_dist_mean = property_value_dist_mean
    self.num_residential = int(num_residential)
    self.num_commercial = int(num_commercial)
    self.num_streets = int(num_streets)

    self.schedule = RandomActivation(self)
    self.grid = MultiGrid(width, height, True)
    # Create agents
    available = []
    indices = []
    count = 0

    for i in range(height):
      for j in range(width - 1):
        available.append((i, j))
        indices.append(count)
        count += 1

    occupied = []
    res = []
    res_ind = []
    count = 0
    sched = 0
    for i in range(self.num_residential):  # place residences randomly
      a = r.Residential(sched, self)
      placed = False
      while not placed:
        position = np.random.choice(indices)
        indices.remove(position)
        position = available[position]
        # if (x,y) is valid and it doesn't already have a house on it, add a house
        if position not in occupied:
          self.grid.place_agent(a, position)
          self.schedule.add(a)
          occupied.append(position)
          res.append(position)
          res_ind.append(count)
          count += 1
          placed = True
          sched += 1

        else:
          print('something wrong 1')

    for i in range(self.num_commercial):  # place commercial randomly
      a = c.Commercial(sched, self)
      placed = False
      while not placed:
        position = np.random.choice(indices)
        indices.remove(position)
        position = available[position]
        # if (x,y) is valid and it doesn't already have a property on it, add a business
        if position not in occupied:
          self.grid.place_agent(a, position)
          self.schedule.add(a)
          occupied.append(position)
          placed = True
          sched += 1

    for i in range(self.num_streets):
      a = s.Street(sched, self)
      placed = False
      while not placed:
        position = np.random.choice(indices)
        indices.remove(position)
        position = available[position]
        # if (x,y) is valid and it doesn't already have a property on it, add a business
        if position not in occupied:
          self.grid.place_agent(a, position)
          self.schedule.add(a)
          occupied.append(position)
          placed = True
          sched += 1

    homes = []

    for i in range(self.people_inside):
      a = p.Person(sched, self, True)
      placed = False
      while not placed:
        position = np.random.choice(res_ind)
        res_ind.remove(position)
        position = res[position]
        if position not in homes:
          self.grid.place_agent(a, position)
          self.schedule.add(a)
          a.Home = position
          a.resident_status = True
          a.in_neighbourhood = True
          homes.append(position)
          a.home = position
          Res = self.grid.get_cell_list_contents(position)
          home = [obj for obj in Res if isinstance(obj, r.Residential)]
          home = home[0]
          home.vacancy = False
          a.econ_status = home.property_value
          placed = True
          sched += 1

    for i in range(self.people_outside):
      a = p.Person(sched, self, False)
      placed = False
      while not placed:
        y = random.randrange(self.grid.height)
        if y != self.grid.height:
          self.grid.place_agent(a, (y, self.grid.width - 1))
          self.schedule.add(a)
          a.resident_status = False
          a.in_neighbourhood = False
          placed = True
          sched += 1

    # DEBUG: Plot econ status distros
    # econ_inside = [person.econ_status for person in self.schedule.agents if
    #   isinstance(person, p.Person) and person.in_neighbourhood]
    # econ_outside = [person.econ_status for person in self.schedule.agents if
    #   isinstance(person, p.Person) and not person.in_neighbourhood]
    #
    # plt.hist(econ_inside)
    # plt.figure()
    # plt.hist(econ_outside)
    # plt.show()

    self.datacollector = DataCollector(model_reporters=model_reporters)

  def step(self):
    self.datacollector.collect(self)
    self.schedule.step()
Exemplo n.º 28
0
class CancerModel(Model):
    def xprint(self, *args):
        logger.info("CANCER MODEL:  " + " ".join(map(str, args)))

    def __init__(self, cure_agent_type, config):

        self.xprint("STARTING SIMULATION !!!")
        self.counter = 0
        self.decay_number = 0
        self.lifetime_counter = 0
        self.metastasis_score = 0
        eat_values = {CancerCell: 1, HealthyCell: -1, CancerStemCell: 5}
        assert (issubclass(cure_agent_type, CureAgent))

        agent_memory_range = config["Agent"]["memory_limit"]
        agent_memory_type = config["Agent"]["memory_type"]
        radoznalost = config["Agent"]["curiosity"]
        turn_off_modifiers = config["Tumor"]["turn_off_modifiers"]
        CC_mutation_probability = config["Tumor"]["mutation_probability"]
        is_tumor_growing = config["Tumor"]["is_growing"]
        tumor_movement_stopping_range = config["Tumor"][
            "movement_stopping_range"]
        steps_before_mutation = config["Model"]["steps_before_mutation"]
        self.SAMPLE_i = config["Model"]["sample_i"]

        self.cure_number = config["Model"]["NA_number"]
        self.probabilites_ranges = config["Agent"]["probabilities_limits"]
        self.modifier_fraction = config["Tumor"]["modifier_fraction"]
        self.mode = config["Simulation"]["mode"]
        fname = "xxx" if self.mode == "learning" else config["Simulation"][
            "fname"]

        self.MUTATION_PERCENTAGE = config["Model"]["mutation_percentage"]
        tumor_growth_probability = config["Tumor"]["growth_probability"]
        cancer_cell_number = config["Model"]["CC_number"]

        #DATA COLLECTION

        self.datacollector = DataCollector(
            model_reporters={
                "FitnessFunction": fitness_funkcija,
                "AverageSpeed": speed_avg,
                "AverageMemoryCapacity": memory_size_all_avg,
                "PopulationHeterogenity": population_heterogenity,
                "MutationAmount": mutation_amount,
                "CancerStemCell Number": CSC_number,
                "CSC Specialized Agents": CSC_specialized_agents,
                "CancerHeterogenity1": cancer_heterogenity_1,
                "CancerHeterogenity2": cancer_heterogenity_2,
                "CC_Number": CC_number,
                "HealthyCell_Number": HC_number,
                "MetastasisScore": "metastasis_score",
                "CancerSize": cancer_size,
                "TotalTumorResiliance": overall_cancer_resiliance,
                "TumorResiliance_Pi": cancer_resiliance_Pi,
                "TumorResiliance_Pd": cancer_resiliance_Pd,
                "TumorResiliance_Pa": cancer_resiliance_Pa,
                "TumorResiliance_Pk": cancer_resiliance_Pk,
                "TumorResiliance_Psd": cancer_resiliance_Psd,
                "NumberOfMutatedCells": mutated_CCs_num,
                "TumorCoverage": tumor_coverage,
                "AveragePd": average_Pd,
                "AveragePa": average_Pa,
                "AveragePi": average_Pi,
                "AveragePk": average_Pk,
                "AveragePsd": average_Psd,
                #      "PopulationClusters":cluster_counts
            },
            agent_reporters={
                "Pi": get_Pi,
                "Pa": get_Pa,
                "Pd": get_Pd,
                "speed": get_speed,
                "Psd": get_Psd,
                "Pk": get_Pk,
                "memory_size": get_memory_size,
                "type": get_agent_type
            })
        grid_size = math.ceil(math.sqrt(cancer_cell_number * 4))

        self.STEPS_BEFORE_MUTATION = steps_before_mutation
        self.grid = MultiGrid(grid_size, grid_size, False)
        self.NUM_OF_INJECTION_POINTS = config["Model"]["injection_points"]
        #        self.speeds = list(range(1,grid_size//2))
        self.speeds = [
            1
        ]  #TODO ovo mozda bolje? ne znam da li treba u config fajlu?
        poss = self.generate_cancer_cell_positions(grid_size,
                                                   cancer_cell_number)
        num_CSC = math.ceil(percentage(1, cancer_cell_number))
        pos_CSC = [self.random.choice(poss) for i in range(num_CSC)]

        #ACTIVATE SIMULATION
        self.schedule = RandomActivation(self)
        self.running = True

        #PLACE CANCER CELLS

        for i in range(cancer_cell_number):
            pos = poss[i]
            has_modifiers = False if ((i < (
                (1 - self.modifier_fraction) * cancer_cell_number))
                                      or turn_off_modifiers is True
                                      ) else True  #10 % will be with modifiers
            c = CancerStemCell("CANCER_STEM_CELL-"+str(uuid.uuid4()),self,value = eat_values[CancerStemCell],has_modifiers=has_modifiers,mutation_probability=CC_mutation_probability,grows=is_tumor_growing,growth_probability=tumor_growth_probability) \
                if pos in pos_CSC else CancerCell("CANCER_CELL-"+str(uuid.uuid4()),self,value=eat_values[CancerCell],has_modifiers=has_modifiers,mutation_probability=CC_mutation_probability,grows=is_tumor_growing,growth_probability=tumor_growth_probability)
            self.grid.place_agent(c, pos)
            self.schedule.add(c)

        #PLACE HEALTHY CELLS

        for (i, (contents, x, y)) in enumerate(self.grid.coord_iter()):
            nbrs = self.grid.get_neighborhood([x, y], moore=True)
            second_nbrs = []
            for nbr in nbrs:
                second_nbrs += self.grid.get_neighborhood(nbr, moore=True)
            nbrs = nbrs + second_nbrs
            nbr_contents = self.grid.get_cell_list_contents(nbrs)
            nbr_CCs = [
                nbr for nbr in nbr_contents if isinstance(nbr, CancerCell)
            ]

            if not contents and len(nbr_CCs) == 0:
                c = HealthyCell(uuid.uuid4(), self, eat_values[HealthyCell])
                self.grid.place_agent(c, (x, y))
                self.schedule.add(c)

        if self.mode == "simulation":
            self.duplicate_mutate_or_kill = self.simulation_mode_function
            self.decay_probability = 0.04  #MAGIC NUMBER
            self.read_nanoagents_from_file(
                fname=fname,
                cure_agent_type=cure_agent_type,
                tumor_movement_stopping_range=tumor_movement_stopping_range,
                agent_memory_range=agent_memory_range,
                radoznalost=radoznalost)

        elif self.mode == "learning":
            self.decay_probability = 0
            self.make_nanoagents_from_scratch(cure_agent_type, radoznalost,
                                              agent_memory_type,
                                              agent_memory_range,
                                              tumor_movement_stopping_range,
                                              grid_size)
        else:
            assert ("False")

    def get_random_positions_on_empty_cells(self):
        """Gets the N random currently empty positions on the grid"""
        #GETTING EMPTY POSITIONS (for placing nano agents)
        empty_cells = [(x, y) for (i, (contents, x,
                                       y)) in enumerate(self.grid.coord_iter())
                       if not contents]
        positions = [
            self.random.choice(empty_cells)
            for i in range(self.NUM_OF_INJECTION_POINTS)
        ]
        self.xprint("The 5 random empty positions are %s" % positions)
        return positions

    def inject_nanoagents(self):
        """Injects the nanoagents, they will be activated slowly after"""
        from itertools import cycle

        positions = cycle(self.get_random_positions_on_empty_cells())
        for a in self.agents:
            self.grid.place_agent(a, next(positions))
        self.agents_iterator = iter(self.agents)

    def activate_next_batch_of_agents(self):
        agents_to_be_placed_at_each_steps = round(len(self.agents) /
                                                  14)  #MAGIC NUMBER
        for i in range(agents_to_be_placed_at_each_steps):
            self.schedule.add(next(self.agents_iterator))

    def read_nanoagents_from_file(self, fname, cure_agent_type, radoznalost,
                                  agent_memory_range,
                                  tumor_movement_stopping_range):
        import pandas as pd
        self.xprint("Reading nanoagents from file")
        df = pd.read_csv(fname)
        self.agents = []

        for i, row in df.iterrows():
            a = cure_agent_type(
                uuid.uuid4(),
                self,
                speeds=self.speeds,
                radoznalost=radoznalost,
                memory_type=row.memory_size,
                memory_range=agent_memory_range,
                tumor_movement_stopping_range=tumor_movement_stopping_range,
                probabilities_ranges=self.probabilites_ranges)
            a.Pi = row.Pi
            a.Pa = row.Pa
            a.Pd = row.Pd
            a.memory_size = row.memory_size
            a.memorija = FixSizeOrderedDict(max=row.memory_size)
            a.tumor_movement_stopping_rate = row.tumor_movement_stopping_rate
            self.agents.append(a)

    def make_nanoagents_from_scratch(self, cure_agent_type, radoznalost,
                                     agent_memory_type, agent_memory_range,
                                     tumor_movement_stopping_range, grid_size):
        from itertools import cycle
        self.xprint("Making nanoagents from scratch")
        positions = cycle(self.get_random_positions_on_empty_cells())
        for i in range(self.cure_number):
            pos = next(positions)
            self.xprint(pos)
            a = cure_agent_type(
                uuid.uuid4(),
                self,
                speeds=self.speeds,
                radoznalost=radoznalost,
                memory_type=agent_memory_type,
                memory_range=agent_memory_range,
                tumor_movement_stopping_range=tumor_movement_stopping_range,
                probabilities_ranges=self.probabilites_ranges)
            self.grid.place_agent(a, pos)
            self.schedule.add(a)

    def simulation_mode_function(self):
        self.xprint("In simulation mode - not duplicating or mutating")
        return

    def generate_cancer_cell_positions(self, grid_size, cancer_cells_number):
        center = grid_size // 2
        poss = [(center, center)]
        for pos in poss:
            poss += [
                n for n in self.grid.get_neighborhood(
                    pos, moore=True, include_center=False) if n not in poss
            ]
            if len(set(poss)) >= cancer_cells_number:
                break
        poss = list(set(poss))
        return poss

    def duplicate_mutate_or_kill(self):
        if self.mode == "simulation":
            assert (False)
        koliko = math.ceil(
            percentage(self.MUTATION_PERCENTAGE, self.cure_number))
        cureagents = [
            c for c in self.schedule.agents if isinstance(c, CureAgent)
        ]
        sortirani = sorted(cureagents, key=lambda x: x.points, reverse=True)
        poslednji = sortirani[-koliko:]
        prvi = sortirani[:koliko]
        sredina = len(sortirani) // 2
        pocetak_sredine = sredina - (koliko // 2)
        kraj_sredine = sredina + (koliko // 2)
        srednji = sortirani[pocetak_sredine:kraj_sredine]
        self.mutate_agents(srednji)
        assert (len(prvi) == len(poslednji))
        self.remove_agents(poslednji)
        self.duplicate_agents(prvi)

    def mutate_agents(self, agents):
        self.xprint("Mutating middle agents")
        for a in agents:
            a.mutate()

    def remove_agents(self, agents):
        for a in agents:
            self.kill_cell(a)

    def duplicate_agents(self, agents):
        for a in agents:
            a_new = a.copy()
            self.grid.place_agent(a_new, (1, 1))
            self.schedule.add(a_new)

    def kill_cell(self, cell):
        self.grid.remove_agent(cell)
        self.schedule.remove(cell)

    def detach_stem_cell(self, cell):
        self.metastasis_score += 1
        self.kill_cell(cell)

    def kill_all_agents(self):
        agents = [a for a in self.schedule.agents if isinstance(a, CureAgent)]
        for a in agents:
            a.kill_self()

    def write_population_to_file(self, i):
        df = record_model_population(self)
        df.to_csv("./Populations/Population{}-step{}.csv".format(
            self.SAMPLE_i, i))

    def step(self):
        self.datacollector.collect(self)

        if self.mode == "simulation":
            self.simulation_step()

        self.write_population_to_file(self.counter)

        self.schedule.step()

        self.counter += 1
        self.lifetime_counter += 1

        if self.counter % self.STEPS_BEFORE_MUTATION == 0:
            #ovde ga stavljamo da izbegnemo da na nultom koraku uradi to
            self.duplicate_mutate_or_kill()

    def simulation_step(self):
        LIFETIME_OF_NANOAGENTS = 80
        REINJECTION_PERIOD = 100
        if self.lifetime_counter > LIFETIME_OF_NANOAGENTS:
            self.kill_all_agents()
        # if self.counter%(LIFETIME_OF_NANOAGENTS+REINJECTION_PERIOD)==0:
        #         #svakih 180 koraka se ubrizgavaju

        #     self.inject_nanoagents()
        #     self.lifetime_counter = 0
        agents_at_each_step = round(self.cure_number / 14)
        for i in range(agents_at_each_step):
            try:
                self.schedule.add(next(self.agents_iterator))
            except StopIteration:
                break
        agents = [a for a in self.schedule.agents if isinstance(a, CureAgent)]
        assert (len(agents) <= self.cure_number)
Exemplo n.º 29
0
class Sugarscape2ConstantGrowback(Model):
    '''
    Sugarscape 2 Constant Growback
    '''

    verbose = True  # Print-monitoring

    def __init__(self,
                 N,
                 beta_c,
                 beta_d,
                 beta_w,
                 beer_consumption,
                 serving_speed,
                 height=34,
                 width=18,
                 bar1_y=1,
                 bar2_y=32,
                 stage=(9, 33)):
        '''
        Create a new Constant Growback model with the given parameters.

        Args:
            initial_population: Number of population to start with
        '''

        # Set parameters
        self.height = height
        self.width = width
        self.initial_population = N
        self.bar1 = (0, bar1_y)
        self.bar1crowd = 0
        self.bar2 = (17, bar1_y)
        self.bar2crowd = 0
        self.bar3 = (0, bar2_y)
        self.bar3crowd = 0
        self.bar4 = (17, bar2_y)
        self.bar4crowd = 0
        self.stage = stage
        self.beta_c = beta_c
        self.beta_w = beta_w
        self.beta_d = beta_d
        self.beer_consumption = beer_consumption
        self.serving_speed = serving_speed
        self.WaitingTimes = []
        self.MaxAgents = 0

        self.schedule = RandomActivationByBreed(self)
        self.grid = MultiGrid(self.width, self.height, torus=False)
        #self.datacollector = DataCollector({"SsAgent": lambda m: m.schedule.get_breed_count(SsAgent), })

        self.datacollector = DataCollector({
            "Waiting":
            lambda m: m.schedule.AverageWaitingTime(True),
            "MaxAgents":
            lambda m: m.schedule.MaxAgents()
        })

        # Create sugar
        import numpy as np

        # Create agent:
        for i in range(self.initial_population):
            #x = random.randrange(self.width)
            #y = random.randrange(self.height)

            # Start position of agents at bottom of 'club'
            x = 7 + int(5 * np.random.random())
            y = 0
            vision = 2
            ssa = SsAgent((x, y), self, beta_c, beta_d, beta_w,
                          beer_consumption, serving_speed, True, vision)
            self.grid.place_agent(ssa, (x, y))
            self.schedule.add(ssa)

        sugar_distribution = np.zeros([self.width, self.height])
        for x in range(self.width):
            for y in range(self.height):
                sugar_distribution[x, y] = 0

        for _, x, y in self.grid.coord_iter():
            sugar = Sugar((x, y), self)
            self.grid.place_agent(sugar, (x, y))
            self.schedule.add(sugar)

        self.running = True

    def WaitingTime(self, bar):

        # Calculate crowd (and thus waiting time) in front of a bar every model interation to decrease computational cost.
        busy = 0
        (x, y) = bar
        for dx in range(-4, 5):
            for dy in range(-4, 5):
                x_cor = x + dx
                y_cor = y + dy
                if 0 <= x_cor < self.width and 0 <= y_cor < self.height:
                    busy += len(
                        self.grid.get_cell_list_contents([(x_cor, y_cor)]))
        return busy

    def step(self):
        self.WaitingTimes = []

        # Calculate bar crowds per bar.
        self.bar1crowd = self.WaitingTime(self.bar1)
        self.bar2crowd = self.WaitingTime(self.bar2)
        self.bar3crowd = self.WaitingTime(self.bar3)
        self.bar4crowd = self.WaitingTime(self.bar4)

        self.schedule.step()
        self.datacollector.collect(self)
        if self.verbose:
            print([self.schedule.time, self.schedule.get_breed_count(SsAgent)])

    def run_model(self, step_count=10):

        if self.verbose:
            print('Initial number Sugarscape Agent: ',
                  self.schedule.get_breed_count(SsAgent))

        for i in range(step_count):
            print(step_count)
            self.step()

        if self.verbose:
            print('')
            print('Final number Sugarscape Agent: ',
                  self.schedule.get_breed_count(SsAgent))
Exemplo n.º 30
0
class ciudad(Model):
    "Inicialización del modelo"
    "Se necesita incluir la base de datos, suponiendo que tendremos varias ciudades para que la inicialización sea genérica"

    def __init__(self, n, m, width, height, porcentaje_infectados, densidad,
                 acumedad, sexo, edades, transporte, Casillas_zona,
                 acummovilidad, movilidad, acummovilidad2, movilidad2,
                 acummovilidad3, movilidad3, dias_cuarentena, long_paso,
                 porcentaje_en_cuarentena, pruebas_disponibles,
                 activacion_testing_aleatorio, activacion_contact_tracing,
                 activación_cuarentena_acordeon, dia_inicio_acordeon,
                 intervalo_acordeon, tiempo_zonificacion):
        self.total_agentes = n  #número de agentes a iniciar
        self.schedule = RandomActivation(
            self)  #inicialización en paralelo de todos los agentes
        self.grid = MultiGrid(width, height,
                              True)  #creación de la grilla genérica

        global PRUEBAS_DISPONIBLES
        global ACTIVACION_CONTACT_TRACING
        global ACTIVACION_TESTING_ALEATORIO
        global OLAS
        global ACTIVACION_CUARENTENA_ACORDEON
        global DIA_INICIO_ACORDEON
        global INTERVALO_ACORDEON
        global ACTIVACION_CUARENTENA
        global DURACION_CUARENTENA
        global PORCENTAJE_EN_CUARENTENA
        global ACTIVACION_CUARENTENA_ZONIFICADA
        global DURACION_CUARENTENA_ZONIFICADA
        global PORCENTAJE_EN_CUARENTENA_ZONIFICADA
        global TIEMPO_ZONIFICACION

        global MATRIZ_CASILLAS
        global MATRIZ_MOVILIDAD2
        global MATRIZ_MOVILIDAD3
        global ACUMULADA_MOVILIDAD2
        global ACUMULADA_MOVILIDAD3

        #Inicialización de las variables globales
        PRUEBAS_DISPONIBLES = pruebas_disponibles
        ACTIVACION_CONTACT_TRACING = activacion_contact_tracing
        ACTIVACION_TESTING_ALEATORIO = activacion_testing_aleatorio
        OLAS = round(PRUEBAS_DISPONIBLES / 12)
        ACTIVACION_CUARENTENA_ACORDEON = activación_cuarentena_acordeon
        DIA_INICIO_ACORDEON = dia_inicio_acordeon
        INTERVALO_ACORDEON = intervalo_acordeon
        ACTIVACION_CUARENTENA = (True if dias_cuarentena > 0 else False)
        DURACION_CUARENTENA = dias_cuarentena
        PORCENTAJE_EN_CUARENTENA = porcentaje_en_cuarentena
        TIEMPO_ZONIFICACION = tiempo_zonificacion

        #Guardar los datos de las nuevas matrices de movilidad
        MATRIZ_CASILLAS = Casillas_zona
        MATRIZ_MOVILIDAD2 = movilidad2
        MATRIZ_MOVILIDAD3 = movilidad3
        ACUMULADA_MOVILIDAD2 = acummovilidad2
        ACUMULADA_MOVILIDAD3 = acummovilidad3

        "Creación de cada agente"
        for i in range(self.total_agentes):
            n_id = random.random()
            estado = (2 if n_id > porcentaje_infectados else 1)
            tcontagio = (random.randint(5, 9) if estado == 2 else 0)
            nuevo = personas(i, self, self.total_agentes, m, estado, tcontagio,
                             densidad, acumedad, sexo, edades, transporte,
                             Casillas_zona, acummovilidad, movilidad,
                             dias_cuarentena, long_paso,
                             porcentaje_en_cuarentena)  #asignación del id
            self.schedule.add(nuevo)  #creación del agente en el sistema

        "Asignación del hogar"
        for i in Casillas_zona:
            values = Casillas_zona.get(i)
            for j in values:
                agentes = self.grid.get_cell_list_contents(j)
                if len(agentes) > 0:
                    num_hogares = (1 if round(len(agentes) / 4) == 0 else
                                   round(len(agentes) / 4))
                    lista = [e for e in range(0, num_hogares)]
                    for z in agentes:
                        z.hogar = random.choice(lista)

        "Configurar el recolector de datos"
        self.datacollector = DataCollector(
            model_reporters={
                "Susceptibles": susceptibles,
                "Total infectados": total_infectados,
                "Graves": infectados_graves,
                "Críticos": infectados_criticos,
                "Leves": infectados_leves,
                "Recuperados": recuperados,
                "Rt": rt,
                "Recuento_zonas": recuento_zonas,
                "0-4": recuento_ge1,
                "5-19": recuento_ge2,
                "20-39": recuento_ge3,
                "40-59": recuento_ge4,
                ">60": recuento_ge5,
                "En_cuarentena": en_cuarentena,
                "Vivos": agentes_vivos,
                "Día": dia,
                "Contactos_prom_trabajo": prom_contactos_trabajo,
                "Contactos_prom_transporte": prom_contactos_transporte,
                "Contactos_prom_casa": prom_contactos_casa,
                "Nuevos_infectados": nuevos_infectados,
                "Detectados": detectados,
                "En_testing": en_testing,
                "En_cama": en_cama,
                "En_UCI": en_uci,
                "Detectados_por_intervencion": detectados_interv,
                "#Intervenidos": intervenidos
            })
        self.running = True

    "Avanzar el modelo"

    def step(self):
        global PRUEBAS_DISPONIBLES
        global ACTIVACION_TESTING_ALEATORIO
        global ACTIVACION_CONTACT_TRACING
        global OLAS
        global ACTIVACION_CUARENTENA_ACORDEON
        global DIA_INICIO_ACORDEON
        global INTERVALO_ACORDEON
        global ACTIVACION_CUARENTENA
        global DIA_INICIO_CUARENTENA
        global DURACION_CUARENTENA
        global PORCENTAJE_EN_CUARENTENA

        self.datacollector.collect(self)
        self.actualizar_movilidad()
        self.cuarentena_regular(ACTIVACION_CUARENTENA, DIA_INICIO_CUARENTENA,
                                DURACION_CUARENTENA, PORCENTAJE_EN_CUARENTENA)
        self.cuarentena_acordeon(ACTIVACION_CUARENTENA_ACORDEON,
                                 DIA_INICIO_ACORDEON, INTERVALO_ACORDEON)
        self.schedule.step()
        self.dinamica_hospitales()
        self.testing_aleatorio(PRUEBAS_DISPONIBLES,
                               ACTIVACION_TESTING_ALEATORIO)
        self.contact_tracing(ACTIVACION_CONTACT_TRACING)
        #self.cuarentena_zonificada(0.2)

    def actualizar_movilidad(self):
        global MATRIZ_CASILLAS
        global MATRIZ_MOVILIDAD2
        global MATRIZ_MOVILIDAD3
        global ACUMULADA_MOVILIDAD2
        global ACUMULADA_MOVILIDAD3

        t = self.schedule.time
        agentes = [agent for agent in self.schedule.agents]
        if t == 35:
            for i in agentes:
                i.set_posf(ACUMULADA_MOVILIDAD2, MATRIZ_MOVILIDAD2,
                           MATRIZ_CASILLAS)
                #print(i.unique_id," Estado:",i.estado, " zona_origen:",i.zona," zona_destino:",i.zona_destino)
        if t == 49:
            for i in agentes:
                i.set_posf(ACUMULADA_MOVILIDAD3, MATRIZ_MOVILIDAD3,
                           MATRIZ_CASILLAS)
                #print(i.unique_id," Estado:",i.estado, " zona_origen:",i.zona," zona_destino:",i.zona_destino)

    def cuarentena_zonificada(self, porcentaje_cierre):
        global TIEMPO_ZONIFICACION
        agentes = [agent for agent in self.schedule.agents]
        zonas = []
        #Saca la lista de zonas
        for i in agentes:
            zonas.append(i.zona)
        zonas = unique(zonas)

        #Cálculo del porcentaje de detectados para cada zona
        for i in range(len(zonas)):
            suma_agentes_en_zona = 0
            suma_detectados = 0
            for j in agentes:
                if j.zona == i:
                    suma_agentes_en_zona += 1
                    suma_detectados += j.detectado
            porcentaje = suma_detectados / suma_agentes_en_zona
            if porcentaje > porcentaje_cierre:
                for j in agentes:
                    if j.cuarentena == 0:
                        j.activar_zonificacion(i, TIEMPO_ZONIFICACION)

    def cuarentena_regular(self, activacion, inicio, duracion, porcentaje):
        if activacion == True:
            t = self.schedule.time
            if t == inicio:
                agentes = [agent for agent in self.schedule.agents]
                print(activacion, inicio, duracion, porcentaje)
                for i in agentes:
                    i.activar_cuarentena(activacion, porcentaje, duracion)
                    #print(i.cuarentena," t:",i.tcuarentena, " dt:",i.dias_cuarentena)

    def cuarentena_acordeon(self, activacion, inicio, intervalo):
        global DIA_INICIO_ACORDEON
        global INTERVALO_ACORDEON
        global PORCENTAJE_EN_CUARENTENA
        if activacion == True:
            t = self.schedule.time
            if t == inicio:
                agentes = [agent for agent in self.schedule.agents]
                for i in agentes:
                    i.activar_cuarentena(activacion, PORCENTAJE_EN_CUARENTENA,
                                         intervalo)
                DIA_INICIO_ACORDEON += 2 * INTERVALO_ACORDEON

    def contact_tracing(self, activacion):
        global PRUEBAS_DISPONIBLES
        if activacion == True:
            if PRUEBAS_DISPONIBLES > 0:
                lista_para_contact_tracing = []
                lista_para_intervenir = []
                agentes = [agent for agent in self.schedule.agents]
                for i in agentes:
                    if i.para_contact == 1 and i.detectado == 1:
                        lista_para_contact_tracing.append(i)
                if len(lista_para_contact_tracing) > 0:
                    for i in lista_para_contact_tracing:
                        i.recopilar_contactos(lista_para_intervenir)
                    if len(lista_para_intervenir) > 0:
                        lista_para_intervenir = unique(lista_para_intervenir)
                        for i in lista_para_intervenir:
                            if PRUEBAS_DISPONIBLES > 1:
                                i.contact_tracing()
                                PRUEBAS_DISPONIBLES -= 1

    def testing_aleatorio(self, pruebas, activacion):
        global TIEMPO
        global PRUEBAS_DISPONIBLES
        global OLAS
        if activacion == True:
            t = self.schedule.time
            agentes = [agent for agent in self.schedule.agents]
            if t == TIEMPO and pruebas > 0 and OLAS > 0:
                disponibles = pruebas / OLAS
                if OLAS == 1:
                    for i in range(pruebas):
                        n_agente = random.choice(agentes)
                        n_agente = self.agente_valido(n_agente)
                        n_agente.testeado = 1
                        n_agente.intervencion = 1
                        PRUEBAS_DISPONIBLES -= 1
                else:
                    for i in range(round(disponibles)):
                        n_agente = random.choice(agentes)
                        n_agente = self.agente_valido(n_agente)
                        n_agente.testeado = 1
                        n_agente.intervencion = 1
                        PRUEBAS_DISPONIBLES -= 1
                TIEMPO += 3
                OLAS -= 1

    def dinamica_hospitales(self):
        global CAMAS_DISPONIBLES
        global UCIS_DISPONIBLES
        agentes = [agent for agent in self.schedule.agents
                   ]  #recopila los agentes del modelo
        agentes_para_hospital = []

        #0. trabajar solo con el arreglo de agentes graves o críticos
        for i in agentes:
            if i.estado == 3 or i.estado == 4:
                agentes_para_hospital.append(i)

        liberar_cama = []
        liberar_uci = []
        requerir_cama = []
        if len(agentes_para_hospital) > 0:
            for i in agentes_para_hospital:
                #crear arreglos para priorizar salidas sobre ingresos en la orden de ejecución
                if i.estado == 3 and i.en_cama == 0:  #ingresa a los graves a hospitalización
                    requerir_cama.append(i)
                if i.estado == 3 and i.en_cama == 1 and i.thospitalizado == 8:  #sale de hospitalización
                    liberar_cama.append(i)
                if i.estado == 4 and i.en_cama == 1 and i.thospitalizado >= 6:  #sale de hospitalización a UCI
                    liberar_cama.append(i)
                if i.estado == 4 and i.en_uci == 1 and i.tuci >= 10:
                    liberar_uci.append(i)
                if i.estado == 4 and i.en_cama == 1 and i.thospitalizado == 6 and i.tcontagio >= 24:
                    liberar_cama.append(i)

        #Se van a liberar las personas de la cama
        if len(liberar_cama) > 0:
            for i in liberar_cama:
                if i.estado == 3 and i.en_cama == 1:  #libero cama si son solo hospitalizados
                    i.en_cama = 0
                    CAMAS_DISPONIBLES += 1
                if i.estado == 4:
                    if i.en_cama == 1 and i.thospitalizado == 6 and i.tcontagio >= 24:  #libero la cama de segunda estancia
                        i.en_cama = 0
                        CAMAS_DISPONIBLES += 1
                    else:
                        if i.en_cama == 1:
                            suma = UCIS_DISPONIBLES - 1
                            if suma >= 0:  #libero cama si lo puedo meter en UCI
                                i.procesado = 1
                                i.en_cama = 0
                                i.thospitalizado = 0
                                CAMAS_DISPONIBLES += 1
                                i.en_uci = 1
                                UCIS_DISPONIBLES -= 1
                            else:
                                i.procesado = 0
        #Se van a liberar las UCIs y se meten en camas si hay disponibles
        if len(liberar_uci) > 0:
            #print("liberando UCIs")
            for i in liberar_uci:
                if i.en_uci == 1:
                    suma = CAMAS_DISPONIBLES - 1
                    if suma >= 0:
                        i.en_uci = 0
                        UCIS_DISPONIBLES += 1
                        i.en_cama = 1
                        CAMAS_DISPONIBLES -= 1
        #Se van a asignar cama para los que las necesitan
        if len(requerir_cama) > 0:
            #print("asignado camas")
            for i in requerir_cama:
                if i.en_cama == 0:
                    suma = CAMAS_DISPONIBLES - 1
                    if suma >= 0:
                        i.en_cama = 1
                        i.procesado = 1
                        CAMAS_DISPONIBLES -= 1

    def agente_valido(self, n_agente):
        if n_agente.testeado == 0 and n_agente.detectado == 0 and n_agente.edad > 17 and n_agente.edad < 70:
            return n_agente
        else:
            agentes = [agent for agent in self.schedule.agents]
            return self.agente_valido(random.choice(agentes))
Exemplo n.º 31
0
class SugarscapeModel(Model):
    def __init__(self, height=50, width=50, init_agents=500, max_metabolism=3, max_vision=10, max_init_sugar=5, min_age=30, max_age=60, init_poll=3, ex_ratio=2, ex_mod=1, poll_growth_rule=True, inheritance_rule=True):
        self.height = height
        self.width = width
        self.init_agents = init_agents
        self.init_poll = init_poll
        self.max_metabolism = max_metabolism
        self.max_vision = max_vision
        self.max_init_sugar = max_init_sugar
        self.min_age = min_age
        self.max_age = max_age
        self.ex_ratio = ex_ratio
        self.ex_mod = ex_mod

        self.replacement_rule = True
        self.pollution_rule = False
        self.diffusion_rule = False
        self.push_rule = False
        self.poll_growth_rule = poll_growth_rule
        self.expend_rule = True
        self.inheritance_rule = inheritance_rule

        self.map = self.import_map()
        self.grid = MultiGrid(height, width, torus=True)
        self.schedule = RandomActivationByType(self)
        self.datacollector = DataCollector({'Pollution': (lambda m: m.total_pollution),
                                            'Wealth': (lambda m: m.total_wealth/m.init_agents),
                                            'Agents': (lambda m: len(m.schedule.agents_by_type[ScapeAgent]))},
                                           {'Wealth': self.collect_wealth,
                                            'Metabolism': self.collect_metabolism,
                                            'Vision': self.collect_vision})

        self.total_wealth = 0
        self.total_pollution = 0

        self.populate_sugar()
        self.populate_agents()


    def step(self):
        ''' Step method run by the visualization module'''
        self.schedule.step([ScapeAgent, SugarPatch])
        self.datacollector.collect(self)

        # if self.schedule.time == 20:
        #     self.pollution_rule = True
        if self.schedule.time == 30:
            self.push_rule = True

        self.total_wealth = 0
        self.total_pollution = 0
        for agent in self.schedule.agents_by_type[ScapeAgent]:
            self.total_wealth += agent.wealth
        for patch in self.schedule.agents_by_type[SugarPatch]:
            self.total_pollution += patch.pollution

    def import_map(self):
        ''' Imports a text file into an array to be used when generating and
            placing the sugar Agents into the grid
        '''

        f = open('Maps/sugar_map.txt', 'r')
        map_list = []
        for line in f:
            num_list = line.split(' ')
            for num in num_list:
                map_list.append(int(num[0]))

        return map_list

    def new_agent(self, uid, inheritance):
        ''' Place a new agent on the sugarscape in order to replace a death'''
        free = False
        while not free:
            location = random.choice([cell for cell in self.grid.coord_iter()])
            if len(location[0]) == 1:
                free = True

        pos = (location[1], location[2])
        patch = self.grid.get_cell_list_contents([pos])[0]

        if self.inheritance_rule:
            if inheritance == 'rand':
                wealth = random.randint(1, self.max_init_sugar)
            else:
                wealth = inheritance
        else:
            wealth = random.randint(1, self.max_init_sugar)

        agent = ScapeAgent(uid, pos, wealth, random.randint(1,self.max_metabolism), random.randint(1,self.max_vision), random.randint(self.min_age, self.max_age), patch, self.ex_ratio, self.ex_mod)

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

    def populate_agents(self):
        ''' Place ScapeAgent's in random unoccupied locations on the grid with randomomized
            sets of parameters
        '''

        cells = [(cell[1], cell[2]) for cell in self.grid.coord_iter()]
        for i in range(self.init_agents):
            uid = 'a' + str(i)
            location = random.choice(cells)
            cells.remove(location)
            patch = self.grid.get_cell_list_contents([location])[0]
            agent = ScapeAgent(uid, location, random.randint(1,self.max_init_sugar), random.randint(1,self.max_metabolism), random.randint(1,self.max_vision), random.randint(self.min_age, self.max_age), patch, self.ex_ratio, self.ex_mod)
            self.grid.place_agent(agent, location)
            self.schedule.add(agent)

    def populate_sugar(self):
        ''' Place SugarPatch's on every cell with maximum sugar content
            according to the imported 'sugar_map.txt' file
        '''

        map_i = 0
        for cell in self.grid.coord_iter():
            x = cell[1]
            y = cell[2]
            uid = 's'+str(y)+str(x)
            # patch = SugarPatch(uid, (x,y), 3)
            patch = SugarPatch(uid, (x,y), self.map[map_i], self.init_poll)
            self.grid.place_agent(patch, (x,y))
            self.schedule.add(patch)
            map_i += 1

    def collect_wealth(self, agent):
        '''Method for datacollector'''
        if isinstance(agent, ScapeAgent):
            return agent.wealth

    def collect_metabolism(self, agent):
        '''Method for datacollector'''
        if isinstance(agent, ScapeAgent):
            return agent.metabolism

    def collect_vision(self, agent):
        '''Method for datacollector'''
        if isinstance(agent, ScapeAgent):
            return agent.vision

    def calc_gini(self, wealths):
        '''Returns gini coefficient'''
        sort_wealths = sorted(wealths)
        num_agents = len(sort_wealths)
        gini,count = 0,0
        for wealth in sort_wealths:
            gini += wealth * (num_agents - count)
            count += 1
        gini /=  (num_agents*sum(sort_wealths))
        return num_agents**(-1) - 2*gini + 1