/** {@inheritDoc} */
  public List<EvaluatedCandidate<T>> evolvePopulation(
      int populationSize,
      int eliteCount,
      Collection<T> seedCandidates,
      TerminationCondition... conditions) {
    if (eliteCount < 0 || eliteCount >= populationSize) {
      throw new IllegalArgumentException(
          "Elite count must be non-negative and less than population size.");
    }
    if (conditions.length == 0) {
      throw new IllegalArgumentException("At least one TerminationCondition must be specified.");
    }

    satisfiedTerminationConditions = null;
    int currentGenerationIndex = 0;
    long startTime = System.currentTimeMillis();

    List<T> population =
        candidateFactory.generateInitialPopulation(populationSize, seedCandidates, rng);

    // Calculate the fitness scores for each member of the initial
    // population.
    List<EvaluatedCandidate<T>> evaluatedPopulation = evaluatePopulation(population);
    EvolutionUtils.sortEvaluatedPopulation(evaluatedPopulation, fitnessEvaluator.isNatural());
    PopulationData<T> data =
        EvolutionUtils.getPopulationData(
            evaluatedPopulation,
            fitnessEvaluator.isNatural(),
            eliteCount,
            currentGenerationIndex,
            startTime);
    // Notify observers of the state of the population.
    notifyPopulationChange(data);

    List<TerminationCondition> satisfiedConditions =
        EvolutionUtils.shouldContinue(data, conditions);
    while (satisfiedConditions == null) {
      ++currentGenerationIndex;
      evaluatedPopulation = nextEvolutionStep(evaluatedPopulation, eliteCount, rng);
      EvolutionUtils.sortEvaluatedPopulation(evaluatedPopulation, fitnessEvaluator.isNatural());
      data =
          EvolutionUtils.getPopulationData(
              evaluatedPopulation,
              fitnessEvaluator.isNatural(),
              eliteCount,
              currentGenerationIndex,
              startTime);
      // Notify observers of the state of the population.
      notifyPopulationChange(data);
      notifyMyPopulationChange(new MyPopulationData<T>(data, evaluatedPopulation));
      satisfiedConditions = EvolutionUtils.shouldContinue(data, conditions);
    }
    this.satisfiedTerminationConditions = satisfiedConditions;
    return evaluatedPopulation;
  }
  /**
   * Takes a population, assigns a fitness score to each member and returns the members with their
   * scores attached, sorted in descending order of fitness (descending order of fitness score for
   * natural scores, ascending order of scores for non-natural scores).
   *
   * @param population The population to evaluate (each candidate is assigned a fitness score).
   * @return The evaluated population (a list of candidates with attached fitness scores).
   */
  protected List<EvaluatedCandidate<T>> evaluatePopulation(List<T> population) {
    List<EvaluatedCandidate<T>> evaluatedPopulation =
        new ArrayList<EvaluatedCandidate<T>>(population.size());

    if (singleThreaded) // Do fitness evaluations on the request thread.
    {
      for (T candidate : population) {
        evaluatedPopulation.add(
            new EvaluatedCandidate<T>(
                candidate, fitnessEvaluator.getFitness(candidate, population)));
      }
    } else {
      // Divide the required number of fitness evaluations equally among
      // the
      // available processors and coordinate the threads so that we do not
      // proceed until all threads have finished processing.
      try {
        List<T> unmodifiablePopulation = Collections.unmodifiableList(population);
        List<Future<EvaluatedCandidate<T>>> results =
            new ArrayList<Future<EvaluatedCandidate<T>>>(population.size());
        // Submit tasks for execution and wait until all threads have
        // finished fitness evaluations.
        for (T candidate : population) {
          results.add(
              getSharedWorker()
                  .submit(
                      new FitnessEvalutationTask<T>(
                          fitnessEvaluator, candidate, unmodifiablePopulation)));
        }
        for (Future<EvaluatedCandidate<T>> result : results) {
          evaluatedPopulation.add(result.get());
        }
      } catch (ExecutionException ex) {
        throw new IllegalStateException("Fitness evaluation task execution failed.", ex);
      } catch (InterruptedException ex) {
        // Restore the interrupted status, allows methods further up the
        // call-stack
        // to abort processing if appropriate.
        Thread.currentThread().interrupt();
      }
    }

    return evaluatedPopulation;
  }
 /**
  * Compares the given Chromosome to this Chromosome. This chromosome is considered to be "less
  * than" the given chromosome if it has a fewer number of genes or if any of its gene values
  * (alleles) are less than their corresponding gene values in the other chromosome.
  *
  * @param other the Chromosome against which to compare this chromosome
  * @return a negative number if this chromosome is "less than" the given chromosome, zero if they
  *     are equal to each other, and a positive number if this chromosome is "greater than" the
  *     given chromosome
  * @author Neil Rotstan
  * @author Klaus Meffert
  * @since 1.0
  */
 public int compareTo(Object other) {
   // First, if the other Chromosome is null, then this chromosome is
   // automatically the "greater" Chromosome.
   // ---------------------------------------------------------------
   if (other == null) {
     return 1;
   }
   int size = size();
   IChromosome otherChromosome = (IChromosome) other;
   Gene[] otherGenes = otherChromosome.getGenes();
   // If the other Chromosome doesn't have the same number of genes,
   // then whichever has more is the "greater" Chromosome.
   // --------------------------------------------------------------
   if (otherChromosome.size() != size) {
     return size() - otherChromosome.size();
   }
   // Next, compare the gene values (alleles) for differences. If
   // one of the genes is not equal, then we return the result of its
   // comparison.
   // ---------------------------------------------------------------
   for (int i = 0; i < size; i++) {
     int comparison = getGene(i).compareTo(otherGenes[i]);
     if (comparison != 0) {
       return comparison;
     }
   }
   // Compare current fitness value.
   // ------------------------------
   if (m_fitnessValue != otherChromosome.getFitnessValueDirectly()) {
     FitnessEvaluator eval = getConfiguration().getFitnessEvaluator();
     if (eval != null) {
       if (eval.isFitter(m_fitnessValue, otherChromosome.getFitnessValueDirectly())) {
         return 1;
       } else {
         return -1;
       }
     } else {
       // undetermined order, but unequal!
       // --------------------------------
       return -1;
     }
   }
   if (m_compareAppData) {
     // Compare application data.
     // -------------------------
     if (getApplicationData() == null) {
       if (otherChromosome.getApplicationData() != null) {
         return -1;
       }
     } else if (otherChromosome.getApplicationData() == null) {
       return 1;
     } else {
       if (getApplicationData() instanceof Comparable) {
         try {
           return ((Comparable) getApplicationData())
               .compareTo(otherChromosome.getApplicationData());
         } catch (ClassCastException cex) {
           /** @todo improve */
           return -1;
         }
       } else {
         return getApplicationData()
             .getClass()
             .getName()
             .compareTo(otherChromosome.getApplicationData().getClass().getName());
       }
     }
   }
   // Everything is equal. Return zero.
   // ---------------------------------
   return 0;
 }
Exemple #4
0
	void run(){
		fitness.evaluate(population);
	}