code: def _binary_crossover(
      population, population_size, mutants, crossover_prob, seed
  ):
      """Performs recombination by binary crossover for the current population.
  
      Let v_i denote the i'th component of the member v and m_i the corresponding
      component of the mutant vector corresponding to v. Then the crossed over
      vector w_i is determined by setting w_i =
      (m_i with probability=crossover_prob else v_i). In addition, DE requires that
      at least one of the components is crossed over (otherwise we end
      up with no change). This is done by choosing on index say k randomly where
      a force crossover is performed (i.e. w_k = m_k). This is the scheme
      implemented in this function.
  
      Args:
        population: A Python list of `Tensor`s where each `Tensor` in the list
          must be of rank at least 1 and all the elements must have a common
          first dimension. The base population to cross over.
        population_size: A scalar integer `Tensor`. The number of elements in the
          population (i.e. size of the first dimension of any member of
          `population`).
        mutants: A Python list of `Tensor`s with the same structure as `population`.
          The mutated population.
        crossover_prob: A positive real scalar `Tensor` bounded above by 1.0. The
          probability of a crossover being performed for each axis.
        seed: `int` or None. The random seed for this `Op`. If `None`, no seed is
          applied.
  
      Returns:
        A list of `Tensor`s of the same structure, dtype and shape as `population`.
        The recombined population.
      """
      sizes = [
          tf.cast(tf.size(x), dtype=tf.float64) for x in population
      ]
      stream = seed_stream.SeedStream(seed, salt="binary_crossover")
      force_crossover_group = categorical.Categorical(sizes).sample(
          [population_size, 1], seed=stream()
      )
      recombinants = []
      for i, population_part in enumerate(population):
          pop_part_flat = tf.reshape(
              population_part, [population_size, -1]
          )
          mutant_part_flat = tf.reshape(
              mutants[i], [population_size, -1]
          )
          part_size = tf.size(population_part) // population_size
          force_crossovers = tf.one_hot(
              tf.random.uniform(
                  [population_size],
                  minval=0,
                  maxval=part_size,
                  dtype=tf.int32,
                  seed=stream(),
              ),
              part_size,
              on_value=True,
              off_value=False,
              dtype=tf.bool,
          )  # Tensor of shape [population_size, size]
          group_mask = tf.math.equal(force_crossover_group, i)
          force_crossovers &= group_mask
          do_binary_crossover = (
              tf.random.uniform(
                  [population_size, part_size],
                  dtype=crossover_prob.dtype.base_dtype,
                  seed=stream(),
              )
              < crossover_prob
          )
          do_binary_crossover |= force_crossovers
          recombinant_flat = tf.where(
              do_binary_crossover, mutant_part_flat, pop_part_flat
          )
          recombinant = tf.reshape(
              recombinant_flat, tf.shape(population_part)
          )
          recombinants.append(recombinant)
      return recombinants
  
imports: import collections
  import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.distributions import categorical
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.util import seed_stream
label_desc: Use image node_id 8 for calling a global function with example usage: _binary_crossover(population, population_size, mutants, crossover_prob, seed) and returns: recombinants