/** * Determine the fitness of the given Chromosome instance. The higher the return value, the more * fit the instance. This method should always return the same fitness value for two equivalent * Chromosome instances. * * @param a_subject the Chromosome instance to evaluate * @return positive double reflecting the fitness rating of the given Chromosome * @since 2.0 (until 1.1: return type int) * @author Neil Rotstan, Klaus Meffert, John Serri */ public double evaluate(IChromosome a_subject) { int i = 0, j, k; for (j = 0; j < EvolvingSubsumptionForRobocode.numberOfEvents; j++) { eventPriority[j] = ((Integer) a_subject.getGene(i++).getAllele()).intValue(); } for (j = 0; j < EvolvingSubsumptionForRobocode.numberOfBehaviours; j++) { behaviourOverwrite[j] = ((Integer) a_subject.getGene(i++).getAllele()).intValue() > 50; } for (j = 0; j < EvolvingSubsumptionForRobocode.numberOfBehaviours; j++) { for (k = 0; k < EvolvingSubsumptionForRobocode.behaviourSize; k++) { behaviourActions[j][k] = ((Integer) a_subject.getGene(i++).getAllele()).intValue(); } } double tempFitness; double fitness = 0; for (j = 0; j < otherRobots.length; j++) { RobotSpecification[] tempRobots = new RobotSpecification[2]; tempRobots[0] = evolvable; tempRobots[1] = otherRobots[j]; battleSpecs = new BattleSpecification(1, new BattlefieldSpecification(800, 600), tempRobots); tempFitness = 0; System.out.println("Testing against " + otherRobots[j].getName() + "..."); for (i = 0; i < EvolvingSubsumptionForRobocode.numberOfBattles; i++) { engine.runBattle(battleSpecs, true); tempFitness += battleObserver.getScoreRobot() / 500; } tempFitness /= EvolvingSubsumptionForRobocode.numberOfBattles; fitness += tempFitness; } fitness /= otherRobots.length; return Math.min(1.0d, fitness); }
/** * Calculates the penalty to apply to the fitness value based on the ammount of coins in the * solution * * @param a_maxFitness maximum fitness value allowed * @param a_coins number of coins in the solution * @return penalty for the fitness value base on the number of coins * @author John Serri * @since 2.2 */ protected double computeCoinNumberPenalty(double a_maxFitness, int a_coins) { if (a_coins == 1) { // we know the solution cannot have less than one coin return 0; } else { // The more coins the more penalty, but not more than the maximum fitness // value possible. Let's avoid linear behavior and use // exponential penalty calculation instead return (Math.min(a_maxFitness, a_coins * a_coins)); } }
/** * Evolves the population of chromosomes within a genotype. This will execute all of the genetic * operators added to the present active configuration and then invoke the natural selector to * choose which chromosomes will be included in the next generation population. * * @param a_pop the population to evolve * @param a_conf the configuration to use for evolution * @return evolved population * @author Klaus Meffert * @since 3.2 */ public Population evolve(Population a_pop, Configuration a_conf) { Population pop = a_pop; int originalPopSize = a_conf.getPopulationSize(); boolean monitorActive = a_conf.getMonitor() != null; IChromosome fittest = null; // If first generation: Set age to one to allow genetic operations, // see CrossoverOperator for an illustration. // ---------------------------------------------------------------- if (a_conf.getGenerationNr() == 0) { int size = pop.size(); for (int i = 0; i < size; i++) { IChromosome chrom = pop.getChromosome(i); chrom.increaseAge(); } } else { // Select fittest chromosome in case it should be preserved and we are // not in the very first generation. // ------------------------------------------------------------------- if (a_conf.isPreserveFittestIndividual()) { /** @todo utilize jobs. In pop do also utilize jobs, especially for fitness computation */ fittest = pop.determineFittestChromosome(0, pop.size() - 1); } } if (a_conf.getGenerationNr() > 0) { // Adjust population size to configured size (if wanted). // Theoretically, this should be done at the end of this method. // But for optimization issues it is not. If it is the last call to // evolve() then the resulting population possibly contains more // chromosomes than the wanted number. But this is no bad thing as // more alternatives mean better chances having a fit candidate. // If it is not the last call to evolve() then the next call will // ensure the correct population size by calling keepPopSizeConstant. // ------------------------------------------------------------------ keepPopSizeConstant(pop, a_conf); } // Ensure fitness value of all chromosomes is udpated. // --------------------------------------------------- if (monitorActive) { // Monitor that fitness value of chromosomes is being updated. // ----------------------------------------------------------- a_conf .getMonitor() .event( IEvolutionMonitor.MONITOR_EVENT_BEFORE_UPDATE_CHROMOSOMES1, a_conf.getGenerationNr(), new Object[] {pop}); } updateChromosomes(pop, a_conf); if (monitorActive) { // Monitor that fitness value of chromosomes is being updated. // ----------------------------------------------------------- a_conf .getMonitor() .event( IEvolutionMonitor.MONITOR_EVENT_AFTER_UPDATE_CHROMOSOMES1, a_conf.getGenerationNr(), new Object[] {pop}); } // Apply certain NaturalSelectors before GeneticOperators will be executed. // ------------------------------------------------------------------------ pop = applyNaturalSelectors(a_conf, pop, true); // Execute all of the Genetic Operators. // ------------------------------------- applyGeneticOperators(a_conf, pop); // Reset fitness value of genetically operated chromosomes. // Normally, this should not be necessary as the Chromosome class // initializes each newly created chromosome with // FitnessFunction.NO_FITNESS_VALUE. But who knows which Chromosome // implementation is used... // ---------------------------------------------------------------- int currentPopSize = pop.size(); for (int i = originalPopSize; i < currentPopSize; i++) { IChromosome chrom = pop.getChromosome(i); chrom.setFitnessValueDirectly(FitnessFunction.NO_FITNESS_VALUE); // Mark chromosome as new-born. // ---------------------------- chrom.resetAge(); // Mark chromosome as being operated on. // ------------------------------------- chrom.increaseOperatedOn(); } // Increase age of all chromosomes which are not modified by genetic // operations. // ----------------------------------------------------------------- int size = Math.min(originalPopSize, currentPopSize); for (int i = 0; i < size; i++) { IChromosome chrom = pop.getChromosome(i); chrom.increaseAge(); // Mark chromosome as not being operated on. // ----------------------------------------- chrom.resetOperatedOn(); } // If a bulk fitness function has been provided, call it. // ------------------------------------------------------ BulkFitnessFunction bulkFunction = a_conf.getBulkFitnessFunction(); if (bulkFunction != null) { if (monitorActive) { // Monitor that bulk fitness will be called for evaluation. // -------------------------------------------------------- a_conf .getMonitor() .event( IEvolutionMonitor.MONITOR_EVENT_BEFORE_BULK_EVAL, a_conf.getGenerationNr(), new Object[] {bulkFunction, pop}); } /** @todo utilize jobs: bulk fitness function is not so important for a prototype! */ bulkFunction.evaluate(pop); if (monitorActive) { // Monitor that bulk fitness has been called for evaluation. // --------------------------------------------------------- a_conf .getMonitor() .event( IEvolutionMonitor.MONITOR_EVENT_AFTER_BULK_EVAL, a_conf.getGenerationNr(), new Object[] {bulkFunction, pop}); } } // Ensure fitness value of all chromosomes is udpated. // --------------------------------------------------- if (monitorActive) { // Monitor that fitness value of chromosomes is being updated. // ----------------------------------------------------------- a_conf .getMonitor() .event( IEvolutionMonitor.MONITOR_EVENT_BEFORE_UPDATE_CHROMOSOMES2, a_conf.getGenerationNr(), new Object[] {pop}); } updateChromosomes(pop, a_conf); if (monitorActive) { // Monitor that fitness value of chromosomes is being updated. // ----------------------------------------------------------- a_conf .getMonitor() .event( IEvolutionMonitor.MONITOR_EVENT_AFTER_UPDATE_CHROMOSOMES2, a_conf.getGenerationNr(), new Object[] {pop}); } // Apply certain NaturalSelectors after GeneticOperators have been applied. // ------------------------------------------------------------------------ pop = applyNaturalSelectors(a_conf, pop, false); // Fill up population randomly if size dropped below specified percentage // of original size. // ---------------------------------------------------------------------- if (a_conf.getMinimumPopSizePercent() > 0) { int sizeWanted = a_conf.getPopulationSize(); int popSize; int minSize = (int) Math.round(sizeWanted * (double) a_conf.getMinimumPopSizePercent() / 100); popSize = pop.size(); if (popSize < minSize) { IChromosome newChrom; IChromosome sampleChrom = a_conf.getSampleChromosome(); Class sampleChromClass = sampleChrom.getClass(); IInitializer chromIniter = a_conf.getJGAPFactory().getInitializerFor(sampleChrom, sampleChromClass); while (pop.size() < minSize) { try { /** * @todo utilize jobs as initialization may be time-consuming as invalid combinations * may have to be filtered out */ newChrom = (IChromosome) chromIniter.perform(sampleChrom, sampleChromClass, null); if (monitorActive) { // Monitor that fitness value of chromosomes is being updated. // ----------------------------------------------------------- a_conf .getMonitor() .event( IEvolutionMonitor.MONITOR_EVENT_BEFORE_ADD_CHROMOSOME, a_conf.getGenerationNr(), new Object[] {pop, newChrom}); } pop.addChromosome(newChrom); } catch (Exception ex) { throw new RuntimeException(ex); } } } } IChromosome newFittest = reAddFittest(pop, fittest); if (monitorActive && newFittest != null) { // Monitor that fitness value of chromosomes is being updated. // ----------------------------------------------------------- a_conf .getMonitor() .event( IEvolutionMonitor.MONITOR_EVENT_READD_FITTEST, a_conf.getGenerationNr(), new Object[] {pop, fittest}); } // Increase number of generations. // ------------------------------- a_conf.incrementGenerationNr(); // Fire an event to indicate we've performed an evolution. // ------------------------------------------------------- m_lastPop = pop; m_lastConf = a_conf; a_conf .getEventManager() .fireGeneticEvent(new GeneticEvent(GeneticEvent.GENOTYPE_EVOLVED_EVENT, this)); return pop; }
public void operate(final Population a_population, final List a_candidateChromosomes) { // Work out the number of crossovers that should be performed. // ----------------------------------------------------------- int m_crossoverRate = getCrossOverRate(); double m_crossoverRatePercent = getCrossOverRatePercent(); int size = Math.min(getConfiguration().getPopulationSize(), a_population.size()); int numCrossovers = 0; if (m_crossoverRate >= 0) { numCrossovers = size / m_crossoverRate; } else if (m_crossoverRateCalc != null) { numCrossovers = size / 6; } else { numCrossovers = (int) (size * m_crossoverRatePercent); } RandomGenerator generator = getConfiguration().getRandomGenerator(); IGeneticOperatorConstraint constraint = getConfiguration().getJGAPFactory().getGeneticOperatorConstraint(); // For each crossover, grab two random chromosomes, pick a random // locus (gene location), and then swap that gene and all genes // to the "right" (those with greater loci) of that gene between // the two chromosomes. // -------------------------------------------------------------- int index1, index2; crossoverValues = new int[size]; for (int i = 0; i < size; i++) { crossoverValues[i] = 0; } List<Integer> chromeSel = new ArrayList<Integer>(); for (int i = 0; i < size; i++) { if (m_crossoverRateCalc != null) { CrossoverRateCalculator ccalc = (CrossoverRateCalculator) m_crossoverRateCalc; ccalc.setCurrentFitness(a_population.getChromosome(i).getFitnessValue()); int numbers = ccalc.calculateCurrentRate(); crossoverValues[i] = numbers; while (numbers > 0) { chromeSel.add(i); numbers--; } } } int justtocheck = chromeSel.size(); if (m_crossoverRateCalc != null) { if (justtocheck == 0) { System.out.println("Exception Caught.. Crossover.. chromesel array is null!!"); for (int fix = 0; fix <= size - 2; fix++) { chromeSel.add(fix); } } } // for (int i = 0; i < numCrossovers; i++) { IChromosome chrom1; IChromosome chrom2; if (m_crossoverRateCalc != null) { index1 = generator.nextInt(chromeSel.size()); index2 = generator.nextInt(chromeSel.size()); chrom1 = a_population.getChromosome(chromeSel.get(index1)); chrom2 = a_population.getChromosome(chromeSel.get(index2)); } else { index1 = generator.nextInt(size); index2 = generator.nextInt(size); chrom1 = a_population.getChromosome(index1); chrom2 = a_population.getChromosome(index2); } // Verify that crossover is allowed. // --------------------------------- if (!isXoverNewAge() && chrom1.getAge() < 1 && chrom2.getAge() < 1) { // Crossing over two newly created chromosomes is not seen as helpful // here. // ------------------------------------------------------------------ continue; } if (constraint != null) { List v = new Vector(); v.add(chrom1); v.add(chrom2); if (!constraint.isValid(a_population, v, this)) { // Constraint forbids crossing over. // --------------------------------- continue; } } // Clone the chromosomes. // ---------------------- IChromosome firstMate = (IChromosome) ((ICloneable) chrom1).clone(); IChromosome secondMate = (IChromosome) ((ICloneable) chrom2).clone(); // Cross over the chromosomes. // --------------------------- doCrossover(firstMate, secondMate, a_candidateChromosomes, generator); } }
public float nextFloat() { return Math.min(Float.MAX_VALUE - 1, (float) (nextCauchy() * Float.MAX_VALUE)); }
public long nextLong() { return Math.min(Long.MAX_VALUE - 1, Math.round(nextCauchy() * Long.MAX_VALUE)); }
public int nextInt(final int a_ceiling) { return Math.min(a_ceiling - 1, (int) Math.round(nextCauchy() * a_ceiling)); }
public int nextInt() { return Math.min(Integer.MAX_VALUE - 1, (int) Math.round(nextCauchy() * Integer.MAX_VALUE)); }