/**
  * Returns the best individual (the elite) currently present in the population, based of the
  * values returned by the <code>getFitness</code> method.
  *
  * @return The elite individual
  */
 public AbstractIndividual getBestIndividual() {
   AbstractIndividual best = this.individuals[0];
   for (AbstractIndividual individual : this.individuals) {
     if (Double.isNaN(best.getFitness()) || individual.getFitness() > best.getFitness()) {
       best = individual;
     }
   }
   return best;
 }
 /**
  * Computes an average fitness of all the individuals in the population, using their <code>
  * getFitness</code> method.
  *
  * @return average fitness in the population
  */
 public double getAvgFitness() {
   avgFitness = 0;
   for (AbstractIndividual individual : individuals) {
     individual.getFitness();
     avgFitness += individual.getFitness();
     bestFitness = Math.max(bestFitness, individual.getFitness());
   }
   avgFitness = avgFitness / individuals.length;
   return avgFitness;
 }
 @Override
 public String toString() {
   StringBuilder sb = new StringBuilder();
   sb.append("=== POPULATION ===\n");
   for (AbstractIndividual individual : individuals) {
     sb.append(individual.toString());
     sb.append("\n");
   }
   sb.append("=== avgFIT: ").append(avgFitness).append(" ===\n");
   return sb.toString();
 }
  /**
   * Returns a <code>pair</code> of two integers. The first one is a number of nodes that are
   * activated and the second one is a number of how many edges are not covered.
   *
   * @param individual Usually the best individual in a population
   * @return <code>pair</code> of two integers
   */
  public Pair getVertexCover(AbstractIndividual individual) {
    Pair<Integer, Integer> pair = new Pair<>();
    int activeNodeCounter = 0;
    int notCoveredEdgesCount = 0;
    for (int i = 0; i < StateSpace.nodesCount(); i++) {
      if (individual.isNodeSelected(i)) {
        activeNodeCounter++;
      } else {
        for (Edge edge : StateSpace.getNode(i).getEdges()) {
          if (!individual.isNodeSelected(edge.getToId())) {
            notCoveredEdgesCount++;
          }
        }
      }
    }
    pair.a = activeNodeCounter;
    pair.b = notCoveredEdgesCount;

    return pair;
  }