/** * Inserts the classifier in the population. Before that, it looks if there is a classifier in the * population with the same action and condition (in this case, increments its numerosity). After, * it checks that the number of micro classifiers is less than the maximum population size. If it * isn't, it deletes one classifier from the population calling the deleteClassifier function. It * inserts the classifier in the population and in the action set if it's not null. * * @param cl is the classifier that has to be inserted in the population. * @param ASet Population where the classifier will be inserted. */ public void insertInPopulation(Classifier cl, Population ASet) { boolean found = false; int i = 0; while (i < macroClSum && !found) { if (set[i].equals(cl)) { set[i].increaseNumerosity(cl.getNumerosity()); microClSum += cl.getNumerosity(); if (ASet != null) { if (ASet.isThereClassifier(set[i]) >= 0) ASet.microClSum += cl.getNumerosity(); } found = true; } i++; } if (!found) { addClassifier(cl); } // Here, the classifier has been added to the population if (microClSum > Config.popSize) { // If we have inserted to many classifiers, we have to delete one. deleteClFromPopulation(ASet); } } // end insertInPopulation
/** * Unmarshall a Genotype instance from a given XML Element representation. Its population of * Chromosomes will be unmarshalled from the Chromosome sub-elements. * * @param a_activeConfiguration the current active Configuration object that is to be used during * construction of the Genotype and Chromosome instances * @param a_xmlElement the XML Element representation of the Genotype * @return a new Genotype instance, complete with a population of Chromosomes, setup with the data * from the XML Element representation * @throws ImproperXMLException if the given Element is improperly structured or missing data * @throws InvalidConfigurationException if the given Configuration is in an inconsistent state * @throws UnsupportedRepresentationException if the actively configured Gene implementation does * not support the string representation of the alleles used in the given XML document * @throws GeneCreationException if there is a problem creating or populating a Gene instance * @author Neil Rotstan * @author Klaus Meffert * @since 1.0 */ public static Genotype getGenotypeFromElement( Configuration a_activeConfiguration, Element a_xmlElement) throws ImproperXMLException, InvalidConfigurationException, UnsupportedRepresentationException, GeneCreationException { // Sanity check. Make sure the XML element isn't null and that it // actually represents a genotype. if (a_xmlElement == null || !(a_xmlElement.getTagName().equals(GENOTYPE_TAG))) { throw new ImproperXMLException( "Unable to build Genotype instance from XML Element: " + "given Element is not a 'genotype' element."); } // Fetch all of the nested chromosome elements and convert them // into Chromosome instances. // ------------------------------------------------------------ NodeList chromosomes = a_xmlElement.getElementsByTagName(CHROMOSOME_TAG); int numChromosomes = chromosomes.getLength(); Population population = new Population(a_activeConfiguration, numChromosomes); for (int i = 0; i < numChromosomes; i++) { population.addChromosome( getChromosomeFromElement(a_activeConfiguration, (Element) chromosomes.item(i))); } // Construct a new Genotype with the chromosomes and return it. // ------------------------------------------------------------ return new Genotype(a_activeConfiguration, population); }
/** * @param a_population the population of chromosomes from the current evolution prior to exposure * to any genetic operators. Chromosomes in this array should not be modified. Please, notice, * that the call in Genotype.evolve() to the implementations of GeneticOperator overgoes this * due to performance issues * @param a_candidateChromosomes the pool of chromosomes that have been selected for the next * evolved population * @author Audrius Meskauskas * @author Klaus Meffert * @since 3.3.2 */ public void operate(final Population a_population, List a_candidateChromosomes) { // this was a private variable, now it is local reference. final IUniversalRateCalculator m_mutationRateCalc = getMutationRateCalc(); // If the mutation rate is set to zero and dynamic mutation rate is // disabled, then we don't perform any mutation. // ---------------------------------------------------------------- if (getMutationRate() == 0 && m_mutationRateCalc == null) { return; } // Determine the mutation rate. If dynamic rate is enabled, then // calculate it based upon the number of genes in the chromosome. // Otherwise, go with the mutation rate set upon construction. // -------------------------------------------------------------- int currentRate; if (m_mutationRateCalc != null) { currentRate = m_mutationRateCalc.calculateCurrentRate(); } else { currentRate = getMutationRate(); } RandomGenerator generator = getConfiguration().getRandomGenerator(); // It would be inefficient to create copies of each Chromosome just // to decide whether to mutate them. Instead, we only make a copy // once we've positively decided to perform a mutation. // ---------------------------------------------------------------- int size = a_population.size(); for (int i = 0; i < size; i++) { IChromosome x = a_population.getChromosome(i); // This returns null if not mutated: IChromosome xm = operate(x, currentRate, generator); if (xm != null) { a_candidateChromosomes.add(xm); } } }
/** * It creates a new Population with only the sufficiently experienced classifiers. * * @param maxReward is the maximum reward of the environment. * @return a Population with the experienced population */ public Population deleteNotExpClassifiers(double maxReward) { // We create a Config.popSize population instead of a macroClSum classifier, because, if it's // used in a training execution, this population can increase (new classifiers can be added). Population pExp = new Population(Config.popSize); for (int i = 0; i < macroClSum; i++) { if (set[i].couldReduce(maxReward)) { pExp.addClassifier(set[i]); } } return pExp; } // end deleteNotExpClassifiers
public static boolean xor_epoch(Population pop, int generation, String filename) { boolean esito = false; // Evaluate each organism if exist the winner......... boolean win = false; Iterator itr_organism; itr_organism = pop.organisms.iterator(); while (itr_organism.hasNext()) { // point to organism Organism _organism = ((Organism) itr_organism.next()); // evaluate esito = xor_evaluate(_organism); // if is a winner , store a flag if (esito) win = true; } // compute average and max fitness for each species Iterator itr_specie; itr_specie = pop.species.iterator(); while (itr_specie.hasNext()) { Species _specie = ((Species) itr_specie.next()); _specie.compute_average_fitness(); _specie.compute_max_fitness(); } // Only print to file every print_every generations if (win || (generation % Neat.p_print_every) == 0) pop.print_to_file_by_species("c:\\jneat\\dati\\" + filename); // if exist a winner write to file if (win) { int cnt = 0; itr_organism = pop.getOrganisms().iterator(); while (itr_organism.hasNext()) { Organism _organism = ((Organism) itr_organism.next()); if (_organism.winner) { System.out.print("\n -WINNER IS #" + _organism.genome.genome_id); _organism.getGenome().print_to_filename("c:\\jneat\\dati\\xor_win" + cnt); cnt++; } } } // wait an epoch and make a reproductionof the best species pop.epoch(generation); if (win) { System.out.print("\t\t** I HAVE FOUND A CHAMPION **"); return true; } else return false; }
public boolean needsToRun(Run run, int generation) { Population pop = getPopulationFor(run, generation); int count = run.getIntProperty(GenetikConstants.POPULATION, Integer.MAX_VALUE, true); int scoreCount = 0; for (int i = 0, max = pop.size(); i < max; i++) { Individual ind = pop.get(i); if (ind.hasFitness() && ind.hasScores()) { scoreCount++; } } return scoreCount != count; }
/** * This constructor creates the match set of the population. It has to cover the uncovered actions * while, at least, the theta_mna actions aren't covered. It uses the actionCovered variable to do * this. * * @param envState is the state of the input (it has to take the classifiers that match with it). * @param pop is the population of the system (it contains all the classifiers). * @param tStamp it's the actual time. It's needed to create the new classifiers). * @param isExploreExecution indicates if the current step is an explore or an exploit trail, * because the covering operator will be applied or not. */ public Population(double[] envState, Population pop, int tStamp, boolean isExploreExecution) { int pos = 0; // A population of size parent.numerosity + numberOfActions is needed, // because in the worst case, it will have to cover all the actions. set = new Classifier[pop.macroClSum + Config.numberOfActions]; microClSum = 0; macroClSum = 0; parentRef = pop; specify = new Specify(); boolean[] actionCovered = new boolean[Config.numberOfActions]; for (pos = 0; pos < actionCovered.length; pos++) { actionCovered[pos] = false; } for (pos = 0; pos < pop.getMacroClSum(); pos++) { if (pop.set[pos].match(envState)) { addClassifier(pop.set[pos]); actionCovered[pop.set[pos].getAction()] = true; } } if (isExploreExecution) { Covering cov = new Covering(); cov.coverActions(pop, this, envState, tStamp, actionCovered); } } // end Population
/** * Marshall a Genotype instance into an XML Element representation, including its population of * Chromosome instances as sub-elements. This may be useful in scenarios where representation as * an entire Document is undesirable, such as when the representation of this Genotype is to be * combined with other elements in a single Document. * * @param a_subject the genotype to represent as an XML element * @param a_xmlDocument a Document instance that will be used to create the Element instance. Note * that the element will NOT be added to the document by this method * @return an Element object representing the given Genotype * @author Neil Rotstan * @since 1.0 * @deprecated use XMLDocumentBuilder instead */ public static Element representGenotypeAsElement( final Genotype a_subject, final Document a_xmlDocument) { Population population = a_subject.getPopulation(); // Start by creating the genotype element and its size attribute, // which represents the number of chromosomes present in the // genotype. // -------------------------------------------------------------- Element genotypeTag = a_xmlDocument.createElement(GENOTYPE_TAG); genotypeTag.setAttribute(SIZE_ATTRIBUTE, Integer.toString(population.size())); // Next, add nested elements for each of the chromosomes in the // genotype. // ------------------------------------------------------------ for (int i = 0; i < population.size(); i++) { Element chromosomeElement = representChromosomeAsElement(population.getChromosome(i), a_xmlDocument); genotypeTag.appendChild(chromosomeElement); } return genotypeTag; }
/** This method applies the action set subsumption */ public void doActionSetSubsumption() { int i, pos = 0; Classifier cl = null; for (i = 0; i < macroClSum; i++) { if (set[i].couldSubsume()) { if (cl == null || set[i].numberOfDontCareSymbols() > cl.numberOfDontCareSymbols() || (set[i].numberOfDontCareSymbols() == cl.numberOfDontCareSymbols() && Config.rand() < 0.5)) { cl = set[i]; pos = i; } } } if (cl != null) { for (i = 0; i < macroClSum; i++) { if (cl != set[i] && cl.isMoreGeneral(set[i])) { cl.increaseNumerosity(set[i].getNumerosity()); // Now, the classifier has to be removed from the actionSet and the population. // It's deleted from the action set. Classifier clDeleted = set[i]; deleteClassifier(i); // And now, it's deleted from the population Population p = parentRef; while (p.parentRef != null) { p = p.parentRef; } pos = p.isThereClassifier( clDeleted); // The classifier is searched in the initial population. if (pos >= 0) p.deleteClassifier(pos); } } } } // end doActionSetSubsumption
/** * It creates the D population defined by Wilson 2002. It creates a population with the minimum * number of classifiers that cover all the input examples. * * @param env Environment to be set in the new population. * @return the D population created */ public Population createMCompPopulation(Environment env) { int moreMatches = 0, maxMatched = 0; // We create a Config.popSize population instead of a macroClSum classifier, because, if it's // used in a training execution, this population can increase (new classifiers can be added). Population Mcomp = new Population(Config.popSize); while (env.getNumberOfExamples() > 0 && macroClSum > 0) { moreMatches = 0; maxMatched = set[0].getNumberMatches(); for (int i = 1; i < macroClSum; i++) { if (set[i].getNumberMatches() > maxMatched) { maxMatched = set[i].getNumberMatches(); moreMatches = i; } } Mcomp.addClassifier(set[moreMatches]); env.deleteMatchedExamples(set[moreMatches]); deleteClassifier(moreMatches); } return Mcomp; } // end createMcompPopulation
/** * This is a sample of creating a new Population with 'size_population' organisms , and simulation * of XOR example This sample can be started in two modality : -cold : each time the population is * re-created from 0; -warm : each time the population re-read last population created and restart * from last epoch. (the population backup file is : 'c:\\jneat\\dati\\population.primitive' */ public static void Experiment3(int size_population, int mode, int gens) { Population pop = null; String fname_prefix = "c:\\jneat\\dati\\population.primitive"; String fnamebuf; int gen; int id; int expcount = 0; String mask6 = "000000"; DecimalFormat fmt6 = new DecimalFormat(mask6); System.out.println("------ Start experiment 3 -------"); for (expcount = 0; expcount < Neat.p_num_runs; expcount++) { System.out.println(" Spawned population off genome"); double prb_link = 0.50; boolean recurrent = true; // default cold is : 3 sensor (1 for bias) , 1 out , 5 nodes max, no recurrent if (mode == NeatConstant.COLD) pop = new Population(size_population, 3, 1, 5, recurrent, prb_link); // cold start-up // pop = new Population(size_population, 3, 1, 5, recurrent, prb_link); // cold start-up else pop = new Population(fname_prefix + ".last"); // warm start-up pop.verify(); System.out.print("\n---------------- Generation starting with----------"); System.out.print("\n Population : innov num = " + pop.getCur_innov_num()); System.out.print("\n : cur_node_id = " + pop.getCur_node_id()); System.out.print("\n---------------------------------------------------"); System.out.print("\n"); for (gen = 1; gen <= gens; gen++) { System.out.print("\n---------------- Generation ----------------------" + gen); fnamebuf = "g_" + fmt6.format(gen); boolean esito = xor_epoch(pop, gen, fnamebuf); System.out.print("\n Population : innov num = " + pop.getCur_innov_num()); System.out.print("\n : cur_node_id = " + pop.getCur_node_id()); System.out.print("\n result : " + esito); } } // backup of population for warm startup pop.print_to_filename(fname_prefix + ".last"); System.out.println("\n\n End of experiment"); }
/** * Deletes one classifier from the population. After that, if the population passed as a parameter * is not null, it looks for the deleted classifier. If it is in the second population, it will * delete it too. * * @param aSet is the population where the deleted classifier has to be searched. * @return a Classifier that contains the deleted classifier. */ public Classifier deleteClFromPopulation(Population aSet) { // A classifier has been deleted from the population Classifier clDeleted = deleteClassifier(); if (aSet != null) { // Now, this classifier has to be deleted from the action set (if it exists in). int pos = aSet.isThereClassifier(clDeleted); // It is searched in the action set. if (pos >= 0) { // It has to be deleted from the action set too. aSet.microClSum--; // If the classifier has 0 numerosity, we remove it from the population. if (clDeleted.getNumerosity() == 0) { // It has to be completely deleted from action set. aSet.macroClSum--; // Decrements the number of macroclassifiers aSet.set[pos] = aSet.set[aSet.macroClSum]; // Moves the last classifier to the deleted one aSet.set[aSet.macroClSum] = null; // Puts the last classifier to null. } } } return clDeleted; } // end deleteClFromPopulation
/** * this is a standard experiment for XOR emulation; is passed a name of a started genome and a * number of times can be execute this experiment; */ public static void Experiment1(String xFileName, int gens) { String fname_prefix = "c:\\jneat\\dati\\population.natural"; Population pop = null; StringTokenizer st; String curword; String xline; String fnamebuf; int gen; IOseq xFile; int id; int expcount = 0; String mask6 = "000000"; DecimalFormat fmt6 = new DecimalFormat(mask6); System.out.println("------ Start experiment 1 -------"); xFile = new IOseq(xFileName); boolean ret = xFile.IOseqOpenR(); if (ret) { try { System.out.println(" Start XOR experiment"); System.out.println(" .read start genome.."); xline = xFile.IOseqRead(); st = new StringTokenizer(xline); // skip curword = st.nextToken(); // id of genome can be readed curword = st.nextToken(); id = Integer.parseInt(curword); System.out.println(" .create genome id " + id); Genome start_genome = new Genome(id, xFile); // backup this 'initial' genome (is only for test // if the read & write are correct start_genome.print_to_filename("c:\\jneat\\dati\\genome.readed"); for (expcount = 0; expcount < Neat.p_num_runs; expcount++) { System.out.println(" Spawned population off genome"); pop = new Population(start_genome, Neat.p_pop_size); System.out.print("\n\n Verifying Spawned Pop"); pop.verify(); System.out.print("\n"); for (gen = 1; gen <= gens; gen++) { System.out.print("\n---------------- E P O C H < " + gen + " >--------------"); fnamebuf = "g_" + fmt6.format(gen); boolean esito = xor_epoch(pop, gen, fnamebuf); } System.out.print("\n Population : innov num = " + pop.getCur_innov_num()); System.out.print("\n : cur_node_id = " + pop.getCur_node_id()); pop.print_to_filename(fname_prefix); } } catch (Throwable e) { System.err.println(e + " : error during read " + xFileName); } xFile.IOseqCloseR(); } else System.err.print("\n : error during open " + xFileName); System.out.println("\n\n End of experiment"); }
/** It's the new reduction algorithm. (Experimental phase) */ private void reductInTrain() { double averageUseful = 0.0, stdUseful = 0.0; int i = 0; int numSum = 0; // A reference to the population is gotten. Population pop = this.getParentRef().getParentRef(); while (i < macroClSum) { if (!set[i].couldComp()) { numSum += set[i].getNumerosity(); set[i].setNumerosity(0); // The classifier is removed from the [A] set[i] = set[macroClSum - 1]; macroClSum--; ///// numAplicacions++; } else { averageUseful += set[i].getUsefulTimes(); stdUseful += (set[i].getUsefulTimes() * set[i].getUsefulTimes()); i++; } } if (macroClSum > 0) { if (macroClSum > 1) stdUseful = Math.sqrt( (stdUseful - ((averageUseful * averageUseful) / macroClSum)) / (macroClSum - 1)); averageUseful = averageUseful / (double) macroClSum; // With the "thres" parameter you can control the compactation pressure (add or substract the // stdUseful) int thres = (int) (averageUseful - stdUseful); i = 0; averageUseful = 0; while (i < macroClSum) { if (set[i].getUsefulTimes() < thres && set[i].getPrediction() > Config.Preduct) { numSum += set[i].getNumerosity(); set[i].setNumerosity(0); set[i] = set[macroClSum - 1]; macroClSum--; ///// numAplicacions++; } else { // We add the contribuion of each classifier to distribute the numerosity at the end averageUseful += set[i].getUsefulTimes(); i++; } } // The numerosity of classifiers deleted are set to other classifiers in the population. int addNum = 0; int discount = 0; for (i = 0; i < macroClSum - 1; i++) { addNum = (int) (((double) set[i].getUsefulTimes() / averageUseful) * (double) numSum); set[i].increaseNumerosity(addNum); discount += addNum; } if (macroClSum > 0) set[macroClSum - 1].increaseNumerosity(numSum - discount); } else { microClSum -= numSum; pop.microClSum -= numSum; } pop.deleteClWithZeroNum(); }