/* Copyright 2009-2016 David Hadka
*
* This file is part of the MOEA Framework.
*
* The MOEA Framework is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* The MOEA Framework is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the MOEA Framework. If not, see <http://www.gnu.org/licenses/>.
*/
package org.moeaframework.algorithm;
import org.moeaframework.core.Initialization;
import org.moeaframework.core.NondominatedPopulation;
import org.moeaframework.core.PRNG;
import org.moeaframework.core.Population;
import org.moeaframework.core.Problem;
import org.moeaframework.core.Selection;
import org.moeaframework.core.Solution;
import org.moeaframework.core.Variation;
import org.moeaframework.core.comparator.ObjectiveComparator;
import org.moeaframework.core.operator.TournamentSelection;
/**
* Implementation of the Vector Evaluated Genetic Algorithm (VEGA). VEGA should
* be avoided in practice, since many modern algorithms outperform it and
* exhibit better convergence properties, but is included due to its historical
* significance. VEGA is considered the earliest MOEA. It supports M
* objectives during the selection phase by selecting M different subgroups,
* each selected based on the i-th objective value, for i=1,...,M.
* <p>
* There is one small algorithmic difference between this implementation and
* [1]. In [1], applying the genetic operators fills the entire population.
* However, since custom variation operators can be specified, it is possible
* that the population will not be filled completely. As a result, this
* implementation will continue selecting parents until the population is full.
* <p>
* References:
* <ol>
* <li>Schaffer, D. (1985). Multiple Objective Optimization with Vector
* Evaluated Genetic Algorithms. Proceedings of the 1st International
* Conference on Genetic Algorithms, pp. 93-100.
* </ol>
*/
public class VEGA extends AbstractEvolutionaryAlgorithm {
/**
* The selection operator.
*/
private Selection selection;
/**
* The variation operator.
*/
private Variation variation;
/**
* Constructs a new VEGA instance.
*
* @param problem the problem
* @param population the population
* @param archive the external archive; or {@code null} if no external
* archive is used
* @param initialization the initialization operator
* @param variation the variation operator
*/
public VEGA(Problem problem, Population population,
NondominatedPopulation archive, Initialization initialization,
Variation variation) {
super(problem, population, archive, initialization);
this.variation = variation;
selection = new VEGASelection();
}
@Override
protected void iterate() {
int populationSize = population.size();
// select the parents from the M different subgroups
Solution[] parents = selection.select(populationSize, population);
// shuffle the parents
PRNG.shuffle(parents);
// loop until the next generation is filled
int index = 0;
boolean filled = false;
population.clear();
while (!filled) {
Solution[] offspring = variation.evolve(
select(parents, index, variation.getArity()));
for (int i = 0; i < offspring.length; i++) {
population.add(offspring[i]);
if (population.size() >= populationSize) {
filled = true;
break;
}
}
index += variation.getArity() % populationSize;
}
// evaluate the offspring
evaluateAll(population);
}
/**
* Returns the subset of parents for the next variation operator.
*
* @param parents all parents
* @param index the starting index
* @param size the size of the subset
* @return the subset of parents
*/
private Solution[] select(Solution[] parents, int index, int size) {
Solution[] result = new Solution[size];
for (int i = 0; i < size; i++) {
result[i] = parents[(index+i) % parents.length];
}
return result;
}
/**
* VEGA selection operator that selects parents based on only one of the
* objectives.
*/
private class VEGASelection implements Selection {
private Selection[] selectors;
public VEGASelection() {
super();
selectors = new Selection[problem.getNumberOfObjectives()];
for (int i = 0; i < problem.getNumberOfObjectives(); i++) {
selectors[i] = new TournamentSelection(
new ObjectiveComparator(i));
}
}
@Override
public Solution[] select(int arity, Population population) {
Solution[] result = new Solution[arity];
for (int i = 0; i < arity; i++) {
Selection selector = selectors[i % problem.getNumberOfObjectives()];
result[i] = selector.select(1, population)[0];
}
return result;
}
}
}