@Override
  public void executeMethod() throws JMException {
    int[] permutation = new int[populationSize];
    Utils.randomPermutation(permutation, populationSize);
    List<Integer> order = tour_selection(10);

    for (int i = 0; i < order.size(); i++) {
      // int n = permutation[i]; // or int n = i;
      int n = order.get(i); // or int n = i;
      frequency_[n]++;

      int type;
      double rnd = PseudoRandom.randDouble();

      // STEP 2.1. Mating selection based on probability
      if (rnd < delta_) // if (rnd < realb)
      {
        type = 1; // neighborhood
      } else {
        type = 2; // whole population
      }
      Vector<Integer> p = new Vector<Integer>();
      matingSelection(p, n, 1, type);

      // STEP 2.2. Reproduction
      Solution[] parents = new Solution[2];

      parents[0] = population.get(p.get(0));
      parents[1] = population.get(n);

      Solution[] offSpring = (Solution[]) crossoverOperator.execute(parents, (CITO_CAITO) problem_);
      mutationOperator.execute(offSpring[0], (CITO_CAITO) problem_);
      // mutationOperator.execute(offSpring[1], problem_);
      problem_.evaluate(offSpring[0]);
      problem_.evaluateConstraints(offSpring[0]);
      // problem_.evaluate(offSpring[1]);
      // problem_.evaluateConstraints(offSpring[1]);
      evaluations++;

      // STEP 2.3. Repair. Not necessary
      // STEP 2.4. Update z_
      updateReference(offSpring[0]);
      // updateReference(offSpring[1]);

      // STEP 2.5. Update of solutions
      updateProblem(offSpring[0], n, type);
      //              updateProblem(offSpring[1], n, type);
    } // for

    gen++;
    if (gen % 30 == 0) {
      comp_utility();
    }
  }
  public void initNeighborhood() {
    double[] x = new double[populationSize];
    int[] idx = new int[populationSize];

    for (int i = 0; i < populationSize; i++) {
      // calculate the distances based on weight vectors
      for (int j = 0; j < populationSize; j++) {
        x[j] = Utils.distVector(lambda_[i], lambda_[j]);
        // x[j] = dist_vector(population[i].namda,population[j].namda);
        idx[j] = j;
        // System.out.println("x["+j+"]: "+x[j]+ ". idx["+j+"]: "+idx[j]) ;
      } // for

      // find 'niche' nearest neighboring subproblems
      Utils.minFastSort(x, idx, populationSize, T_);
      // minfastsort(x,idx,population.size(),niche);

      System.arraycopy(idx, 0, neighborhood_[i], 0, T_);
    } // for
  } // initNeighborhood
  /**
   * @param individual
   * @param id
   * @param type
   */
  void updateProblem(Solution indiv, int id, int type) {
    // indiv: child solution
    // id:   the id of current subproblem
    // type: update solutions in - neighborhood (1) or whole population (otherwise)
    int size;
    int time;

    time = 0;

    if (type == 1) {
      size = neighborhood_[id].length;
    } else {
      size = population.size();
    }
    int[] perm = new int[size];

    Utils.randomPermutation(perm, size);

    for (int i = 0; i < size; i++) {
      int k;
      if (type == 1) {
        k = neighborhood_[id][perm[i]];
      } else {
        k = perm[i]; // calculate the values of objective function regarding the current subproblem
      }
      double f1, f2;

      f1 = fitnessFunction(population.get(k), lambda_[k]);
      f2 = fitnessFunction(indiv, lambda_[k]);

      if (f2 < f1) {
        population.replace(k, new Solution(indiv));
        // population[k].indiv = indiv;
        time++;
      }
      // the maximal number of solutions updated is not allowed to exceed 'limit'
      if (time >= nr_) {
        return;
      }
    }
  } // updateProblem