Source code for rog_rl.agent

from mesa import Agent
from rog_rl.agent_state import AgentState


[docs]class DiseaseSimAgent(Agent): # noqa """ DiseaseSimAgent """ pos = None moore = True prob_agent_movement = 0.0 def __init__(self, unique_id, model, prob_agent_movement=0.0, moore=True): """ Customize the agent """ self.unique_id = unique_id super().__init__(unique_id, model) self._is_infection_scheduled = False self.prob_agent_movement = prob_agent_movement self.moore = moore # self.state = self.random.choice([x for x in AgentState]) # Holds the state transition plan, with timestep as the key self.state_transition_plan = {} # Default State for Agents self.state = AgentState.SUSCEPTIBLE
[docs] def step(self): self.random_move() self.process_state_transitions()
[docs] def set_state(self, new_state: AgentState): previous_state = self.state self.state = new_state # Update Agent State Registry in Scheduler self.model.schedule.update_agent_state_in_registry( self, previous_state=previous_state) # Update Global Observation in model observation buffer self.model.observation[self.pos[0], self.pos[1], :] = 0 self.model.observation[self.pos[0], self.pos[1], self.state.value] = 1
[docs] def process_state_transitions(self): try: _event = self.state_transition_plan[self.model.schedule.steps] assert self.state == _event.previous_state, \ "Mismatch in state during state_transition" self.set_state(_event.new_state) _event.mark_as_executed() except KeyError: """ If not state transition plan exists for the said timestep then ignore """ pass
[docs] def trigger_infection(self, prob_infection=1.0): """ Attempts to trigger an infection, and if infection is triggered, then it returns True, else returns False. """ if self._is_infection_scheduled: return False else: if self.random.random() < prob_infection: # Prepare a disease plan disease_plan = \ self.model.disease_planner.get_disease_plan( base_timestep=self.model.schedule.steps) for _agent_event in disease_plan: # Check if a state transition plan is already present # for the said timestep try: foo = self.state_transition_plan[_agent_event.update_timestep] # noqa raise Exception( "Attempt to assign multiple state transition plans for the same timestep") # noqa except KeyError: pass # Mark the state transition plan for the said timestep self.state_transition_plan[_agent_event.update_timestep] = _agent_event # noqa self._is_infection_scheduled = True return True else: return False
[docs] def move_to(self, new_position): """ Move the agent to a new location on the grid and do other associated house keeping tasks - Update global observation in model """ # Clear up global observation cache in model at the previous coord self.model.observation[self.pos[0], self.pos[1], :] = 0 # Move Agent in Grid self.model.grid.move_agent(self, new_position) # Add a new entry in the global observation cache for the new position self.model.observation[self.pos[0], self.pos[1], self.state.value] = 1
[docs] def random_move(self): if self.random.random() < self.prob_agent_movement: # Find empty cells in neighborhood empty_cells_in_neighborhood = [] for x, y in self.model.grid.iter_neighborhood( pos=self.pos, moore=self.moore, include_center=False, radius=1): # noqa if (x, y) in self.model.grid.empties: empty_cells_in_neighborhood.append((x, y)) # If empty cells are availabel - move to a randomly chosen one if len(empty_cells_in_neighborhood) > 0: new_position = self.random.choice(empty_cells_in_neighborhood) # Move to a randomly selected empty cell in the neighborhood self.move_to(new_position)