All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.jenetics.ext.moea.UFTournamentSelector Maven / Gradle / Ivy

The newest version!
/*
 * Java Genetic Algorithm Library (jenetics-8.1.0).
 * Copyright (c) 2007-2024 Franz Wilhelmstötter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author:
 *    Franz Wilhelmstötter ([email protected])
 */
package io.jenetics.ext.moea;

import static java.lang.Math.min;
import static java.util.Objects.requireNonNull;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.ToIntFunction;

import io.jenetics.Gene;
import io.jenetics.Optimize;
import io.jenetics.Phenotype;
import io.jenetics.Selector;
import io.jenetics.internal.math.Subsets;
import io.jenetics.util.ISeq;
import io.jenetics.util.RandomRegistry;
import io.jenetics.util.Seq;

/**
 * Unique fitness based tournament selection.
 * 

* The selection of unique fitnesses lifts the selection bias towards * over-represented fitnesses by reducing multiple solutions sharing the same * fitness to a single point in the objective space. It is therefore no longer * required to assign a crowding distance of zero to individual of equal fitness * as the selection operator correctly enforces diversity preservation by * picking unique points in the objective space. *

* Reference: * Félix-Antoine Fortin and Marc Parizeau. 2013. Revisiting the NSGA-II * crowding-distance computation. In Proceedings of the 15th annual * conference on Genetic and evolutionary computation (GECCO '13), * Christian Blum (Ed.). ACM, New York, NY, USA, 623-630. * DOI= * 10.1145/2463372.2463456 * * * @author Franz Wilhelmstötter * @version 4.1 * @since 4.1 */ public class UFTournamentSelector< G extends Gene, C extends Comparable > implements Selector { private final Comparator> _dominance; private final ElementComparator> _comparator; private final ElementDistance> _distance; private final ToIntFunction> _dimension; /** * Creates a new {@code UFTournamentSelector} with the functions needed for * handling the multi-objective result type {@code C}. For the {@link Vec} * classes, a selector is created like in the following example: * {@snippet lang="java": * new UFTournamentSelector<>( * Vec::dominance, * Vec::compare, * Vec::distance, * Vec::length * ); * } * * @see #ofVec() * * @param dominance the pareto dominance comparator * @param comparator the vector element comparator * @param distance the vector element distance * @param dimension the dimensionality of vector type {@code C} */ public UFTournamentSelector( final Comparator dominance, final ElementComparator comparator, final ElementDistance distance, final ToIntFunction dimension ) { requireNonNull(dominance); requireNonNull(comparator); requireNonNull(distance); requireNonNull(dimension); _dominance = (a, b) -> dominance.compare(a.fitness(), b.fitness()); _comparator = comparator.map(Phenotype::fitness); _distance = distance.map(Phenotype::fitness); _dimension = v -> dimension.applyAsInt(v.fitness()); } @Override public ISeq> select( final Seq> population, final int count, final Optimize opt ) { final var random = RandomRegistry.random(); final CrowdedComparator> cc = new CrowdedComparator<>( population, opt, _dominance, _comparator, _distance, _dimension ); final List> S = new ArrayList<>(); while (S.size() < count) { final int k = min(2*count - S.size(), population.size()); final int[] G = Subsets.next(random, population.size(), k); for (int j = 0; j < G.length - 1 && S.size() < count; j += 2) { final int cmp = cc.compare(G[j], G[j + 1]); final int p; if (cmp > 0) { p = G[j]; } else if (cmp < 0) { p = G[j + 1]; } else { p = random.nextBoolean() ? G[j] : G[j + 1]; } final C fitness = population.get(p).fitness(); final List> list = population.stream() .filter(pt -> pt.fitness().equals(fitness)) .toList(); S.add(list.get(random.nextInt(list.size()))); } } return ISeq.of(S); } /** * Return a new selector for the given result type {@code V}. This method is * a shortcut for * {@snippet lang="java": * new UFTournamentSelector<>( * Vec::dominance, * Vec::compare, * Vec::distance, * Vec::length * ); * } * * @param the gene type * @param the array type, e.g. {@code double[]} * @param the multi object result type vector * @return a new selector for the given result type {@code V} */ public static , T, V extends Vec> UFTournamentSelector ofVec() { return new UFTournamentSelector<>( Vec::dominance, Vec::compare, Vec::distance, Vec::length ); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy