MOOCMAES added

This commit is contained in:
Michael de Paly
2010-03-26 15:13:05 +00:00
parent 075cbf09a7
commit 9848734f07
4 changed files with 738 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
package eva2.server.go.operators.archiving;
import java.util.Arrays;
import java.util.Collections;
import java.util.Vector;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.AbstractEAIndividualComparator;
import eva2.server.go.populations.Population;
public class ArchivingNSGAIISMeasure extends ArchivingNSGAII {
/** This method will cacluated the NSGAII crowding distance
* for all individuals
* @param fronts The pareto fronts
*/
public void calculateCrowdingDistance(Population[] fronts) {
//TODO Dimension der Zielfunktion checken
for (int rank = 0; rank < fronts.length; rank++)
{
calculateCrowdingDistance(fronts[rank]);
}
}
/** This mehtod will test if a given individual is dominant within
* a given population
* @param indy The individual that is to be tested.
* @param pop The population that the individual is to be tested against.
* @return True if the individual is dominating
*/
@Override
public boolean isDominant(AbstractEAIndividual indy, Population pop) {
if (this.m_ObeyDebsConstViolationPrinciple) {
for (int i = 0; i < pop.size(); i++) {
if (!(indy.equals(pop.get(i))||indy.equalFitness((AbstractEAIndividual) pop.get(i))) && (((AbstractEAIndividual)pop.get(i)).isDominatingDebConstraints(indy))) return false;
}
} else {
for (int i = 0; i < pop.size(); i++) {
if (!(indy.equals(pop.get(i))||indy.equalFitness((AbstractEAIndividual) pop.get(i))) && (((AbstractEAIndividual)pop.get(i)).isDominating(indy))) return false;
}
}
return true;
}
public void calculateCrowdingDistance(Population front) {
Object[] frontArray= front.toArray();
boolean[] assigned=new boolean[frontArray.length];
double[] v=new double[frontArray.length];
int i, left, right;
// initialization of assignment vector
for (i = 0; i < frontArray.length; i++)
{
assigned[ i ] = false;
}
Arrays.sort(frontArray,new AbstractEAIndividualComparator(0));
((AbstractEAIndividual)frontArray[0]).putData("HyperCube",Double.MAX_VALUE); //die beiden au<61>en bekommen maximal wert als smeasure
((AbstractEAIndividual)frontArray[frontArray.length-1]).putData("HyperCube",Double.MAX_VALUE);
v[0]=Double.MAX_VALUE;
v[frontArray.length-1]=Double.MAX_VALUE;
for (int e = 1; e < frontArray.length - 1; e++)
{ // loop over all non-border elements
for (i = 1; (assigned[ i ]); i++); // determine 1st not assigned, non-border element
for (left = 0; i < frontArray.length - 1;)
{ // loop over all not assigned elements
// determine right not assigned neighbor
for (right = i + 1; (assigned[ right]); right++);
v[i] = (((AbstractEAIndividual)frontArray[right]).getFitness(0) - ((AbstractEAIndividual)frontArray[i]).getFitness(0)) *
(((AbstractEAIndividual)frontArray[left]).getFitness(1) - ((AbstractEAIndividual)frontArray[i]).getFitness(1));
left = i;
i = right;
}
int minIndex = 0;
double min=v[minIndex];
for (int f = 1; f < frontArray.length - 1; f++)
{
if (!assigned[ f ])
if (v[f] < min)
{
min = v[f];
minIndex = f;
}
}
assigned[ minIndex ] = true;
((AbstractEAIndividual)frontArray[ minIndex]).putData("HyperCube",new Double(e));
}
}
}

View File

