RouletteWheelSelector.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-4.3.0).
003  * Copyright (c) 2007-2018 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019  */
020 package io.jenetics;
021 
022 import static io.jenetics.internal.util.Hashes.hash;
023 import static io.jenetics.stat.DoubleSummary.min;
024 
025 import java.util.Arrays;
026 
027 import io.jenetics.internal.math.DoubleAdder;
028 import io.jenetics.util.Seq;
029 
030 /**
031  * The roulette-wheel selector is also known as fitness proportional selector,
032  * but in the <em>Jenetics</em> library it is implemented as probability selector.
033  * The fitness value <i>f<sub>i</sub></i>  is used to calculate the selection
034  * probability of individual <i>i</i>.
035  *
036  @see <a href="http://en.wikipedia.org/wiki/Roulette_wheel_selection">
037  *          Wikipedia: Roulette wheel selection
038  *      </a>
039  *
040  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
041  @since 1.0
042  @version 4.0
043  */
044 public class RouletteWheelSelector<
045     extends Gene<?, G>,
046     extends Number & Comparable<? super N>
047 >
048     extends ProbabilitySelector<G, N>
049 {
050 
051     public RouletteWheelSelector() {
052         this(false);
053     }
054 
055     protected RouletteWheelSelector(final boolean sorted) {
056         super(sorted);
057     }
058 
059     @Override
060     protected double[] probabilities(
061         final Seq<Phenotype<G, N>> population,
062         final int count
063     ) {
064         assert population != null "Population must not be null. ";
065         assert population.nonEmpty() "Population is empty.";
066         assert count > "Population to select must be greater than zero. ";
067 
068         // Copy the fitness values to probabilities arrays.
069         final double[] fitness = new double[population.size()];
070         for (int i = population.size(); --i >= 0;) {
071             fitness[i= population.get(i).getFitness().doubleValue();
072         }
073 
074         final double worst = Math.min(min(fitness)0.0);
075         final double sum = DoubleAdder.sum(fitness- worst*population.size();
076 
077         if (eq(sum, 0.0)) {
078             Arrays.fill(fitness, 1.0/population.size());
079         else {
080             for (int i = population.size(); --i >= 0;) {
081                 fitness[i(fitness[i- worst)/sum;
082             }
083         }
084 
085         return fitness;
086     }
087 
088     @Override
089     public int hashCode() {
090         return hash(getClass());
091     }
092 
093     @Override
094     public boolean equals(final Object obj) {
095         return obj == this || obj != null && getClass() == obj.getClass();
096     }
097 
098     @Override
099     public String toString() {
100         return getClass().getSimpleName();
101     }
102 
103 }