/** * @throws Exception * @author Klaus Meffert */ public void testGetPopulationSize_0() throws Exception { Configuration conf = new Configuration(); assertEquals(0, conf.getPopulationSize()); final int SIZE = 22; conf.setPopulationSize(SIZE); assertEquals(SIZE, conf.getPopulationSize()); }
/** * @throws Exception * @author Klaus Meffert */ public void testGetter_0() throws Exception { Configuration conf = new Configuration(); Genotype.setStaticConfiguration(conf); assertEquals(false, conf.isLocked()); FitnessFunction fitFunc = new StaticFitnessFunction(2); conf.setFitnessFunction(fitFunc); Gene gene = new BooleanGene(conf); Chromosome sample = new Chromosome(conf, gene, 55); conf.setSampleChromosome(sample); NaturalSelector natSel = new WeightedRouletteSelector(); conf.addNaturalSelector(natSel, false); RandomGenerator randGen = new StockRandomGenerator(); conf.setRandomGenerator(randGen); IEventManager evMan = new EventManager(); conf.setEventManager(evMan); GeneticOperator mutOp = new MutationOperator(conf); conf.addGeneticOperator(mutOp); GeneticOperator croOp = new CrossoverOperator(conf); conf.addGeneticOperator(croOp); conf.setPopulationSize(7); assertEquals(fitFunc, conf.getFitnessFunction()); assertEquals(natSel, conf.getNaturalSelectors(false).get(0)); assertEquals(randGen, conf.getRandomGenerator()); assertEquals(sample, conf.getSampleChromosome()); assertEquals(evMan, conf.getEventManager()); assertEquals(7, conf.getPopulationSize()); assertEquals(2, conf.getGeneticOperators().size()); assertEquals(mutOp, conf.getGeneticOperators().get(0)); assertEquals(croOp, conf.getGeneticOperators().get(1)); }
/** * The reproduce method will be invoked on each of the reproduction operators referenced by the * current Configuration object during the evolution phase. Operators are given an opportunity to * run in the order they are added to the Configuration. Iterates over species and determines each * one's number of offspring based on fitness, then passes control to subclass <code> * reproduce( final Configuration config, * final List parents, int numOffspring, List offspring )</code> method to perform specific * reproduction. * * @param config The current active genetic configuration. * @param parentSpecies <code>List</code> contains <code>Species</code> objects containing parent * chromosomes from which to produce offspring. * @param offspring <code>List</code> contains offspring <code>ChromosomeMaterial</code> objects; * this method adds new offspring to this list * @throws InvalidConfigurationException * @see ReproductionOperator#reproduce(Configuration, List, int, List) */ public final void reproduce( final Configuration config, final List<Species> parentSpecies, List<ChromosomeMaterial> offspring) throws InvalidConfigurationException { // Calculate total fitness and number of elites int totalEliteCount = 0; // double totalSpeciesFitnessTemp = 0; final double[] speciesNewSizeProportional = new double[parentSpecies.size()]; int si = 0; for (Species species : parentSpecies) { // totalSpeciesFitnessTemp += species.getAverageFitnessValue(); totalEliteCount += species.getEliteCount(); speciesNewSizeProportional[si++] = species.getAverageFitnessValue(); } ArrayUtil.normaliseSum(speciesNewSizeProportional); final int targetNewOffspringCount = (int) Math.round((config.getPopulationSize() - totalEliteCount) * getSlice()); // final double totalSpeciesFitness = totalSpeciesFitnessTemp; // Make sure species don't drastically increase in size (in some cases an oscillation can // develop in the size // of a species where the species size increases massively and then decreases massively in // alternate // generations, for a reason too long to explain here). si = 0; for (Species species : parentSpecies) { int newSpeciesSize = (int) Math.round(speciesNewSizeProportional[si] * targetNewOffspringCount); if (newSpeciesSize > 1.5 * species.size()) { // Reduce new size. speciesNewSizeProportional[si] /= newSpeciesSize / (species.size() * 1.45); } si++; } // Allow for adjustments just made for proportional sizes. ArrayUtil.normaliseSum(speciesNewSizeProportional); si = 0; for (Species species : parentSpecies) { species.newProportionalSize = speciesNewSizeProportional[si++]; } if (targetNewOffspringCount > 0) { if (parentSpecies.isEmpty()) { throw new IllegalStateException("no parent species from which to produce offspring"); } final List<ChromosomeMaterial> newOffspring = Collections.synchronizedList(new ArrayList<ChromosomeMaterial>(targetNewOffspringCount)); // Reproduce from each species relative to its percentage of total fitness Parallel.foreach( parentSpecies, 0, new Parallel.Operation<Species>() { public void perform(Species species) { if (!species.isEmpty()) { double percentFitness = species.getAverageFitnessValue() / species.newProportionalSize; int numSpecieOffspring = (int) Math.round(species.newProportionalSize * targetNewOffspringCount) - species.getEliteCount(); // Always create at least one offspring with the clone operator, or any operator if // it has more than 50% of the slice. // (Otherwise there's no point hanging on to a species). if (numSpecieOffspring <= 0 && (getSlice() > 0.5 || getClass().equals(CloneReproductionOperator.class))) numSpecieOffspring = 1; if (numSpecieOffspring > 0) try { reproduce(config, species.getChromosomes(), numSpecieOffspring, newOffspring); } catch (InvalidConfigurationException e) { e.printStackTrace(); } } } }); // Remove random offspring if we have too many. while (newOffspring.size() > targetNewOffspringCount) { Collections.shuffle(newOffspring, config.getRandomGenerator()); newOffspring.remove(newOffspring.size() - 1); } for (ChromosomeMaterial c : newOffspring) { // Mutate if it has the same parents, otherwise according to probability. boolean mutate = c.getSecondaryParentId() != null && c.getPrimaryParentId().equals(c.getSecondaryParentId()); mutate |= mutateProbability > config.getRandomGenerator().nextDouble(); c.setShouldMutate(mutate); } // Add clones of random offspring if we don't have enough. while (newOffspring.size() > 0 && newOffspring.size() < targetNewOffspringCount) { int idx = config.getRandomGenerator().nextInt(newOffspring.size()); ChromosomeMaterial clonee = (ChromosomeMaterial) newOffspring.get(idx); ChromosomeMaterial c = clonee.clone(null); // Clones should always be mutated. c.setShouldMutate(true); newOffspring.add(c); } offspring.addAll(newOffspring); } }
public static void main(String[] args) { Funid funid = new Funid(); int executionTimes = 10; System.out.println("Start"); // Map<String, List<GeneticApplication>> applicationMap = new // HashMap<String, List<GeneticApplication>>(); // List<GeneticApplication> applications; List<Configuration> configurations = Configuration.getBasicsConfigurations(); try { for (Configuration config : configurations) { System.out.println(config.toString()); System.out.println("Algo 1"); System.out.println("Execucao;Melhor;Gen. Enc.;Med. P. Ini; Med. P. Fin.;Razao;Tempo"); for (int i = 0; i < executionTimes; i++) { funid.setPopulationSize(config.getPopulationSize()); System.out.print((i + 1) + ";"); GeneticParameters params = new GeneticParameters( config.getCrossoverRate(), config.getMutationRate(), config.getPopulationSize(), config.getMaxGeneration(), MAXIMIZE, new Elitism(), new OnePointCrosserOver(), new RoulleteSelector(MAXIMIZE), new InversionMutator(), funid); new GeneticApplication(funid.getInitialPopulation()).setParams(params).execute(); } System.out.println(config.toString()); System.out.println("Algo 2"); System.out.println("Execucao;Melhor;Gen. Enc.;Med. P. Ini; Med. P. Fin.;Razao;Tempo"); for (int i = 0; i < executionTimes; i++) { System.out.print((i + 1) + ";"); GeneticParameters params = new GeneticParameters( config.getCrossoverRate(), config.getMutationRate(), config.getPopulationSize(), config.getMaxGeneration(), MAXIMIZE, new Generational(), new TwoPointsCrosserOver(), new RoulleteSelector(MAXIMIZE), new InversionMutator(), funid); new GeneticApplication(funid.getInitialPopulation()).setParams(params).execute(); } } } catch (IOException e) { e.printStackTrace(); } }
/** * 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; }
/** * @throws Exception * @author Klaus Meffert * @since 2.6 */ public void testToString_1() throws Exception { Configuration conf = new ConfigurationForTesting(); conf.getGeneticOperators().clear(); conf.getNaturalSelectors(false).clear(); conf.getNaturalSelectors(true).clear(); privateAccessor.setField(conf, "m_eventManager", null); String s = trimString(conf.toString()); String eventmgr = conf.S_NONE; String genops = conf.S_NONE; // natural selectors (pre) String natselsPre = conf.S_NONE; // natural selectors (post) String natselsPost = conf.S_NONE; assertEquals( trimString( conf.S_CONFIGURATION + ":" + conf.S_CONFIGURATION_NAME + ":" + conf.getName() + " " + conf.S_POPULATION_SIZE + ":" + conf.getPopulationSize() + " " + conf.S_MINPOPSIZE + ":" + conf.getMinimumPopSizePercent() + " " + conf.S_CHROMOSOME_SIZE + ":" + conf.getChromosomeSize() + " " + conf.S_SAMPLE_CHROM + ":" + conf.S_SIZE + ":" + conf.getSampleChromosome().size() + " " + conf.S_TOSTRING + ":" + conf.getSampleChromosome().toString() + " " + conf.S_RANDOM_GENERATOR + ":" + conf.getRandomGenerator().getClass().getName() + " " + conf.S_EVENT_MANAGER + ":" + eventmgr + " " + conf.S_CONFIGURATION_HANDLER + ":" + conf.getConfigurationHandler().getName() + " " + conf.S_FITNESS_FUNCTION + ":" + conf.getFitnessFunction().getClass().getName() + " " + conf.S_FITNESS_EVALUATOR + ":" + conf.getFitnessEvaluator().getClass().getName() + " " + conf.S_GENETIC_OPERATORS + ":" + genops + " " + conf.S_NATURAL_SELECTORS + "(" + conf.S_PRE + ")" + ":" + natselsPre + " " + conf.S_NATURAL_SELECTORS + "(" + conf.S_POST + ")" + ":" + natselsPost + " " // + conf.S_POPCONSTANT_SELECTOR + ":" // + "null" + " " ), s); }
/** * @throws Exception * @author Klaus Meffert * @since 2.4 */ public void testToString_0() throws Exception { Configuration conf = new ConfigurationForTesting(); conf.addGeneticOperator(new MutationOperator(conf)); conf.addNaturalSelector(new WeightedRouletteSelector(conf), true); conf.addNaturalSelector(new WeightedRouletteSelector(conf), false); conf.addNaturalSelector(new BestChromosomesSelector(conf), false); String s = trimString(conf.toString()); String eventmgr = conf.getEventManager() != null ? conf.getEventManager().getClass().getName() : conf.S_NONE; String genops = ""; if (conf.getGeneticOperators().size() < 1) { genops = conf.S_NONE; } else { for (int i = 0; i < conf.getGeneticOperators().size(); i++) { if (i > 0) { genops += "; "; } genops += conf.getGeneticOperators().get(i).getClass().getName(); ; } } // natural selectors (pre) String natselsPre = ""; int natsize = conf.getNaturalSelectors(true).size(); if (natsize < 1) { natselsPre = conf.S_NONE; } else { for (int i = 0; i < natsize; i++) { if (i > 0) { natselsPre += "; "; } natselsPre += " " + conf.getNaturalSelectors(true).get(i).getClass().getName(); } } // natural selectors (post) String natselsPost = ""; natsize = conf.getNaturalSelectors(false).size(); if (natsize < 1) { natselsPost = conf.S_NONE; } else { for (int i = 0; i < natsize; i++) { if (i > 0) { natselsPost += "; "; } natselsPost += " " + conf.getNaturalSelectors(false).get(i).getClass().getName(); } } assertEquals( trimString( conf.S_CONFIGURATION + ":" + conf.S_CONFIGURATION_NAME + ":" + conf.getName() + " " + conf.S_POPULATION_SIZE + ":" + conf.getPopulationSize() + " " + conf.S_MINPOPSIZE + ":" + conf.getMinimumPopSizePercent() + " " + conf.S_CHROMOSOME_SIZE + ":" + conf.getChromosomeSize() + " " + conf.S_SAMPLE_CHROM + ":" + conf.S_SIZE + ":" + conf.getSampleChromosome().size() + " " + conf.S_TOSTRING + ":" + conf.getSampleChromosome().toString() + " " + conf.S_RANDOM_GENERATOR + ":" + conf.getRandomGenerator().getClass().getName() + " " + conf.S_EVENT_MANAGER + ":" + eventmgr + " " + conf.S_CONFIGURATION_HANDLER + ":" + conf.getConfigurationHandler().getName() + " " + conf.S_FITNESS_FUNCTION + ":" + conf.getFitnessFunction().getClass().getName() + " " + conf.S_FITNESS_EVALUATOR + ":" + conf.getFitnessEvaluator().getClass().getName() + " " + conf.S_GENETIC_OPERATORS + ":" + genops + " " + conf.S_NATURAL_SELECTORS + "(" + conf.S_PRE + ")" + ":" + natselsPre + " " + conf.S_NATURAL_SELECTORS + "(" + conf.S_POST + ")" + ":" + natselsPost + " " // + conf.S_POPCONSTANT_SELECTOR + ":" // + "null" + " " ), s); }