Skip to content

Commit

Permalink
Merge 4c52546 into 6f469a4
Browse files Browse the repository at this point in the history
  • Loading branch information
FedorSmirnov89 committed Mar 21, 2018
2 parents 6f469a4 + 4c52546 commit 499dc3c
Show file tree
Hide file tree
Showing 25 changed files with 1,819 additions and 104 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id 'com.github.kt3k.coveralls' version '2.6.3'

}
apply plugin: 'base'
apply plugin: 'application'
Expand Down
3 changes: 3 additions & 0 deletions opt4j-optimizers/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
dependencies {
compile project(':opt4j-core')
compile project(':opt4j-operators')

testCompile group: 'junit', name: 'junit', version: '[4.0,)'
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.9.5'
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/


package org.opt4j.optimizers.ea;

Expand Down Expand Up @@ -47,19 +46,19 @@ public class EvolutionaryAlgorithmModule extends OptimizerModule {
protected int generations = 1000;

@Constant(value = "alpha", namespace = EvolutionaryAlgorithm.class)
@Info("The size of the population.")
@Info("The size of the population α.")
@Order(1)
protected int alpha = 100;
protected int populationSize = 100;

@Constant(value = "mu", namespace = EvolutionaryAlgorithm.class)
@Info("The number of parents per generation.")
@Info("The number of parents per generation μ.")
@Order(2)
protected int mu = 25;
protected int parentsPerGeneration = 25;

@Constant(value = "lambda", namespace = EvolutionaryAlgorithm.class)
@Info("The number of offspring per generation.")
@Info("The number of offsprings per generation λ.")
@Order(3)
protected int lambda = 25;
protected int offspringsPerGeneration = 25;

@Info("Performs a crossover operation with this given rate.")
@Order(4)
Expand All @@ -86,28 +85,25 @@ public enum CrossoverRateType {
/**
* Returns the population size {@code alpha}.
*
* @see #setAlpha
* @return the population size
*/
public int getAlpha() {
return alpha;
public int getPopulationSize() {
return populationSize;
}

/**
* Sets the population size {@code alpha}.
*
* @see #getAlpha
* @param alpha
* the population size to set
*/
public void setAlpha(int alpha) {
this.alpha = alpha;
public void setPopulationSize(int alpha) {
this.populationSize = alpha;
}

/**
* Returns the number of generations.
*
* @see #setGenerations
* @return the number of generations
*/
public int getGenerations() {
Expand All @@ -128,49 +124,44 @@ public void setGenerations(int generations) {
/**
* Returns the number of children {@code lambda}.
*
* @see #setLambda
* @return the number of children
*/
public int getLambda() {
return lambda;
public int getOffspringsPerGeneration() {
return offspringsPerGeneration;
}

/**
* Sets the number of children {@code lambda}.
*
* @see #getLambda
* @param lambda
* the number of children
*/
public void setLambda(int lambda) {
this.lambda = lambda;
public void setOffspringsPerGeneration(int lambda) {
this.offspringsPerGeneration = lambda;
}

/**
* Returns the number of parents {@code mu}.
*
* @see #setMu
* @return the number of parents
*/
public int getMu() {
return mu;
public int getParentsPerGeneration() {
return parentsPerGeneration;
}

/**
* Sets the number of parents {@code mu}.
*
* @see #getMu
* @param mu
* the number of parents
*/
public void setMu(int mu) {
this.mu = mu;
public void setParentsPerGeneration(int mu) {
this.parentsPerGeneration = mu;
}

/**
* Returns the type of crossover rate that is used.
*
* @see #setCrossoverRateType
* @return the crossoverRateType
*/
public CrossoverRateType getCrossoverRateType() {
Expand All @@ -180,7 +171,6 @@ public CrossoverRateType getCrossoverRateType() {
/**
* Sets the type of crossover rate to use.
*
* @see #getCrossoverRateType
* @param crossoverRateType
* the crossoverRateType to set
*/
Expand All @@ -191,7 +181,6 @@ public void setCrossoverRateType(CrossoverRateType crossoverRateType) {
/**
* Returns the used crossover rate.
*
* @see #setCrossoverRate
* @return the crossoverRate
*/
public double getCrossoverRate() {
Expand All @@ -201,7 +190,6 @@ public double getCrossoverRate() {
/**
* Sets the crossover rate.
*
* @see #getCrossoverRate
* @param crossoverRate
* the crossoverRate to set
*/
Expand All @@ -216,9 +204,7 @@ public void setCrossoverRate(double crossoverRate) {
*/
@Override
public void config() {

bindIterativeOptimizer(EvolutionaryAlgorithm.class);

bind(CrossoverRate.class).to(ConstantCrossoverRate.class).in(SINGLETON);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package org.opt4j.optimizers.ea;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.opt4j.core.Individual;
import org.opt4j.core.Objective;
import org.opt4j.core.Objectives;

/**
* The NonDominatedFronts sorts each evaluated individual into fronts based on
* the number of other individuals it is dominated by. The first front consists
* of points that are not dominated at all and so on.
*
* @author Fedor Smirnov
*
*/
public class NonDominatedFronts extends ArrayList<List<Individual>> {

private static final long serialVersionUID = -7008617060878292974L;

public NonDominatedFronts(Collection<Individual> individuals) {
generateFronts(individuals);
}

/**
* sort the given individuals into non-dominated fronts
*
* @param individuals
*/
public void generateFronts(Collection<Individual> individuals) {
// assign an id to each individual that corresponds to its index in an
// array
List<Individual> individualList = new ArrayList<Individual>(individuals);
Map<Individual, Integer> indexMap = new HashMap<Individual, Integer>();
for (int i = 0; i < individualList.size(); i++) {
indexMap.put(individualList.get(i), i);
}
// Initialize a map where an individual is assigned to the individuals
// that it dominates
Map<Individual, List<Individual>> dominatedIndividualsMap = new HashMap<Individual, List<Individual>>();
// n is an array where for each individual, the number of individuals
// that dominate it is stored
int[] dominatingIndividualNumber = new int[individualList.size()];
for (Individual e : individualList) {
dominatedIndividualsMap.put(e, new ArrayList<Individual>());
dominatingIndividualNumber[indexMap.get(e)] = 0;
}
determineDomination(individualList, dominatedIndividualsMap, dominatingIndividualNumber, indexMap);
// The first front consists of individuals that are dominated by zero
// other individuals
List<Individual> f1 = new ArrayList<Individual>();
for (Individual i : individualList) {
if (dominatingIndividualNumber[indexMap.get(i)] == 0) {
f1.add(i);
}
}
add(f1);
List<Individual> currentFront = f1;
// Create the subsequent fronts. Front f_i is made up by individuals
// that
// are not dominated if all individuals from fronts f_j with j < i are
// removed.
while (!currentFront.isEmpty()) {
List<Individual> nextFront = getNextFront(currentFront, dominatedIndividualsMap, dominatingIndividualNumber,
indexMap);
if (!nextFront.isEmpty())
add(nextFront);
currentFront = nextFront;
}
}

/**
* Find the next non-dominated front by processing the current non-dominated
* front. The individuals found therein are removed from consideration. The
* individuals that are then not dominated form the next non-dominated front.
*
* @param currentFront
* the list of individuals forming the current non-dominated front
* @param dominatedIndividualsMap
* map mapping an individual on the collection of individuals that
* it dominates
* @param dominatingIndividualNumber
* an array where the number of dominating individuals is stored
* for each individual
* @param individual2IndexMap
* a map storing the indices of the individuals used to access the
* dominatingIndividualNumber
* @return the list of individuals forming the next non-dominated front
*/
protected List<Individual> getNextFront(List<Individual> currentFront,
Map<Individual, List<Individual>> dominatedIndividualsMap, int[] dominatingIndividualNumber,
Map<Individual, Integer> individual2IndexMap) {
List<Individual> nextFront = new ArrayList<Individual>();
for (Individual dominant : currentFront) {
for (Individual dominated : dominatedIndividualsMap.get(dominant)) {
dominatingIndividualNumber[individual2IndexMap.get(dominated)]--;
if (dominatingIndividualNumber[individual2IndexMap.get(dominated)] == 0) {
nextFront.add(dominated);
}
}
}
return nextFront;
}

/**
* Compare all possible individual pairs. For each individual, store 1) the
* number of individuals it is dominated by and 2) the set of individuals it
* dominates.
*
* @param individualList
* a list of the individuals
* @param dominatedIndividualsMap
* A map that is filled during the execution of the method. Each
* individual is mapped onto the set of individuals that are
* dominated by this individual.
* @param dominatingIndividualNumber
* An integer array (initialized with zeros) that is filled during
* the execution of this method. Each individual is associated with
* an entry of this array. The integer therein is the number of
* individuals this individual is dominated by.
* @param individual2IndexMap
* a map mapping each individual onto its index in the
* dominatingIndividualNumber - array
*/
protected void determineDomination(List<Individual> individualList,
Map<Individual, List<Individual>> dominatedIndividualsMap, int[] dominatingIndividualNumber,
Map<Individual, Integer> individual2IndexMap) {
// compare each individual with each other individual
for (int i = 0; i < individualList.size(); i++) {
for (int j = i + 1; j < individualList.size(); j++) {
Individual p = individualList.get(i);
Individual q = individualList.get(j);
Objectives po = p.getObjectives();
Objectives qo = q.getObjectives();
if (po.dominates(qo)) {
dominatedIndividualsMap.get(p).add(q);
dominatingIndividualNumber[individual2IndexMap.get(q)]++;
} else if (qo.dominates(po)) {
dominatedIndividualsMap.get(q).add(p);
dominatingIndividualNumber[individual2IndexMap.get(p)]++;
}
}
}
}

/**
* returns the individuals with the best values for the individual objectives
*
* @return the set of the extreme individuals
*/
public Set<Individual> getExtremeIndividuals() {
Map<Objective, Individual> bestIndis = new HashMap<Objective, Individual>();
Map<Objective, Double> extremeValues = new HashMap<Objective, Double>();
List<Individual> firstFront = get(0);
Individual firstIndi = firstFront.iterator().next();
List<Objective> objList = new ArrayList<Objective>(firstIndi.getObjectives().getKeys());
// iterate the individuals
for (Individual indi : firstFront) {
// iterate the objectives and their values
double[] values = indi.getObjectives().array();
for (int i = 0; i < objList.size(); i++) {
Objective obj = objList.get(i);
double value = values[i];
if (!bestIndis.containsKey(obj) || extremeValues.get(obj) > value) {
bestIndis.put(obj, indi);
extremeValues.put(obj, value);
}
}
}
return new HashSet<Individual>(bestIndis.values());
}
}

0 comments on commit 499dc3c

Please sign in to comment.