code: public List<T> apply(List<T> selectedCandidates, Random rng)
      {
          double ratio = weightVariable.nextValue();
          int size = (int) Math.round(ratio * selectedCandidates.size());
  
          // Shuffle the collection before applying each operation so that the
          // split is not influenced by any ordering artifacts from previous
          // operations.
          List<T> selectionClone = new ArrayList<T>(selectedCandidates);
          Collections.shuffle(selectionClone, rng);
  
          List<T> list1 = selectionClone.subList(0, size);
          List<T> list2 = selectionClone.subList(size, selectedCandidates.size());
          List<T> result = new ArrayList<T>(selectedCandidates.size());
          result.addAll(operator1.apply(list1, rng));
          result.addAll(operator2.apply(list2, rng));
          return result;
      }
docs: Applies one evolutionary operator to part of the population and another
  to the remainder.  Returns a list combining the output of both.  Which
  candidates are submitted to which stream is determined randomly.
  @param selectedCandidates A list of the candidates that survived to be
  eligible for evolution.
  @param rng A source of randomness passed to each of the two delegate
  evolutionary operators.
  @return The combined results from the two streams of evolution.