@@ -0,0 +1,195 @@
package eva2.server.go.operators.mutation;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceESIndividual;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.math.Jama.Matrix;
public class MutateESCovarianceMatrixAdaptionPlus extends MutateESCovarianceMatrixAdaption implements InterfaceMutationGenerational
{
protected double m_psuccess;
protected double m_cp;
protected double m_psuccesstarget=0.44;
protected double m_stepd;
protected double m_pthresh;
protected int m_lambda=1;
public MutateESCovarianceMatrixAdaptionPlus() {
super();
}
public MutateESCovarianceMatrixAdaptionPlus(MutateESCovarianceMatrixAdaptionPlus mutator) {
super(mutator);
m_psuccess=mutator.m_psuccess;
m_cp=mutator.m_cp;
m_psuccesstarget=mutator.m_psuccesstarget;
m_lambda=mutator.m_lambda;
m_pthresh=mutator.m_pthresh;
m_stepd=mutator.m_stepd;
}
/** This method will enable you to clone a given mutation operator
* @return The clone
*/
public Object clone() {
return new MutateESCovarianceMatrixAdaptionPlus(this);
}
/** This method allows you to init the mutation operator
* @param individual The individual that will be mutated.
* @param opt The optimization problem.
*/
public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) {
if (!(individual instanceof InterfaceESIndividual)) return;
super.init(individual,opt);
m_psuccesstarget=1.0/(5+Math.sqrt(m_lambda)/2);
m_psuccess=m_psuccesstarget;
m_stepd=1.0+m_D/(2.0*m_lambda);
m_cp=m_psuccesstarget*m_lambda/(2+m_psuccesstarget*m_lambda);
m_c=2.0/(2.0+m_D);
this.cov = 2.0/(6.0+Math.pow(m_D, 2)); //ATTN: differs from the standard CMA-ES
m_pthresh=0.44;
}
protected void adaptStrategyGen(AbstractEAIndividual child,AbstractEAIndividual parent) {
if(child.getFitness(0)<=parent.getFitness(0)){
//updatecov
updateCovariance(child, parent);
//updateCovariance();
}
}
/**
* @param parent
* @param child
*/
public void updateCovariance(AbstractEAIndividual child,AbstractEAIndividual parent) {
double[] step=new double[m_D];
for(int i=0;i<m_D;i++){
step[i]=((InterfaceESIndividual)parent).getDGenotype()[i]-((InterfaceESIndividual)child).getDGenotype()[i];
}
updateCovariance(step);
}
public void updateCovariance() {
double[] step=new double[m_D];
for(int i=0;i<m_D;i++){
step[i]=Bz[i];
}
updateCovariance(step);
}
/**
* @param step
*
*/
public void updateCovariance(double[] step) {
for(int i=0;i<m_D;i++){
if(m_psuccess<m_pthresh){
m_PathS[i]=(1.0-m_c)*m_PathS[i]+Math.sqrt(m_c*(2.0-m_c))*(step[i])/m_SigmaGlobal;
}else{
m_PathS[i]=(1.0-m_c)*m_PathS[i];
}
}
if(m_psuccess<m_pthresh){
m_C=m_C.multi((1.0-cov));
m_C.plusEquals(Matrix.outer(m_PathS, m_PathS).multi(cov));
}else{
m_C=m_C.multi((1.0-cov)).plus(
(Matrix.outer(m_PathS, m_PathS).plus(
m_C.multi(m_c*(2.0-m_c))
).multi(cov))
);
}
}
protected void adaptStrategy() {
}
public int getM_lambda() {
return m_lambda;
}
public void setM_lambda(int mLambda) {
m_lambda = mLambda;
}
@Override
public void crossoverOnStrategyParameters(AbstractEAIndividual indy1,
Population partners) {
// ATTN: Crossover is not defined for this
}
@Override
public void adaptAfterSelection(Population oldPop, Population selectedPop) {
// TODO Auto-generated method stub
}
@Override
public void adaptGenerational(Population selectedPop, Population parentPop, Population newPop, boolean updateSelected) {
double rate = 0.;
for (int i = 0; i < parentPop.size(); i++) {
// calculate success rate
// System.out.println("new fit / old fit: " + BeanInspector.toString(newPop.getEAIndividual(i).getFitness()) + " , " + BeanInspector.toString(parentPop.getEAIndividual(i).getFitness()));
if (newPop.getEAIndividual(i).getFitness(0) < parentPop.getEAIndividual(i).getFitness(0)) rate++;
}
rate = rate / parentPop.size();
if (updateSelected) for (int i = 0; i < selectedPop.size(); i++) { // applied to the old population as well in case of plus strategy
MutateESCovarianceMatrixAdaptionPlus mutator = (MutateESCovarianceMatrixAdaptionPlus)((AbstractEAIndividual)selectedPop.get(i)).getMutationOperator();
updateMutator(rate, mutator);
if(selectedPop.getEAIndividual(i).getFitness(0)<=parentPop.getEAIndividual(0).getFitness(0)){
mutator.adaptStrategyGen(selectedPop.getEAIndividual(i),parentPop.getEAIndividual(0));
}
// System.out.println("old pop step size " + mutator.getSigma()+ " (" + mutator+ ")");
}
for (int i = 0; i < newPop.size(); i++) {
MutateESCovarianceMatrixAdaptionPlus mutator = (MutateESCovarianceMatrixAdaptionPlus)((AbstractEAIndividual)newPop.get(i)).getMutationOperator();
updateMutator(rate, mutator);
if(newPop.getEAIndividual(i).getFitness(0)<=parentPop.getEAIndividual(0).getFitness(0)){
mutator.adaptStrategyGen(newPop.getEAIndividual(i),parentPop.getEAIndividual(0));
}
// System.out.println("new pop step size " + mutator.getSigma()+ " (" + mutator+ ")");
}
}
private void updateMutator(double rate, MutateESCovarianceMatrixAdaptionPlus mutator) {
mutator.updateStepSize(rate);
}
public double getM_psuccess() {
return m_psuccess;
}
public void updateStepSize(double psuccess) {
this.m_psuccess=(1-m_cp)*m_psuccess+m_cp*psuccess;
m_SigmaGlobal=m_SigmaGlobal*Math.exp(1/m_stepd*(m_psuccess-m_psuccesstarget)/(1-m_psuccesstarget));
}
public String getName() {
return "CMA mutation for plus Strategies";
}
/** This method returns a global info string
* @return description
*/
public static String globalInfo() {
return "This is the CMA mutation according to Igel,Hansen,Roth 2007";
}
@Override
public String getStringRepresentation() {
// TODO Auto-generated method stub
return "CMA-plus mutation";
}
}

