ListPopulation.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.math4.legacy.genetics;

  18. import java.util.ArrayList;
  19. import java.util.Collection;
  20. import java.util.Collections;
  21. import java.util.Iterator;
  22. import java.util.List;

  23. import org.apache.commons.math4.legacy.exception.NotPositiveException;
  24. import org.apache.commons.math4.legacy.exception.NullArgumentException;
  25. import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException;
  26. import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
  27. import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;

  28. /**
  29.  * Population of chromosomes represented by a {@link List}.
  30.  *
  31.  * @since 2.0
  32.  */
  33. public abstract class ListPopulation implements Population {

  34.     /** List of chromosomes. */
  35.     private final List<Chromosome> chromosomes;

  36.     /** maximal size of the population. */
  37.     private int populationLimit;

  38.     /**
  39.      * Creates a new ListPopulation instance and initializes its inner chromosome list.
  40.      *
  41.      * @param populationLimit maximal size of the population
  42.      * @throws NotPositiveException if the population limit is not a positive number (&lt; 1)
  43.      */
  44.     public ListPopulation(final int populationLimit) throws NotPositiveException {
  45.         this(Collections.<Chromosome>emptyList(), populationLimit);
  46.     }

  47.     /**
  48.      * Creates a new ListPopulation instance.
  49.      * <p>
  50.      * Note: the chromosomes of the specified list are added to the population.
  51.      *
  52.      * @param chromosomes list of chromosomes to be added to the population
  53.      * @param populationLimit maximal size of the population
  54.      * @throws NullArgumentException if the list of chromosomes is {@code null}
  55.      * @throws NotPositiveException if the population limit is not a positive number (&lt; 1)
  56.      * @throws NumberIsTooLargeException if the list of chromosomes exceeds the population limit
  57.      */
  58.     public ListPopulation(final List<Chromosome> chromosomes, final int populationLimit)
  59.         throws NullArgumentException, NotPositiveException, NumberIsTooLargeException {

  60.         if (chromosomes == null) {
  61.             throw new NullArgumentException();
  62.         }
  63.         if (populationLimit <= 0) {
  64.             throw new NotPositiveException(LocalizedFormats.POPULATION_LIMIT_NOT_POSITIVE, populationLimit);
  65.         }
  66.         if (chromosomes.size() > populationLimit) {
  67.             throw new NumberIsTooLargeException(LocalizedFormats.LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE,
  68.                                                 chromosomes.size(), populationLimit, false);
  69.         }
  70.         this.populationLimit = populationLimit;
  71.         this.chromosomes = new ArrayList<>(populationLimit);
  72.         this.chromosomes.addAll(chromosomes);
  73.     }

  74.     /**
  75.      * Add a {@link Collection} of chromosomes to this {@link Population}.
  76.      * @param chromosomeColl a {@link Collection} of chromosomes
  77.      * @throws NumberIsTooLargeException if the population would exceed the population limit when
  78.      * adding this chromosome
  79.      * @since 3.1
  80.      */
  81.     public void addChromosomes(final Collection<Chromosome> chromosomeColl) throws NumberIsTooLargeException {
  82.         if (chromosomes.size() + chromosomeColl.size() > populationLimit) {
  83.             throw new NumberIsTooLargeException(LocalizedFormats.LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE,
  84.                                                 chromosomes.size(), populationLimit, false);
  85.         }
  86.         this.chromosomes.addAll(chromosomeColl);
  87.     }

  88.     /**
  89.      * Returns an unmodifiable list of the chromosomes in this population.
  90.      * @return the unmodifiable list of chromosomes
  91.      */
  92.     public List<Chromosome> getChromosomes() {
  93.         return Collections.unmodifiableList(chromosomes);
  94.     }

  95.     /**
  96.      * Access the list of chromosomes.
  97.      * @return the list of chromosomes
  98.      * @since 3.1
  99.      */
  100.     protected List<Chromosome> getChromosomeList() {
  101.         return chromosomes;
  102.     }

  103.     /**
  104.      * Add the given chromosome to the population.
  105.      *
  106.      * @param chromosome the chromosome to add.
  107.      * @throws NumberIsTooLargeException if the population would exceed the {@code populationLimit} after
  108.      *   adding this chromosome
  109.      */
  110.     @Override
  111.     public void addChromosome(final Chromosome chromosome) throws NumberIsTooLargeException {
  112.         if (chromosomes.size() >= populationLimit) {
  113.             throw new NumberIsTooLargeException(LocalizedFormats.LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE,
  114.                                                 chromosomes.size(), populationLimit, false);
  115.         }
  116.         this.chromosomes.add(chromosome);
  117.     }

  118.     /**
  119.      * Access the fittest chromosome in this population.
  120.      * @return the fittest chromosome.
  121.      */
  122.     @Override
  123.     public Chromosome getFittestChromosome() {
  124.         // best so far
  125.         Chromosome bestChromosome = this.chromosomes.get(0);
  126.         for (Chromosome chromosome : this.chromosomes) {
  127.             if (chromosome.compareTo(bestChromosome) > 0) {
  128.                 // better chromosome found
  129.                 bestChromosome = chromosome;
  130.             }
  131.         }
  132.         return bestChromosome;
  133.     }

  134.     /**
  135.      * Access the maximum population size.
  136.      * @return the maximum population size.
  137.      */
  138.     @Override
  139.     public int getPopulationLimit() {
  140.         return this.populationLimit;
  141.     }

  142.     /**
  143.      * Sets the maximal population size.
  144.      * @param populationLimit maximal population size.
  145.      * @throws NotPositiveException if the population limit is not a positive number (&lt; 1)
  146.      * @throws NumberIsTooSmallException if the new population size is smaller than the current number
  147.      *   of chromosomes in the population
  148.      */
  149.     public void setPopulationLimit(final int populationLimit) throws NotPositiveException, NumberIsTooSmallException {
  150.         if (populationLimit <= 0) {
  151.             throw new NotPositiveException(LocalizedFormats.POPULATION_LIMIT_NOT_POSITIVE, populationLimit);
  152.         }
  153.         if (populationLimit < chromosomes.size()) {
  154.             throw new NumberIsTooSmallException(populationLimit, chromosomes.size(), true);
  155.         }
  156.         this.populationLimit = populationLimit;
  157.     }

  158.     /**
  159.      * Access the current population size.
  160.      * @return the current population size.
  161.      */
  162.     @Override
  163.     public int getPopulationSize() {
  164.         return this.chromosomes.size();
  165.     }

  166.     /**
  167.      * {@inheritDoc}
  168.      */
  169.     @Override
  170.     public String toString() {
  171.         return this.chromosomes.toString();
  172.     }

  173.     /**
  174.      * Returns an iterator over the unmodifiable list of chromosomes.
  175.      * <p>Any call to {@link Iterator#remove()} will result in a {@link UnsupportedOperationException}.</p>
  176.      *
  177.      * @return chromosome iterator
  178.      */
  179.     @Override
  180.     public Iterator<Chromosome> iterator() {
  181.         return getChromosomes().iterator();
  182.     }
  183. }