/** * Clones an object by using clone handlers. If no deep cloning possible, then return the * reference. * * @param a_object the object to clone * @return the cloned object, or the object itself if no coning supported * @throws Exception * @author Klaus Meffert * @since 2.6 */ protected Object cloneObject(Object a_object) throws Exception { if (a_object == null) { return null; } // Try to clone via a registered clone handler. // -------------------------------------------- ICloneHandler cloner = getConfiguration().getJGAPFactory().getCloneHandlerFor(a_object, a_object.getClass()); if (cloner != null) { return cloner.perform(a_object, null, this); } else { // No cloning supported, so just return the reference. // --------------------------------------------------- return a_object; } }
/** * Returns a copy of this Chromosome. The returned instance can evolve independently of this * instance. Note that, if possible, this method will first attempt to acquire a Chromosome * instance from the active ChromosomePool (if any) and set its value appropriately before * returning it. If that is not possible, then a new Chromosome instance will be constructed and * its value set appropriately before returning. * * @return copy of this Chromosome * @throws IllegalStateException instead of CloneNotSupportedException * @author Neil Rotstan * @author Klaus Meffert * @since 1.0 */ public synchronized Object clone() { // Before doing anything, make sure that a Configuration object // has been set on this Chromosome. If not, then throw an // IllegalStateException. // ------------------------------------------------------------ if (getConfiguration() == null) { throw new IllegalStateException( "The active Configuration object must be set on this " + "Chromosome prior to invocation of the clone() method."); } IChromosome copy = null; // Now, first see if we can pull a Chromosome from the pool and just // set its gene values (alleles) appropriately. // ------------------------------------------------------------ IChromosomePool pool = getConfiguration().getChromosomePool(); if (pool != null) { copy = pool.acquireChromosome(); if (copy != null) { Gene[] genes = copy.getGenes(); for (int i = 0; i < size(); i++) { genes[i].setAllele(getGene(i).getAllele()); } } } try { if (copy == null) { // We couldn't fetch a Chromosome from the pool, so we need to create // a new one. First we make a copy of each of the Genes. We explicity // use the Gene at each respective gene location (locus) to create the // new Gene that is to occupy that same locus in the new Chromosome. // ------------------------------------------------------------------- int size = size(); if (size > 0) { Gene[] copyOfGenes = new Gene[size]; for (int i = 0; i < copyOfGenes.length; i++) { copyOfGenes[i] = getGene(i).newGene(); Object allele = getGene(i).getAllele(); if (allele != null) { IJGAPFactory factory = getConfiguration().getJGAPFactory(); if (factory != null) { ICloneHandler cloner = factory.getCloneHandlerFor(allele, allele.getClass()); if (cloner != null) { try { allele = cloner.perform(allele, null, this); } catch (Exception ex) { throw new RuntimeException(ex); } } } } copyOfGenes[i].setAllele(allele); } // Now construct a new Chromosome with the copies of the genes and // return it. Also clone the IApplicationData object later on. // --------------------------------------------------------------- if (getClass() == Chromosome.class) { copy = new Chromosome(getConfiguration(), copyOfGenes); } else { copy = (IChromosome) getConfiguration().getSampleChromosome().clone(); copy.setGenes(copyOfGenes); } } else { if (getClass() == Chromosome.class) { copy = new Chromosome(getConfiguration()); } else { copy = (IChromosome) getConfiguration().getSampleChromosome().clone(); } } } copy.setFitnessValue(m_fitnessValue); // Clone constraint checker. // ------------------------- copy.setConstraintChecker(getConstraintChecker()); } catch (InvalidConfigurationException iex) { throw new IllegalStateException(iex.getMessage()); } // Also clone the IApplicationData object. // --------------------------------------- try { copy.setApplicationData(cloneObject(getApplicationData())); } catch (Exception ex) { throw new IllegalStateException(ex.getMessage()); } // Clone multi-objective object if necessary and possible. // ------------------------------------------------------- if (m_multiObjective != null) { if (getClass() == Chromosome.class) { try { ((Chromosome) copy).setMultiObjectives((List) cloneObject(m_multiObjective)); } catch (Exception ex) { throw new IllegalStateException(ex.getMessage()); } } } return copy; }