def initialize(self): self._mode = NORMAL if self.num_agents < self.num_agents_max else CONSTANT_NUMBER self._processAgent = {NORMAL:self._processAgentNormalMode, CONSTANT_NUMBER:self._processAgentConstantNumberMode} self.sizethresh_hi = self.num_agents_max self.sizethresh_lo = -1 self.world._ts = [self.world._time] self.world._size = [self.num_agents] self.nbirths = 0 self.ndeaths = 0 # initialize state variables with user-defined function self.state_initializer(self.world, self.agents) # schedule simulation channels self.world._scheduleAllChannels() for agent in self.agents: agent._scheduleAllChannels() # set up global timetable event_times = [agent._next_event_time for agent in self.agents] self.timetable = IndexedPriorityQueue(zip(self.agents, event_times)) # TODO: make this better for recorder in self.recorders: recorder.record(self.world._time, self.world, self.agents)
def initialize(self): self._mode = NORMAL if self.num_agents < self.num_agents_max else CONSTANT_NUMBER self._processAgent = {NORMAL:self._processAgentNormalMode, CONSTANT_NUMBER:self._processAgentConstantNumberMode} self.nbirths = 0 self.ndeaths = 0 # initialize state variables with user-defined function self.world.critical_size = 1 self.state_initializer(self.world, self.agents) self.world.size = self.world.critical_size*(self.num_agents/self.num_agents_max) # schedule simulation channels self.world._scheduleAllChannels() for agent in self.agents: agent._scheduleAllChannels() # set up global timetable event_times = [agent._next_event_time for agent in self.agents] self.timetable = IndexedPriorityQueue(zip(self.agents, event_times))
class FMSimulator(BaseSimulator): def initialize(self): self._mode = NORMAL if self.num_agents < self.num_agents_max else CONSTANT_NUMBER self._processAgent = {NORMAL:self._processAgentNormalMode, CONSTANT_NUMBER:self._processAgentConstantNumberMode} self.nbirths = 0 self.ndeaths = 0 # initialize state variables with user-defined function self.world.critical_size = 1 self.state_initializer(self.world, self.agents) self.world.size = self.world.critical_size*(self.num_agents/self.num_agents_max) # schedule simulation channels self.world._scheduleAllChannels() for agent in self.agents: agent._scheduleAllChannels() # set up global timetable event_times = [agent._next_event_time for agent in self.agents] self.timetable = IndexedPriorityQueue(zip(self.agents, event_times)) def runSimulation(self, tstop): world = self.world agents = self.agents timetable = self.timetable emin, tmin = self._earliestItem() #TODO:should force it to pick agent over world while (tmin <= tstop): if emin is world: # fire agent sync channels if self._do_sync: for agent in agents: agent._synchronize(tmin) if agent in timetable: timetable.updateitem(agent, agent._next_event_time) emin, tmin = self._earliestItem() if emin is not world: continue # fire next world channel world._processNextChannel() #processes queue #timetable.updateitem(world, world.next_event_time) if world._is_modified: for agent in agents: agent._rescheduleFromWorld(world) timetable.updateitem(agent, agent._next_event_time) # if world was stopped, terminate simulation if not world._enabled: self.finalize() return elif not emin._enabled: # if agent was stopped or killed, remove from global timetable del timetable[emin] else: # fire next agent channel emin._processNextChannel() #processes queue if emin in timetable: timetable.updateitem(emin, emin._next_event_time) if emin._is_modified: world._rescheduleFromAgent(emin) #timetable.updateitem(world, world.next_event_time) if not emin._enabled: del timetable[emin] emin, tmin = self._earliestItem() self.finalize() def finalize(self): pass def _earliestItem(self): world, t_world = self.world, self.world._next_event_time agent, t_agent = self.timetable.peek() if t_agent <= t_world: return agent, t_agent else: return world, t_world def _processAgentQueue(self): q = self.agent_queue while q: action, agent = q.dequeue() self._processAgent[self._mode](action, agent) #del agent def _processAgentNormalMode(self, action, agent): agents = self.agents world = self.world timetable = self.timetable q = self.agent_queue if action == q.ADD_AGENT: new_agent = agent new_agent._parent = None # Add the new agent agents.append(new_agent) timetable.add(new_agent, new_agent._next_event_time) self.num_agents += 1 self.nbirths += 1 world.size += world.critical_size/self.num_agents_max # Switch modes if we reach the size threshold if self.num_agents == self.num_agents_max: self._mode = CONSTANT_NUMBER elif action == q.DELETE_AGENT: target = agent # Remove agent from population try: agents.remove(target) except ValueError: raise SimulationError("Agent not found.") timetable.pop(target) self.num_agents -= 1 self.ndeaths += 1 world.size -= world.critical_size/self.num_agents_max # Raise error if sample population crashes if self.num_agents == 0: raise ZeroPopulationError("The population crashed!") def _processAgentConstantNumberMode(self, action, agent): agents = self.agents world = self.world timetable = self.timetable q = self.agent_queue if action == q.ADD_AGENT: new_agent = agent new_agent._parent = None # Choose a random agent to replace index = random.randint(0, len(self.agents)-1) target = agents[index] # Substitute new agent into agent list and ipq agents[index] = new_agent timetable.replaceitem(target, new_agent, new_agent._next_event_time) del target self.nbirths += 1 world.size += (world.size/self.num_agents_max)*(world.critical_size/self.num_agents_max) elif action == q.DELETE_AGENT: # This shouldn't happen... if self.num_agents <= 1: raise SimulationError # Find target agent in the agent list target = agent try: i_target = agents.index(target) except ValueError: raise SimulationError("Agent not found.") # Choose a random agent to copy i_source = i_target while i_source == i_target: i_source = random.randint(0, self.num_agents-1) new_agent = agents[i_source].__copy__() # Replace target agent with the copy agents[i_target] = new_agent timetable.replaceitem(target, new_agent, new_agent._next_event_time) del target self.ndeaths += 1 world.size -= (world.size/self.num_agents_max)*(world.critical_size/self.num_agents_max) # Switch to normal mode if the size drops below the threshold if self.num_agents < self.num_agents_max: #THIS IS WRONG... self._mode = NORMAL
class FMSimulator(BaseSimulator): def initialize(self): self._mode = NORMAL if self.num_agents < self.num_agents_max else CONSTANT_NUMBER self._processAgent = {NORMAL:self._processAgentNormalMode, CONSTANT_NUMBER:self._processAgentConstantNumberMode} self.sizethresh_hi = self.num_agents_max self.sizethresh_lo = -1 self.world._ts = [self.world._time] self.world._size = [self.num_agents] self.nbirths = 0 self.ndeaths = 0 # initialize state variables with user-defined function self.state_initializer(self.world, self.agents) # schedule simulation channels self.world._scheduleAllChannels() for agent in self.agents: agent._scheduleAllChannels() # set up global timetable event_times = [agent._next_event_time for agent in self.agents] self.timetable = IndexedPriorityQueue(zip(self.agents, event_times)) # TODO: make this better for recorder in self.recorders: recorder.record(self.world._time, self.world, self.agents) def runSimulation(self, tstop): world = self.world agents = self.agents timetable = self.timetable emin, tmin = self._earliestItem() while (tmin <= tstop): if emin is world: # fire agent sync channels if self._do_sync: for agent in agents: agent._synchronize(tmin) if agent in timetable: timetable.updateitem(agent, agent._next_event_time) emin, tmin = self._earliestItem() if emin is not world: continue # fire next world channel world._processNextChannel() #processes queue #timetable.updateitem(world, world.next_event_time) if world._is_modified: for agent in agents: agent._rescheduleFromWorld(world) timetable.updateitem(agent, agent._next_event_time) # if world was stopped, terminate simulation if not world._enabled: self.finalize() return elif not emin._enabled: # if agent was stopped or killed, remove from global timetable del timetable[emin] else: # fire next agent channel emin._processNextChannel() #processes queue if emin in timetable: if not emin._enabled: del timetable[emin] else: timetable.updateitem(emin, emin._next_event_time) if emin._is_modified: world._rescheduleFromAgent(emin) #timetable.updateitem(world, world.next_event_time) emin, tmin = self._earliestItem() self.finalize() def finalize(self): pass def _earliestItem(self): world, t_world = self.world, self.world._next_event_time agent, t_agent = self.timetable.peek() if t_agent <= t_world: return agent, t_agent else: return world, t_world def _processAgentQueue(self): q = self.agent_queue size = self.world._size[-1] while q: action, agent = q.dequeue() size += self._processAgent[self._mode](action, agent) # Switch modes if we reach the size threshold if self._mode == NORMAL and self.num_agents == self.sizethresh_hi: self._mode = CONSTANT_NUMBER # Switch modes if we drop to or below the size threshold elif self._mode == CONSTANT_NUMBER and size <= self.sizethresh_lo: size = self.self.sizethresh_lo self._mode = NORMAL self.world._ts.append( self.world._time ) self.world._size.append( size ) def _processAgentNormalMode(self, action, agent): agents = self.agents timetable = self.timetable q = self.agent_queue if action == q.ADD_AGENT: new_agent = agent new_agent._parent = None agents.append(new_agent) timetable.add(new_agent, new_agent._next_event_time) self.num_agents += 1 self.nbirths += 1 return 1 elif action == q.DELETE_AGENT: target = agent try: agents.remove(target) except ValueError: raise SimulationError("Agent not found.") timetable.pop(target) self.num_agents -= 1 # Raise error if sample population crashes if self.num_agents == 0: raise ZeroPopulationError("The population crashed!") self.ndeaths += 1 return -1 def _processAgentConstantNumberMode(self, action, agent): agents = self.agents world = self.world timetable = self.timetable q = self.agent_queue if action == q.ADD_AGENT: new_agent = agent new_agent._parent = None # Choose a random agent to replace index = random.randint(0, len(self.agents)-1) target = agents[index] # Substitute new agent into agent list and ipq agents[index] = new_agent try: timetable.replaceitem(target, new_agent, new_agent._next_event_time) except KeyError: timetable.add(new_agent, new_agent._next_event_time) #target may be inactivated and no longer in the ipq del target self.nbirths += 1 return world._size[-1]/self.num_agents_max elif action == q.DELETE_AGENT: # This shouldn't happen... if self.num_agents <= 1: raise SimulationError # Find target agent in the agent list target = agent try: i_target = agents.index(target) except ValueError: raise SimulationError("Agent not found.") # Choose a random agent to copy i_source = i_target while i_source == i_target: i_source = random.randint(0, self.num_agents-1) # Replace target agent with the copy new_agent = agents[i_source].__copy__() agents[i_target] = new_agent if new_agent._enabled: timetable.replaceitem(target, new_agent, new_agent._next_event_time) #will fail if cell is killed twice! del target self.ndeaths += 1 return -(world._size[-1]/self.num_agents_max)