docs: public List<PermutationSolution<Integer>> doCrossover(double probability, List<PermutationSolution<Integer>> parents) {
      List<PermutationSolution<Integer>> offspring = new ArrayList<>(2);
  
      offspring.add((PermutationSolution<Integer>) parents.get(0).copy()) ;
      offspring.add((PermutationSolution<Integer>) parents.get(1).copy()) ;
  
      int permutationLength = parents.get(0).getNumberOfVariables() ;
  
      if (crossoverRandomGenerator.getRandomValue() < probability) {
        int cuttingPoint1;
        int cuttingPoint2;
  
        // STEP 1: Get two cutting points
        cuttingPoint1 = cuttingPointRandomGenerator.getRandomValue(0, permutationLength - 1);
        cuttingPoint2 = cuttingPointRandomGenerator.getRandomValue(0, permutationLength - 1);
        while (cuttingPoint2 == cuttingPoint1)
          cuttingPoint2 = cuttingPointRandomGenerator.getRandomValue(0, permutationLength - 1);
  
        if (cuttingPoint1 > cuttingPoint2) {
          int swap;
          swap = cuttingPoint1;
          cuttingPoint1 = cuttingPoint2;
          cuttingPoint2 = swap;
        }
  
        // STEP 2: Get the subchains to interchange
        int replacement1[] = new int[permutationLength];
        int replacement2[] = new int[permutationLength];
        for (int i = 0; i < permutationLength; i++)
          replacement1[i] = replacement2[i] = -1;
  
        // STEP 3: Interchange
        for (int i = cuttingPoint1; i <= cuttingPoint2; i++) {
          offspring.get(0).setVariableValue(i, parents.get(1).getVariableValue(i));
          offspring.get(1).setVariableValue(i, parents.get(0).getVariableValue(i));
  
          replacement1[parents.get(1).getVariableValue(i)] = parents.get(0).getVariableValue(i) ;
          replacement2[parents.get(0).getVariableValue(i)] = parents.get(1).getVariableValue(i) ;
        }
  
        // STEP 4: Repair offspring
        for (int i = 0; i < permutationLength; i++) {
          if ((i >= cuttingPoint1) && (i <= cuttingPoint2))
            continue;
  
          int n1 = parents.get(0).getVariableValue(i);
          int m1 = replacement1[n1];
  
          int n2 = parents.get(1).getVariableValue(i);
          int m2 = replacement2[n2];
  
          while (m1 != -1) {
            n1 = m1;
            m1 = replacement1[m1];
          }
  
          while (m2 != -1) {
            n2 = m2;
            m2 = replacement2[m2];
          }
  
          offspring.get(0).setVariableValue(i, n1);
          offspring.get(1).setVariableValue(i, n2);
        }
      }
  
      return offspring;
    }