@Override
 public int compare(AggregationIndividual i1, AggregationIndividual i2) {
   PerformanceVector pv1 = i1.getPerformance();
   PerformanceVector pv2 = i2.getPerformance();
   return (-1)
       * Double.compare(pv1.getCriterion(m).getFitness(), pv2.getCriterion(m).getFitness());
 }
 /**
  * Returns true if the second performance vector is better in all fitness criteria than the first
  * one (remember: the criteria should be maximized).
  */
 public static boolean isDominated(AggregationIndividual i1, AggregationIndividual i2) {
   PerformanceVector pv1 = i1.getPerformance();
   PerformanceVector pv2 = i2.getPerformance();
   double[][] performances = new double[pv1.getSize()][2];
   for (int p = 0; p < performances.length; p++) {
     performances[p][0] = pv1.getCriterion(p).getFitness();
     performances[p][1] = pv2.getCriterion(p).getFitness();
   }
   boolean dominated = true;
   for (int p = 0; p < performances.length; p++) {
     dominated &= (performances[p][1] >= performances[p][0]);
   }
   boolean oneActuallyBetter = false;
   for (int p = 0; p < performances.length; p++) {
     oneActuallyBetter |= (performances[p][1] > performances[p][0]);
   }
   dominated &= oneActuallyBetter;
   return dominated;
 }
  /** Can be used by subclasses to set the performance of the example set. */
  protected final void setResult(PerformanceVector pv) {
    this.lastMainPerformance = Double.NaN;
    this.lastMainVariance = Double.NaN;
    this.lastMainDeviation = Double.NaN;
    this.lastFirstPerformance = Double.NaN;
    this.lastSecondPerformance = Double.NaN;
    this.lastThirdPerformance = Double.NaN;

    if (pv != null) {
      // main result
      PerformanceCriterion mainCriterion = pv.getMainCriterion();
      if ((mainCriterion == null)
          && (pv.size() > 0)) { // use first if no main criterion was defined
        mainCriterion = pv.getCriterion(0);
      }
      if (mainCriterion != null) {
        this.lastMainPerformance = mainCriterion.getAverage();
        this.lastMainVariance = mainCriterion.getVariance();
        this.lastMainDeviation = mainCriterion.getStandardDeviation();
      }

      if (pv.size() >= 1) {
        PerformanceCriterion criterion = pv.getCriterion(0);
        if (criterion != null) {
          this.lastFirstPerformance = criterion.getAverage();
        }
      }

      if (pv.size() >= 2) {
        PerformanceCriterion criterion = pv.getCriterion(1);
        if (criterion != null) {
          this.lastSecondPerformance = criterion.getAverage();
        }
      }

      if (pv.size() >= 3) {
        PerformanceCriterion criterion = pv.getCriterion(2);
        if (criterion != null) {
          this.lastThirdPerformance = criterion.getAverage();
        }
      }
    }
  }
  public void checkOutput(IOContainer output) throws MissingIOObjectException {

    if (similarity.equals("Tree")) {
      TreeDistance treedistance = output.get(TreeDistance.class);
      for (int i = 0; i < expectedValues.length; i++) {
        assertEquals(treedistance.similarity(first[i], second[i]), expectedValues[i]);
      }
    }
    if (similarity.equals("Euclidean")) {
      EuclideanDistance euclideandistance = output.get(EuclideanDistance.class);
      for (int i = 0; i < expectedValues.length; i++) {
        assertEquals(euclideandistance.similarity(first[i], second[i]), expectedValues[i]);
      }
    }
    if (similarity.equals("Comparator")) {
      PerformanceVector performancevector = output.get(PerformanceVector.class);
      assertEquals(
          expectedValues[0], performancevector.getCriterion("similarity").getAverage(), 0.00001);
    }
  }
  public static int fillDataTable(
      SimpleDataTable dataTable,
      Map<String, double[]> lastPopulation,
      Population pop,
      boolean drawDominated) {
    lastPopulation.clear();
    dataTable.clear();
    int numberOfCriteria = 0;
    for (int i = 0; i < pop.getNumberOfIndividuals(); i++) {
      boolean dominated = false;
      if (!drawDominated) {
        for (int j = 0; j < pop.getNumberOfIndividuals(); j++) {
          if (i == j) continue;
          if (NonDominatedSortingSelection.isDominated(pop.get(i), pop.get(j))) {
            dominated = true;
            break;
          }
        }
      }

      if (drawDominated || (!dominated)) {
        StringBuffer id = new StringBuffer(i + " (");
        PerformanceVector current = pop.get(i).getPerformance();
        numberOfCriteria = Math.max(numberOfCriteria, current.getSize());
        double[] data = new double[current.getSize()];
        for (int d = 0; d < data.length; d++) {
          data[d] = current.getCriterion(d).getFitness();
          if (d != 0) id.append(", ");
          id.append(Tools.formatNumber(data[d]));
        }
        id.append(")");
        dataTable.add(new SimpleDataTableRow(data, id.toString()));
        double[] weights = pop.get(i).getWeights();
        double[] clone = new double[weights.length];
        System.arraycopy(weights, 0, clone, 0, weights.length);
        lastPopulation.put(id.toString(), clone);
      }
    }
    return numberOfCriteria;
  }
  public PerformanceVectorViewer(
      final PerformanceVector performanceVector, final IOContainer container) {
    setLayout(new BorderLayout());

    // all criteria
    final CardLayout cardLayout = new CardLayout();
    final JPanel mainPanel = new JPanel(cardLayout);
    add(mainPanel, BorderLayout.CENTER);
    List<String> criteriaNameList = new LinkedList<>();
    for (int i = 0; i < performanceVector.getSize(); i++) {
      PerformanceCriterion criterion = performanceVector.getCriterion(i);
      criteriaNameList.add(criterion.getName());
      JPanel component =
          ResultDisplayTools.createVisualizationComponent(
              criterion, container, "Performance Criterion", false);
      JScrollPane criterionPane = new ExtendedJScrollPane(component);
      criterionPane.setBorder(null);
      criterionPane.setBackground(Colors.WHITE);
      mainPanel.add(criterionPane, criterion.getName());
    }
    if (criteriaNameList.isEmpty()) {
      remove(mainPanel);
      add(new ResourceLabel("result_view.no_criterions"));
      return;
    }
    String[] criteriaNames = new String[criteriaNameList.size()];
    criteriaNameList.toArray(criteriaNames);

    // selection list
    final JList<String> criteriaList =
        new JList<String>(criteriaNames) {

          private static final long serialVersionUID = 3031125186920370793L;

          @Override
          public Dimension getPreferredSize() {
            Dimension dim = super.getPreferredSize();
            dim.width = Math.max(150, dim.width);
            return dim;
          }
        };
    criteriaList.setCellRenderer(new CriterionListCellRenderer());
    criteriaList.setOpaque(false);

    criteriaList.setBorder(BorderFactory.createTitledBorder("Criterion"));
    criteriaList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    criteriaList.addListSelectionListener(
        new ListSelectionListener() {

          @Override
          public void valueChanged(ListSelectionEvent e) {
            String selected = criteriaList.getSelectedValue();
            cardLayout.show(mainPanel, selected);
          }
        });

    JScrollPane listScrollPane = new ExtendedJScrollPane(criteriaList);
    listScrollPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 2));
    add(listScrollPane, BorderLayout.WEST);

    // select first criterion
    criteriaList.setSelectedIndices(new int[] {0});
  }