docs: public void stmSelection() {
  
      int[] idx = new int[populationSize];
      double[] nicheCount = new double[populationSize];
  
      int[][] solPref = new int[jointPopulation.size()][];
      double[][] solMatrix = new double[jointPopulation.size()][];
      double[][] distMatrix = new double[jointPopulation.size()][];
      double[][] fitnessMatrix = new double[jointPopulation.size()][];
  
      for (int i = 0; i < jointPopulation.size(); i++) {
        solPref[i] = new int[populationSize];
        solMatrix[i] = new double[populationSize];
        distMatrix[i] = new double[populationSize];
        fitnessMatrix[i] = new double[populationSize];
      }
      int[][] subpPref = new int[populationSize][];
      double[][] subpMatrix = new double[populationSize][];
      for (int i = 0; i < populationSize; i++) {
        subpPref[i] = new int[jointPopulation.size()];
        subpMatrix[i] = new double[jointPopulation.size()];
      }
  
      // Calculate the preference values of solution matrix
      for (int i = 0; i < jointPopulation.size(); i++) {
        int minIndex = 0;
        for (int j = 0; j < populationSize; j++) {
          fitnessMatrix[i][j] = fitnessFunction(jointPopulation.get(i), lambda[j]);
          distMatrix[i][j] = calculateDistance2(jointPopulation.get(i), lambda[j]);
          if (distMatrix[i][j] < distMatrix[i][minIndex]) {
            minIndex = j;
          }
        }
        nicheCount[minIndex] = nicheCount[minIndex] + 1;
      }
  
      // calculate the preference values of subproblem matrix and solution matrix
      for (int i = 0; i < jointPopulation.size(); i++) {
        for (int j = 0; j < populationSize; j++) {
          subpMatrix[j][i] = fitnessFunction(jointPopulation.get(i), lambda[j]);
          solMatrix[i][j] = distMatrix[i][j] + nicheCount[j];
        }
      }
  
      // sort the preference value matrix to get the preference rank matrix
      for (int i = 0; i < populationSize; i++) {
        for (int j = 0; j < jointPopulation.size(); j++) {
          subpPref[i][j] = j;
        }
        MOEADUtils.quickSort(subpMatrix[i], subpPref[i], 0, jointPopulation.size() - 1);
      }
      for (int i = 0; i < jointPopulation.size(); i++) {
        for (int j = 0; j < populationSize; j++) {
          solPref[i][j] = j;
        }
        MOEADUtils.quickSort(solMatrix[i], solPref[i], 0, populationSize - 1);
      }
  
      idx = stableMatching(subpPref, solPref, populationSize, jointPopulation.size());
  
      population.clear();
      for (int i = 0; i < populationSize; i++) {
        population.add(i, jointPopulation.get(idx[i]));
      }
    }