Population.java
package net.bmahe.genetics4j.core;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.Validate;
public class Population<T extends Comparable<T>> implements Iterable<Individual<T>> {
private List<Genotype> genotypes;
private List<T> fitnesses;
public Population() {
this.genotypes = new ArrayList<>();
this.fitnesses = new ArrayList<>();
}
public Population(final List<Genotype> _genotype, final List<T> _fitnesses) {
Validate.notNull(_genotype);
Validate.notNull(_fitnesses);
Validate.isTrue(_genotype.size() == _fitnesses.size(),
"Size of genotype (%d) does not match size of fitnesses (%d)",
_genotype.size(),
_fitnesses.size());
this.genotypes = new ArrayList<Genotype>(_genotype);
this.fitnesses = new ArrayList<>(_fitnesses);
}
public void add(final Genotype genotype, final T fitness) {
Validate.notNull(genotype);
Validate.notNull(fitness);
genotypes.add(genotype);
fitnesses.add(fitness);
}
public void add(final Individual<T> individual) {
Validate.notNull(individual);
genotypes.add(individual.genotype());
fitnesses.add(individual.fitness());
}
public void addAll(final Population<T> population) {
Validate.notNull(population);
this.genotypes.addAll(population.getAllGenotypes());
this.fitnesses.addAll(population.getAllFitnesses());
}
@Override
public Iterator<Individual<T>> iterator() {
return new PopulationIterator<>(this);
}
public Genotype getGenotype(final int index) {
Validate.inclusiveBetween(0, genotypes.size() - 1, index);
return genotypes.get(index);
}
public T getFitness(final int index) {
Validate.inclusiveBetween(0, fitnesses.size() - 1, index);
return fitnesses.get(index);
}
public Individual<T> getIndividual(final int index) {
return Individual.of(getGenotype(index), getFitness(index));
}
public List<Genotype> getAllGenotypes() {
return genotypes;
}
public List<T> getAllFitnesses() {
return fitnesses;
}
public int size() {
return genotypes.size();
}
public boolean isEmpty() {
return size() == 0;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((fitnesses == null) ? 0 : fitnesses.hashCode());
result = prime * result + ((genotypes == null) ? 0 : genotypes.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("rawtypes")
Population other = (Population) obj;
if (fitnesses == null) {
if (other.fitnesses != null)
return false;
} else if (!fitnesses.equals(other.fitnesses))
return false;
if (genotypes == null) {
if (other.genotypes != null)
return false;
} else if (!genotypes.equals(other.genotypes))
return false;
return true;
}
@Override
public String toString() {
return "Population [genotypes=" + genotypes + ", fitnesses=" + fitnesses + "]";
}
public static <U extends Comparable<U>> Population<U> of(final List<Genotype> _genotype, final List<U> _fitnesses) {
return new Population<U>(_genotype, _fitnesses);
}
public static <U extends Comparable<U>> Population<U> of(final List<Individual<U>> individuals) {
Validate.notNull(individuals);
final List<Genotype> genotypes = individuals.stream()
.map(Individual::genotype)
.toList();
final List<U> fitnesses = individuals.stream()
.map(Individual::fitness)
.toList();
return new Population<U>(genotypes, fitnesses);
}
public static <U extends Comparable<U>> Population<U> empty() {
return new Population<U>(List.of(), List.of());
}
}