docs: def simulated_annealing_replacement(random, population, parents, offspring, args):
      """Replaces population using the simulated annealing schedule.
      
      This function performs simulated annealing replacement based
      on a temperature and a cooling rate. These can be specified
      by the keyword arguments `temperature`, which should be the
      initial temperature, and `cooling_rate`, which should be the
      coefficient by which the temperature is reduced. If these
      keyword arguments are not present, then the function will
      attempt to base the cooling schedule either on the ratio of 
      evaluations to the maximum allowed evaluations or on the 
      ratio of generations to the maximum allowed generations. 
      Each of these ratios is of the form ``(max - current)/max``
      so that the cooling schedule moves smoothly from 1 to 0.
      
      .. 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:    
      
      - *temperature* -- the initial temperature
      - *cooling_rate* -- a real-valued coefficient in the range (0, 1) 
        by which the temperature should be reduced 
      
      """
      try:
          temp = args['temperature']
          cooling_rate = args['cooling_rate']
          temp = temp * cooling_rate
          args['temperature'] = temp
      except KeyError:
          try:
              num_evals = args['_ec'].num_evaluations
              max_evals = args['max_evaluations']
              temp = float(max_evals - num_evals) / float(max_evals)
          except KeyError:
              num_gens = args['_ec'].num_generations
              max_gens = args['max_generations']
              temp = 1 - float(max_gens - num_gens) / float(max_gens)
          
      new_pop = []
      for p, o in zip(parents, offspring):
          if o >= p:
              new_pop.append(o)
          elif temp > 0 and random.random() < math.exp(-abs(p.fitness - o.fitness) / float(temp)):
              new_pop.append(o)
          else:
              new_pop.append(p)
              
      return new_pop