1 package net.bmahe.genetics4j.core;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6 import java.util.Objects;
7
8 import org.apache.commons.lang3.Validate;
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 public class Population<T extends Comparable<T>> implements Iterable<Individual<T>> {
24
25 private List<Genotype> genotypes;
26 private List<T> fitnesses;
27
28
29
30
31 public Population() {
32 this.genotypes = new ArrayList<>();
33 this.fitnesses = new ArrayList<>();
34 }
35
36
37
38
39
40
41
42
43 public Population(final List<Genotype> _genotype, final List<T> _fitnesses) {
44 Objects.requireNonNull(_genotype);
45 Objects.requireNonNull(_fitnesses);
46 Validate.isTrue(
47 _genotype.size() == _fitnesses.size(),
48 "Size of genotype (%d) does not match size of fitnesses (%d)",
49 _genotype.size(),
50 _fitnesses.size());
51
52 this.genotypes = new ArrayList<>(_genotype);
53 this.fitnesses = new ArrayList<>(_fitnesses);
54 }
55
56
57
58
59
60
61
62
63 public void add(final Genotype genotype, final T fitness) {
64 Objects.requireNonNull(genotype);
65 Objects.requireNonNull(fitness);
66
67 genotypes.add(genotype);
68 fitnesses.add(fitness);
69 }
70
71
72
73
74
75
76
77 public void add(final Individual<T> individual) {
78 Objects.requireNonNull(individual);
79
80 genotypes.add(individual.genotype());
81 fitnesses.add(individual.fitness());
82 }
83
84
85
86
87
88
89
90 public void addAll(final Population<T> population) {
91 Objects.requireNonNull(population);
92
93 this.genotypes.addAll(population.getAllGenotypes());
94 this.fitnesses.addAll(population.getAllFitnesses());
95 }
96
97 @Override
98 public Iterator<Individual<T>> iterator() {
99 return new PopulationIterator<>(this);
100 }
101
102
103
104
105
106
107
108
109 public Genotype getGenotype(final int index) {
110 Validate.inclusiveBetween(0, genotypes.size() - 1, index);
111
112 return genotypes.get(index);
113 }
114
115
116
117
118
119
120
121
122 public T getFitness(final int index) {
123 Validate.inclusiveBetween(0, fitnesses.size() - 1, index);
124
125 return fitnesses.get(index);
126 }
127
128
129
130
131
132
133
134
135 public Individual<T> getIndividual(final int index) {
136 return Individual.of(getGenotype(index), getFitness(index));
137 }
138
139
140
141
142
143
144 public List<Genotype> getAllGenotypes() {
145 return genotypes;
146 }
147
148
149
150
151
152
153 public List<T> getAllFitnesses() {
154 return fitnesses;
155 }
156
157
158
159
160
161
162 public int size() {
163 return genotypes.size();
164 }
165
166
167
168
169
170
171 public boolean isEmpty() {
172 return size() == 0;
173 }
174
175 @Override
176 public int hashCode() {
177 final int prime = 31;
178 int result = 1;
179 result = prime * result + (fitnesses == null ? 0 : fitnesses.hashCode());
180 return prime * result + (genotypes == null ? 0 : genotypes.hashCode());
181 }
182
183 @Override
184 public boolean equals(Object obj) {
185 if (this == obj) {
186 return true;
187 }
188 if (obj == null) {
189 return false;
190 }
191 if (getClass() != obj.getClass()) {
192 return false;
193 }
194
195 @SuppressWarnings("rawtypes")
196 Population other = (Population) obj;
197 if (fitnesses == null) {
198 if (other.fitnesses != null) {
199 return false;
200 }
201 } else if (!fitnesses.equals(other.fitnesses)) {
202 return false;
203 }
204 if (genotypes == null) {
205 if (other.genotypes != null) {
206 return false;
207 }
208 } else if (!genotypes.equals(other.genotypes)) {
209 return false;
210 }
211 return true;
212 }
213
214 @Override
215 public String toString() {
216 return "Population [genotypes=" + genotypes + ", fitnesses=" + fitnesses + "]";
217 }
218
219
220
221
222
223
224
225
226
227
228 public static <U extends Comparable<U>> Population<U> of(final List<Genotype> _genotype, final List<U> _fitnesses) {
229 return new Population<>(_genotype, _fitnesses);
230 }
231
232
233
234
235
236
237
238
239
240 public static <U extends Comparable<U>> Population<U> of(final List<Individual<U>> individuals) {
241 Objects.requireNonNull(individuals);
242
243 final List<Genotype> genotypes = individuals.stream().map(Individual::genotype).toList();
244
245 final List<U> fitnesses = individuals.stream().map(Individual::fitness).toList();
246
247 return new Population<>(genotypes, fitnesses);
248 }
249
250
251
252
253
254
255
256 public static <U extends Comparable<U>> Population<U> empty() {
257 return new Population<U>(List.of(), List.of());
258 }
259
260 }