def execute(self, agent: Agent, state: SimState) -> None: """ Isolate (Remove from Grid) a given share of infected people for the sickness-duration. Afterwards they need to be added again to the Grid as removed/dead/immune. """ if agent.is_quarantined(): if agent.state() is AgentState.DEAD or agent.state() is AgentState.IMMUNE or agent.state() is AgentState.REMOVED: grid = agent.grid() for row in range(grid.get_size()): for col in range(grid.get_size()): grid_pos = GridPos(np.uint(row), np.uint(col)) if not grid.is_occupied(grid_pos): grid.set_agent(agent, grid_pos) agent.set_pos(grid_pos) agent.set_quarantined(False) agent.grid().get_quarantinedAgents().remove(agent) state.add_to_quarantined_count(-1) return else: isolate_share = state.quarantine_share() # Share of infected cells to isolate infected = state.infected_count() if agent.state() == AgentState.INFECTIVE and state.get_quarantined_count() < isolate_share * ( infected + state.get_quarantined_count()): agent.set_quarantined(True) agent.grid().get_quarantinedAgents().append(agent) agent.grid().set_agent(None, agent.get_pos()) agent.get_scheduler().update_gui_state(agent.get_pos(), AgentState.EMPTY) state.add_to_quarantined_count(1)
def move_agent(self, agent: Agent, state: SimState) -> None: grid = agent.grid() if grid.is_fully_occupied(): return if agent.state() is AgentState.DEAD or agent.is_quarantined(): return # We don't want zombies move_probability = np.random.randint(low=0, high=100) if move_probability <= state.get_mixing_value_m() * 100: radius = state.movement_limit_radius() if state.movement_limit_high_distances_are_uncommon(): # Recalculate radius -> lower radius is more probable mean = 0 standard_deviation = radius / 3 radius = min( max( 1, int( np.round( np.abs( norm.rvs(size=1, loc=mean, scale=standard_deviation)[0])))), radius) try: new_grid_pos = get_free_pos_limited( grid, pos=agent.get_pos(), radius=radius, metric=state.movement_limit_metric(), ) old_grid_pos = agent.get_pos() grid.move_agent(old_grid_pos, new_grid_pos) finally: return
def move_agent(self, agent: Agent, state: SimState) -> None: grid = agent.grid() if grid.is_fully_occupied(): return if agent.state() is AgentState.DEAD or agent.is_quarantined(): return # We don't want zombies move_probability = np.random.randint(low=0, high=100) if move_probability <= state.get_mixing_value_m() * 100: new_grid_pos = get_free_pos(grid) old_grid_pos = agent.get_pos() grid.move_agent(old_grid_pos, new_grid_pos)
def execute(self, agent: Agent, state: SimState) -> None: if agent.is_quarantined(): return if agent.state() is AgentState.INFECTIVE or AgentState.INCUBATION: infection_radius = state.infection_env_radius() infection_env_size = infection_radius * 2 + 1 size = agent.grid().get_size() check_list = list() grid_pos = agent.get_pos() x = grid_pos.row() y = grid_pos.col() if state.infection_env_metric() == EnvironmentMetric.MANHATTAN: for r in range(0, infection_env_size): offset = abs(infection_radius - r) check_row = y - infection_radius + r for c in range(offset, infection_env_size - offset): check_column = x - infection_radius + c check_list.append((check_column, check_row)) elif state.infection_env_metric() == EnvironmentMetric.EUCLIDEAN: for r in range(0, infection_env_size): check_row = y - infection_radius + r for c in range(0, infection_env_size): check_column = x - infection_radius + c distance = np.round(np.sqrt((infection_radius - r) ** 2 + (infection_radius - c) ** 2)) if 0 < distance <= infection_radius: check_list.append((check_column, check_row)) else: raise ValueError('Metric not implemented') check_list = list(filter(lambda pos: 0 <= pos[0] < size and 0 <= pos[1] < size, check_list)) for check_pos in check_list: to_check = agent.grid().get_agent(GridPos(np.uint(check_pos[0]), np.uint(check_pos[1]))) if to_check is not None and to_check.state() is AgentState.SUSCEPTIBLE: if np.random.random() < state.infection_prob(): if state.incubation_period_enabled(): to_check.set_state(AgentState.INCUBATION) else: to_check.set_state(AgentState.INFECTIVE) agent.update_infected_count()