docs: def heuristic_crossover(random, candidates, args):
      """Return the offspring of heuristic crossover on the candidates.
  
      It performs heuristic crossover (HX), which is similar to the 
      update rule used in particle swarm optimization. This function 
      also makes use of the bounder function as specified in the EC's 
      ``evolve`` method.
  
      .. note::
      
         This function assumes that candidates can be pickled (for hashing 
         as keys to a dictionary).
  
      .. Arguments:
         random -- the random number generator object
         candidates -- the candidate solutions
         args -- a dictionary of keyword arguments
  
      Optional keyword arguments in args:
      
      - *crossover_rate* -- the rate at which crossover is performed 
        (default 1.0)
      
      """
      crossover_rate = args.setdefault('crossover_rate', 1.0)
      bounder = args['_ec'].bounder
          
      if len(candidates) % 2 == 1:
          candidates = candidates[:-1]
          
      # Since we don't have fitness information in the candidates, we need 
      # to make a dictionary containing the candidate and its corresponding 
      # individual in the population.
      population = list(args['_ec'].population)
      lookup = dict(zip([pickle.dumps(p.candidate, 1) for p in population], population))
      
      moms = candidates[::2]
      dads = candidates[1::2]
      children = []
      for mom, dad in zip(moms, dads):
          if random.random() < crossover_rate:
              bro = copy.copy(dad)
              sis = copy.copy(mom)
              mom_is_better = lookup[pickle.dumps(mom, 1)] > lookup[pickle.dumps(dad, 1)]
              for i, (m, d) in enumerate(zip(mom, dad)):
                  negpos = 1 if mom_is_better else -1
                  val = d if mom_is_better else m
                  bro[i] = val + random.random() * negpos * (m - d)
                  sis[i] = val + random.random() * negpos * (m - d)
              bro = bounder(bro, args)
              sis = bounder(sis, args)
              children.append(bro)
              children.append(sis)
          else:
              children.append(mom)
              children.append(dad)
      return children