View File

@@ -0,0 +1,134 @@
package eva2.server.go.operators.mutation;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceESIndividual;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.math.RNG;
/**
* Created by IntelliJ IDEA.
* User: streiche
* Date: 08.09.2004
* Time: 17:05:23
* To change this template use File | Settings | File Templates.
*/
public class MutateESPolynomial implements InterfaceMutation, java.io.Serializable {
private double m_Eta = 0.2;
public MutateESPolynomial() {
}
public MutateESPolynomial(MutateESPolynomial mutator) {
this.m_Eta = mutator.m_Eta;
}
public MutateESPolynomial(double eta) {
m_Eta = eta;
}
/** This method will enable you to clone a given mutation operator
* @return The clone
*/
public Object clone() {
return new MutateESPolynomial(this);
}
/** This method allows you to evaluate wether two mutation operators
* are actually the same.
* @param mutator The other mutation operator
*/
public boolean equals(Object mutator) {
if (mutator instanceof MutateESPolynomial) {
MutateESPolynomial mut = (MutateESPolynomial)mutator;
if (this.m_Eta != mut.m_Eta) return false;
return true;
} else return false;
}
/** This method allows you to init the mutation operator
* @param individual The individual that will be mutated.
* @param opt The optimization problem.
*/
public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) {
}
/** This method will mutate a given AbstractEAIndividual. If the individual
* doesn't implement InterfaceGAIndividual nothing happens.
* @param individual The individual that is to be mutated
*/
public void mutate(AbstractEAIndividual individual) {
//System.out.println("Before Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
if (individual instanceof InterfaceESIndividual) {
double[] x = ((InterfaceESIndividual)individual).getDGenotype();
double[][] range = ((InterfaceESIndividual)individual).getDoubleRange();
for (int i = 0; i < x.length; i++) {
double r = RNG.randomDouble();
double delta=0;
if(r < 0.5){
delta = Math.pow((2*r),(1/(m_Eta+1))) - 1;
}else{
delta = 1 - Math.pow((2*(1 - r)),(1/(m_Eta+1)));
}
x[i] += delta;
if (range[i][0] > x[i]) x[i] = range[i][0];
if (range[i][1] < x[i]) x[i] = range[i][1];
}
((InterfaceESIndividual)individual).SetDGenotype(x);
}
//System.out.println("After Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
}
/** This method allows you to perform either crossover on the strategy parameters
* or to deal in some other way with the crossover event.
* @param indy1 The original mother
* @param partners The original partners
*/
public void crossoverOnStrategyParameters(AbstractEAIndividual indy1, Population partners) {
// nothing to do here
}
/** This method allows you to get a string representation of the mutation
* operator
* @return A descriptive string.
*/
public String getStringRepresentation() {
return "ES fixed step size mutation";
}
/**********************************************************************************************************************
* These are for GUI
*/
/** This method allows the CommonJavaObjectEditorPanel to read the
* name to the current object.
* @return The name.
*/
public String getName() {
return "ES polynomial mutation";
}
/** This method returns a global info string
* @return description
*/
public String globalInfo() {
return "The polynomial mutation alters all elements according to a polynomial distribution";
}
/** This method allows you to set the number of crossovers that occur in the
* genotype.
* @param a The number of crossovers.
*/
public void setEta(double a) {
if (a < 0) a = 0;
this.m_Eta = a;
}
public double getEta() {
return this.m_Eta;
}
public String etaTipText() {
return "Set the Eta_c value (the larger the value, the more restricted the search).";
}
}

