def compete(self, chromosomes):
        """
        Simulate competition/survival of the fittest.
        
        The fitness of each chromosome is used to calculate a survival probability
        based on how it compares to the overall fitness range of the run and the
        fitness range of the current generation. The ``abs_fit_weight`` and 
        ``rel_fit_weight`` attributes determine the degree to which overall and
        current fitness ranges affect the final survival probability.
        
        return:  list of surviving chromosomes
        """
        # update overall fitness for this run
        self.sort(chromosomes)
        min_fit = self.get_fitness(chromosomes[0])
        max_fit = self.get_fitness(chromosomes[-1])
        
        if min_fit < self.min_fit_ever:
            self.min_fit_ever = min_fit
        if max_fit > self.max_fit_ever:
            self.max_fit_ever = max_fit
        
        overall_fit_range = self.max_fit_ever - self.min_fit_ever  # "absolute" fitness range
        current_fit_range = max_fit - min_fit                      # "relative" fitness range
        
        # choose survivors based on relative fitness within overall fitness range
        survivors = []
        for chromosome in chromosomes:
            fit = self.get_fitness(chromosome)
            p_survival_absolute = (fit - self.min_fit_ever) / overall_fit_range if overall_fit_range != 0 else 1
            p_survival_relative = (fit - min_fit) / current_fit_range if current_fit_range != 0 else 1
            
            # compute weighted average survival probability
            # a portion accounts for absolute overall fitness for all chromosomes ever encountered (environment-driven)
            # the other portion accounts for relative fitness within the current population (competition-driven)
            p_survival = p_survival_absolute * self.abs_fit_weight + p_survival_relative * self.rel_fit_weight

            if random.random() < p_survival:
                survivors.append(chromosome)

        if not survivors:
            # rarely, nothing survives -- allow everyone to live
            return chromosomes
                
        return survivors
def compete ( self , chromosomes ) : self . sort ( chromosomes ) min_fit = self . get_fitness ( chromosomes [ 0 ] ) max_fit = self . get_fitness ( chromosomes [ - 1 ] ) if min_fit < self . min_fit_ever : self . min_fit_ever = min_fit if max_fit > self . max_fit_ever : self . max_fit_ever = max_fit overall_fit_range = self . max_fit_ever - self . min_fit_ever current_fit_range = max_fit - min_fit survivors = [ ] for chromosome in chromosomes : fit = self . get_fitness ( chromosome ) p_survival_absolute = ( fit - self . min_fit_ever ) / overall_fit_range if overall_fit_range != 0 else 1 p_survival_relative = ( fit - min_fit ) / current_fit_range if current_fit_range != 0 else 1 p_survival = p_survival_absolute * self . abs_fit_weight + p_survival_relative * self . rel_fit_weight if random . random ( ) < p_survival : survivors . append ( chromosome ) if not survivors : return chromosomes return survivors
Simulate competition/survival of the fittest.
        
        The fitness of each chromosome is used to calculate a survival probability
        based on how it compares to the overall fitness range of the run and the
        fitness range of the current generation. The ``abs_fit_weight`` and 
        ``rel_fit_weight`` attributes determine the degree to which overall and
        current fitness ranges affect the final survival probability.
        
        return:  list of surviving chromosomes