Example #1
0
    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)
Example #2
0
    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))
Example #3
0
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
Example #4
0
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)