View File

@@ -0,0 +1,303 @@
package eva2.server.go.strategies;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceESIndividual;
import eva2.server.go.operators.archiving.AbstractArchiving;
import eva2.server.go.operators.archiving.ArchivingNSGAII;
import eva2.server.go.operators.archiving.ArchivingNSGAIISMeasure;
import eva2.server.go.operators.mutation.InterfaceMutationGenerational;
import eva2.server.go.operators.mutation.MutateESCovarianceMatrixAdaptionPlus;
import eva2.server.go.operators.selection.InterfaceSelection;
import eva2.server.go.operators.selection.SelectBestIndividuals;
import eva2.server.go.operators.selection.SelectMONSGAIICrowedTournament;
import eva2.server.go.operators.selection.SelectMONonDominated;
import eva2.server.go.populations.InterfaceSolutionSet;
import eva2.server.go.populations.Population;
import eva2.server.go.populations.SolutionSet;
import eva2.server.go.problems.AbstractOptimizationProblem;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.math.Mathematics;
import eva2.tools.math.RNG;
import eva2.tools.math.Jama.EigenvalueDecomposition;
import eva2.tools.math.Jama.Matrix;
public class MultiObjectiveCMAES implements InterfaceOptimizer, Serializable
{
class CounterClass{
public CounterClass(int i) {
value=i;
}
public int value;
public boolean seen=false;
}
private String m_Identifier = "NelderMeadSimplex";
private Population m_Population;
private AbstractOptimizationProblem m_Problem;
transient private InterfacePopulationChangedEventListener m_Listener;
private int m_lambda = 1;
private int m_lambdamo=1;
public MultiObjectiveCMAES() {
m_Population=new Population(m_lambdamo);
}
public MultiObjectiveCMAES(MultiObjectiveCMAES a) {
m_Problem = (AbstractOptimizationProblem)a.m_Problem.clone();
setPopulation((Population)a.m_Population.clone());
m_lambda = a.m_lambda;
m_Identifier = a.m_Identifier;
}
public MultiObjectiveCMAES clone() {
return new MultiObjectiveCMAES(this);
}
@Override
public void SetIdentifier(String name) {
m_Identifier=name;
}
@Override
public void SetProblem(InterfaceOptimizationProblem problem) {
m_Problem = (AbstractOptimizationProblem)problem;
}
/** This method allows you to add the LectureGUI as listener to the Optimizer
* @param ea
*/
public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) {
this.m_Listener = ea;
}
@Override
public void freeWilly() {
}
@Override
public InterfaceSolutionSet getAllSolutions() {
Population pop = getPopulation();
return new SolutionSet(pop, pop);
}
@Override
public String getIdentifier() {
return m_Identifier;
}
@Override
public String getName() {
return "(1+"+m_lambda+") MO-CMA-ES";
}
@Override
public Population getPopulation() {
return m_Population;
}
@Override
public InterfaceOptimizationProblem getProblem() {
return m_Problem;
}
@Override
public String getStringRepresentation() {
StringBuilder strB = new StringBuilder(200);
strB.append("(1+"+m_lambda+") MO-CMA-ES:\nOptimization Problem: ");
strB.append(this.m_Problem.getStringRepresentationForProblem(this));
strB.append("\n");
strB.append(this.m_Population.getStringRepresentation());
return strB.toString();
}
@Override
public void init() {
//initByPopulation(m_Population, true);
this.m_Population.setTargetSize(m_lambdamo);
this.m_Problem.initPopulation(this.m_Population);
// children = new Population(m_Population.size());
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent(Population.nextGenerationPerformed);
}
@Override
public void initByPopulation(Population pop, boolean reset) {
setPopulation(pop);
if (reset) {
m_Problem.initPopulation(m_Population);
m_Problem.evaluate(m_Population);
}
}
/** This method will evaluate the current population using the
* given problem.
* @param population The population that is to be evaluated
*/
private void evaluatePopulation(Population population) {
this.m_Problem.evaluate(population);
}
@Override
public void optimize() {
HashMap<Long, CounterClass> SuccessCounterMap=new HashMap<Long, CounterClass>();
//Eltern markieren und f<>r die Z<>hlung vorbereiten
for(int j=0;j<m_lambdamo&&j<m_Population.size();j++){
m_Population.getEAIndividual(j).putData("Parent",m_Population.getEAIndividual(j) );
SuccessCounterMap.put(m_Population.getEAIndividual(j).getIndyID(),new CounterClass(0));
}
//Kinder erzeugen
Population children=new Population(m_lambdamo*m_lambda);
children.setGenerationTo(m_Population.getGeneration());
for(int j=0;j<children.getTargetSize();j++){
AbstractEAIndividual parent=m_Population.getEAIndividual(j%m_lambdamo);
AbstractEAIndividual indy=(AbstractEAIndividual)parent.clone();
indy.mutate();
indy.putData("Parent", parent);
children.add(indy);
}
evaluatePopulation(children);
m_Population.addPopulation(children);
//Ranking
ArchivingNSGAII dummyArchive=new ArchivingNSGAIISMeasure();
Population []store=dummyArchive.getNonDomiatedSortedFronts(m_Population);
store=dummyArchive.getNonDomiatedSortedFronts(m_Population);
dummyArchive.calculateCrowdingDistance(store);
//Vergleichen und den Successcounter hochz<68>hlen wenn wir besser als unser Elter sind
for(int j=0;j<m_Population.size();j++){
AbstractEAIndividual parent= (AbstractEAIndividual) m_Population.getEAIndividual(j).getData("Parent");
if(m_Population.getEAIndividual(j)!=parent){ //Eltern nicht mit sich selber vergleichen
int parentParetoLevel=((Integer) parent.getData("ParetoLevel")).intValue();
double parentSMeasure=((Double) parent.getData("HyperCube")).doubleValue();
int childParetoLevel=((Integer) m_Population.getEAIndividual(j).getData("ParetoLevel")).intValue();
double childSMeasure=((Double) m_Population.getEAIndividual(j).getData("HyperCube")).doubleValue();
if( childParetoLevel<parentParetoLevel||((childParetoLevel==parentParetoLevel)&&childSMeasure>parentSMeasure ) ){
SuccessCounterMap.get(parent.getIndyID()).value++;
}
}else{ //Debug
SuccessCounterMap.get(parent.getIndyID()).seen=true;
}
}
//Selection
m_Population.clear();
for(int i=0;i<store.length;i++){
if(m_Population.size()+store[i].size()<=m_lambdamo){ //Die Front passt noch komplett
m_Population.addPopulation(store[i]);
}else{ //die besten aus der aktuellen Front heraussuchen bis voll
while(store[i].size()>0&&m_Population.size()<m_lambdamo){
AbstractEAIndividual indy=store[i].getEAIndividual(0);
double bestMeasure=((Double) indy.getData("HyperCube")).doubleValue(); //TODO mal noch effizient machen (sortieren und die besten n herausholen)
for(int j=1;j<store[i].size();j++ ){
if(bestMeasure<((Double) store[i].getEAIndividual(j).getData("HyperCube")).doubleValue()){
bestMeasure=((Double) store[i].getEAIndividual(j).getData("HyperCube")).doubleValue();
indy=store[i].getEAIndividual(j);
}
}
m_Population.add(indy);
store[i].removeMember(indy);
}
}
}
//Strategieparemeter updaten
for(int j=0;j<m_Population.size();j++){
AbstractEAIndividual indy=m_Population.getEAIndividual(j);
if(indy.getMutationOperator() instanceof MutateESCovarianceMatrixAdaptionPlus ){ //Das geht nur wenn wir auch die richtige Mutation haben
AbstractEAIndividual parent=(AbstractEAIndividual)indy.getData("Parent");
MutateESCovarianceMatrixAdaptionPlus muta=(MutateESCovarianceMatrixAdaptionPlus) indy.getMutationOperator();
double rate=((double) SuccessCounterMap.get(parent.getIndyID()).value)/((double) m_lambda);
if(indy!=parent){
muta.updateCovariance();
}
muta.updateStepSize(rate);
}
}
for(int j=0;j<children.size();j++){
children.getEAIndividual(j).putData("Parent", null);
}
m_Population.incrFunctionCallsBy(children.size());
m_Population.incrGeneration();
this.firePropertyChangedEvent(Population.nextGenerationPerformed);
}
@Override
public boolean removePopulationChangedEventListener(
InterfacePopulationChangedEventListener ea) {
return false;
}
@Override
public void setPopulation(Population pop) {
m_Population = pop;
m_Population.setNotifyEvalInterval(1);
m_lambdamo=m_Population.getTargetSize();
}
/** Something has changed
* @param name
*/
protected void firePropertyChangedEvent (String name) {
if (this.m_Listener != null) this.m_Listener.registerPopulationStateChanged(this, name);
}
public int getLambda() {
return m_lambda;
}
public void setLambda(int mLambda) {
m_lambda = mLambda;
}
/*public int getLambdaMo() {
return m_lambdamo;
}
public void setLambdaMo(int mLambda) {
m_lambdamo = mLambda;
}*/
}