docs: def crowding_replacement(random, population, parents, offspring, args):
      """Performs crowding replacement as a form of niching.
      
      This function performs crowding replacement, which means that
      the members of the population are replaced one-at-a-time with
      each of the offspring. A random sample of `crowding_distance`
      individuals is pulled from the current population, and the
      closest individual to the current offspring (where "closest"
      is determined by the `distance_function`) is replaced by that
      offspring, if the offspring is better. It is possible for one 
      offspring to replace an earlier offspring in the same generation, 
      given the random sample that is taken of the current survivors 
      for each offspring.
      
      .. Arguments:
         random -- the random number generator object
         population -- the population of individuals
         parents -- the list of parent individuals
         offspring -- the list of offspring individuals
         args -- a dictionary of keyword arguments
  
      Optional keyword arguments in args:    
      
      - *distance_function* -- a function that accepts two candidate 
        solutions and returns the distance between them (default 
        Euclidean L2 distance)
      - *crowding_distance* -- a positive integer representing the 
        number of closest solutions to consider as a "crowd" (default 2)
         
      """
      def distance(x, y):
          return math.sqrt(sum([(a - b)**2 for a, b in zip(x, y)]))
      try:
          distance_function = args['distance_function']
      except KeyError:
          distance_function = distance
          args['distance_function'] = distance_function
      crowding_distance = args.setdefault('crowding_distance', 2)
      survivors = population
      for o in offspring:
          pool = random.sample(survivors, crowding_distance)
          closest = min(pool, key=lambda x: distance_function(o.candidate, x.candidate))
          if o > closest:
              survivors.remove(closest)
              survivors.append(o)
      return survivors