001: /*
002: * This file is part of JGAP.
003: *
004: * JGAP offers a dual license model containing the LGPL as well as the MPL.
005: *
006: * For licencing information please see the file license.txt included with JGAP
007: * or have a look at the top of class org.jgap.Chromosome which representatively
008: * includes the JGAP license policy applicable for any file delivered with JGAP.
009: */
010: package examples.multiobjective;
011:
012: import java.util.*;
013: import org.jgap.*;
014: import org.jgap.impl.*;
015:
016: /**
017: * Example for a multiobjective problem. Here, we have a function F with one
018: * input parameter t and two output values F1 and F2, with F1 = t²
019: * and F2 = (t - 2)². This example is from Goldberg (pp. 199), who adapted it
020: * from Schaffer (1984).
021: *
022: * @author Klaus Meffert
023: * @since 2.6
024: */
025: public class MultiObjectiveExample {
026: /** String containing the CVS revision. Read out via reflection!*/
027: private final static String CVS_REVISION = "$Revision: 1.5 $";
028:
029: /**
030: * The total number of times we'll let the population evolve.
031: */
032: private static final int MAX_ALLOWED_EVOLUTIONS = 200;
033:
034: /**
035: * Executes the genetic algorithm.
036: *
037: * @throws Exception
038: *
039: * @author Klaus Meffert
040: * @since 2.6
041: */
042: public void execute() throws Exception {
043: // Start with a DefaultConfiguration, which comes setup with the
044: // most common settings.
045: // -------------------------------------------------------------
046: Configuration conf = new DefaultConfiguration();
047: // Add BestChromosomesSelector with doublettes allowed.
048: // ----------------------------------------------------
049: conf.removeNaturalSelectors(true);
050: BestChromosomesSelector bestChromsSelector = new BestChromosomesSelector(
051: conf, 0.95d);
052: bestChromsSelector.setDoubletteChromosomesAllowed(true);
053: conf.addNaturalSelector(bestChromsSelector, true);
054:
055: conf.reset();
056: conf.setFitnessEvaluator(new MOFitnessEvaluator());
057: conf.setPreservFittestIndividual(false);
058: conf.setKeepPopulationSizeConstant(false);
059: // Set the fitness function we want to use, which is our
060: // MinimizingMakeChangeFitnessFunction. We construct it with
061: // the target amount of change passed in to this method.
062: // ---------------------------------------------------------
063: BulkFitnessFunction myFunc = new MultiObjectiveFitnessFunction();
064: conf.setBulkFitnessFunction(myFunc);
065:
066: // Set sample chromosome.
067: // ----------------------
068: Gene[] sampleGenes = new Gene[1];
069: sampleGenes[0] = new DoubleGene(conf,
070: MultiObjectiveFitnessFunction.MIN_X,
071: MultiObjectiveFitnessFunction.MAX_X);
072: IChromosome sampleChromosome = new Chromosome(conf, sampleGenes);
073: conf.setSampleChromosome(sampleChromosome);
074:
075: // Finally, we need to tell the Configuration object how many
076: // Chromosomes we want in our population. The more Chromosomes,
077: // the larger number of potential solutions (which is good for
078: // finding the answer), but the longer it will take to evolve
079: // the population (which could be seen as bad).
080: // ------------------------------------------------------------
081: conf.setPopulationSize(500);
082: // Create random initial population of Chromosomes.
083: // ------------------------------------------------
084: Genotype population = Genotype.randomInitialGenotype(conf);
085: // Evolve the population. Since we don't know what the best answer
086: // is going to be, we just evolve the max number of times.
087: // ---------------------------------------------------------------
088: for (int i = 0; i < MAX_ALLOWED_EVOLUTIONS; i++) {
089: population.evolve();
090: }
091: // Remove solutions that are not Pareto-optimal.
092: // ---------------------------------------------
093: List chroms = population.getPopulation().getChromosomes();
094: int size = population.getPopulation().getChromosomes().size();
095: int i = 0;
096: boolean removed = false;
097: MOFitnessComparator comp = new MOFitnessComparator();
098: while (i < size - 1) {
099: IChromosome chrom1 = population.getPopulation()
100: .getChromosome(i);
101: int j = i + 1;
102: while (j < size) {
103: IChromosome chrom2 = population.getPopulation()
104: .getChromosome(j);
105: int res = comp.compare(chrom1, chrom2);
106: if (res != 0) {
107: if (res == -1) {
108: population.getPopulation().getChromosomes()
109: .remove(i);
110: size--;
111: removed = true;
112: break;
113: } else {
114: population.getPopulation().getChromosomes()
115: .remove(j);
116: size--;
117: }
118: } else {
119: j++;
120: }
121: }
122: if (removed) {
123: removed = false;
124: } else {
125: i++;
126: }
127: }
128: // Print all Pareto-optimal solutions.
129: // -----------------------------------
130: Collections.sort(chroms, comp);
131: for (int k = 0; k < chroms.size(); k++) {
132: Chromosome bestSolutionSoFar = (Chromosome) chroms.get(k);
133: System.out.println(MultiObjectiveFitnessFunction
134: .getVector(bestSolutionSoFar));
135: }
136: }
137:
138: /**
139: * Main method to run the example.
140: *
141: * @param args ignored
142: * @throws Exception
143: *
144: * @author Klaus Meffert
145: * @since 2.6
146: */
147: public static void main(String[] args) throws Exception {
148: MultiObjectiveExample instance = new MultiObjectiveExample();
149: instance.execute();
150: }
151:
152: /**
153: * @author Klaus Meffert
154: * @since 2.6
155: */
156: public class MOFitnessComparator implements java.util.Comparator {
157:
158: public int compare(final Object a_chrom1, final Object a_chrom2) {
159: List v1 = ((Chromosome) a_chrom1).getMultiObjectives();
160: List v2 = ((Chromosome) a_chrom2).getMultiObjectives();
161: int size = v1.size();
162: if (size != v2.size()) {
163: throw new RuntimeException(
164: "Size of objectives inconsistent!");
165: }
166: boolean better1 = false;
167: boolean better2 = false;
168: for (int i = 0; i < size; i++) {
169: double d1 = ((Double) v1.get(i)).doubleValue();
170: double d2 = ((Double) v2.get(i)).doubleValue();
171: if (d1 < d2) {
172: better1 = true;
173: } else if (d2 < d1) {
174: better2 = true;
175: }
176: }
177: if (better1) {
178: if (better2) {
179: return 0;
180: } else {
181: return 1;
182: }
183: } else {
184: if (better2) {
185: return -1;
186: } else {
187: return 0;
188: }
189: }
190: }
191: }
192: }
|