docs: @Override
    public List<DoubleSolution> execute(List<DoubleSolution> parentSolutions) {
      DoubleSolution child;
  
      int jrand;
  
      child = (DoubleSolution)currentSolution.copy() ;
  
      int numberOfVariables = parentSolutions.get(0).getNumberOfVariables();
      jrand = jRandomGenerator.getRandomValue(0, numberOfVariables - 1);
  
      // STEP 4. Checking the DE variant
      if ((DEFAULT_DE_VARIANT.equals(variant)) ||
              "best/1/bin".equals(variant)) {
        for (int j = 0; j < numberOfVariables; j++) {
          if (crRandomGenerator.getRandomValue(0.0, 1.0) < cr || j == jrand) {
            double value;
            value = parentSolutions.get(2).getVariableValue(j) + f * (parentSolutions.get(0).getVariableValue(
              j) -
              parentSolutions.get(1).getVariableValue(j));
  
            if (value < child.getLowerBound(j)) {
              value = child.getLowerBound(j);
            }
            if (value > child.getUpperBound(j)) {
              value = child.getUpperBound(j);
            }
            child.setVariableValue(j, value);
          } else {
            double value;
            value = currentSolution.getVariableValue(j);
            child.setVariableValue(j, value);
          }
        }
      } else if ("rand/1/exp".equals(variant) ||
              "best/1/exp".equals(variant)) {
        for (int j = 0; j < numberOfVariables; j++) {
          if (crRandomGenerator.getRandomValue(0.0, 1.0) < cr || j == jrand) {
            double value;
            value = parentSolutions.get(2).getVariableValue(j) + f * (parentSolutions.get(0).getVariableValue(j) -
                    parentSolutions.get(1).getVariableValue(j));
  
            if (value < child.getLowerBound(j)) {
              value = child.getLowerBound(j);
            }
            if (value > child.getUpperBound(j)) {
              value = child.getUpperBound(j);
            }
  
            child.setVariableValue(j, value);
          } else {
            cr = 0.0;
            double value;
            value = currentSolution.getVariableValue(j);
            child.setVariableValue(j, value);
          }
        }
      } else if ("current-to-rand/1".equals(variant) ||
              "current-to-best/1".equals(variant)) {
        for (int j = 0; j < numberOfVariables; j++) {
          double value;
          value = currentSolution.getVariableValue(j) + k * (parentSolutions.get(2).getVariableValue(j) -
                  currentSolution.getVariableValue(j)) +
                  f * (parentSolutions.get(0).getVariableValue(j) - parentSolutions.get(1).getVariableValue(j));
  
          if (value < child.getLowerBound(j)) {
            value = child.getLowerBound(j);
          }
          if (value > child.getUpperBound(j)) {
            value = child.getUpperBound(j);
          }
  
          child.setVariableValue(j, value);
        }
      } else if ("current-to-rand/1/bin".equals(variant) ||
              "current-to-best/1/bin".equals(variant)) {
        for (int j = 0; j < numberOfVariables; j++) {
          if (crRandomGenerator.getRandomValue(0.0, 1.0) < cr || j == jrand) {
            double value;
            value = currentSolution.getVariableValue(j) + k * (parentSolutions.get(2).getVariableValue(j) -
                    currentSolution.getVariableValue(j)) +
                    f * (parentSolutions.get(0).getVariableValue(j) - parentSolutions.get(1).getVariableValue(j));
  
            if (value < child.getLowerBound(j)) {
              value = child.getLowerBound(j);
            }
            if (value > child.getUpperBound(j)) {
              value = child.getUpperBound(j);
            }
  
            child.setVariableValue(j, value);
          } else {
            double value;
            value = currentSolution.getVariableValue(j);
            child.setVariableValue(j, value);
          }
        }
      } else if ("current-to-rand/1/exp".equals(variant) ||
              "current-to-best/1/exp".equals(variant)) {
        for (int j = 0; j < numberOfVariables; j++) {
          if (crRandomGenerator.getRandomValue(0.0, 1.0) < cr || j == jrand) {
            double value;
            value = currentSolution.getVariableValue(j) + k * (parentSolutions.get(2).getVariableValue(j) -
                    currentSolution.getVariableValue(j)) +
                    f * (parentSolutions.get(0).getVariableValue(j) - parentSolutions.get(1).getVariableValue(j));
  
            if (value < child.getLowerBound(j)) {
              value = child.getLowerBound(j);
            }
            if (value > child.getUpperBound(j)) {
              value = child.getUpperBound(j);
            }
  
            child.setVariableValue(j, value);
          } else {
            cr = 0.0;
            double value;
            value = currentSolution.getVariableValue(j);
            child.setVariableValue(j, value);
          }
        }
      } else {
        JMetalLogger.logger.severe("DifferentialEvolutionCrossover.execute: " +
                " unknown DE variant (" + variant + ")");
        Class<String> cls = String.class;
        String name = cls.getName();
        throw new JMetalException("Exception in " + name + ".execute()");
      }
  
      List<DoubleSolution> result = new ArrayList<>(1) ;
      result.add(child) ;
      return result;
    }