/*
* This file is part of JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licensing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*/
package examples.multiobjective;
import java.util.*;
import org.jgap.*;
import org.jgap.impl.*;
import org.jgap.util.*;
/**
* Example for a multiobjective problem. Here, we have a function F with one
* input parameter t and two output values F1 and F2, with F1 = t�
* and F2 = (t - 2)�. The input value is restricted from -10 to 10.
* We are looking for a t where F1 and F2 get minimal.
* This example is from Goldberg (pp. 199), who adapted it from Schaffer (1984).
*
*
* @author Klaus Meffert
* @since 2.6
*/
public class MultiObjectiveExample {
/** String containing the CVS revision. Read out via reflection!*/
private final static String CVS_REVISION = "$Revision: 1.8 $";
/**
* The total number of times we'll let the population evolve.
*/
private static final int MAX_ALLOWED_EVOLUTIONS = 20;
/**
* Executes the genetic algorithm.
*
* @throws Exception
*
* @author Klaus Meffert
* @since 2.6
*/
public void execute()
throws Exception {
// Start with a DefaultConfiguration, which comes setup with the
// most common settings.
// -------------------------------------------------------------
Configuration conf = new DefaultConfiguration();
// Add BestChromosomesSelector with doublettes allowed.
// ----------------------------------------------------
conf.removeNaturalSelectors(true);
BestChromosomesSelector bestChromsSelector = new BestChromosomesSelector(
conf, 0.95d);
bestChromsSelector.setDoubletteChromosomesAllowed(true);
conf.addNaturalSelector(bestChromsSelector, true);
conf.reset();
conf.setFitnessEvaluator(new MOFitnessEvaluator());
conf.setPreservFittestIndividual(false);
conf.setKeepPopulationSizeConstant(false);
// Set the fitness function we want to use, which is our
// MultiObjectiveFitnessFunction. We construct it with
// the target amount of change passed in to this method.
// -----------------------------------------------------
BulkFitnessFunction myFunc =
new MultiObjectiveFitnessFunction();
conf.setBulkFitnessFunction(myFunc);
// Set sample chromosome.
// ----------------------
Gene[] sampleGenes = new Gene[1];
sampleGenes[0] = new DoubleGene(conf, MultiObjectiveFitnessFunction.MIN_X,
MultiObjectiveFitnessFunction.MAX_X);
IChromosome sampleChromosome = new Chromosome(conf, sampleGenes);
conf.setSampleChromosome(sampleChromosome);
// Finally, we need to tell the Configuration object how many
// Chromosomes we want in our population. The more Chromosomes,
// the larger number of potential solutions (which is good for
// finding the answer), but the longer it will take to evolve
// the population (which could be seen as bad).
// ------------------------------------------------------------
conf.setPopulationSize(500);
// Create random initial population of Chromosomes.
// ------------------------------------------------
Genotype population = Genotype.randomInitialGenotype(conf);
// Evolve the population. Since we don't know what the best answer
// is going to be, we just evolve the max number of times.
// ---------------------------------------------------------------
for (int i = 0; i < MAX_ALLOWED_EVOLUTIONS; i++) {
population.evolve();
}
// Now we have at least one solution.
// ----------------------------------
List chroms = population.getPopulation().getChromosomes();
MOFitnessComparator comp = new MOFitnessComparator();
// Remove all duplicate solutions.
// -------------------------------
Collections.sort(chroms, comp);
int index = 0;
while (index < chroms.size() - 1) {
// First solution to compare.
Chromosome aSolution1 = (Chromosome) chroms.get(index);
Vector<Double> v1 = MultiObjectiveFitnessFunction.getVector(aSolution1);
Double d1 = v1.get(0);
// Second solution to compare.
Chromosome aSolution2 = (Chromosome) chroms.get(index + 1);
Vector<Double> v2 = MultiObjectiveFitnessFunction.getVector(aSolution2);
Double d2 = v2.get(0);
if (Math.abs(d1 - d2) < 0.000001) {
// Duplicate solution found
chroms.remove(index);
}
else {
index++;
}
}
// Print all Pareto-optimal solutions.
// -----------------------------------
System.out.println("Formula F1(x) = x�");
System.out.println("Formula F2(x) = (x-2)�");
System.out.println("\nFound pareto-optimal solutions:");
System.out.println("===============================\n");
System.out.println("Input value x F1(x) F2(x)"
+ " Difference from optimum");
System.out.println("============= ===== ====="
+ " =======================");
for (int k = 0; k < chroms.size(); k++) {
Chromosome bestSolutionSoFar = (Chromosome) chroms.get(k);
String s = "";
Vector<Double>
v = MultiObjectiveFitnessFunction.getVector(bestSolutionSoFar);
for (int j = 0; j < 4; j++) {
Double d = v.get(j);
String t = NumberKit.niceDecimalNumber(d, 9);
t = StringKit.fill(t, 15, ' ');
s += t;
}
System.out.println(s);
}
}
/**
* Main method to run the example.
*
* @param args ignored
* @throws Exception
*
* @author Klaus Meffert
* @since 2.6
*/
public static void main(String[] args)
throws Exception {
MultiObjectiveExample instance = new MultiObjectiveExample();
instance.execute();
}
/**
* @author Klaus Meffert
* @since 2.6
*/
public class MOFitnessComparator
implements java.util.Comparator {
public int compare(final Object a_chrom1, final Object a_chrom2) {
List v1 = ( (Chromosome) a_chrom1).getMultiObjectives();
List v2 = ( (Chromosome) a_chrom2).getMultiObjectives();
int size = v1.size();
if (size != v2.size()) {
throw new RuntimeException("Size of objectives inconsistent!");
}
double d1Total = 0;
double d2Total = 0;
for (int i = 0; i < size; i++) {
double d1 = ( (Double) v1.get(i)).doubleValue();
double d2 = ( (Double) v2.get(i)).doubleValue();
d1Total += d1;
d2Total += d2;
}
if (d1Total < d2Total) {
return -1;
}
else {
if (d1Total > d2Total) {
return 1;
}
else {
return 0;
}
}
}
}
}