Skip to content

[BUG] Chapter 12 notebook treats probability of survival as probability of death #66

@gwtaylor

Description

@gwtaylor

In chapter 11's default implementation of choose_dead we see that a random 10% of agents die in every round. So 0.1 is the probability of death:

def choose_dead(self, ps):
        """Choose which agents die in the next timestep.
        ps: probability of survival for each agent
        returns: indices of the chosen ones
        """
        n = len(self.agents)
        is_dead = np.random.random(n) < 0.1
        index_dead = np.nonzero(is_dead)[0]
        return index_dead

When this is overridden to use differential survival, we flip < to > in the is_dead line to interpret ps as probability of survival:

class SimWithDiffSurvival(Simulation):
    def choose_dead(self, ps):
        """Choose which agents die in the next timestep.
        ps: probability of survival for each agent
        returns: indices of the chosen ones
        """
        n = len(self.agents)
        is_dead = np.random.random(n) > ps
        index_dead = np.nonzero(is_dead)[0]
        return index_dead

However, this doesn't happen in chapter 12 and I believe it's a bug that affects the conclusions made in the chapter.

Note that chapter 12 uses the same default implementation of choose_dead as chapter 11. It interprets 0.1 as probability of death. But when introducing differential survival, choose_dead is overridden as this:

# class PDSimulation(Simulation):

    def choose_dead(self, fits):
        """Choose which agents die in the next timestep.
        fits: fitness of each agent
        returns: indices of the chosen ones
        """
        ps = prob_survive(fits)
        n = len(self.agents)
        is_dead = np.random.random(n) < ps
        index_dead = np.nonzero(is_dead)[0]
        return index_dead

Note that < isn't flipped this time. So imagine that all the agents had infinite fitness and therefore their probability of survival was 1.0 . The line is_dead = np.random.random(n) < ps would return all True and kill them all off. This doesn't make sense.

Since choose_dead takes a parameter ps (stands for probability of survival), I think that we should flip < to > and use 0.9 in the default implementation so that the semantics are consistent. Then we never need to do a sign flip and there won't be confusion down the road.

However, this still leaves open the experiments & conclusions made in chapter 12, which, I believe, come with this bug in place.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions