Source Code Cross Referenced for Chromosome.java in  » Development » jgap » org » jgap » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » jgap » org.jgap 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * JGAP offers a dual license model(see below for specific license information):
0003:         * + The LGPL may be used anytime.
0004:         * + The MPL may be used if at least $20 have been donated to the JGAP project
0005:         *   thru PayPal (see http://www.sourceforge.net/projects/jgap or, directly,
0006:         *   http://sourceforge.net/donate/index.php?group_id=11618).
0007:         *   Details about usage of JGAP under the MPL can be found at the homepage
0008:         *   http://jgap.sourceforge.net/.
0009:         *
0010:         * Specific license information (MPL and LGPL)
0011:         * -------------------------------------------
0012:         * The contents of this file are subject to the Mozilla Public License Version
0013:         * 1.1 (the "License"); you may not use this file except in compliance with the
0014:         * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
0015:         *
0016:         * Software distributed under the License is distributed on an "AS IS" basis,
0017:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
0018:         * the specific language governing rights and limitations under the License.
0019:         *
0020:         * The Original Code is 'JGAP - Java Genetic Algorithms Package'.
0021:         * The Initial Developer of the Original Code is Neil Rotstan. Portions created
0022:         * by the Initial Developer are Copyright (C) 2002- 2003 by Neil Rotstan.
0023:         * All Rights Reserved.
0024:         * Co-developer of the code is Klaus Meffert. Portions created by the co-
0025:         * developer are Copyright (C) 2003-2006 by Klaus Meffert. All Rights Reserved.
0026:         * Contributor(s): all the names of the contributors are added in the source
0027:         * code where applicable.
0028:         *
0029:         * Alternatively, the contents of this file may be used under the terms of the
0030:         * LGPL license (the "GNU LESSER PUBLIC LICENSE"), in which case the
0031:         * provisions of LGPL are applicable instead of those above.  If you wish to
0032:         * allow use of your version of this file only under the terms of the LGPL
0033:         * License and not to allow others to use your version of this file under
0034:         * the MPL, indicate your decision by deleting the provisions above and
0035:         * replace them with the notice and other provisions required by the LGPL.
0036:         * If you do not delete the provisions above, a recipient may use your version
0037:         * of this file under either the MPL or the LGPL.
0038:         *
0039:         * This library is free software; you can redistribute it and/or modify it
0040:         * under the terms of the MPL as stated above or under the terms of the LGPL.
0041:         * This library is distributed in the hope that it will be useful, but WITHOUT
0042:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
0043:         * FOR A PARTICULAR PURPOSE. See the GNU Lesser Public License for more
0044:         * details.
0045:         */package org.jgap;
0046:
0047:        import java.util.*;
0048:
0049:        /**
0050:         * Chromosomes represent potential solutions and consist of a fixed-length
0051:         * collection of genes. Each gene represents a discrete part of the solution.
0052:         * Each gene in the Chromosome may be backed by a different concrete
0053:         * implementation of the Gene interface, but all genes in a respective
0054:         * position (locus) must share the same concrete implementation across
0055:         * Chromosomes within a single population (genotype). In other words, gene 1
0056:         * in a chromosome must share the same concrete implementation as gene 1 in all
0057:         * other chromosomes in the population.
0058:         *
0059:         * @author Neil Rotstan
0060:         * @author Klaus Meffert
0061:         * @since 1.0
0062:         */
0063:        public class Chromosome extends BaseChromosome {
0064:            /** String containing the CVS revision. Read out via reflection!*/
0065:            private final static String CVS_REVISION = "$Revision: 1.95 $";
0066:            /**
0067:             * Application-specific data that is attached to this Chromosome.
0068:             * This data may assist the application in evaluating this Chromosome
0069:             * in the fitness function. JGAP does not operate on the data, aside
0070:             * from allowing it to be set and retrieved, and considering it with
0071:             * comparations (if user opted in to do so).
0072:             */
0073:            private Object m_applicationData;
0074:
0075:            /**
0076:             * Holds multiobjective values.
0077:             *
0078:             * @since 2.6
0079:             * @todo move to new subclass of Chromosome (and introduce new interface
0080:             * IMultiObjective with that)
0081:             */
0082:            private List m_multiObjective;
0083:
0084:            /**
0085:             * Keeps track of whether or not this Chromosome has been selected by
0086:             * the natural selector to move on to the next generation.
0087:             */
0088:            private boolean m_isSelectedForNextGeneration;
0089:
0090:            /**
0091:             * Stores the fitness value of this Chromosome as determined by the
0092:             * active fitness function. A value of -1 indicates that this field
0093:             * has not yet been set with this Chromosome's fitness values (valid
0094:             * fitness values are always positive).
0095:             *
0096:             * @since 2.0 (until 1.1: type int)
0097:             */
0098:            protected double m_fitnessValue = FitnessFunction.NO_FITNESS_VALUE;
0099:
0100:            /**
0101:             * Method compareTo(): Should we also consider the application data when
0102:             * comparing? Default is "false", as "true" means a Chromosome's losing its
0103:             * identity when application data is set differently!
0104:             *
0105:             * @since 2.2
0106:             */
0107:            private boolean m_compareAppData;
0108:
0109:            /**
0110:             * Optional helper class for checking if a given allele value to be set
0111:             * for a given gene is valid. If not, the allele value may not be set for the
0112:             * gene or the gene type (e.g. IntegerGene) is not allowed in general!
0113:             *
0114:             * @since 2.5
0115:             */
0116:            private IGeneConstraintChecker m_geneAlleleChecker;
0117:
0118:            /**
0119:             * If set to true the method getFitnessValue() will always (re-)calculate the
0120:             * fitness value. This may be necessary in case of environments where the
0121:             * state changes without the chromosome to notice
0122:             *
0123:             * @since 3.2.2
0124:             */
0125:            private boolean m_alwaysCalculate;
0126:
0127:            /**
0128:             * Default constructor, only provided for dynamic instantiation.<p>
0129:             * Attention: The configuration used is the one set with the static method
0130:             * Genotype.setConfiguration.
0131:             *
0132:             * @throws InvalidConfigurationException
0133:             *
0134:             * @author Klaus Meffert
0135:             * @since 2.4
0136:             */
0137:            public Chromosome() throws InvalidConfigurationException {
0138:                this (Genotype.getStaticConfiguration());
0139:            }
0140:
0141:            /**
0142:             * Constructor, provided for dynamic or minimal instantiation.
0143:             *
0144:             * @param a_configuration the configuration to use
0145:             * @throws InvalidConfigurationException
0146:             *
0147:             * @author Klaus Meffert
0148:             * @since 3.0
0149:             */
0150:            public Chromosome(final Configuration a_configuration)
0151:                    throws InvalidConfigurationException {
0152:                super (a_configuration);
0153:                m_alwaysCalculate = a_configuration.isAlwaysCalculateFitness();
0154:            }
0155:
0156:            /**
0157:             * Constructor, provided for instantiation via persistent representation.
0158:             *
0159:             * @param a_configuration the configuration to use
0160:             * @param a_persistentRepresentatuion valid persistent representation that
0161:             * was most likely obtained via getPersistentRepresentation()
0162:             * @throws InvalidConfigurationException
0163:             * @throws UnsupportedRepresentationException
0164:             *
0165:             * @author Klaus Meffert
0166:             * @since 3.2
0167:             */
0168:            public Chromosome(final Configuration a_configuration,
0169:                    String a_persistentRepresentatuion)
0170:                    throws InvalidConfigurationException,
0171:                    UnsupportedRepresentationException {
0172:                this (a_configuration);
0173:                setValueFromPersistentRepresentation(a_persistentRepresentatuion);
0174:            }
0175:
0176:            /**
0177:             * Constructor for specifying the number of genes.
0178:             *
0179:             * @param a_configuration the configuration to use
0180:             * @param a_desiredSize number of genes the chromosome contains of
0181:             * @throws InvalidConfigurationException
0182:             *
0183:             * @author Klaus Meffert
0184:             * @since 2.2
0185:             */
0186:            public Chromosome(final Configuration a_configuration,
0187:                    final int a_desiredSize)
0188:                    throws InvalidConfigurationException {
0189:                this (a_configuration);
0190:                if (a_desiredSize <= 0) {
0191:                    throw new IllegalArgumentException(
0192:                            "Chromosome size must be greater than zero");
0193:                }
0194:                setGenes(new Gene[a_desiredSize]);
0195:            }
0196:
0197:            /**
0198:             * Constructs a Chromosome of the given size separate from any specific
0199:             * Configuration. This constructor will use the given sample Gene to
0200:             * construct a new Chromosome instance containing genes all of the same
0201:             * type as the sample Gene. This can be useful for constructing sample
0202:             * chromosomes that use the same Gene type for all of their genes and that
0203:             * are to be used to setup a Configuration object.
0204:             *
0205:             * @param a_configuration the configuration to use
0206:             * @param a_sampleGene a concrete sampleGene instance that will be used
0207:             * as a template for all of the genes in this Chromosome
0208:             * @param a_desiredSize the desired size (number of genes) of this Chromosome
0209:             * @throws InvalidConfigurationException
0210:             *
0211:             * @author Neil Rotstan
0212:             * @author Klaus Meffert
0213:             * @since 1.0
0214:             */
0215:            public Chromosome(final Configuration a_configuration,
0216:                    final Gene a_sampleGene, final int a_desiredSize)
0217:                    throws InvalidConfigurationException {
0218:                this (a_configuration, a_desiredSize);
0219:                initFromGene(a_sampleGene);
0220:            }
0221:
0222:            public Chromosome(final Configuration a_configuration,
0223:                    Gene a_sampleGene, int a_desiredSize,
0224:                    IGeneConstraintChecker a_constraintChecker)
0225:                    throws InvalidConfigurationException {
0226:                this (a_configuration, a_desiredSize);
0227:                initFromGene(a_sampleGene);
0228:                setConstraintChecker(a_constraintChecker);
0229:            }
0230:
0231:            protected void initFromGene(Gene a_sampleGene) {
0232:                // Do sanity checking to make sure the parameters we were
0233:                // given are valid.
0234:                // ------------------------------------------------------
0235:                if (a_sampleGene == null) {
0236:                    throw new IllegalArgumentException(
0237:                            "Sample Gene cannot be null.");
0238:                }
0239:                // Populate the array of genes it with new Gene instances
0240:                // created from the sample gene.
0241:                // ------------------------------------------------------
0242:                int size = size();
0243:                for (int i = 0; i < size; i++) {
0244:                    setGene(i, a_sampleGene.newGene());
0245:                }
0246:            }
0247:
0248:            /**
0249:             * Constructs a Chromosome separate from any specific Configuration. This
0250:             * can be useful for constructing sample chromosomes that are to be used
0251:             * to setup a Configuration object.
0252:             *
0253:             * @param a_configuration the configuration to use
0254:             * @param a_initialGenes the initial genes of this Chromosome
0255:             * @throws InvalidConfigurationException
0256:             *
0257:             * @author Neil Rotstan
0258:             * @since 1.0
0259:             */
0260:            public Chromosome(final Configuration a_configuration,
0261:                    Gene[] a_initialGenes) throws InvalidConfigurationException {
0262:                this (a_configuration, a_initialGenes == null ? 0
0263:                        : a_initialGenes.length);
0264:                checkGenes(a_initialGenes);
0265:                setGenes(a_initialGenes);
0266:            }
0267:
0268:            /**
0269:             * Constructs a Chromosome separate from any specific Configuration. This
0270:             * can be useful for constructing sample chromosomes that are to be used
0271:             * to setup a Configuration object. Additionally, a constraint checker can be
0272:             * specified. It is used right here to verify the validity of the gene types
0273:             * supplied.
0274:             *
0275:             * @param a_configuration the configuration to use
0276:             * @param a_initialGenes the initial genes of this Chromosome
0277:             * @param a_constraintChecker constraint checker to use
0278:             * @throws InvalidConfigurationException in case the constraint checker
0279:             * reports a configuration error
0280:             *
0281:             * @author Klaus Meffert
0282:             * @since 2.5
0283:             */
0284:            public Chromosome(final Configuration a_configuration,
0285:                    Gene[] a_initialGenes,
0286:                    IGeneConstraintChecker a_constraintChecker)
0287:                    throws InvalidConfigurationException {
0288:                this (a_configuration, a_initialGenes.length);
0289:                checkGenes(a_initialGenes);
0290:                setGenes(a_initialGenes);
0291:                setConstraintChecker(a_constraintChecker);
0292:            }
0293:
0294:            /**
0295:             * Helper: called by constructors only to verify the initial genes.
0296:             *
0297:             * @param a_initialGenes the initial genes of this Chromosome to verify
0298:             *
0299:             * @author Klaus Meffert
0300:             * @since 2.5
0301:             */
0302:            protected void checkGenes(Gene[] a_initialGenes) {
0303:                // Sanity checks: make sure the genes array isn't null and
0304:                // that none of the genes contained within it are null.
0305:                // Check against null already done in constructors!
0306:                // -------------------------------------------------------
0307:                for (int i = 0; i < a_initialGenes.length; i++) {
0308:                    if (a_initialGenes[i] == null) {
0309:                        throw new IllegalArgumentException(
0310:                                "The gene at index "
0311:                                        + i
0312:                                        + " in the given array of "
0313:                                        + "genes was found to be null. No gene in the array "
0314:                                        + "may be null.");
0315:                    }
0316:                }
0317:            }
0318:
0319:            /**
0320:             * Returns a copy of this Chromosome. The returned instance can evolve
0321:             * independently of this instance. Note that, if possible, this method
0322:             * will first attempt to acquire a Chromosome instance from the active
0323:             * ChromosomePool (if any) and set its value appropriately before
0324:             * returning it. If that is not possible, then a new Chromosome instance
0325:             * will be constructed and its value set appropriately before returning.
0326:             *
0327:             * @return copy of this Chromosome
0328:             * @throws IllegalStateException instead of CloneNotSupportedException
0329:             *
0330:             * @author Neil Rotstan
0331:             * @author Klaus Meffert
0332:             * @since 1.0
0333:             */
0334:            public synchronized Object clone() {
0335:                // Before doing anything, make sure that a Configuration object
0336:                // has been set on this Chromosome. If not, then throw an
0337:                // IllegalStateException.
0338:                // ------------------------------------------------------------
0339:                if (getConfiguration() == null) {
0340:                    throw new IllegalStateException(
0341:                            "The active Configuration object must be set on this "
0342:                                    + "Chromosome prior to invocation of the clone() method.");
0343:                }
0344:                IChromosome copy = null;
0345:                // Now, first see if we can pull a Chromosome from the pool and just
0346:                // set its gene values (alleles) appropriately.
0347:                // ------------------------------------------------------------
0348:                IChromosomePool pool = getConfiguration().getChromosomePool();
0349:                if (pool != null) {
0350:                    copy = pool.acquireChromosome();
0351:                    if (copy != null) {
0352:                        Gene[] genes = copy.getGenes();
0353:                        for (int i = 0; i < size(); i++) {
0354:                            genes[i].setAllele(getGene(i).getAllele());
0355:                        }
0356:                    }
0357:                }
0358:                try {
0359:                    if (copy == null) {
0360:                        // We couldn't fetch a Chromosome from the pool, so we need to create
0361:                        // a new one. First we make a copy of each of the Genes. We explicity
0362:                        // use the Gene at each respective gene location (locus) to create the
0363:                        // new Gene that is to occupy that same locus in the new Chromosome.
0364:                        // -------------------------------------------------------------------
0365:                        int size = size();
0366:                        if (size > 0) {
0367:                            Gene[] copyOfGenes = new Gene[size];
0368:                            for (int i = 0; i < copyOfGenes.length; i++) {
0369:                                copyOfGenes[i] = getGene(i).newGene();
0370:                                copyOfGenes[i]
0371:                                        .setAllele(getGene(i).getAllele());
0372:                            }
0373:                            // Now construct a new Chromosome with the copies of the genes and
0374:                            // return it. Also clone the IApplicationData object.
0375:                            // ---------------------------------------------------------------
0376:                            /**@todo clone Config!*/
0377:                            copy = new Chromosome(getConfiguration(),
0378:                                    copyOfGenes);
0379:                        } else {
0380:                            copy = new Chromosome(getConfiguration());
0381:                        }
0382:                        copy.setFitnessValue(m_fitnessValue);
0383:                    }
0384:                    // Clone constraint checker.
0385:                    // -------------------------
0386:                    copy.setConstraintChecker(getConstraintChecker());
0387:                } catch (InvalidConfigurationException iex) {
0388:                    throw new IllegalStateException(iex.getMessage());
0389:                }
0390:                // Also clone the IApplicationData object.
0391:                // ---------------------------------------
0392:                try {
0393:                    copy.setApplicationData(cloneObject(getApplicationData()));
0394:                } catch (Exception ex) {
0395:                    throw new IllegalStateException(ex.getMessage());
0396:                }
0397:                return copy;
0398:            }
0399:
0400:            /**
0401:             * Clones an object by using clone handlers. If no deep cloning possible, then
0402:             * return the reference.
0403:             *
0404:             * @param a_object the object to clone
0405:             * @return the cloned object, or the object itself if no coning supported
0406:             * @throws Exception
0407:             *
0408:             * @author Klaus Meffert
0409:             * @since 2.6
0410:             */
0411:            protected Object cloneObject(Object a_object) throws Exception {
0412:                if (a_object == null) {
0413:                    return null;
0414:                }
0415:                // Try to clone via a registered clone handler.
0416:                // --------------------------------------------
0417:                ICloneHandler cloner = getConfiguration().getJGAPFactory()
0418:                        .getCloneHandlerFor(a_object, a_object.getClass());
0419:                if (cloner != null) {
0420:                    return cloner.perform(a_object, null, this );
0421:                } else {
0422:                    // No cloning supported, so just return the reference.
0423:                    // ---------------------------------------------------
0424:                    return a_object;
0425:                }
0426:            }
0427:
0428:            /**
0429:             * Retrieves the fitness value of this Chromosome, as determined by the
0430:             * active fitness function. If a bulk fitness function is in use and
0431:             * has not yet assigned a fitness value to this Chromosome, then -1 is
0432:             * returned.<p>
0433:             * Attention: should not be called from toString() as the fitness value would
0434:             * be computed if it was initial!
0435:             *
0436:             * @return a positive double value representing the fitness of this
0437:             * Chromosome, or -1 if a bulk fitness function is in use and has not yet
0438:             * assigned a fitness value to this Chromosome
0439:             *
0440:             * @author Neil Rotstan
0441:             * @author Klaus Meffert
0442:             * @since 2.0
0443:             */
0444:            public double getFitnessValue() {
0445:                if (m_fitnessValue >= 0.000d && !m_alwaysCalculate) {
0446:                    return m_fitnessValue;
0447:                } else {
0448:                    return calcFitnessValue();
0449:                }
0450:            }
0451:
0452:            /**
0453:             * @return the lastly computed fitness value, or FitnessFunction.NO_FITNESS_VALUE
0454:             * in case no value has been computed yet.
0455:             *
0456:             * @author Klaus Meffert
0457:             */
0458:            public double getFitnessValueDirectly() {
0459:                return m_fitnessValue;
0460:            }
0461:
0462:            /**
0463:             * @return fitness value of this chromosome determined via the registered
0464:             * fitness function
0465:             *
0466:             * @author Klaus Meffert
0467:             * @since 2.4
0468:             */
0469:            protected double calcFitnessValue() {
0470:                if (getConfiguration() != null) {
0471:                    FitnessFunction normalFitnessFunction = getConfiguration()
0472:                            .getFitnessFunction();
0473:                    if (normalFitnessFunction != null) {
0474:                        // Grab the "normal" fitness function and ask it to calculate our
0475:                        // fitness value.
0476:                        // --------------------------------------------------------------
0477:                        m_fitnessValue = normalFitnessFunction
0478:                                .getFitnessValue(this );
0479:                    }
0480:                }
0481:                return m_fitnessValue;
0482:            }
0483:
0484:            /**
0485:             * Sets the fitness value of this Chromosome. This method is for use
0486:             * by bulk fitness functions and should not be invokved from anything
0487:             * else (except test cases).
0488:             *
0489:             * @param a_newFitnessValue a positive integer representing the fitness
0490:             * of this Chromosome
0491:             *
0492:             * @author Neil Rotstan
0493:             * @since 1.0
0494:             */
0495:            public void setFitnessValue(double a_newFitnessValue) {
0496:                if (a_newFitnessValue >= 0
0497:                        && Math.abs(m_fitnessValue - a_newFitnessValue) > 0.0000001) {
0498:                    m_fitnessValue = a_newFitnessValue;
0499:                }
0500:            }
0501:
0502:            /**
0503:             * Sets the fitness value of this Chromosome directly without any
0504:             * constraint checks, conversions or checks. Only use if you know what
0505:             * you do.
0506:             *
0507:             * @param a_newFitnessValue a positive integer representing the fitness
0508:             * of this Chromosome
0509:             *
0510:             * @author Klaus Meffert
0511:             */
0512:            public void setFitnessValueDirectly(double a_newFitnessValue) {
0513:                m_fitnessValue = a_newFitnessValue;
0514:            }
0515:
0516:            /**
0517:             * @return a string representation of this Chromosome, useful for display
0518:             * purposes
0519:             *
0520:             * @author Neil Rotstan
0521:             * @author Klaus Meffert
0522:             * @since 1.0
0523:             */
0524:            public String toString() {
0525:                StringBuffer representation = new StringBuffer();
0526:                representation.append(S_SIZE + ":" + size());
0527:                // Don't use getFitnessValue() here as it would then be initialized if
0528:                // it was not. We want to capture the current state here!
0529:                // -------------------------------------------------------------------
0530:                representation.append(", " + S_FITNESS_VALUE + ":"
0531:                        + m_fitnessValue);
0532:                representation.append(", " + S_ALLELES + ":");
0533:                representation.append("[");
0534:                // Append the representations of each of the genes' alleles.
0535:                // ---------------------------------------------------------
0536:                int size = size();
0537:                for (int i = 0; i < size; i++) {
0538:                    if (i > 0) {
0539:                        representation.append(", ");
0540:                    }
0541:                    if (getGene(i) == null) {
0542:                        representation.append("null");
0543:                    } else {
0544:                        representation.append(getGene(i).toString());
0545:                    }
0546:                }
0547:                representation.append("]");
0548:                String appData;
0549:                if (getApplicationData() != null) {
0550:                    appData = getApplicationData().toString();
0551:                } else {
0552:                    appData = "null";
0553:                }
0554:                representation
0555:                        .append(", " + S_APPLICATION_DATA + ":" + appData);
0556:                return representation.toString();
0557:            }
0558:
0559:            /**
0560:             * Convenience method that returns a new Chromosome instance with its
0561:             * genes values (alleles) randomized. Note that, if possible, this method
0562:             * will acquire a Chromosome instance from the active ChromosomePool
0563:             * (if any) and then randomize its gene values before returning it. If a
0564:             * Chromosome cannot be acquired from the pool, then a new instance will
0565:             * be constructed and its gene values randomized before returning it.
0566:             *
0567:             * @param a_configuration the configuration to use
0568:             * @return randomly initialized Chromosome
0569:             * @throws InvalidConfigurationException if the given Configuration
0570:             * instance is invalid
0571:             * @throws IllegalArgumentException if the given Configuration instance
0572:             * is null
0573:             *
0574:             * @author Neil Rotstan
0575:             * @author Klaus Meffert
0576:             * @since 1.0
0577:             */
0578:            public static IChromosome randomInitialChromosome(
0579:                    Configuration a_configuration)
0580:                    throws InvalidConfigurationException {
0581:                // Sanity check: make sure the given configuration isn't null.
0582:                // -----------------------------------------------------------
0583:                if (a_configuration == null) {
0584:                    throw new IllegalArgumentException(
0585:                            "Configuration instance must not be null");
0586:                }
0587:                // Lock the configuration settings so that they can't be changed
0588:                // from now on.
0589:                // -------------------------------------------------------------
0590:                a_configuration.lockSettings();
0591:                // First see if we can get a Chromosome instance from the pool.
0592:                // If we can, we'll randomize its gene values (alleles) and then
0593:                // return it.
0594:                // -------------------------------------------------------------
0595:                IChromosomePool pool = a_configuration.getChromosomePool();
0596:                if (pool != null) {
0597:                    IChromosome randomChromosome = pool.acquireChromosome();
0598:                    if (randomChromosome != null) {
0599:                        Gene[] genes = randomChromosome.getGenes();
0600:                        RandomGenerator generator = a_configuration
0601:                                .getRandomGenerator();
0602:                        for (int i = 0; i < genes.length; i++) {
0603:                            genes[i].setToRandomValue(generator);
0604:                            /**@todo what about Gene's energy?*/
0605:                        }
0606:                        randomChromosome
0607:                                .setFitnessValueDirectly(FitnessFunction.NO_FITNESS_VALUE);
0608:                        return randomChromosome;
0609:                    }
0610:                }
0611:                // We weren't able to get a Chromosome from the pool, so we have to
0612:                // construct a new instance and build it from scratch.
0613:                // ------------------------------------------------------------------
0614:                IChromosome sampleChromosome = a_configuration
0615:                        .getSampleChromosome();
0616:                sampleChromosome
0617:                        .setFitnessValue(FitnessFunction.NO_FITNESS_VALUE);
0618:                Gene[] sampleGenes = sampleChromosome.getGenes();
0619:                Gene[] newGenes = new Gene[sampleGenes.length];
0620:                RandomGenerator generator = a_configuration
0621:                        .getRandomGenerator();
0622:                for (int i = 0; i < newGenes.length; i++) {
0623:                    // We use the newGene() method on each of the genes in the
0624:                    // sample Chromosome to generate our new Gene instances for
0625:                    // the Chromosome we're returning. This guarantees that the
0626:                    // new Genes are setup with all of the correct internal state
0627:                    // for the respective gene position they're going to inhabit.
0628:                    // -----------------------------------------------------------
0629:                    newGenes[i] = sampleGenes[i].newGene();
0630:                    // Set the gene's value (allele) to a random value.
0631:                    // ------------------------------------------------
0632:                    newGenes[i].setToRandomValue(generator);
0633:                    /**@todo what about Gene's energy?*/
0634:                }
0635:                // Finally, construct the new chromosome with the new random
0636:                // genes values and return it.
0637:                // ---------------------------------------------------------
0638:                return new Chromosome(a_configuration, newGenes);
0639:            }
0640:
0641:            /**
0642:             * Compares this Chromosome against the specified object. The result is
0643:             * true if and the argument is an instance of the Chromosome class
0644:             * and has a set of genes equal to this one.
0645:             *
0646:             * @param other the object to compare against
0647:             * @return true: if the objects are the same, false otherwise
0648:             *
0649:             * @author Neil Rotstan
0650:             * @author Klaus Meffert
0651:             * @since 1.0
0652:             */
0653:            public boolean equals(Object other) {
0654:                // If class is not equal, return false. Therefor catch
0655:                // ClasscastException's. The cleaner way (commented out below) would
0656:                // be too slow, indeed.
0657:                // -----------------------------------------------------------------
0658:                /*
0659:                   if (other != null &&
0660:                    !this.getClass ().getName ().equals (other.getClass ().getName ()))
0661:                    {
0662:                        return false;
0663:                    }
0664:                 */
0665:                try {
0666:                    return compareTo(other) == 0;
0667:                } catch (ClassCastException cex) {
0668:                    return false;
0669:                }
0670:            }
0671:
0672:            /**
0673:             * Retrieve a hash code for this Chromosome. Does not considers the order
0674:             * of the Genes for all cases (especially when gene is empty).
0675:             *
0676:             * @return the hash code of this Chromosome
0677:             *
0678:             * @author Neil Rotstan
0679:             * @author Klaus Meffert
0680:             * @since 1.0
0681:             */
0682:            public int hashCode() {
0683:                // Do what java.util.AbstractList does.
0684:                // ------------------------------------
0685:                int geneHashcode;
0686:                int hashCode = 1;
0687:                if (getGenes() != null) {
0688:                    int size = size();
0689:                    for (int i = 0; i < size; i++) {
0690:                        Gene gene = getGene(i);
0691:                        if (gene == null) {
0692:                            geneHashcode = -55;
0693:                        } else {
0694:                            geneHashcode = gene.hashCode();
0695:                        }
0696:                        hashCode = 31 * hashCode + geneHashcode;
0697:                    }
0698:                }
0699:                return hashCode;
0700:            }
0701:
0702:            /**
0703:             * Compares the given Chromosome to this Chromosome. This chromosome is
0704:             * considered to be "less than" the given chromosome if it has a fewer
0705:             * number of genes or if any of its gene values (alleles) are less than
0706:             * their corresponding gene values in the other chromosome.
0707:             *
0708:             * @param other the Chromosome against which to compare this chromosome
0709:             * @return a negative number if this chromosome is "less than" the given
0710:             * chromosome, zero if they are equal to each other, and a positive number if
0711:             * this chromosome is "greater than" the given chromosome
0712:             *
0713:             * @author Neil Rotstan
0714:             * @author Klaus Meffert
0715:             * @since 1.0
0716:             */
0717:            public int compareTo(Object other) {
0718:                // First, if the other Chromosome is null, then this chromosome is
0719:                // automatically the "greater" Chromosome.
0720:                // ---------------------------------------------------------------
0721:                if (other == null) {
0722:                    return 1;
0723:                }
0724:                int size = size();
0725:                IChromosome otherChromosome = (IChromosome) other;
0726:                Gene[] otherGenes = otherChromosome.getGenes();
0727:                // If the other Chromosome doesn't have the same number of genes,
0728:                // then whichever has more is the "greater" Chromosome.
0729:                // --------------------------------------------------------------
0730:                if (otherChromosome.size() != size) {
0731:                    return size() - otherChromosome.size();
0732:                }
0733:                // Next, compare the gene values (alleles) for differences. If
0734:                // one of the genes is not equal, then we return the result of its
0735:                // comparison.
0736:                // ---------------------------------------------------------------
0737:                for (int i = 0; i < size; i++) {
0738:                    int comparison = getGene(i).compareTo(otherGenes[i]);
0739:                    if (comparison != 0) {
0740:                        return comparison;
0741:                    }
0742:                }
0743:                // Compare current fitness value.
0744:                // ------------------------------
0745:                if (m_fitnessValue != otherChromosome.getFitnessValueDirectly()) {
0746:                    FitnessEvaluator eval = getConfiguration()
0747:                            .getFitnessEvaluator();
0748:                    if (eval != null) {
0749:                        if (eval.isFitter(m_fitnessValue, otherChromosome
0750:                                .getFitnessValueDirectly())) {
0751:                            return 1;
0752:                        } else {
0753:                            return -1;
0754:                        }
0755:                    } else {
0756:                        // undetermined order, but unequal!
0757:                        // --------------------------------
0758:                        return -1;
0759:                    }
0760:                }
0761:                if (m_compareAppData) {
0762:                    // Compare application data.
0763:                    // -------------------------
0764:                    if (getApplicationData() == null) {
0765:                        if (otherChromosome.getApplicationData() != null) {
0766:                            return -1;
0767:                        }
0768:                    } else if (otherChromosome.getApplicationData() == null) {
0769:                        return 1;
0770:                    } else {
0771:                        if (getApplicationData() instanceof  Comparable) {
0772:                            try {
0773:                                return ((Comparable) getApplicationData())
0774:                                        .compareTo(otherChromosome
0775:                                                .getApplicationData());
0776:                            } catch (ClassCastException cex) {
0777:                                /**@todo improve*/
0778:                                return -1;
0779:                            }
0780:                        } else {
0781:                            return getApplicationData().getClass().getName()
0782:                                    .compareTo(
0783:                                            otherChromosome
0784:                                                    .getApplicationData()
0785:                                                    .getClass().getName());
0786:                        }
0787:                    }
0788:                }
0789:                // Everything is equal. Return zero.
0790:                // ---------------------------------
0791:                return 0;
0792:            }
0793:
0794:            /**
0795:             * Sets whether this Chromosome has been selected by the natural selector
0796:             * to continue to the next generation or manually (e.g. via an add-method).
0797:             *
0798:             * @param a_isSelected true if this Chromosome has been selected, false
0799:             * otherwise
0800:             *
0801:             * @author Neil Rotstan
0802:             * @since 1.0
0803:             */
0804:            public void setIsSelectedForNextGeneration(boolean a_isSelected) {
0805:                m_isSelectedForNextGeneration = a_isSelected;
0806:            }
0807:
0808:            /**
0809:             * Retrieves whether this Chromosome has been selected by the natural
0810:             * selector to continue to the next generation.
0811:             *
0812:             * @return true if this Chromosome has been selected, false otherwise
0813:             *
0814:             * @author Neil Rotstan
0815:             * @since 1.0
0816:             */
0817:            public boolean isSelectedForNextGeneration() {
0818:                return m_isSelectedForNextGeneration;
0819:            }
0820:
0821:            /**
0822:             * Invoked when this Chromosome is no longer needed and should perform
0823:             * any necessary cleanup. Note that this method will attempt to release
0824:             * this Chromosome instance to the active ChromosomePool, if any.
0825:             *
0826:             * @author Neil Rotstan
0827:             * @since 1.0
0828:             */
0829:            public void cleanup() {
0830:                if (getConfiguration() == null) {
0831:                    throw new IllegalStateException(
0832:                            "The active Configuration object must be set on this "
0833:                                    + "Chromosome prior to invocation of the cleanup() method.");
0834:                }
0835:                // First, reset our internal state.
0836:                // --------------------------------
0837:                m_fitnessValue = getConfiguration().getFitnessFunction().NO_FITNESS_VALUE;
0838:                m_isSelectedForNextGeneration = false;
0839:                // Next we want to try to release this Chromosome to a ChromosomePool
0840:                // if one has been setup so that we can save a little time and memory
0841:                // next time a Chromosome is needed.
0842:                // ------------------------------------------------------------------
0843:                // Now fetch the active ChromosomePool from the Configuration object
0844:                // and, if the pool exists, release this Chromosome to it.
0845:                // -----------------------------------------------------------------
0846:                IChromosomePool pool = getConfiguration().getChromosomePool();
0847:                if (pool != null) {
0848:                    // Note that the pool will take care of any gene cleanup for us,
0849:                    // so we don't need to worry about it here.
0850:                    // -------------------------------------------------------------
0851:                    pool.releaseChromosome(this );
0852:                } else {
0853:                    // No pool is available, so we need to finish cleaning up, which
0854:                    // basically entails requesting each of our genes to clean
0855:                    // themselves up as well.
0856:                    // -------------------------------------------------------------
0857:                    for (int i = 0; i < size(); i++) {
0858:                        getGene(i).cleanup();
0859:                    }
0860:                }
0861:            }
0862:
0863:            /**
0864:             * This sets the application-specific data that is attached to this
0865:             * Chromosome. Attaching application-specific data may be useful for
0866:             * some applications when it comes time to evaluate this Chromosome
0867:             * in the fitness function. JGAP ignores this data, except for cloning and
0868:             * comparison (latter only if opted in via setCompareApplicationData(..))
0869:             *
0870:             * @param a_newData the new application-specific data to attach to this
0871:             * Chromosome. Should be an instance of IApplicationData
0872:             *
0873:             * @author Neil Rotstan
0874:             * @since 1.1
0875:             */
0876:            public void setApplicationData(Object a_newData) {
0877:                m_applicationData = a_newData;
0878:            }
0879:
0880:            /**
0881:             * Retrieves the application-specific data that is attached to this
0882:             * Chromosome. Attaching application-specific data may be useful for
0883:             * some applications when it comes time to evaluate this Chromosome
0884:             * in the fitness function. JGAP ignores this data functionally.
0885:             *
0886:             * @return the application-specific data previously attached to this
0887:             * Chromosome, or null if there is no data attached
0888:             *
0889:             * @author Neil Rotstan
0890:             * @since 1.1
0891:             */
0892:            public Object getApplicationData() {
0893:                return m_applicationData;
0894:            }
0895:
0896:            /**
0897:             * Sets the genes for the chromosome.
0898:             * @param a_genes the genes to set for the chromosome
0899:             *
0900:             * @throws InvalidConfigurationException in case constraint checker is
0901:             * provided
0902:             *
0903:             * @author Klaus Meffert
0904:             */
0905:            public void setGenes(Gene[] a_genes)
0906:                    throws InvalidConfigurationException {
0907:                super .setGenes(a_genes);
0908:                verify(getConstraintChecker());
0909:            }
0910:
0911:            /**
0912:             * Should we also consider the application data when comparing? Default is
0913:             * "false" as "true" means a Chromosome is losing its identity when
0914:             * application data is set differently!
0915:             *
0916:             * @param a_doCompare true: consider application data in method compareTo
0917:             *
0918:             * @author Klaus Meffert
0919:             * @since 2.2
0920:             */
0921:            public void setCompareApplicationData(boolean a_doCompare) {
0922:                m_compareAppData = a_doCompare;
0923:            }
0924:
0925:            /*
0926:             * @return should we also consider the application data when comparing?
0927:             *
0928:             * @author Klaus Meffert
0929:             * @since 2.2
0930:             */
0931:            public boolean isCompareApplicationData() {
0932:                return m_compareAppData;
0933:            }
0934:
0935:            /**
0936:             * Sets the constraint checker to be used for this gene whenever method
0937:             * setAllele(Object) is called.
0938:             *
0939:             * @param a_constraintChecker the constraint checker to be set
0940:             * @throws InvalidConfigurationException
0941:             *
0942:             * @author Klaus Meffert
0943:             * @since 2.5
0944:             */
0945:            public void setConstraintChecker(
0946:                    IGeneConstraintChecker a_constraintChecker)
0947:                    throws InvalidConfigurationException {
0948:                verify(a_constraintChecker);
0949:                m_geneAlleleChecker = a_constraintChecker;
0950:            }
0951:
0952:            /**
0953:             * @return IGeneConstraintChecker the constraint checker to be used whenever
0954:             * method setGenes(Gene[]) is called.
0955:             *
0956:             * @author Klaus Meffert
0957:             * @since 2.5
0958:             */
0959:            public IGeneConstraintChecker getConstraintChecker() {
0960:                return m_geneAlleleChecker;
0961:            }
0962:
0963:            /**
0964:             * Verifies the state of the chromosome. Especially takes care of the
0965:             * given constraint checker.
0966:             * @param a_constraintChecker the constraint checker to verify
0967:             *
0968:             * @throws InvalidConfigurationException
0969:             *
0970:             * @author Klaus Meffert
0971:             * @since 2.5
0972:             */
0973:            protected void verify(IGeneConstraintChecker a_constraintChecker)
0974:                    throws InvalidConfigurationException {
0975:                if (a_constraintChecker != null && getGenes() != null) {
0976:                    int len = getGenes().length;
0977:                    for (int i = 0; i < len; i++) {
0978:                        Gene gene = getGene(i);
0979:                        if (!a_constraintChecker.verify(gene, null, this , i)) {
0980:                            throw new InvalidConfigurationException(
0981:                                    "The gene type "
0982:                                            + gene.getClass().getName()
0983:                                            + " is not allowed to be used in the chromosome due to the"
0984:                                            + " constraint checker used.");
0985:                        }
0986:                    }
0987:                }
0988:            }
0989:
0990:            // ------------------------------------
0991:            // Begin of IInitializer implementation
0992:            // ------------------------------------
0993:
0994:            /**{@inheritDoc}*/
0995:            public boolean isHandlerFor(Object a_obj, Class a_class) {
0996:                if (a_class == Chromosome.class) {
0997:                    return true;
0998:                } else {
0999:                    return false;
1000:                }
1001:            }
1002:
1003:            /**{@inheritDoc}*/
1004:            public Object perform(Object a_obj, Class a_class, Object a_params)
1005:                    throws Exception {
1006:                return randomInitialChromosome(getConfiguration());
1007:            }
1008:
1009:            // ----------------------------------
1010:            // End of IInitializer implementation
1011:            // ----------------------------------
1012:            public void setMultiObjectives(List a_values) {
1013:                if (m_multiObjective == null) {
1014:                    m_multiObjective = new Vector();
1015:                }
1016:                m_multiObjective.clear();
1017:                m_multiObjective.addAll(a_values);
1018:            }
1019:
1020:            public List getMultiObjectives() {
1021:                return m_multiObjective;
1022:            }
1023:
1024:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.