Source Code Cross Referenced for Configuration.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:         * This file is part of JGAP.
0003:         *
0004:         * JGAP offers a dual license model containing the LGPL as well as the MPL.
0005:         *
0006:         * For licensing information please see the file license.txt included with JGAP
0007:         * or have a look at the top of class org.jgap.Chromosome which representatively
0008:         * includes the JGAP license policy applicable for any file delivered with JGAP.
0009:         */
0010:        package org.jgap;
0011:
0012:        import java.io.*;
0013:        import java.util.*;
0014:
0015:        import org.apache.commons.lang.builder.*;
0016:        import org.jgap.data.config.*;
0017:        import org.jgap.event.*;
0018:        import org.jgap.impl.*;
0019:        import org.jgap.util.*;
0020:
0021:        /**
0022:         * The Configuration class represents the current configuration of
0023:         * plugins and parameters necessary to execute the genetic algorithm (such
0024:         * as fitness function, natural selector, genetic operators, and so on).
0025:         * <p>
0026:         * Note that, while during setup, the settings, flags, and other
0027:         * values may be set multiple times. But once the lockSettings() method
0028:         * is invoked, they cannot be changed. The default behavior of the
0029:         * Genotype constructor is to invoke this method, meaning that
0030:         * once a Configuration object is passed to a Genotype, it cannot
0031:         * be subsequently modified. There is no mechanism for unlocking
0032:         * the settings once they are locked.
0033:         * <p>
0034:         * Not all configuration options are required. See the documentation
0035:         * for each of the respective mutator methods to determine whether
0036:         * it is required to provide a value for that setting, and what the
0037:         * setting will default to if not.
0038:         *
0039:         * @author Neil Rotstan
0040:         * @author Klaus Meffert
0041:         * @since 1.0
0042:         */
0043:        public class Configuration implements  Configurable, Serializable,
0044:                ICloneable, Comparable {
0045:            /** String containing the CVS revision. Read out via reflection!*/
0046:            private final static String CVS_REVISION = "$Revision: 1.93 $";
0047:
0048:            /**
0049:             * Constant for class name of JGAP Factory to use. Use as:
0050:             * System.setProperty(PROPERTY_JGAPFACTORY_CLASS, "myJGAPFactory");
0051:             * If none such property set, class JGAPFactory will be used.
0052:             */
0053:            public static final String PROPERTY_JGAPFACTORY_CLASS = "JGAPFACTORYCLASS";
0054:
0055:            public static final String PROPERTY_FITFUNC_INST = "JGAPFITFUNCINST";
0056:
0057:            public static final String PROPERTY_BFITFNC_INST = "JGAPBFITFNCINST";
0058:
0059:            public static final String PROPERTY_FITEVAL_INST = "JGAPFITEVALINST";
0060:
0061:            public static final String PROPERTY_SAMPLE_CHROM_INST = "JGAPSAMPLECHRMINST";
0062:
0063:            public static final String PROPERTY_EVENT_MGR_INST = "JGAPEVNTMGRINST";
0064:
0065:            /**
0066:             * Constants for toString()
0067:             */
0068:            public static final String S_CONFIGURATION = "Configuration";
0069:
0070:            public static final String S_CONFIGURATION_NAME = "Configuration name";
0071:
0072:            public static final String S_POPULATION_SIZE = "Population size";
0073:
0074:            public static final String S_MINPOPSIZE = "Minimum pop. size [%]";
0075:
0076:            public static final String S_CHROMOSOME_SIZE = "Chromosome size";
0077:
0078:            public static final String S_SAMPLE_CHROM = "Sample Chromosome";
0079:
0080:            public static final String S_SIZE = "Size";
0081:
0082:            public static final String S_TOSTRING = "toString";
0083:
0084:            public static final String S_RANDOM_GENERATOR = "Random generator";
0085:
0086:            public static final String S_EVENT_MANAGER = "Event manager";
0087:
0088:            public static final String S_NONE = "none";
0089:
0090:            public static final String S_CONFIGURATION_HANDLER = "Configuration handler";
0091:
0092:            public static final String S_FITNESS_FUNCTION = "Fitness function";
0093:
0094:            public static final String S_FITNESS_EVALUATOR = "Fitness evaluator";
0095:
0096:            //  public static final String S_POPCONSTANT_SELECTOR = "Constant Population Selector";
0097:
0098:            public static final String S_GENETIC_OPERATORS = "Genetic operators";
0099:
0100:            public static final String S_NATURAL_SELECTORS = "Natural Selectors";
0101:
0102:            public static final String S_PRE = "pre";
0103:
0104:            public static final String S_POST = "post";
0105:
0106:            /**
0107:             * Contains a bag of custom properties. Can be empty.
0108:             * A custom property is such that is not included in the standard JGAP
0109:             * configuration.
0110:             *
0111:             * @since 3.3.1
0112:             */
0113:            //  private Map m_propertyBag;
0114:            private ConfigurationConfigurable m_config = new ConfigurationConfigurable();
0115:
0116:            /**
0117:             * References the current fitness function that will be used to evaluate
0118:             * chromosomes during the natural selection process. Note that only this
0119:             * or the bulk fitness function may be set - the two are mutually exclusive.
0120:             *
0121:             * @author Neil Rotstan
0122:             * @since 1.0
0123:             */
0124:            private FitnessFunction m_objectiveFunction;
0125:
0126:            /**
0127:             * The fitness evaluator. See interface class FitnessEvaluator for details.
0128:             *
0129:             * @since 2.0 (since 1.1 in class Genotype)
0130:             */
0131:            private FitnessEvaluator m_fitnessEvaluator;
0132:
0133:            /**
0134:             * Performs the evolution.
0135:             */
0136:            private IBreeder m_breeder;
0137:
0138:            /**
0139:             * Minimum size guaranteed for population. If zero or below then no ensurance.
0140:             *
0141:             * @author Klaus Meffert
0142:             */
0143:            private int m_minPercentageSizePopulation;
0144:
0145:            /**
0146:             * References the current bulk fitness function that will be used to
0147:             * evaluate chromosomes (in bulk) during the natural selection
0148:             * process. Note that only this or the normal fitness function
0149:             * may be set - the two are mutually exclusive.
0150:             *
0151:             * @author Neil Rotstan
0152:             * @since 1.0
0153:             */
0154:            private BulkFitnessFunction m_bulkObjectiveFunction;
0155:
0156:            //  /**
0157:            //   * If population size should be kept constant then this selector determines
0158:            //   * which of the chromosomes to select into the next generation.
0159:            //   *
0160:            //   * @author Klaus Meffert
0161:            //   * @since 3.2.2
0162:            //   */
0163:            //  private INaturalSelector m_popConstantSelector;
0164:
0165:            /**
0166:             * References a Chromosome that serves as a sample of the Gene setup
0167:             * that is to be used. Each gene in the Chromosome should be represented
0168:             * with the desired Gene type.
0169:             *
0170:             * @author Neil Rotstan
0171:             * @since 1.0
0172:             */
0173:            private IChromosome m_sampleChromosome;
0174:
0175:            /**
0176:             * References the random number generator implementation that is to be
0177:             * used for the generation of any random numbers during the various
0178:             * genetic operations and processes.
0179:             *
0180:             * @author Neil Rotstan
0181:             * @since 1.0
0182:             */
0183:            private RandomGenerator m_randomGenerator;
0184:
0185:            /**
0186:             * References the event manager that is to be used for the notification
0187:             * of genetic events and the management of event subscribers.
0188:             *
0189:             * @author Neil Rotstan
0190:             * @since 1.0
0191:             */
0192:            private IEventManager m_eventManager;
0193:
0194:            /**
0195:             * References the chromosome pool, if any, that is to be used to pool
0196:             * discarded Chromosome instances so that they may be recycled later,
0197:             * thereby saving memory and the time to construct them from scratch.
0198:             *
0199:             * @author Neil Rotstan
0200:             * @since 1.0
0201:             */
0202:            private transient IChromosomePool m_chromosomePool;
0203:
0204:            /**
0205:             * Stores all of the GeneticOperator implementations that are to be used
0206:             * to operate upon the chromosomes of a population prior to natural
0207:             * selection. Operators will be executed in the order that they are
0208:             * added to this list.
0209:             *
0210:             * @author Klaus Meffert
0211:             * @since 1.1
0212:             */
0213:            private List m_geneticOperators;
0214:
0215:            /**
0216:             * The number of genes that will be stored in each chromosome in the
0217:             * population.
0218:             */
0219:            private int m_chromosomeSize;
0220:
0221:            /**
0222:             * Indicates whether the settings of this Configuration instance have
0223:             * been locked. Prior to locking, the settings may be set and reset
0224:             * as desired. Once this flag is set to true, no settings may be
0225:             * altered.
0226:             */
0227:            private boolean m_settingsLocked;
0228:
0229:            /**
0230:             * Ordered chain of NaturalSelector's which will be executed before applying
0231:             * Genetic Operators.
0232:             *
0233:             * @author Klaus Meffert
0234:             * @since 1.1
0235:             */
0236:            private ChainOfSelectors m_preSelectors;
0237:
0238:            /**
0239:             * Ordered chain of NaturalSelector's which will be executed after applying
0240:             * Genetic Operators.
0241:             *
0242:             * @author Klaus Meffert
0243:             * @since 1.1
0244:             */
0245:            private ChainOfSelectors m_postSelectors;
0246:
0247:            /**
0248:             * Should the fittest chromosome in the population be preserved to the next
0249:             * generation when evolving (in Genotype.evolve()) ?
0250:             */
0251:            private boolean m_preserveFittestIndividual;
0252:
0253:            /**
0254:             * How many chromosomes should be selected from previous generation?
0255:             * The missing chromosomes will be filled up with randomly created new
0256:             * ones.
0257:             * 1 = all
0258:             */
0259:            private double m_selectFromPrevGen;
0260:
0261:            /**
0262:             * Indicates how many times the evolve()-method in class Genotype has been
0263:             * called. Represents the number of the current population.
0264:             *
0265:             * @author Klaus Meffert
0266:             * @since 2.2
0267:             */
0268:            private int m_generationNr;
0269:
0270:            /**
0271:             * The Configuration handler for this Configurable.
0272:             *
0273:             * @author Siddhartha Azad
0274:             * @since 2.3
0275:             */
0276:            private transient RootConfigurationHandler m_conHandler;
0277:
0278:            /**
0279:             * Informative name for output.
0280:             *
0281:             * @author Klaus Meffert
0282:             * @since 2.3
0283:             */
0284:            private String m_name;
0285:
0286:            /**
0287:             * True: population size will be kept constant at specified size in
0288:             * configuration. False: population size will grow dependently on used
0289:             * NaturalSelector's and GeneticOperator's.
0290:             * Default is TRUE
0291:             *
0292:             * @author Klaus Meffert
0293:             * @since 2.4
0294:             */
0295:            private boolean m_keepPopulationSizeConstant;
0296:
0297:            /**
0298:             * Holds the central configurable factory for creating default objects.
0299:             *
0300:             * @author Klaus Meffert
0301:             * @since 2.6
0302:             */
0303:            private IJGAPFactory m_factory;
0304:
0305:            /**
0306:             * See Chromosome class, field m_alwaysCalculate, for description
0307:             *
0308:             * @author Klaus Meffert
0309:             * @since 3.2.2
0310:             */
0311:            private boolean m_alwaysCalculateFitness;
0312:
0313:            private transient String threadKey;
0314:
0315:            /**
0316:             * Unique ID for a configuration to distinguish it from other configurations
0317:             * instantiated within the same thread.
0318:             *
0319:             * @author Klaus Meffert
0320:             * @since 3.01
0321:             */
0322:            private String m_id;
0323:
0324:            public Configuration() {
0325:                this ("", null);
0326:            }
0327:
0328:            /**
0329:             * Initialize with default values.
0330:             *
0331:             * @param a_id unique id for the configuration within the current thread
0332:             * @param a_name informative name of the configuration, may be null
0333:             *
0334:             * @author Neil Rotstan
0335:             * @author Klaus Meffert
0336:             * @since 1.0
0337:             */
0338:            public Configuration(String a_id, String a_name) {
0339:                //    m_propertyBag = new Hashtable();
0340:                m_id = a_id;
0341:                setName(a_name);
0342:                makeThreadKey();
0343:                m_preSelectors = new ChainOfSelectors(this );
0344:                m_postSelectors = new ChainOfSelectors(this );
0345:                m_selectFromPrevGen = 1.0d;
0346:                // Use synchronized list for distributed computing.
0347:                // ------------------------------------------------
0348:                m_geneticOperators = new Vector();
0349:                m_conHandler = new RootConfigurationHandler();
0350:                m_conHandler.setConfigurable(this );
0351:                m_keepPopulationSizeConstant = true;
0352:                m_alwaysCalculateFitness = false;
0353:                // Create factory for being able to configure the used default objects,
0354:                // like random generators or fitness evaluators.
0355:                // --------------------------------------------------------------------
0356:                String clazz = System.getProperty(PROPERTY_JGAPFACTORY_CLASS);
0357:                if (clazz != null && clazz.length() > 0) {
0358:                    try {
0359:                        m_factory = (IJGAPFactory) Class.forName(clazz)
0360:                                .newInstance();
0361:                    } catch (Throwable ex) {
0362:                        throw new RuntimeException("Class " + clazz
0363:                                + " could not be instantiated"
0364:                                + " as type IJGAPFactory", ex);
0365:                    }
0366:                } else {
0367:                    m_factory = new JGAPFactory(false);
0368:                }
0369:            }
0370:
0371:            /**
0372:             * Constructs a configuration with an informative name but without a unique
0373:             * ID. This practically prevents more than one configurations to be
0374:             * instantiated within the same thread.
0375:             *
0376:             * @param a_name informative name of the configuration, may be null
0377:             *
0378:             * @author Klaus Meffert
0379:             */
0380:            public Configuration(final String a_name) {
0381:                this ();
0382:                setName(a_name);
0383:            }
0384:
0385:            /**
0386:             * Reads in the configuration from the given file.
0387:             *
0388:             * @param a_configFileName the config file from which to load the
0389:             * configuration
0390:             * @param a_ignore just there to create distinct signatures :-(
0391:             *
0392:             * @throws ConfigException
0393:             * @throws InvalidConfigurationException
0394:             *
0395:             * @author Siddhartha Azad
0396:             * @since 2.3
0397:             */
0398:            public Configuration(final String a_configFileName, boolean a_ignore)
0399:                    throws ConfigException, InvalidConfigurationException {
0400:                this ();
0401:                ConfigFileReader.instance().setFileName(a_configFileName);
0402:                // Set the configuration statically for constructing classes by the
0403:                // default constructor.
0404:                // ----------------------------------------------------------------
0405:                Genotype.setStaticConfiguration(this );
0406:                // Read in the config, thus creating instances of configurable classes
0407:                // by invoking their default constructor.
0408:                // -------------------------------------------------------------------
0409:                getConfigurationHandler().readConfig();
0410:            }
0411:
0412:            /**
0413:             * SHOULD NOT BE NECESSARY TO CALL UNDER NORMAL CIRCUMSTANCES. May be useful
0414:             * for unit tests.<p>
0415:             * Reset the configuration so that re-setting parameters such as fitness
0416:             * function is possible (without calling this method, an overwriting of a
0417:             * previously set fitness function results in a RuntimeException).
0418:             *
0419:             * @author Klaus Meffert
0420:             * @since 3.0
0421:             */
0422:            public static void reset() {
0423:                reset("");
0424:            }
0425:
0426:            /**
0427:             * Reset the configuration so that re-setting parameters such as fitness
0428:             * function is possible (without calling this method, an overwriting of a
0429:             * previously set fitness function results in a RuntimeException).
0430:             *
0431:             * @param a_id a hopefully unique id of the configuration
0432:             *
0433:             * @author Klaus Meffert
0434:             * @since 3.0
0435:             */
0436:            public static void reset(final String a_id) {
0437:                String threadKey = getThreadKey(Thread.currentThread(), a_id);
0438:                System.setProperty(threadKey
0439:                        + Configuration.PROPERTY_FITFUNC_INST, "");
0440:                System.setProperty(threadKey
0441:                        + Configuration.PROPERTY_BFITFNC_INST, "");
0442:                System.setProperty(threadKey
0443:                        + Configuration.PROPERTY_FITEVAL_INST, "");
0444:                System.setProperty(threadKey
0445:                        + Configuration.PROPERTY_SAMPLE_CHROM_INST, "");
0446:                System.setProperty(threadKey
0447:                        + Configuration.PROPERTY_EVENT_MGR_INST, "");
0448:            }
0449:
0450:            /**
0451:             * See Configuration.reset().
0452:             * @param a_propName the property to reset
0453:             *
0454:             * @author Klaus Meffert
0455:             * @since 3.0
0456:             */
0457:            public static void resetProperty(final String a_propName) {
0458:                resetProperty(a_propName, "");
0459:            }
0460:
0461:            public static void resetProperty(final String a_propName,
0462:                    final String a_id) {
0463:                String threadKey = getThreadKey(Thread.currentThread(), a_id);
0464:                System.setProperty(threadKey + a_propName, "");
0465:            }
0466:
0467:            /**
0468:             * @param a_name informative name of the configuration
0469:             *
0470:             * @author Klaus Meffert
0471:             * @since 2.3
0472:             */
0473:            public void setName(final String a_name) {
0474:                m_name = a_name;
0475:            }
0476:
0477:            /**
0478:             * @return informative name of the configuration
0479:             *
0480:             * @author Klaus Meffert
0481:             * @since 2.3
0482:             */
0483:            public String getName() {
0484:                return m_name;
0485:            }
0486:
0487:            /**
0488:             * Sets the fitness function to be used for this genetic algorithm.
0489:             * The fitness function is responsible for evaluating a given Chromosome and
0490:             * returning a positive integer that represents its worth as a candidate
0491:             * solution. These values are used as a guide by the natural to determine
0492:             * which Chromosome instances will be allowed to move on to the next round of
0493:             * evolution, and which will instead be eliminated.
0494:             *
0495:             * Note that it is illegal to set both this fitness function and a bulk
0496:             * fitness function. Although one or the other must be set, the two are
0497:             * mutually exclusive.
0498:             *
0499:             * @param a_functionToSet fitness function to be used
0500:             *
0501:             * @throws InvalidConfigurationException if the fitness function is null, a
0502:             * bulk fitness function has already been set, or if this Configuration
0503:             * object is locked.
0504:             *
0505:             * @author Neil Rotstan
0506:             * @since 1.1
0507:             */
0508:            public synchronized void setFitnessFunction(
0509:                    final FitnessFunction a_functionToSet)
0510:                    throws InvalidConfigurationException {
0511:                verifyChangesAllowed();
0512:                // Sanity check: Make sure that the given fitness function isn't null.
0513:                // -------------------------------------------------------------------
0514:                if (a_functionToSet == null) {
0515:                    throw new InvalidConfigurationException(
0516:                            "The FitnessFunction instance may not be null.");
0517:                }
0518:                // Make sure the bulk fitness function hasn't already been set.
0519:                // ------------------------------------------------------------
0520:                if (m_bulkObjectiveFunction != null) {
0521:                    throw new InvalidConfigurationException(
0522:                            "The bulk fitness function and normal fitness function "
0523:                                    + "may not both be set.");
0524:                }
0525:                // Ensure that no other fitness function has been set in a different
0526:                // configuration object within the same thread!
0527:                // -----------------------------------------------------------------
0528:                checkProperty(PROPERTY_FITFUNC_INST, a_functionToSet,
0529:                        m_objectiveFunction,
0530:                        "Fitness function has already been set differently.");
0531:                m_objectiveFunction = a_functionToSet;
0532:            }
0533:
0534:            /**
0535:             * Verifies that a property is not set. If not set, set it, otherwise throw
0536:             * a RuntimeException with a_errmsg as text.
0537:             * @param a_propname the property to check (the current thread will be
0538:             * considered as a part of the property's name, too)
0539:             * @param a_obj the object that should be set in charge of the property
0540:             * @param a_oldObj the old object that is set until now. Not used yet
0541:             * @param a_errmsg the error message to throw in case the property is already
0542:             * set for the current thread
0543:             *
0544:             * @author Klaus Meffert
0545:             * @since 3.0
0546:             */
0547:            protected void checkProperty(final String a_propname,
0548:                    final Object a_obj, final Object a_oldObj,
0549:                    final String a_errmsg) {
0550:                String instanceHash = System.getProperty(
0551:                        threadKey + a_propname, null);
0552:                String key = makeKey(a_obj);
0553:                if (instanceHash == null || instanceHash.length() < 1) {
0554:                    System.setProperty(threadKey + a_propname, key);
0555:                } else if (!instanceHash.equals(key)) {
0556:                    throw new RuntimeException(a_errmsg
0557:                            + "\nIf you want to set or construct"
0558:                            + " a configuration multiple times, please call"
0559:                            + " static method Configuration.reset() before"
0560:                            + " each setting!");
0561:                }
0562:            }
0563:
0564:            /**
0565:             * @param a_obj the object to make a key for, must not be null
0566:             * @return key produced for the object (hashCode() is used, so it should be
0567:             * implemented properly!)
0568:             *
0569:             * @author Klaus Meffert
0570:             * @since 3.0
0571:             */
0572:            protected String makeKey(final Object a_obj) {
0573:                String key = String.valueOf(a_obj.hashCode())
0574:                        + a_obj.getClass().getName();
0575:                return key;
0576:            }
0577:
0578:            /**
0579:             * Retrieves the fitness function previously setup in this Configuration
0580:             * object.
0581:             *
0582:             * @return the fitness function
0583:             *
0584:             * @author Neil Rotstan
0585:             * @since 1.0
0586:             */
0587:            public synchronized FitnessFunction getFitnessFunction() {
0588:                return m_objectiveFunction;
0589:            }
0590:
0591:            /**
0592:             * Sets the bulk fitness function to be used for this genetic algorithm.
0593:             * The bulk fitness function may be used to evaluate and assign fitness
0594:             * values to the entire group of candidate Chromosomes in a single batch.
0595:             * This can be useful in cases where it's difficult to assign fitness
0596:             * values to a Chromosome in isolation from the other candidate
0597:             * Chromosomes.
0598:             * <p>
0599:             * Note that it is illegal to set both a bulk fitness function and a
0600:             * normal fitness function. Although one or the other is required, the
0601:             * two are mutually exclusive.
0602:             *
0603:             * @param a_functionToSet bulk fitness function to be used
0604:             *
0605:             * @throws InvalidConfigurationException if the bulk fitness function is
0606:             * null, the normal fitness function has already been set, or if this
0607:             * Configuration object is locked
0608:             *
0609:             * @author Neil Rotstan
0610:             * @author Klaus Meffert
0611:             * @since 1.0
0612:             */
0613:            public synchronized void setBulkFitnessFunction(
0614:                    final BulkFitnessFunction a_functionToSet)
0615:                    throws InvalidConfigurationException {
0616:                verifyChangesAllowed();
0617:                // Sanity check: Make sure that the given bulk fitness function
0618:                // isn't null.
0619:                // ------------------------------------------------------------
0620:                if (a_functionToSet == null) {
0621:                    throw new InvalidConfigurationException(
0622:                            "The BulkFitnessFunction instance may not be null.");
0623:                }
0624:                // Make sure a normal fitness function hasn't already been set.
0625:                // ------------------------------------------------------------
0626:                if (m_objectiveFunction != null) {
0627:                    throw new InvalidConfigurationException(
0628:                            "The bulk fitness function and normal fitness function "
0629:                                    + "may not both be set.");
0630:                }
0631:                // Ensure that no other bulk fitness function has been set in a
0632:                // different configuration object within the same thread!
0633:                // ------------------------------------------------------------
0634:                checkProperty(PROPERTY_BFITFNC_INST, a_functionToSet,
0635:                        m_bulkObjectiveFunction,
0636:                        "Bulk fitness function has already been set differently.");
0637:                m_bulkObjectiveFunction = a_functionToSet;
0638:            }
0639:
0640:            /**
0641:             * Retrieves the bulk fitness function previously setup in this
0642:             * Configuration object.
0643:             *
0644:             * @return the bulk fitness function
0645:             *
0646:             * @author Neil Rotstan
0647:             * @since 1.0
0648:             */
0649:            public synchronized BulkFitnessFunction getBulkFitnessFunction() {
0650:                return m_bulkObjectiveFunction;
0651:            }
0652:
0653:            /**
0654:             * Sets the sample Chromosome that is to be used as a guide for the
0655:             * construction of other Chromosomes. The Chromosome should be setup
0656:             * with each gene represented by the desired concrete Gene implementation
0657:             * for that gene position (locus). Anytime a new Chromosome is created,
0658:             * it will be constructed with the same Gene setup as that provided in
0659:             * this sample Chromosome.
0660:             *
0661:             * @param a_sampleChromosomeToSet Chromosome to be used as the sample
0662:             * @throws InvalidConfigurationException if the given Chromosome is null or
0663:             * this Configuration object is locked
0664:             *
0665:             * @author Neil Rotstan
0666:             * @since 1.0
0667:             */
0668:            public void setSampleChromosome(
0669:                    final IChromosome a_sampleChromosomeToSet)
0670:                    throws InvalidConfigurationException {
0671:                verifyChangesAllowed();
0672:                // Sanity check: Make sure that the given chromosome isn't null.
0673:
0674:                // -----------------------------------------------------------
0675:                if (a_sampleChromosomeToSet == null) {
0676:                    throw new InvalidConfigurationException(
0677:                            "The sample chromosome instance may not be null.");
0678:                }
0679:                if (a_sampleChromosomeToSet.getConfiguration() == null) {
0680:                    throw new InvalidConfigurationException(
0681:                            "The sample chromosome's configuration may not be null.");
0682:                }
0683:                // Ensure that no other sample chromosome has been set in a
0684:                // different configuration object within the same thread!
0685:                // --------------------------------------------------------
0686:                checkProperty(PROPERTY_SAMPLE_CHROM_INST,
0687:                        a_sampleChromosomeToSet, m_sampleChromosome,
0688:                        "Sample chromosome has already been set differently.");
0689:                m_sampleChromosome = a_sampleChromosomeToSet;
0690:                m_chromosomeSize = m_sampleChromosome.size();
0691:            }
0692:
0693:            /**
0694:             * Retrieves the sample Chromosome that contains the desired Gene setup
0695:             * for each respective gene position (locus).
0696:             *
0697:             * @return sample Chromosome instance
0698:             *
0699:             * @author Neil Rotstan
0700:             * @since 1.0
0701:             */
0702:            public IChromosome getSampleChromosome() {
0703:                return m_sampleChromosome;
0704:            }
0705:
0706:            /**
0707:             * Retrieves the chromosome size being used by this genetic
0708:             * algorithm. This value is set automatically when the sample chromosome
0709:             * is provided.
0710:             *
0711:             * @return chromosome size used in this configuration
0712:             *
0713:             * @author Neil Rotstan
0714:             * @since 1.0
0715:             */
0716:            public int getChromosomeSize() {
0717:                return m_chromosomeSize;
0718:            }
0719:
0720:            /**
0721:             * Sets the natural selector to be used for this genetic algorithm.
0722:             * The natural selector is responsible for actually selecting
0723:             * which Chromosome instances are allowed to move on to the next
0724:             * round of evolution (usually guided by the fitness values
0725:             * provided by the fitness function). This setting is required.
0726:             *
0727:             * @param a_selectorToSet the natural selector to be used
0728:             *
0729:             * @throws InvalidConfigurationException if the natural selector is null or
0730:             * this Configuration object is locked
0731:             *
0732:             * @author Neil Rotstan
0733:             * @since 1.0
0734:             * @deprecated use addNaturalSelector(false) instead
0735:             */
0736:            public synchronized void setNaturalSelector(
0737:                    final NaturalSelector a_selectorToSet)
0738:                    throws InvalidConfigurationException {
0739:                addNaturalSelector(a_selectorToSet, false);
0740:            }
0741:
0742:            /**
0743:             * Retrieves the natural selector setup in this Configuration instance.
0744:             *
0745:             * @return the natural selector
0746:             *
0747:             * @author Neil Rotstan
0748:             * @since 1.0
0749:             * @deprecated use getNaturalSelectors(true) or getNaturalSelectors(false)
0750:             * to obtain the relevant chain of NaturalSelector's and then call the
0751:             * chain's get(index) method
0752:             */
0753:            public synchronized NaturalSelector getNaturalSelector() {
0754:                if (getNaturalSelectors(false).size() < 1) {
0755:                    return null;
0756:                }
0757:                return getNaturalSelectors(false).get(0);
0758:            }
0759:
0760:            /**
0761:             * @param a_processBeforeGeneticOperators true: retrieve selector that is
0762:             * registered to be executed before genetic operators, false: get the one
0763:             * that is registered to be executed after genetic operators
0764:             * @param a_index index of the selector to get
0765:             * @return NaturalSelector
0766:             *
0767:             * @author Klaus Meffert
0768:             * @since 1.1
0769:             */
0770:            public synchronized NaturalSelector getNaturalSelector(
0771:                    final boolean a_processBeforeGeneticOperators,
0772:                    final int a_index) {
0773:                if (a_processBeforeGeneticOperators) {
0774:                    return m_preSelectors.get(a_index);
0775:                } else {
0776:                    return m_postSelectors.get(a_index);
0777:                }
0778:            }
0779:
0780:            /**
0781:             * Only use for read-only access! Especially don't call clear() for the
0782:             * returned ChainOfSelectors object!
0783:             *
0784:             * @param a_processBeforeGeneticOperators true: retrieve selector that is
0785:             * registered to be executed before genetic operators, false: get the one
0786:             * that is registered to be executed after genetic operators
0787:             * @return ChainOfSelectors
0788:             *
0789:             * @author Klaus Meffert
0790:             * @since 1.1
0791:             */
0792:            public ChainOfSelectors getNaturalSelectors(
0793:                    final boolean a_processBeforeGeneticOperators) {
0794:                if (a_processBeforeGeneticOperators) {
0795:                    return m_preSelectors;
0796:                } else {
0797:                    return m_postSelectors;
0798:                }
0799:            }
0800:
0801:            /**
0802:             * @param a_processBeforeGeneticOperators true: retrieve selector that is
0803:             * registered to be executed before genetic operators, false: get the one
0804:             * that is registered to be executed after genetic operators
0805:             * @return size of selector list (distinct by a_processBeforeGeneticOperators)
0806:             *
0807:             * @author Klaus Meffert
0808:             * @since 1.1
0809:             */
0810:            public int getNaturalSelectorsSize(
0811:                    final boolean a_processBeforeGeneticOperators) {
0812:                if (a_processBeforeGeneticOperators) {
0813:                    return m_preSelectors.size();
0814:                } else {
0815:                    return m_postSelectors.size();
0816:                }
0817:            }
0818:
0819:            /**
0820:             * Removes all natural selectors (either pre or post ones).
0821:             *
0822:             * @param a_processBeforeGeneticOperators true: remove all selectors
0823:             * processed before genetic operators, false: remove the ones processed
0824:             * afterwards
0825:             *
0826:             * @author Klaus Meffert
0827:             * @since 2.3
0828:             */
0829:            public void removeNaturalSelectors(
0830:                    final boolean a_processBeforeGeneticOperators) {
0831:                if (a_processBeforeGeneticOperators) {
0832:                    getNaturalSelectors(true).clear();
0833:                } else {
0834:                    getNaturalSelectors(false).clear();
0835:                }
0836:            }
0837:
0838:            /**
0839:             * Sets the random generator to be used for this genetic algorithm.
0840:             * The random generator is responsible for generating random numbers,
0841:             * which are used throughout the process of genetic evolution and
0842:             * selection. This setting is required.
0843:             *
0844:             * @param a_generatorToSet random generator to be used
0845:             *
0846:             * @throws InvalidConfigurationException if the random generator is null or
0847:             * this object is locked
0848:             *
0849:             * @author Neil Rotstan
0850:             * @since 1.0
0851:             */
0852:            public synchronized void setRandomGenerator(
0853:                    final RandomGenerator a_generatorToSet)
0854:                    throws InvalidConfigurationException {
0855:                verifyChangesAllowed();
0856:                // Sanity check: Make sure that the given random generator isn't null.
0857:                // -------------------------------------------------------------------
0858:                if (a_generatorToSet == null) {
0859:                    throw new InvalidConfigurationException(
0860:                            "The RandomGenerator instance may not be null.");
0861:                }
0862:                m_randomGenerator = a_generatorToSet;
0863:            }
0864:
0865:            /**
0866:             * Retrieves the random generator setup in this Configuration instance.
0867:             *
0868:             * @return the random generator
0869:             *
0870:             * @author Neil Rotstan
0871:             * @since 1.0
0872:             */
0873:            public synchronized RandomGenerator getRandomGenerator() {
0874:                return m_randomGenerator;
0875:            }
0876:
0877:            /**
0878:             * Adds a genetic operator for use in this algorithm. Genetic operators
0879:             * represent evolutionary steps that, when combined, make up the
0880:             * evolutionary process. Examples of genetic operators are reproduction,
0881:             * crossover, and mutation. During the evolution process, all of the
0882:             * genetic operators added via this method are invoked in the order
0883:             * they were added. At least one genetic operator must be provided.
0884:             *
0885:             * @param a_operatorToAdd the genetic operator to add.
0886:             *
0887:             * @throws InvalidConfigurationException if the genetic operator is null or
0888:             * if this Configuration object is locked
0889:             *
0890:             * @author Neil Rotstan
0891:             * @since 1.0
0892:             */
0893:            public synchronized void addGeneticOperator(
0894:                    final GeneticOperator a_operatorToAdd)
0895:                    throws InvalidConfigurationException {
0896:                verifyChangesAllowed();
0897:                // Sanity check: Make sure that the given genetic operator isn't null.
0898:                // -------------------------------------------------------------------
0899:                if (a_operatorToAdd == null) {
0900:                    throw new InvalidConfigurationException(
0901:                            "The GeneticOperator instance may not be null.");
0902:                }
0903:                m_geneticOperators.add(a_operatorToAdd);
0904:            }
0905:
0906:            /**
0907:             * Retrieves the genetic operators setup in this Configuration instance.
0908:             * Note that once this Configuration instance is locked, a new, immutable list
0909:             * of operators is used and any lists previously retrieved with this method
0910:             * will no longer reflect the actual list in use.
0911:             *
0912:             * @return the list of genetic operators
0913:             *
0914:             * @author Neil Rotstan
0915:             * @since 1.0
0916:             */
0917:            public List getGeneticOperators() {
0918:                return m_geneticOperators;
0919:            }
0920:
0921:            /**
0922:             * Sets the population size to be used for this genetic algorithm.
0923:             * The population size is a fixed value that represents the
0924:             * number of Chromosomes contained within the Genotype (population).
0925:             * This setting is required.
0926:             *
0927:             * @param a_sizeOfPopulation population size to be used
0928:             *
0929:             * @throws InvalidConfigurationException if the population size is not
0930:             * positive or this object is locked
0931:             *
0932:             * @author Neil Rotstan
0933:             * @since 1.0
0934:             */
0935:            public synchronized void setPopulationSize(
0936:                    final int a_sizeOfPopulation)
0937:                    throws InvalidConfigurationException {
0938:                verifyChangesAllowed();
0939:                // Sanity check: Make sure the population size is positive.
0940:                // --------------------------------------------------------
0941:                if (a_sizeOfPopulation < 1) {
0942:                    throw new InvalidConfigurationException(
0943:                            "The population size must be positive.");
0944:                }
0945:                m_config.m_populationSize = a_sizeOfPopulation;
0946:            }
0947:
0948:            /**
0949:             * Retrieves the population size setup in this Configuration instance.
0950:             *
0951:             * @return population size
0952:             */
0953:            public synchronized int getPopulationSize() {
0954:                return m_config.m_populationSize;
0955:            }
0956:
0957:            /**
0958:             * Sets the event manager that is to be associated with this configuration.
0959:             * The event manager is responsible for the management of event subscribers
0960:             * and event notifications.
0961:             *
0962:             * @param a_eventManagerToSet the EventManager instance to use in this
0963:             * configuration
0964:             *
0965:             * @throws InvalidConfigurationException if the event manager is null
0966:             * or this Configuration object is locked
0967:             *
0968:             * @author Neil Rotstan
0969:             * @since 1.0
0970:             */
0971:            public void setEventManager(final IEventManager a_eventManagerToSet)
0972:                    throws InvalidConfigurationException {
0973:                verifyChangesAllowed();
0974:                // Sanity check: Make sure that the given event manager isn't null.
0975:                // ----------------------------------------------------------------
0976:                if (a_eventManagerToSet == null) {
0977:                    throw new InvalidConfigurationException(
0978:                            "The event manager instance may not be null.");
0979:                }
0980:                // Ensure that no other event manager has been set in a different
0981:                // configuration object within the same thread!
0982:                // --------------------------------------------------------------
0983:                checkProperty(PROPERTY_EVENT_MGR_INST, a_eventManagerToSet,
0984:                        m_eventManager,
0985:                        "Event manager has already been set differently.");
0986:                m_eventManager = a_eventManagerToSet;
0987:            }
0988:
0989:            /**
0990:             * Retrieves the event manager associated with this configuration. The event
0991:             * manager is responsible for the management of event subscribers
0992:             * and event notifications.
0993:             *
0994:             * @return the actively configured event manager instance
0995:             *
0996:             * @since 1.0
0997:             */
0998:            public IEventManager getEventManager() {
0999:                return m_eventManager;
1000:            }
1001:
1002:            /**
1003:             * Sets the ChromosomePool that is to be associated with this
1004:             * configuration. The ChromosomePool is used to pool discarded Chromosome
1005:             * instances so that they may be recycled later, thereby saving memory and
1006:             * the time to construct them from scratch. The presence of a ChromosomePool
1007:             * is optional. If none exists, then a new Chromosome will be constructed
1008:             * each time one is needed.
1009:             *
1010:             * @param a_chromosomePoolToSet the ChromosomePool instance to use
1011:             * @throws InvalidConfigurationException if this object is locked
1012:             *
1013:             * @author Neil Rotstan
1014:             * @since 1.0
1015:             */
1016:            public void setChromosomePool(
1017:                    final IChromosomePool a_chromosomePoolToSet)
1018:                    throws InvalidConfigurationException {
1019:                verifyChangesAllowed();
1020:                m_chromosomePool = a_chromosomePoolToSet;
1021:            }
1022:
1023:            /**
1024:             * Retrieves the ChromosomePool instance, if any, that is associated with
1025:             * this configuration. The ChromosomePool is used to pool discarded
1026:             * Chromosome instances so that they may be recycled later, thereby
1027:             * saving memory and the time to construct them from scratch. The presence
1028:             * of a ChromosomePool instance is optional. If none exists, then new
1029:             * Chromosomes should be constructed each time one is needed.
1030:             *
1031:             * @return the ChromosomePool instance associated this configuration, or
1032:             * null if none has been provided
1033:             *
1034:             * @author Neil Rotstan
1035:             * @since 1.0
1036:             */
1037:            public IChromosomePool getChromosomePool() {
1038:                return m_chromosomePool;
1039:            }
1040:
1041:            /**
1042:             * Locks all of the settings in this configuration object. Once
1043:             * this method is successfully invoked, none of the settings may
1044:             * be changed. There is no way to unlock this object once it is locked.
1045:             * <p>
1046:             * Prior to returning successfully, this method will first invoke the
1047:             * verifyStateIsValid() method to make sure that any required configuration
1048:             * options have been properly set. If it detects a problem, it will
1049:             * throw an InvalidConfigurationException and leave the object unlocked.
1050:             * <p>
1051:             * It's possible to test whether this object is locked through the
1052:             * isLocked() method.
1053:             * <p>
1054:             * It is ok to lock an object more than once. In that case, this method
1055:             * does nothing and simply returns.
1056:             *
1057:             * @throws InvalidConfigurationException if this Configuration object is
1058:             * in an invalid state at the time of invocation
1059:             *
1060:             * @author Neil Rotstan
1061:             * @since 1.0
1062:             */
1063:            public synchronized void lockSettings()
1064:                    throws InvalidConfigurationException {
1065:                if (!m_settingsLocked) {
1066:                    verifyStateIsValid();
1067:                    //      // Make genetic operators list immutable.
1068:                    //      // --------------------------------------
1069:                    //      m_geneticOperators = Collections.unmodifiableList(m_geneticOperators);
1070:                    m_settingsLocked = true;
1071:                }
1072:            }
1073:
1074:            /**
1075:             * Retrieves the lock status of this object.
1076:             *
1077:             * @return true if this object has been locked by a previous successful
1078:             * call to the lockSettings() method, false otherwise
1079:             *
1080:             * @author Neil Rotstan
1081:             * @since 1.0
1082:             */
1083:            public boolean isLocked() {
1084:                return m_settingsLocked;
1085:            }
1086:
1087:            /**
1088:             * Tests the state of this Configuration object to make sure it's valid.
1089:             * This generally consists of verifying that required settings have, in
1090:             * fact, been set. If this object is not in a valid state, then an
1091:             * exception will be thrown detailing the reason the state is not valid.
1092:             *
1093:             * @throws InvalidConfigurationException if the state of this Configuration
1094:             * is not valid. The error message in the exception will detail the reason
1095:             * for invalidity
1096:             *
1097:             * @author Neil Rotstan
1098:             * @since 1.0
1099:             */
1100:            public synchronized void verifyStateIsValid()
1101:                    throws InvalidConfigurationException {
1102:                // First, make sure all of the required fields have been set to
1103:                // appropriate values.
1104:                // ------------------------------------------------------------
1105:                if (m_objectiveFunction == null
1106:                        && m_bulkObjectiveFunction == null) {
1107:                    throw new InvalidConfigurationException(
1108:                            "A desired fitness function or bulk fitness function must "
1109:                                    + "be specified in the active configuration.");
1110:                }
1111:                if (m_sampleChromosome == null) {
1112:                    throw new InvalidConfigurationException(
1113:                            "A sample instance of the desired Chromosome "
1114:                                    + "setup must be specified in the active configuration.");
1115:                }
1116:                if (m_preSelectors.size() == 0 && m_postSelectors.size() == 0) {
1117:                    throw new InvalidConfigurationException(
1118:                            "At least one desired natural selector must be specified in the"
1119:                                    + " active configuration.");
1120:                }
1121:                if (m_randomGenerator == null) {
1122:                    throw new InvalidConfigurationException(
1123:                            "A desired random number generator must be specified in the "
1124:                                    + "active configuration.");
1125:                }
1126:                if (m_eventManager == null) {
1127:                    throw new InvalidConfigurationException(
1128:                            "A desired event manager must be specified in the active "
1129:                                    + "configuration.");
1130:                }
1131:                if (m_geneticOperators.isEmpty()) {
1132:                    throw new InvalidConfigurationException(
1133:                            "At least one genetic operator must be specified in the "
1134:                                    + "configuration.");
1135:                }
1136:                if (m_chromosomeSize <= 0) {
1137:                    throw new InvalidConfigurationException(
1138:                            "A chromosome size greater than zero must be specified in "
1139:                                    + "the active configuration.");
1140:                }
1141:                if (m_config.m_populationSize <= 0) {
1142:                    throw new InvalidConfigurationException(
1143:                            "A population size greater than zero must be specified in "
1144:                                    + "the active configuration.");
1145:                }
1146:                if (m_fitnessEvaluator == null) {
1147:                    throw new IllegalArgumentException(
1148:                            "The fitness evaluator may not be null.");
1149:                }
1150:                // Next, it's critical that each Gene implementation in the sample
1151:                // Chromosome has a working equals() method, or else the genetic
1152:                // engine will end up failing in mysterious and unpredictable ways.
1153:                // We therefore verify right here that this method is working properly
1154:                // in each of the Gene implementations used in the sample Chromosome.
1155:                // -------------------------------------------------------------------
1156:                Gene[] sampleGenes = m_sampleChromosome.getGenes();
1157:                for (int i = 0; i < sampleGenes.length; i++) {
1158:                    Gene sampleCopy = sampleGenes[i].newGene();
1159:                    sampleCopy.setAllele(sampleGenes[i].getAllele());
1160:                    if (!(sampleCopy.equals(sampleGenes[i]))) {
1161:                        throw new InvalidConfigurationException(
1162:                                "The sample Gene at gene position (locus) "
1163:                                        + i
1164:                                        + " does not appear to have a working equals() or compareTo()"
1165:                                        + " method.\n"
1166:                                        + "It could also be that you forgot to implement method"
1167:                                        + " newGene() in your Gene implementation.\n"
1168:                                        + "When tested, the method returned false when comparing "
1169:                                        + "the sample gene with a gene of the same type and "
1170:                                        + "possessing the same value (allele).");
1171:                    }
1172:                }
1173:            }
1174:
1175:            /**
1176:             * Makes sure that this Configuration object isn't locked. If it is, then
1177:             * an exception is thrown with an appropriate message indicating
1178:             * that settings in this object may not be altered. This method
1179:             * should be invoked by any mutator method in this object prior
1180:             * to making any state alterations.
1181:             *
1182:             * @throws InvalidConfigurationException if this Configuration object is
1183:             * locked
1184:             *
1185:             * @author Neil Rotstan
1186:             * @since 1.0
1187:             */
1188:            protected void verifyChangesAllowed()
1189:                    throws InvalidConfigurationException {
1190:                if (m_settingsLocked) {
1191:                    throw new InvalidConfigurationException(
1192:                            "This Configuration object is locked. Settings may not be "
1193:                                    + "altered.");
1194:                }
1195:            }
1196:
1197:            /**
1198:             * Adds a NaturalSelector to the ordered chain of registered
1199:             * NaturalSelector's. It's possible to execute the NaturalSelector before
1200:             * or after (registered) genetic operations have been applied.
1201:             * @param a_selector the selector to be added to the chain
1202:             * @param a_processBeforeGeneticOperators true: execute NaturalSelector
1203:             * before any genetic operator will be applied, false: .. after..
1204:             * @throws InvalidConfigurationException
1205:             *
1206:             * @author Klaus Meffert
1207:             * @since 1.1
1208:             */
1209:            public void addNaturalSelector(NaturalSelector a_selector,
1210:                    boolean a_processBeforeGeneticOperators)
1211:                    throws InvalidConfigurationException {
1212:                verifyChangesAllowed();
1213:                if (a_processBeforeGeneticOperators) {
1214:                    m_preSelectors.addNaturalSelector(a_selector);
1215:                } else {
1216:                    m_postSelectors.addNaturalSelector(a_selector);
1217:                }
1218:            }
1219:
1220:            /**
1221:             * Minimum size guaranteed for population. This is significant during
1222:             * evolution as natural selectors could select fewer chromosomes for the next
1223:             * generation than the initial population size was.
1224:             * @param a_minimumSizeGuaranteedPercent if zero or below then no ensurance
1225:             * for size given, see Genotype.evolve()
1226:             *
1227:             * @author Klaus Meffert
1228:             */
1229:            public void setMinimumPopSizePercent(
1230:                    int a_minimumSizeGuaranteedPercent) {
1231:                m_minPercentageSizePopulation = a_minimumSizeGuaranteedPercent;
1232:            }
1233:
1234:            public int getMinimumPopSizePercent() {
1235:                return m_minPercentageSizePopulation;
1236:            }
1237:
1238:            /**
1239:             * @return the assigned FitnessEvaluator
1240:             *
1241:             * @author Klaus Meffert
1242:             * @since 2.0
1243:             */
1244:            public FitnessEvaluator getFitnessEvaluator() {
1245:                return m_fitnessEvaluator;
1246:            }
1247:
1248:            /**
1249:             * Set the fitness evaluator (deciding if a given fitness value is better
1250:             * when it's higher or better when it's lower).
1251:             * @param a_fitnessEvaluator the FitnessEvaluator to be used
1252:             *
1253:             * @author Klaus Meffert
1254:             * @since 2.0
1255:             */
1256:            public void setFitnessEvaluator(FitnessEvaluator a_fitnessEvaluator) {
1257:                if (a_fitnessEvaluator == null) {
1258:                    throw new IllegalStateException(
1259:                            "The fitness evaluator object must not be null!");
1260:                }
1261:                // Ensure that no other fitness evaluator has been set in a
1262:                // different configuration object within the same thread!
1263:                // --------------------------------------------------------
1264:                checkProperty(PROPERTY_FITEVAL_INST, a_fitnessEvaluator,
1265:                        m_fitnessEvaluator,
1266:                        "Fitness evaluator has already been set differently.");
1267:                m_fitnessEvaluator = a_fitnessEvaluator;
1268:            }
1269:
1270:            /**
1271:             * @return true: fittest chromosome should always be transferred to next
1272:             * generation
1273:             *
1274:             * @author Klaus Meffert
1275:             * @since 2.1
1276:             */
1277:            public boolean isPreserveFittestIndividual() {
1278:                return m_preserveFittestIndividual;
1279:            }
1280:
1281:            /**
1282:             * Determines whether to save (keep) the fittest individual.
1283:             * @param a_preserveFittest true: always transfer fittest chromosome to next
1284:             * generation
1285:             *
1286:             * @author Klaus Meffert
1287:             * @since 2.1
1288:             */
1289:            public void setPreservFittestIndividual(boolean a_preserveFittest) {
1290:                m_preserveFittestIndividual = a_preserveFittest;
1291:            }
1292:
1293:            public void incrementGenerationNr() {
1294:                m_generationNr++;
1295:            }
1296:
1297:            public int getGenerationNr() {
1298:                return m_generationNr;
1299:            }
1300:
1301:            /**
1302:             * Implementation of the Configurable interface.
1303:             * @return ConfigurationHandler
1304:             * @throws ConfigException
1305:             *
1306:             * @author Siddhartha Azad
1307:             */
1308:            public ConfigurationHandler getConfigurationHandler() {
1309:                return m_conHandler;
1310:            }
1311:
1312:            /**
1313:             * @return string representation of the configuration containing all
1314:             * configurable elements
1315:             *
1316:             * @author Klaus Meffert
1317:             * @since 2.3
1318:             */
1319:            public String toString() {
1320:                String result = S_CONFIGURATION + ":";
1321:                // Basic parameters.
1322:                // -----------------
1323:                result += "\n " + S_CONFIGURATION_NAME + ": " + getName();
1324:                result += "\n " + S_POPULATION_SIZE + ": "
1325:                        + getPopulationSize();
1326:                result += "\n " + S_MINPOPSIZE + ": "
1327:                        + getMinimumPopSizePercent();
1328:                result += "\n " + S_CHROMOSOME_SIZE + ": "
1329:                        + getChromosomeSize();
1330:                // Sample chromosome.
1331:                // ------------------
1332:                result += "\n " + S_SAMPLE_CHROM + ":\n";
1333:                if (getSampleChromosome() == null) {
1334:                    result += "\n null";
1335:                } else {
1336:                    result += "\n    " + S_SIZE + ": "
1337:                            + getSampleChromosome().size();
1338:                    result += "\n    " + S_TOSTRING + ": "
1339:                            + getSampleChromosome().toString();
1340:                }
1341:                // Random generator.
1342:                // -----------------
1343:                result += "\n  " + S_RANDOM_GENERATOR + ": ";
1344:                if (getRandomGenerator() != null) {
1345:                    result += getRandomGenerator().getClass().getName();
1346:                } else {
1347:                    result += S_NONE;
1348:                }
1349:                result += "\n  " + S_EVENT_MANAGER + ": ";
1350:                // Event manager.
1351:                // --------------
1352:                if (getEventManager() == null) {
1353:                    result += S_NONE;
1354:                } else {
1355:                    result += getEventManager().getClass().getName();
1356:                }
1357:                // Configuration handler.
1358:                // ----------------------
1359:                result += "\n " + S_CONFIGURATION_HANDLER + ": ";
1360:                if (getConfigurationHandler() == null) {
1361:                    result += "null";
1362:                } else {
1363:                    result += getConfigurationHandler().getName();
1364:                }
1365:                // Fitness function.
1366:                // -----------------
1367:                result += "\n " + S_FITNESS_FUNCTION + ": ";
1368:                if (getFitnessFunction() == null) {
1369:                    result += "null";
1370:                } else {
1371:                    result += getFitnessFunction().getClass().getName();
1372:                }
1373:                // Fitness evaluator.
1374:                // ------------------
1375:                result += "\n " + S_FITNESS_EVALUATOR + ": ";
1376:                if (getFitnessEvaluator() == null) {
1377:                    result += "null";
1378:                } else {
1379:                    result += getFitnessEvaluator().getClass().getName();
1380:                }
1381:                // Genetic operators.
1382:                // ------------------
1383:                result += "\n  " + S_GENETIC_OPERATORS + ": ";
1384:                if (getGeneticOperators() == null) {
1385:                    result += "null";
1386:                } else {
1387:                    int gensize = getGeneticOperators().size();
1388:                    if (gensize < 1) {
1389:                        result += S_NONE;
1390:                    } else {
1391:                        for (int i = 0; i < gensize; i++) {
1392:                            if (i > 0) {
1393:                                result += "; ";
1394:                            }
1395:                            result += " "
1396:                                    + getGeneticOperators().get(i).getClass()
1397:                                            .getName();
1398:                        }
1399:                    }
1400:                }
1401:                // Natural selectors (pre).
1402:                // ------------------------
1403:                int natsize = getNaturalSelectors(true).size();
1404:                result += "\n  " + S_NATURAL_SELECTORS + "(" + S_PRE + "): ";
1405:                if (natsize < 1) {
1406:                    result += S_NONE;
1407:                } else {
1408:                    for (int i = 0; i < natsize; i++) {
1409:                        if (i > 0) {
1410:                            result += "; ";
1411:                        }
1412:                        result += " "
1413:                                + getNaturalSelectors(true).get(i).getClass()
1414:                                        .getName();
1415:                    }
1416:                }
1417:                // Natural selectors (post).
1418:                // -------------------------
1419:                natsize = getNaturalSelectors(false).size();
1420:                result += "\n  " + S_NATURAL_SELECTORS + "(" + S_POST + "): ";
1421:                if (natsize < 1) {
1422:                    result += "none";
1423:                } else {
1424:                    for (int i = 0; i < natsize; i++) {
1425:                        if (i > 0) {
1426:                            result += "; ";
1427:                        }
1428:                        result += " "
1429:                                + getNaturalSelectors(false).get(i).getClass()
1430:                                        .getName();
1431:                    }
1432:                }
1433:                //    String popSelector;
1434:                //    if (m_popConstantSelector == null) {
1435:                //      popSelector = "null";
1436:                //    }
1437:                //    else {
1438:                //      popSelector = m_popConstantSelector.getClass().getName();
1439:                //    }
1440:                //    result += "\n " + S_POPCONSTANT_SELECTOR + ": "
1441:                //        + popSelector;
1442:                return result;
1443:            }
1444:
1445:            /**
1446:             * See setKeepPopulationSizeConstant for description.
1447:             * @return true: population size will always be the same size
1448:             * (as given with Configuration.setPopulationSize(int)
1449:             *
1450:             * @author Klaus Meffert
1451:             * @since 2.4
1452:             */
1453:            public boolean isKeepPopulationSizeConstant() {
1454:                return m_keepPopulationSizeConstant;
1455:            }
1456:
1457:            /**
1458:             * Allows to keep the population size constant after one evolution, even if
1459:             * there is no appropriate instance of NaturalSelector (such as
1460:             * WeightedRouletteSelector) registered with the Configuration.<p>
1461:             * Be aware that keeping the population size constant often means that a
1462:             * higher population size is necessary (e.g. for the MinimizingMakeChange
1463:             * example)!
1464:             * @param a_keepPopSizeConstant true: population size will always be
1465:             * the same size (as given with Configuration.setPopulationSize(int)
1466:             *
1467:             * @author Klaus Meffert
1468:             * @since 2.4
1469:             */
1470:            public void setKeepPopulationSizeConstant(
1471:                    boolean a_keepPopSizeConstant) {
1472:                m_keepPopulationSizeConstant = a_keepPopSizeConstant;
1473:            }
1474:
1475:            public void setSelectFromPrevGen(double a_percentage) {
1476:                if (a_percentage < 0 || a_percentage > 1.00) {
1477:                    throw new IllegalArgumentException(
1478:                            "Argument must be between 0 and 1");
1479:                }
1480:                m_selectFromPrevGen = a_percentage;
1481:            }
1482:
1483:            public double getSelectFromPrevGen() {
1484:                return m_selectFromPrevGen;
1485:            }
1486:
1487:            /**
1488:             * @return the JGAP factory registered
1489:             *
1490:             * @author Klaus Meffert
1491:             */
1492:            public IJGAPFactory getJGAPFactory() {
1493:                return m_factory;
1494:            }
1495:
1496:            class ConfigurationConfigurable implements  Serializable {
1497:                /**
1498:                 * The number of chromosomes that will be stored in the Genotype.
1499:                 */
1500:                int m_populationSize;
1501:            }
1502:
1503:            /**
1504:             * Builds a string considering the current thread and the given id.
1505:             *
1506:             * @param current the current Thread
1507:             * @param a_id a hopefully unique id of the configuration
1508:             *
1509:             * @return string built up
1510:             *
1511:             * @author Klaus Meffert
1512:             * @since 3.01
1513:             */
1514:            protected static String getThreadKey(Thread current, String a_id) {
1515:                return current.toString() + "|" + a_id + "|";
1516:            }
1517:
1518:            /**
1519:             * @param a_factory the IJGAPFactory to use
1520:             *
1521:             * @author Klaus Meffert
1522:             * @since 3.01
1523:             */
1524:            public void setJGAPFactory(IJGAPFactory a_factory) {
1525:                m_factory = a_factory;
1526:            }
1527:
1528:            /**
1529:             * @param a_breeder the breeder to use
1530:             *
1531:             * @author Klaus Meffert
1532:             * @since 3.2
1533:             */
1534:            public void setBreeder(IBreeder a_breeder) {
1535:                assert (a_breeder != null);
1536:                m_breeder = a_breeder;
1537:            }
1538:
1539:            /**
1540:             * @return the breeder set or new standard breeder instance in case no breeder
1541:             * was set before.
1542:             *
1543:             * @author Klaus Meffert
1544:             * @since 3.2
1545:             */
1546:            public IBreeder getBreeder() {
1547:                if (m_breeder == null) {
1548:                    m_breeder = new GABreeder();
1549:                }
1550:                return m_breeder;
1551:            }
1552:
1553:            //  /**
1554:            //   * If population size should be kept constant then this selector determines
1555:            //   * which of the chromosomes to select into the next generation.
1556:            //   *
1557:            //   * @param a_popConstantSelector the selector to use
1558:            //   * @throws InvalidConfigurationException
1559:            //   *
1560:            //   * @author Klaus Meffert
1561:            //   * @since 3.2.2
1562:            //   */
1563:            //  public void setKeepPopConstantSelector(INaturalSelector a_popConstantSelector)
1564:            //      throws InvalidConfigurationException {
1565:            //    verifyChangesAllowed();
1566:            //    m_popConstantSelector = a_popConstantSelector;
1567:            //  }
1568:
1569:            //  /**
1570:            //   * @return the registered selector to keep population size constant. If none
1571:            //   * is set, the NewestChromosomesSelector is instantiated, assigned and
1572:            //   * returned
1573:            //   *
1574:            //   * @throws InvalidConfigurationException
1575:            //   *
1576:            //   * @author Klaus Meffert
1577:            //   * @since 3.2.2
1578:            //   */
1579:            //  public INaturalSelector getKeepPopConstantSelector()
1580:            //  throws InvalidConfigurationException{
1581:            //    if (m_popConstantSelector == null) {
1582:            //      m_popConstantSelector = new NewestChromosomesSelector(this);
1583:            //    }
1584:            //    return m_popConstantSelector;
1585:            //  }
1586:
1587:            /**
1588:             * @param a_alwaysCalculate true: Chromosome.getFitnessValue() will always
1589:             * (re-)calculate the fitness value. This may be necessary in case of
1590:             * environments where the state changes without the chromosome to notice.
1591:             *
1592:             * @author Klaus Meffert
1593:             * @since 3.2.2
1594:             */
1595:            public void setAlwaysCaculateFitness(boolean a_alwaysCalculate) {
1596:                m_alwaysCalculateFitness = a_alwaysCalculate;
1597:            }
1598:
1599:            /**
1600:             * @return true: Chromosome.getFitnessValue() will always (re-)calculate the
1601:             * fitness value. This may be necessary in case of environments where the
1602:             * state changes without the chromosome to notice.
1603:             *
1604:             * @author Klaus Meffert
1605:             * @since 3.2.2
1606:             */
1607:            public boolean isAlwaysCalculateFitness() {
1608:                return m_alwaysCalculateFitness;
1609:            }
1610:
1611:            protected String makeThreadKey() {
1612:                Thread current = Thread.currentThread();
1613:                threadKey = getThreadKey(current, m_id);
1614:                return threadKey;
1615:            }
1616:
1617:            /**
1618:             * Sets a property in the bag.
1619:             *
1620:             * Be aware that setting in unserializable value here leads to problems with
1621:             * distributed computing or other scenarios based on serialization!
1622:             *
1623:             * Be aware that cloning may also lead to conflicts
1624:             * in case you use unsupported object types!
1625:             *
1626:             * @param a_propName name of the property to se the value for
1627:             * @param a_value value of the property
1628:             *
1629:             * @author Klaus Meffert
1630:             * @since 3.3.1
1631:             */
1632:            //  public void setPropertyInBag(String a_propName, Object a_value) {
1633:            //    m_propertyBag.put(a_propName, a_value);
1634:            //  }
1635:            /**
1636:             *
1637:             * @param a_propName name of the property to retrieve the value from
1638:             * @return value of the property
1639:             *
1640:             * @author Klaus Meffert
1641:             * @since 3.3.1
1642:             */
1643:            //  public Object getPropertyFromBag(String a_propName) {
1644:            //   return m_propertyBag.get(a_propName);
1645:            //  }
1646:            /**
1647:             * Deserialize the object. Needed to provide a unique ID for each thread the
1648:             * object is used in.
1649:             *
1650:             * @param a_inputStream the ObjectInputStream provided for deserialzation
1651:             * @throws ClassNotFoundException
1652:             * @throws IOException
1653:             *
1654:             * @author Klaus Meffert
1655:             * @since 3.01
1656:             */
1657:            private void readObject(ObjectInputStream a_inputStream)
1658:                    throws ClassNotFoundException, IOException {
1659:                // Always perform the default de-serialization first.
1660:                // --------------------------------------------------
1661:                a_inputStream.defaultReadObject();
1662:                makeThreadKey();
1663:            }
1664:
1665:            /**
1666:             * @return the id of the configuration set
1667:             *
1668:             * @author Klaus Meffert
1669:             * @since 3.1
1670:             */
1671:            public String getId() {
1672:                return m_id;
1673:            }
1674:
1675:            /**
1676:             * Only to be called by sub classes, such as GPConfiguration.
1677:             *
1678:             * @param a_id the id to set
1679:             *
1680:             * @author Klaus Meffert
1681:             * @since 3.2
1682:             */
1683:            protected void setId(String a_id) {
1684:                m_id = a_id;
1685:            }
1686:
1687:            /**
1688:             * @return deep clone of this instance
1689:             *
1690:             * @author Klaus Meffert
1691:             * @since 3.2
1692:             */
1693:            public Object clone() {
1694:                return newInstance(m_id, m_name);
1695:            }
1696:
1697:            /**
1698:             * Creates a new Configuration instance by cloning. Allows to preset the
1699:             * ID and the name.
1700:             *
1701:             * @param a_id new ID for clone
1702:             * @param a_name new name for clone
1703:             * @return deep clone of this instance
1704:             *
1705:             * @author Klaus Meffert
1706:             * @since 3.2
1707:             */
1708:            public Configuration newInstance(String a_id, String a_name) {
1709:                try {
1710:                    Configuration result = new Configuration(m_name);
1711:                    // Clone JGAPFactory first because it helps in cloning other objects.
1712:                    // ------------------------------------------------------------------
1713:                    if (m_factory instanceof  ICloneable) {
1714:                        result.m_factory = (IJGAPFactory) ((ICloneable) m_factory)
1715:                                .clone();
1716:                    } else {
1717:                        // We must fallback to a standardized solution.
1718:                        // --------------------------------------------
1719:                        m_factory = new JGAPFactory(false);
1720:                        result.m_factory = (IJGAPFactory) ((JGAPFactory) m_factory)
1721:                                .clone();
1722:                    }
1723:                    if (m_breeder != null) {
1724:                        result.m_breeder = (IBreeder) doClone(m_breeder);
1725:                    }
1726:                    if (m_bulkObjectiveFunction != null) {
1727:                        result.m_bulkObjectiveFunction = m_bulkObjectiveFunction;
1728:                    }
1729:                    result.m_chromosomeSize = m_chromosomeSize;
1730:                    //    result.m_chromosomePool = m_chromosomePool.clone();
1731:                    //    result.m_conHandler = m_conHandler.clone();
1732:                    result.m_eventManager = (IEventManager) doClone(m_eventManager);
1733:                    result.m_fitnessEvaluator = (FitnessEvaluator) doClone(m_fitnessEvaluator);
1734:                    result.m_generationNr = 0;
1735:                    result.m_geneticOperators = (List) doClone(m_geneticOperators);
1736:                    result.m_keepPopulationSizeConstant = m_keepPopulationSizeConstant;
1737:                    result.m_minPercentageSizePopulation = m_minPercentageSizePopulation;
1738:                    result.m_selectFromPrevGen = m_selectFromPrevGen;
1739:                    result.m_objectiveFunction = (FitnessFunction) doClone(m_objectiveFunction);
1740:                    //      result.m_popConstantSelector = (INaturalSelector)doClone(m_popConstantSelector);
1741:                    result.m_postSelectors = (ChainOfSelectors) doClone(m_postSelectors);
1742:                    result.m_preSelectors = (ChainOfSelectors) doClone(m_preSelectors);
1743:                    result.m_preserveFittestIndividual = m_preserveFittestIndividual;
1744:                    result.m_randomGenerator = (RandomGenerator) doClone(m_randomGenerator);
1745:                    result.m_sampleChromosome = (IChromosome) m_sampleChromosome
1746:                            .clone();
1747:                    result.m_alwaysCalculateFitness = m_alwaysCalculateFitness;
1748:                    result.m_settingsLocked = m_settingsLocked;
1749:                    //      result.m_propertyBag = (Map)doClone(m_propertyBag);
1750:                    // Configurable data.
1751:                    // ------------------
1752:                    result.m_config = new ConfigurationConfigurable();
1753:                    result.m_config.m_populationSize = m_config.m_populationSize;
1754:                    // Identificative data.
1755:                    // --------------------
1756:                    result.m_name = a_name;
1757:                    result.m_id = a_id;
1758:                    result.makeThreadKey();// Must be called after m_id is set
1759:                    return result;
1760:                } catch (Throwable t) {
1761:                    throw new CloneException(t);
1762:                }
1763:            }
1764:
1765:            /**
1766:             * Helper called from clone.
1767:             *
1768:             * @param a_objToClone the object to clone
1769:             * @return cloned object or null, if cloning not possible
1770:             * @throws Exception
1771:             *
1772:             * @author Klaus Meffert
1773:             * @since 3.2
1774:             */
1775:            protected Object doClone(Object a_objToClone) throws Exception {
1776:                if (a_objToClone != null) {
1777:                    ICloneHandler handler = getJGAPFactory()
1778:                            .getCloneHandlerFor(a_objToClone, null);
1779:                    if (handler != null) {
1780:                        return handler.perform(a_objToClone, null, null);
1781:                    }
1782:                }
1783:                return null;
1784:            }
1785:
1786:            /**
1787:             * The equals-method.
1788:             *
1789:             * @param a_other the other object to compare
1790:             * @return true if seen as equal
1791:             *
1792:             * @author Klaus Meffert
1793:             * @since 3.2
1794:             */
1795:            public boolean equals(Object a_other) {
1796:                return compareTo(a_other) == 0;
1797:            }
1798:
1799:            /**
1800:             * The compareTo-method.
1801:             *
1802:             * @param a_other the other object to compare
1803:             * @return -1, 0, 1
1804:             *
1805:             * @author Klaus Meffert
1806:             * @since 3.2
1807:             */
1808:            public int compareTo(Object a_other) {
1809:                if (a_other == null) {
1810:                    return 1;
1811:                } else {
1812:                    Configuration other = (Configuration) a_other;
1813:                    try {
1814:                        return new CompareToBuilder()
1815:                                .append(m_config.m_populationSize,
1816:                                        other.m_config.m_populationSize)
1817:                                .append(m_factory, other.m_factory)
1818:                                .append(m_breeder, other.m_breeder)
1819:                                .append(m_objectiveFunction,
1820:                                        other.m_objectiveFunction)
1821:                                .append(m_fitnessEvaluator,
1822:                                        other.m_fitnessEvaluator)
1823:                                .append(m_bulkObjectiveFunction,
1824:                                        other.m_bulkObjectiveFunction)
1825:                                .append(m_sampleChromosome,
1826:                                        other.m_sampleChromosome)
1827:                                .append(m_randomGenerator,
1828:                                        other.m_randomGenerator)
1829:                                //            .append(m_eventManager, other.m_eventManager)
1830:                                //            .append(m_chromosomePool, other.m_chromosomePool)
1831:                                .append(m_geneticOperators.toArray(),
1832:                                        other.m_geneticOperators.toArray())
1833:                                .append(m_chromosomeSize,
1834:                                        other.m_chromosomeSize)
1835:                                .append(m_preSelectors, other.m_preSelectors)
1836:                                .append(m_postSelectors, other.m_postSelectors)
1837:                                //            .append(m_popConstantSelector, other.m_popConstantSelector)
1838:                                .append(m_preserveFittestIndividual,
1839:                                        other.m_preserveFittestIndividual)
1840:                                //            .append(m_conHandler, other.m_conHandler)
1841:                                .append(threadKey, other.threadKey).append(
1842:                                        m_keepPopulationSizeConstant,
1843:                                        other.m_keepPopulationSizeConstant)
1844:                                .append(m_alwaysCalculateFitness,
1845:                                        other.m_alwaysCalculateFitness).append(
1846:                                        m_minPercentageSizePopulation,
1847:                                        other.m_minPercentageSizePopulation)
1848:                                .append(m_selectFromPrevGen,
1849:                                        other.m_selectFromPrevGen).append(
1850:                                        m_generationNr, other.m_generationNr)
1851:                                .append(m_name, other.m_name)
1852:                                //            .append(m_propertyBag, other.m_propertyBag)
1853:                                .append(m_settingsLocked,
1854:                                        other.m_settingsLocked).toComparison();
1855:                    } catch (ClassCastException cex) {
1856:                        throw new RuntimeException(
1857:                                "Cannot compare all objects within"
1858:                                        + " org.jgap.Configuration, because at"
1859:                                        + " least one does not implement interface"
1860:                                        + " java.lang.Comparable!");
1861:                    }
1862:                }
1863:            }
1864:
1865:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.