1 package net.bmahe.genetics4j.core.chromosomes.factory;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.List;
6 import java.util.Objects;
7 import java.util.function.Function;
8 import java.util.random.RandomGenerator;
9
10 import org.apache.logging.log4j.LogManager;
11 import org.apache.logging.log4j.Logger;
12 import org.immutables.value.Value;
13
14 import net.bmahe.genetics4j.core.chromosomes.Chromosome;
15 import net.bmahe.genetics4j.core.spec.chromosome.ChromosomeSpec;
16
17 @Value.Immutable
18 public abstract class ChromosomeFactoryProvider {
19 public static final Logger logger = LogManager.getLogger(ChromosomeFactoryProvider.class);
20
21 public abstract RandomGenerator randomGenerator();
22
23 @Value.Default
24 public List<ChromosomeFactory<? extends Chromosome>> defaultChromosomeFactories() {
25 final var randomGenerator = randomGenerator();
26
27 return Arrays.asList(
28 new BitChromosomeFactory(randomGenerator),
29 new IntChromosomeFactory(randomGenerator),
30 new DoubleChromosomeFactory(randomGenerator),
31 new FloatChromosomeFactory(randomGenerator));
32 }
33
34 public abstract List<Function<ChromosomeFactoryProvider, ChromosomeFactory<? extends Chromosome>>> chromosomeFactoriesGenerator();
35
36 @Value.Derived
37 public List<ChromosomeFactory<? extends Chromosome>> chromosomeFactories() {
38
39 final List<ChromosomeFactory<? extends Chromosome>> chromosomeFactories = new ArrayList<>();
40
41 final List<ChromosomeFactory<? extends Chromosome>> defaultChromosomeFactories = defaultChromosomeFactories();
42 if (defaultChromosomeFactories.isEmpty() == false) {
43 chromosomeFactories.addAll(defaultChromosomeFactories);
44 }
45
46 chromosomeFactoriesGenerator().stream()
47 .map(generator -> generator.apply(this))
48 .forEach(cf -> chromosomeFactories.add(cf));
49
50 return chromosomeFactories;
51 }
52
53 public ChromosomeFactory<? extends Chromosome> provideChromosomeFactory(final ChromosomeSpec chromosomeSpec) {
54 Objects.requireNonNull(chromosomeSpec);
55
56 final List<ChromosomeFactory<? extends Chromosome>> chromosomeFactories = chromosomeFactories();
57
58 logger.trace("Known chromosome factories: {}", chromosomeFactories);
59
60 return chromosomeFactories.stream()
61 .dropWhile(chromosomeFactory -> chromosomeFactory.canHandle(chromosomeSpec) == false)
62 .findFirst()
63 .orElseThrow(
64 () -> new IllegalStateException(
65 "Could not find a chromosome factory for chromosome spec: " + chromosomeSpec));
66 }
67
68 public static ImmutableChromosomeFactoryProvider.Builder builder() {
69 return ImmutableChromosomeFactoryProvider.builder();
70 }
71 }