gt:         int Selected[] = new int[n];
context: /*
   * ABCGradientDescent.java
   * Created on 30. Juni 2006, 15:12
   *
   * This file is part of JAMS
   * Copyright (C) 2005 S. Kralisch and P. Krause
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public License
   * as published by the Free Software Foundation; either version 3
   * of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public License
   * along with this program; if not, see <http://www.gnu.org/licenses/>.
   *
   */
  package optas.optimizer;
  
  
  import optas.core.SampleLimitException;
  import java.util.*;
  import jams.data.*;
  import jams.model.*;
  import jams.JAMS;
  import optas.optimizer.management.NumericOptimizerParameter;
  import optas.core.ObjectiveAchievedException;
  import optas.optimizer.management.OptimizerDescription;
  
  /**
   *
   * @author Christian Fischer
   */
  @JAMSComponentDescription(title = "MOCOM Optimization Component",
  author = "Christian Fischer",
  description = "performs multi objective optimization")
  public class MOCOM extends Optimizer {
  
      public OptimizerDescription getDescription() {
          OptimizerDescription desc = OptimizerLibrary.getDefaultOptimizerDescription(MOCOM.class.getSimpleName(), MOCOM.class.getName(), 500, false);
  
          desc.addParameter(new NumericOptimizerParameter("populationSize", JAMS.i18n("size_of_population"), 500, 0, 100000));
  
          return desc;
      }
      /**
       * @return the populationSize
       */
      public int getPopulationSize() {
          return populationSize;
      }
  
      /**
       * @param populationSize the populationSize to set
       */
      public void setPopulationSize(int populationSize) {
          this.populationSize = populationSize;
      }
                                              
      public int populationSize = 250;
      int currentCount;
                      
      int s; //population size        
      int icall = 0;
      int MaxIter;
      boolean continuousOutput = false;
      long start, end = 0;
      String effNames[];
          
      //sometimes useful e.g for using matlab random numbers
      public double customRand() {        
          return generator.nextDouble();
      }
  
      private boolean isSampleValid(double[] sample) {
          Attribute.Double conv_sample[] = new JAMSDouble[sample.length];
          for (int i = 0; i < sample.length; i++) {
              conv_sample[i] = DefaultDataFactory.getDataFactory().createDouble();
              conv_sample[i].setValue(sample[i]);
          }
          return isSampleValid(conv_sample);
      }
  
      private boolean isSampleValid(Attribute.Double[] sample) {                
          for (int i = 0; i < super.n; i++) 
              if (sample[i].getValue() < lowBound[i] || sample[i].getValue() > upBound[i]) 
                  return false;                    
          return true;
      }
     
      @SuppressWarnings("unchecked")
      public void sort(double x[][], int col) {
          ArrayColumnComparator comparator = new ArrayColumnComparator(col, false);
          java.util.Arrays.sort(x, comparator);
      }
  
      public int[] randperm(int upto) {
          int perm[] = new int[upto];
          int freenums[] = new int[upto];
  
          for (int i = 0; i < upto; i++) {
              freenums[i] = i + 1;
          }
  
          for (int i = 1; i <= upto; i++) {
              int num = (int) Math.floor(customRand() * (upto + 1 - i) + 1.0);
              perm[i - 1] = freenums[num - 1];
              freenums[num - 1] = freenums[upto - i];
          }
  
          return perm;
      }
  
      public double[][] lhsu(double[] xmin, double[] xmax, int nsample) {
          int nvar = xmin.length;
          double s[][] = new double[nsample][nvar];
  
          int idx[];
          for (int j = 0; j < nvar; j++) {
              idx = randperm(nsample);
  
              for (int i = 0; i < nsample; i++) {
                  double P = (idx[i] - customRand()) / (double) nsample;
                  s[i][j] = xmin[j] + P * (xmax[j] - xmin[j]);
              }
          }
          return s;
      }
  
      public double[][] compf(double[][] D)throws SampleLimitException, ObjectiveAchievedException {
          int s = D.length, r = 0;
          if (s == 0) {
              return null;
          } else {
              r = D[0].length;
          }
          double F[][] = new double[s][];
          
          for (int i = 0; i < s; i++) {            
              F[i] = this.getSample((D[i])).F();
          }
          return F;
      }
  
      public int IntMax(int R[]) {
          int RMax = Integer.MIN_VALUE;
          for (int i = 0; i < R.length; i++) {
              if (RMax < R[i]) {
                  RMax = R[i];
              }
          }
          return RMax;
      }
  
      @SuppressWarnings("unchecked")
      public Object[] parrank(double[][] ObjVals, int nmbOfObjs) {
          // Pareto ranking of individuals in population
          int nmbOfIndivs = ObjVals.length;
          // set of individuals a particular individual dominates
          Vector<Integer> Dominated[] = new Vector[nmbOfIndivs];
          // Pareto-optimal fronts
          Vector<Vector<Integer>> Front = new Vector<Vector<Integer>>();
  
          // number of Pareto-optimal front for each individual; 2nd highest priority sorting key
          int NmbOfFront[] = new int[nmbOfIndivs];
          // number of individuals by which a particular individual is dominated
          int NmbOfDominating[] = new int[nmbOfIndivs];
  
          for (int i = 0; i < nmbOfIndivs; i++) {
              NmbOfFront[i] = 0;
              NmbOfDominating[i] = 0;
              Dominated[i] = new Vector<Integer>();
          }
  
          for (int p = 0; p < nmbOfIndivs; p++) {
              for (int q = 0; q < nmbOfIndivs; q++) {
                  int sumA1 = 0, sumA2 = 0;
                  int sumB1 = 0, sumB2 = 0;
                  for (int k = 0; k < nmbOfObjs; k++) {
                      if (ObjVals[p][k] <= ObjVals[q][k]) {
                          sumA1++;
                      }
                      if (ObjVals[p][k] < ObjVals[q][k]) {
                          sumA2++;
                      }
                  }
                  for (int k = 0; k < nmbOfObjs; k++) {
                      if (ObjVals[q][k] <= ObjVals[p][k]) {
                          sumB1++;
                      }
                      if (ObjVals[q][k] < ObjVals[p][k]) {
                          sumB2++;
                      }
                  }
                  if (sumA1 == nmbOfObjs && sumA2 > 0) {
                      Dominated[p].addElement(new Integer(q));
                  } else if (sumB1 == nmbOfObjs && sumB2 > 0) {
                      NmbOfDominating[p]++;
                  }
              }
              if (NmbOfDominating[p] == 0) {
                  NmbOfFront[p] = 1;
                  if (Front.size() == 0) {
                      Front.add(new Vector<Integer>());
                  }
                  Front.get(0).add(new Integer(p));
              }
          }
  
          int i = 0;
          while (Front.get(i).size() != 0) {
              Vector<Integer> NextFront = new Vector<Integer>();
              for (int k = 0; k < Front.get(i).size(); k++) {
                  int p = Front.get(i).get(k).intValue();
                  for (int l = 0; l < Dominated[p].size(); l++) {
                      int q = Dominated[p].get(l);
                      NmbOfDominating[q]--;
                      if (NmbOfDominating[q] == 0) {
                          NmbOfFront[q] = i + 2;
                          NextFront.add(new Integer(q));
                      }
                  }
              }
              i++;
              Front.add(NextFront);
          }
  
          Integer RMax = IntMax(NmbOfFront);
  
          return new Object[]{NmbOfFront, RMax};
      }
  
      public double[] asswght(int R[], int RMax, int s) {
          double P[] = new double[s];
          double sum = 0;
          for (int i = 0; i < R.length; i++) {
              sum += R[i];
          }
          for (int i = 0; i < s; i++) {
              P[i] = (RMax - R[i] + 1) / ((double) (RMax + 1) * s - sum);
          }
          return P;
      }
  
      public Object[] worst(double D[][], int n, int R[], int Rmax) {
          //[L] = find(R==Rmax);
          Vector<Integer> Ltmp = new Vector<Integer>();
  
          for (int i = 0; i < R.length; i++) {
              if (R[i] == Rmax) {
                  Ltmp.add(new Integer(i));
              }
          }
          int L[] = new int[Ltmp.size()];
          for (int i = 0; i < Ltmp.size(); i++) {
              L[i] = Ltmp.get(i).intValue();
          }
  
          int nA = L.length;
          double A[][] = new double[nA][n];
          for (int i = 0; i < L.length; i++) {
              for (int j = 0; j < n; j++) {
                  A[i][j] = D[L[i]][j];
              }
          }
          return new Object[]{A, L, new Integer(nA)};
      }
  
      public Object[] choose(double P[], double D[][], double F[][], int Rank[], int n) {
          double sP[] = new double[P.length];
          double sum = 0;
          int counter = 0;
  