/** {@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; }
void run(){ fitness.evaluate(population); }