001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. 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 package org.apache.commons.math3.genetics; 018 019 import java.util.ArrayList; 020 import java.util.Collection; 021 import java.util.Collections; 022 import java.util.Iterator; 023 import java.util.List; 024 025 import org.apache.commons.math3.exception.util.LocalizedFormats; 026 import org.apache.commons.math3.exception.NotPositiveException; 027 import org.apache.commons.math3.exception.NullArgumentException; 028 import org.apache.commons.math3.exception.NumberIsTooLargeException; 029 import org.apache.commons.math3.exception.NumberIsTooSmallException; 030 031 /** 032 * Population of chromosomes represented by a {@link List}. 033 * 034 * @since 2.0 035 * @version $Id: ListPopulation.java 1422195 2012-12-15 06:45:18Z psteitz $ 036 */ 037 public abstract class ListPopulation implements Population { 038 039 /** List of chromosomes */ 040 private List<Chromosome> chromosomes; 041 042 /** maximal size of the population */ 043 private int populationLimit; 044 045 /** 046 * Creates a new ListPopulation instance and initializes its inner chromosome list. 047 * 048 * @param populationLimit maximal size of the population 049 * @throws NotPositiveException if the population limit is not a positive number (< 1) 050 */ 051 public ListPopulation(final int populationLimit) throws NotPositiveException { 052 this(Collections.<Chromosome> emptyList(), populationLimit); 053 } 054 055 /** 056 * Creates a new ListPopulation instance. 057 * <p> 058 * Note: the chromosomes of the specified list are added to the population. 059 * 060 * @param chromosomes list of chromosomes to be added to the population 061 * @param populationLimit maximal size of the population 062 * @throws NullArgumentException if the list of chromosomes is {@code null} 063 * @throws NotPositiveException if the population limit is not a positive number (< 1) 064 * @throws NumberIsTooLargeException if the list of chromosomes exceeds the population limit 065 */ 066 public ListPopulation(final List<Chromosome> chromosomes, final int populationLimit) 067 throws NullArgumentException, NotPositiveException, NumberIsTooLargeException { 068 069 if (chromosomes == null) { 070 throw new NullArgumentException(); 071 } 072 if (populationLimit <= 0) { 073 throw new NotPositiveException(LocalizedFormats.POPULATION_LIMIT_NOT_POSITIVE, populationLimit); 074 } 075 if (chromosomes.size() > populationLimit) { 076 throw new NumberIsTooLargeException(LocalizedFormats.LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE, 077 chromosomes.size(), populationLimit, false); 078 } 079 this.populationLimit = populationLimit; 080 this.chromosomes = new ArrayList<Chromosome>(populationLimit); 081 this.chromosomes.addAll(chromosomes); 082 } 083 084 /** 085 * Sets the list of chromosomes. 086 * <p> 087 * Note: this method removed all existing chromosomes in the population and adds all chromosomes 088 * of the specified list to the population. 089 * 090 * @param chromosomes the list of chromosomes 091 * @throws NullArgumentException if the list of chromosomes is {@code null} 092 * @throws NumberIsTooLargeException if the list of chromosomes exceeds the population limit 093 * @deprecated use {@link #addChromosomes(Collection)} instead 094 */ 095 @Deprecated 096 public void setChromosomes(final List<Chromosome> chromosomes) 097 throws NullArgumentException, NumberIsTooLargeException { 098 099 if (chromosomes == null) { 100 throw new NullArgumentException(); 101 } 102 if (chromosomes.size() > populationLimit) { 103 throw new NumberIsTooLargeException(LocalizedFormats.LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE, 104 chromosomes.size(), populationLimit, false); 105 } 106 this.chromosomes.clear(); 107 this.chromosomes.addAll(chromosomes); 108 } 109 110 /** 111 * Add a {@link Collection} of chromosomes to this {@link Population}. 112 * @param chromosomeColl a {@link Collection} of chromosomes 113 * @throws NumberIsTooLargeException if the population would exceed the population limit when 114 * adding this chromosome 115 * @since 3.1 116 */ 117 public void addChromosomes(final Collection<Chromosome> chromosomeColl) throws NumberIsTooLargeException { 118 if (chromosomes.size() + chromosomeColl.size() > populationLimit) { 119 throw new NumberIsTooLargeException(LocalizedFormats.LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE, 120 chromosomes.size(), populationLimit, false); 121 } 122 this.chromosomes.addAll(chromosomeColl); 123 } 124 125 /** 126 * Returns an unmodifiable list of the chromosomes in this population. 127 * @return the unmodifiable list of chromosomes 128 */ 129 public List<Chromosome> getChromosomes() { 130 return Collections.unmodifiableList(chromosomes); 131 } 132 133 /** 134 * Access the list of chromosomes. 135 * @return the list of chromosomes 136 * @since 3.1 137 */ 138 protected List<Chromosome> getChromosomeList() { 139 return chromosomes; 140 } 141 142 /** 143 * Add the given chromosome to the population. 144 * 145 * @param chromosome the chromosome to add. 146 * @throws NumberIsTooLargeException if the population would exceed the {@code populationLimit} after 147 * adding this chromosome 148 */ 149 public void addChromosome(final Chromosome chromosome) throws NumberIsTooLargeException { 150 if (chromosomes.size() >= populationLimit) { 151 throw new NumberIsTooLargeException(LocalizedFormats.LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE, 152 chromosomes.size(), populationLimit, false); 153 } 154 this.chromosomes.add(chromosome); 155 } 156 157 /** 158 * Access the fittest chromosome in this population. 159 * @return the fittest chromosome. 160 */ 161 public Chromosome getFittestChromosome() { 162 // best so far 163 Chromosome bestChromosome = this.chromosomes.get(0); 164 for (Chromosome chromosome : this.chromosomes) { 165 if (chromosome.compareTo(bestChromosome) > 0) { 166 // better chromosome found 167 bestChromosome = chromosome; 168 } 169 } 170 return bestChromosome; 171 } 172 173 /** 174 * Access the maximum population size. 175 * @return the maximum population size. 176 */ 177 public int getPopulationLimit() { 178 return this.populationLimit; 179 } 180 181 /** 182 * Sets the maximal population size. 183 * @param populationLimit maximal population size. 184 * @throws NotPositiveException if the population limit is not a positive number (< 1) 185 * @throws NumberIsTooSmallException if the new population size is smaller than the current number 186 * of chromosomes in the population 187 */ 188 public void setPopulationLimit(final int populationLimit) throws NotPositiveException, NumberIsTooSmallException { 189 if (populationLimit <= 0) { 190 throw new NotPositiveException(LocalizedFormats.POPULATION_LIMIT_NOT_POSITIVE, populationLimit); 191 } 192 if (populationLimit < chromosomes.size()) { 193 throw new NumberIsTooSmallException(populationLimit, chromosomes.size(), true); 194 } 195 this.populationLimit = populationLimit; 196 } 197 198 /** 199 * Access the current population size. 200 * @return the current population size. 201 */ 202 public int getPopulationSize() { 203 return this.chromosomes.size(); 204 } 205 206 /** 207 * {@inheritDoc} 208 */ 209 @Override 210 public String toString() { 211 return this.chromosomes.toString(); 212 } 213 214 /** 215 * Returns an iterator over the unmodifiable list of chromosomes. 216 * <p>Any call to {@link Iterator#remove()} will result in a {@link UnsupportedOperationException}.</p> 217 * 218 * @return chromosome iterator 219 */ 220 public Iterator<Chromosome> iterator() { 221 return getChromosomes().iterator(); 222 } 223 }