docs: public List<DoubleSolution> doCrossover(
        double probability, DoubleSolution parent1, DoubleSolution parent2) {
      List<DoubleSolution> offspring = new ArrayList<DoubleSolution>(2);
  
      offspring.add((DoubleSolution) parent1.copy()) ;
      offspring.add((DoubleSolution) parent2.copy()) ;
  
      int i;
      double random;
      double valueY1;
      double valueY2;
      double valueX1;
      double valueX2;
      double upperBound;
      double lowerBound;
  
      if (randomGenerator.getRandomValue() <= probability) {
        for (i = 0; i < parent1.getNumberOfVariables(); i++) {
          upperBound = parent1.getUpperBound(i);
          lowerBound = parent1.getLowerBound(i);
          valueX1 = parent1.getVariableValue(i);
          valueX2 = parent2.getVariableValue(i);
  
          double max;
          double min;
          double range;
  
          if (valueX2 > valueX1) {
            max = valueX2;
            min = valueX1;
          } else {
            max = valueX1;
            min = valueX2;
          }
  
          range = max - min;
  
          double minRange;
          double maxRange;
  
          minRange = min - range * alpha;
          maxRange = max + range * alpha;
  
          random = randomGenerator.getRandomValue();
          valueY1 = minRange + random * (maxRange - minRange);
  
          random = randomGenerator.getRandomValue();
          valueY2 = minRange + random * (maxRange - minRange);
  
          valueY1 = solutionRepair.repairSolutionVariableValue(valueY1, lowerBound, upperBound) ;
          valueY2 = solutionRepair.repairSolutionVariableValue(valueY2, lowerBound, upperBound) ;
  
          offspring.get(0).setVariableValue(i, valueY1);
          offspring.get(1).setVariableValue(i, valueY2);
        }
      }
  
      return offspring;
    }