package net.sf.jclec.problem.funopt.binarray; import net.sf.jclec.IConfigure; import net.sf.jclec.util.range.IRange; import net.sf.jclec.binarray.AbstractBinArraySpecies; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationRuntimeException; /** * Species for FunctOptBinArrayIndividuals. * * @author Sebastián Ventura */ public class FuncOptBinArrayIndividualSpecies extends AbstractBinArraySpecies<FuncOptBinArrayIndividual> implements IConfigure { ///////////////////////////////////////////////////////////////// // --------------------------------------- Serialization constant ///////////////////////////////////////////////////////////////// /** Generated by Eclipse */ private static final long serialVersionUID = -852163469373712320L; ///////////////////////////////////////////////////////////////// // --------------------------------------------------- Properties ///////////////////////////////////////////////////////////////// /** Search subspace */ protected SearchSpaceElement [] searchSpace; ///////////////////////////////////////////////////////////////// // ------------------------------------------------- Constructors ///////////////////////////////////////////////////////////////// /** * Empty (default) constructor */ public FuncOptBinArrayIndividualSpecies() { super(); } ///////////////////////////////////////////////////////////////// // ------------------------------- Setting and getting properties ///////////////////////////////////////////////////////////////// public SearchSpaceElement [] getSearchSpace() { return searchSpace; } public void setSearchSpace(SearchSpaceElement [] searchSpace) { this.searchSpace = searchSpace; } ///////////////////////////////////////////////////////////////// // ---------------------------------------------- Factory methods ///////////////////////////////////////////////////////////////// /** * Default factory method. */ public FuncOptBinArrayIndividual createIndividual() { return new FuncOptBinArrayIndividual(); } /** * Factory method. Create new individuals from its genotype. * * @param genotype Individual genotype */ public FuncOptBinArrayIndividual createIndividual(byte[] genotype) { return new FuncOptBinArrayIndividual(genotype, decode(genotype)); } ///////////////////////////////////////////////////////////////// // ------------------ Overwriting AbstractBinArraySpecies methods ///////////////////////////////////////////////////////////////// @Override public int getGenotypeLength() { // Set genotypeSchema, if necessary if (genotypeSchema == null) setGenotypeSchema(); // Call super method return genotypeSchema.length; } @Override public byte [] getGenotypeSchema() { // Set genotypeSchema, if necessary if (genotypeSchema == null) setGenotypeSchema(); // Call super method return genotypeSchema; } ///////////////////////////////////////////////////////////////// // ---------------------------- Implementing IConfigure interface ///////////////////////////////////////////////////////////////// /** * Configuration method. * * Configuration settings for FuncOptBinArrayIndividualSpecies are: * * <ul> * <li> * <code>search-space: complex</code> * <ul> * <li> * <code>search-space[@number-of-dimensions]: int</code></p> * Number of dimensions in search space * </li> * <li> * <code>search-space.dimension(i) complex (i=0...'number-of-dimensions'-1) * <ul> * <li> * <code>search-space.dimension(i).precission int</code></p> * Number of bits used to represent this space dimension. * </li> * <li> * <code>search-space.dimension(i).range IRange (complex)</code></p> * Search space range. * </li> * </ul> * </li> * </ul> * </li> * </ul> */ @SuppressWarnings("unchecked") public void configure(Configuration settings) { // Get number of dimensions atribute int dimension = settings.getInt("search-space[@number-of-dimensions]"); // Allocate space for search space searchSpace = new SearchSpaceElement[dimension]; // Get all search space elements for (int i=0; i<dimension; i++) { // Create searchSpaceElement object SearchSpaceElement element = new SearchSpaceElement(); // Configuration header String header = "search-space.dimension("+i+")"; // Precission int precission = settings.getInt(header+".precission"); // Set element precission element.setPrecission(precission); // Search range try { // Range classname String rangeClassname = settings.getString(header+".range[@type]"); // Evaluator class Class<? extends IRange> rangeClass = (Class<? extends IRange>) Class.forName(rangeClassname); // Evaluator instance IRange range = rangeClass.newInstance(); // Configure species if (range instanceof IConfigure) { ((IConfigure) range).configure(settings.subset(header+".range")); } // Set range element.setRange(range); } catch (ClassNotFoundException e) { throw new ConfigurationRuntimeException("Illegal range classname"); } catch (InstantiationException e) { throw new ConfigurationRuntimeException("Problems creating an instance of range", e); } catch (IllegalAccessException e) { throw new ConfigurationRuntimeException("Problems creating an instance of range", e); } // Set this search space element searchSpace[i] = element; } setSearchSpace(searchSpace); } ///////////////////////////////////////////////////////////////// // ---------------------------------- Implementing Object methods ///////////////////////////////////////////////////////////////// /** * {@inheritDoc} */ public boolean equals(Object other) { if (other instanceof FuncOptBinArrayIndividualSpecies) { FuncOptBinArrayIndividualSpecies cother = (FuncOptBinArrayIndividualSpecies) other; int dimension = searchSpace.length; if (dimension == cother.searchSpace.length) { EqualsBuilder eb = new EqualsBuilder(); for (int i=0; i<dimension; i++) { eb.append(searchSpace[i], cother.searchSpace[i]); } return eb.isEquals(); } else { return false; } } else { return false; } } ///////////////////////////////////////////////////////////////// // ---------------------------------------------- Private methods ///////////////////////////////////////////////////////////////// /** * Sets genotype schema as demand */ private final void setGenotypeSchema() { if (searchSpace == null) { throw new IllegalStateException(""); } else { // Phenotype length int phenotypeLength = searchSpace.length; // Calculate genotype length int genotypeLength = 0; for (int i=0; i<phenotypeLength; i++) { genotypeLength += searchSpace[i].getPrecission(); } // Set genotype schema genotypeSchema = new byte[genotypeLength]; for (int i=0; i<genotypeLength; i++) { genotypeSchema[i] = -1; } } } /** * Produces an individual phenotype from its genotype. * * @param An individual genotype * * @return An individual phenotype */ protected double [] decode(byte [] genotype) { // Phentoype length int phenotypeLength = searchSpace.length; // Allocate space for phenotype double [] result = new double[phenotypeLength]; // Actual locus counter int actualLocus = 0; // Decode all phenotype elements for (int i=0; i<phenotypeLength; i++) { // Genotype long conversion long lval = 0, mxval = 0; // Precission int precission = searchSpace[i].getPrecission(); // Value construction for (long j=0; j<precission; j++, actualLocus++) { int locus = genotype[actualLocus]; lval |= ((long) locus << j); mxval |= (1L << j); } // Resulting value result[i] = searchSpace[i].range.scale((double) lval/(double) mxval); } // Return phenotype return result; } }