package twin;
/**
* This class implements a deterministic variant of the Genetic Algorithm described in the script, section 5.1.1.
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class PBILTwin {
/** 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 double 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;
/** mean fitness **/
private double meanFitness;
private double[] propVector;
private double learnrate;
/**
* 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 PBILTwin(int genotypeLength, int mu, double lambda,
int optimizationSteps, int multiRuns) {
assert multiRuns > 9; // use run configurations: vmargument: -ea
this.m_GenotypeLength = genotypeLength;
this.m_Lambda = lambda;
this.m_Mu = mu;
this.m_OptimizationSteps = optimizationSteps;
this.m_MultiRuns = multiRuns;
this.propVector = new double[m_GenotypeLength];
for (int i = 0; i < propVector.length; i++) {
propVector[i] = 0.5;
}
// this.learnrate = 1 / lambda;
this.learnrate = 0.05;
}
/**
* 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() {
for (int i = 0; i < m_OptimizationSteps; i++) {
List<PBilIndividualTwin> population = new ArrayList<PBilIndividualTwin>();
for (int j = 0; j < m_Mu; j++) {
population.add(new PBilIndividualTwin(propVector));
}
Collections.sort(population, Collections.reverseOrder()); // comparable
// implemente
// in
// PBilIndividual m_population =
// m_population.subList(0, m_Mu);
// for (int j = 0; j < population.size(); j++) {
// System.out.println(population.get(j).getStringRepresentation());
// }
List<PBilIndividualTwin> m_Best = population.subList(0, m_Mu);
System.out.println("Print best:");
System.out.println(m_Best.get(0).getStringRepresentation());
for (PBilIndividualTwin p : m_Best) {
for (int k = 0; k < m_GenotypeLength; k++) {
propVector[k] = (propVector[k] * (1 - learnrate))
+ ((p.getGenotype().get(k) ? 1 : 0) * learnrate);
}
}
System.out.println(Arrays.toString(propVector));
double fitnessPV = 0;
for (int j = 0; j < propVector.length; j++) {
double p=propVector[j];
if (j < propVector.length / 2) {
fitnessPV += p;
}
else{
fitnessPV-=p;
}
}
meanFitness = Math.abs(fitnessPV);
if (fitnessPV != propVector.length) {
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 = 50;
int mu = 15;
int lambda = 50;
int optimizationSteps = 1000;
// int optimizationSteps = 100;
int multiRuns = 1;
PBILTwin program = new PBILTwin(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.meanFitness;
}
TmpMeanCalls = TmpMeanCalls / program.m_MultiRuns;
TmpMeanFitness = TmpMeanFitness / program.m_MultiRuns;
System.out.println("(" + program.m_MultiRuns + "/"
+ program.m_OptimizationSteps + ") Mean Fitness : "
+ TmpMeanFitness + " Mean Calls needed: " + TmpMeanCalls);
}
}