package strategies;
/**
* This class implements a deterministic variant of the Genetic Algorithm described in the script, section 5.1.1.
*/
import individuals.GAIndividual;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import tools.RandomNumberGenerator;
public class GeneticAlgorithm {
/** The length of the genotype of the individuals **/
private int m_GenotypeLength;
/** The number of individuals in the population **/
private int m_Mu;
/** The number of children generated **/
private int m_Lambda;
/** The number of single optimization steps to be evaluated **/
private int m_OptimizationSteps;
/** The number of times the experiment is repeated **/
private int m_MultiRuns;
/** Number of steps needed to reach best result **/
private int m_OptimizationStepsNeeded = 0;
/** Current best individual **/
private GAIndividual m_Best;
/**
* This constructor sets up GeneticAlgorithm
*
* @param genotypeLength
* The length of the genotype of the individuals
* @param mu
* The number of individuals in the population
* @param lambda
* The number of children generated in each iteration
* @param optimizationSteps
* The number of single optimization steps to be evaluated
* (adjust as necessary)
* @param multiRuns
* The number of times the experiment is repeated (at least 10)
*/
public GeneticAlgorithm(int genotypeLength, int mu, int lambda,
int optimizationSteps, int multiRuns) {
assert multiRuns > 9; // use run configurations: vmargument: -ea
this.m_GenotypeLength = genotypeLength;
this.m_Mu = mu;
this.m_Lambda = lambda;
this.m_OptimizationSteps = optimizationSteps;
this.m_MultiRuns = multiRuns;
this.m_Best = null;
}
/**
* This method will initialize the GeneticAlgorithm
*/
public void initialize() {
m_OptimizationStepsNeeded = 0;
}
/**
* This method will optimize the evaulateAsMaxiBits Problem. Use
* m_FitnessCallsNeeded to return the number of FitnessCalls (e.g., calling
* evaluateAsMaxiBits()) needed to find the optimum. The optimization should
* terminate after m_FitnessCalls.
*/
public void optimize() {
// The deterministic Genetic Algorithm works as follows:
// initialize the population
// while maxSteps not reached do
// do select 2 (distinct) parents from population randomly
// perform crossover to generate two children
// until lambda children generated
// mutate the children (p_m = 0.5, use randomBoolean from
// RandomNumberGenerator)
// calculate the fitness of the children (use
// GAIndividual.evaluateAsMaxiBits())
// select the mu best individuals for the new population
// od
List<GAIndividual> population = new ArrayList<GAIndividual>();
for (int i = 0; i < m_Mu; i++) {
population.add(new GAIndividual(m_GenotypeLength));
}
for (int i = 0; i < m_OptimizationSteps; i++) {
ArrayList<GAIndividual> children = new ArrayList<GAIndividual>();
for (int a = 0; a < (m_Lambda / 2); a++) {
GAIndividual parent1;
GAIndividual parent2;
do {
parent1 = population.get(RandomNumberGenerator.randomInt(0,
m_Mu - 1));
parent2 = population.get(RandomNumberGenerator.randomInt(0,
m_Mu - 1));
} while (parent1 == parent2);// distinct parents
children.addAll(Arrays.asList(GAIndividual.crossover(parent1,
parent2)));
}
for (GAIndividual child : children) {
if (RandomNumberGenerator.randomBoolean()) {
child.mutate();
}
}
Collections.sort(children); // comparable
// implemented
// in
// GAIndividual
// m_population = m_population.subList(0, m_Mu);
m_Best = children.get(0);
population = children.subList(0, m_Mu);
if (m_Best.evaluateAsMaxiBits() != 0) {
m_OptimizationStepsNeeded++;
}
}
}
/**
* This main method will start a simple GeneticAlgorithm search. No
* arguments necessary.
*
* @param args
*/
public static void main(String[] args) {
// TODO: parameters for the GeneticAlgorithm, adjust these values as
// necessary
int genotypeLength = 25;
int mu = 10;
int lambda = 50;
// int optimizationSteps = 100000;
int optimizationSteps = 100;
int multiRuns = 100;
GeneticAlgorithm program = new GeneticAlgorithm(genotypeLength, mu,
lambda, optimizationSteps, multiRuns);
int TmpMeanCalls = 0, TmpMeanFitness = 0;
// perform repeated optimization
for (int i = 0; i < program.m_MultiRuns; i++) {
program.initialize();
program.optimize();
TmpMeanCalls += program.m_OptimizationStepsNeeded;
TmpMeanFitness += program.m_Best.evaluateAsMaxiBits();
}
TmpMeanCalls = TmpMeanCalls / program.m_MultiRuns; // ja klar 3.9 =3
TmpMeanFitness = TmpMeanFitness / program.m_MultiRuns;
System.out.println("(" + program.m_MultiRuns + "/"
+ program.m_OptimizationSteps + ") Mean Fitness : "
+ TmpMeanFitness + " Mean Calls needed: " + TmpMeanCalls);
}
}