From 8fd131f0497cd87f658a880b07ceb21a672d3be6 Mon Sep 17 00:00:00 2001 From: "Bernhard J. Berger" <bernhard.berger@uni-bremen.de> Date: Thu, 19 Jan 2023 00:05:35 +0100 Subject: [PATCH] Added a repair strategy for kill at birth that uses training data. --- .../strategies/RepairStrategy.java | 16 ++++ .../JeneticsConstraintProducer.java | 21 ++++- .../JeneticsConstraintStrategy.java | 1 + .../constraint/RandomGenotypeStrategy.java | 12 +++ .../strategies/constraint/RepairStrategy.java | 8 -- .../src/main/java/module-info.java | 1 + .../main/ea/TrainingRepairStrategy.java | 82 +++++++++++++++++++ 7 files changed, 129 insertions(+), 12 deletions(-) create mode 100644 src/core/de.evoal.core/src/main/java/de/evoal/core/api/ea/constraints/strategies/RepairStrategy.java delete mode 100644 src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/RepairStrategy.java create mode 100644 src/core/de.evoal.surrogate.api/src/main/java/de/evoal/surrogate/main/ea/TrainingRepairStrategy.java diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/api/ea/constraints/strategies/RepairStrategy.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/ea/constraints/strategies/RepairStrategy.java new file mode 100644 index 00000000..f9b54934 --- /dev/null +++ b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/ea/constraints/strategies/RepairStrategy.java @@ -0,0 +1,16 @@ +package de.evoal.core.api.ea.constraints.strategies; + +import de.evoal.languages.model.instance.Instance; +import io.jenetics.Gene; +import io.jenetics.Phenotype; + +/** + * Repair strategy used by kill-at-birth. + * @param <G> + * @param <C> + */ +public interface RepairStrategy<G extends Gene<?, G>, C extends Comparable<? super C>> { + public Phenotype<G,C> apply(Phenotype<G,C> individual, long generation); + + RepairStrategy init(final Instance configuration); +} diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/JeneticsConstraintProducer.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/JeneticsConstraintProducer.java index 28ab5ec4..cacd3c56 100644 --- a/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/JeneticsConstraintProducer.java +++ b/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/JeneticsConstraintProducer.java @@ -1,14 +1,17 @@ package de.evoal.core.main.ea.constraints.constraint.strategies.constraint; import de.evoal.core.api.cdi.BeanFactory; +import de.evoal.core.api.ea.constraints.calculation.CalculationStrategy; import de.evoal.core.api.ea.constraints.model.Constraint; import de.evoal.core.api.ea.constraints.model.Constraints; import de.evoal.core.api.ea.constraints.calculation.CalculationFactory; import de.evoal.core.api.board.BlackboardEntry; import de.evoal.core.api.cdi.ConfigurationValue; import de.evoal.core.api.ea.codec.CustomCodec; +import de.evoal.core.api.ea.constraints.strategies.RepairStrategy; import de.evoal.core.api.ea.fitness.FitnessFunction; import de.evoal.core.api.properties.PropertiesSpecification; +import de.evoal.core.api.utils.LanguageHelper; import de.evoal.core.main.ea.constraints.constraint.utils.ConfigurationUtils; import de.evoal.languages.model.instance.*; import org.apache.deltaspike.core.api.provider.BeanProvider; @@ -18,6 +21,7 @@ import javax.enterprise.inject.Produces; import javax.inject.Named; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; @ApplicationScoped @@ -33,14 +37,23 @@ public class JeneticsConstraintProducer { // collect group information to handle final List<Instance> groups = ConfigurationUtils.findConstraintHandlerByHandlingStrategy(handlerConfigurations, "kill-at-birth"); - final Set<String> allGroups = groups.stream().map(i -> (String)((LiteralValue)i.findAttribute("category").getValue()).getLiteral().getValue()).collect(Collectors.toSet()); + final Map<String, Instance> configurationMap = groups.stream().collect(Collectors.toMap(i -> (String)((LiteralValue)i.findAttribute("category").getValue()).getLiteral().getValue(), Function.identity())); final List<Constraint> listOfConstraints = constraints.getConstraints(); + return listOfConstraints .stream() - .filter(c -> allGroups.contains(c.getGroup())) - .map(factory::create) - .map(s -> new JeneticsConstraintStrategy(s, codec, function, optimizationSpec, new RandomGenotypeStrategy())) + .filter(c -> configurationMap.keySet().contains(c.getGroup())) + .map(s -> { + final Instance handlerConfiguration = configurationMap.get(s.getGroup()); + final Instance repairConfiguration = LanguageHelper.lookup(handlerConfiguration, "constraint-handling.repair-strategy"); + + final CalculationStrategy cStrategy = factory.create(s); + final RepairStrategy rStrategy = BeanFactory.create(repairConfiguration.getName().getName(), RepairStrategy.class) + .init(repairConfiguration); + + return new JeneticsConstraintStrategy(cStrategy, codec, function, optimizationSpec, rStrategy); + }) .collect(Collectors.toList()); } } diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/JeneticsConstraintStrategy.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/JeneticsConstraintStrategy.java index 85388f55..30672a6d 100644 --- a/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/JeneticsConstraintStrategy.java +++ b/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/JeneticsConstraintStrategy.java @@ -3,6 +3,7 @@ package de.evoal.core.main.ea.constraints.constraint.strategies.constraint; import de.evoal.core.api.ea.constraints.calculation.CalculationStrategy; import de.evoal.core.api.ea.constraints.strategies.HandlingStrategy; import de.evoal.core.api.ea.codec.CustomCodec; +import de.evoal.core.api.ea.constraints.strategies.RepairStrategy; import de.evoal.core.api.ea.fitness.FitnessFunction; import de.evoal.core.api.properties.Properties; import de.evoal.core.api.properties.PropertiesSpecification; diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/RandomGenotypeStrategy.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/RandomGenotypeStrategy.java index 2ea8f5f8..ea28d1f9 100644 --- a/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/RandomGenotypeStrategy.java +++ b/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/RandomGenotypeStrategy.java @@ -1,9 +1,16 @@ package de.evoal.core.main.ea.constraints.constraint.strategies.constraint; +import de.evoal.core.api.ea.constraints.strategies.RepairStrategy; +import de.evoal.languages.model.instance.Instance; import io.jenetics.Gene; import io.jenetics.Genotype; import io.jenetics.Phenotype; +import javax.enterprise.context.Dependent; +import javax.inject.Named; + +@Dependent +@Named("repair-with-random") public class RandomGenotypeStrategy<G extends Gene<?, G>, C extends Comparable<? super C>> implements RepairStrategy<G, C> { @Override public Phenotype apply(final Phenotype<G, C> individual, long generation) { @@ -11,4 +18,9 @@ public class RandomGenotypeStrategy<G extends Gene<?, G>, C extends Comparable<? return Phenotype.of(newInstance, generation); } + + @Override + public RepairStrategy init(Instance configuration) { + return null; + } } diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/RepairStrategy.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/RepairStrategy.java deleted file mode 100644 index 425036cc..00000000 --- a/src/core/de.evoal.core/src/main/java/de/evoal/core/main/ea/constraints/constraint/strategies/constraint/RepairStrategy.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.evoal.core.main.ea.constraints.constraint.strategies.constraint; - -import io.jenetics.Gene; -import io.jenetics.Phenotype; - -public interface RepairStrategy<G extends Gene<?, G>, C extends Comparable<? super C>> { - public Phenotype<G,C> apply(Phenotype<G,C> individual, long generation); -} diff --git a/src/core/de.evoal.core/src/main/java/module-info.java b/src/core/de.evoal.core/src/main/java/module-info.java index 511c8a70..43401de0 100644 --- a/src/core/de.evoal.core/src/main/java/module-info.java +++ b/src/core/de.evoal.core/src/main/java/module-info.java @@ -94,4 +94,5 @@ module de.evoal.core { opens de.evoal.core.api.ea.correlations to weld.core.impl; opens de.evoal.core.api.ea.constraints.calculation to weld.core.impl; opens de.evoal.core.api.properties.info to weld.core.impl; + opens de.evoal.core.api.ea.constraints.strategies to weld.core.impl; } diff --git a/src/core/de.evoal.surrogate.api/src/main/java/de/evoal/surrogate/main/ea/TrainingRepairStrategy.java b/src/core/de.evoal.surrogate.api/src/main/java/de/evoal/surrogate/main/ea/TrainingRepairStrategy.java new file mode 100644 index 00000000..33a89c13 --- /dev/null +++ b/src/core/de.evoal.surrogate.api/src/main/java/de/evoal/surrogate/main/ea/TrainingRepairStrategy.java @@ -0,0 +1,82 @@ +package de.evoal.surrogate.main.ea; + +import de.evoal.core.api.board.Blackboard; +import de.evoal.core.api.ea.codec.CustomCodec; +import de.evoal.core.api.ea.constraints.strategies.RepairStrategy; +import de.evoal.core.api.properties.Properties; +import de.evoal.core.api.properties.PropertiesSpecification; +import de.evoal.core.api.properties.stream.FileBasedPropertiesStreamSupplier; +import de.evoal.core.api.properties.stream.PropertiesStreamSupplier; +import de.evoal.languages.model.instance.Instance; +import de.evoal.surrogate.api.SurrogateBlackboardEntry; +import io.jenetics.Gene; +import io.jenetics.Genotype; +import io.jenetics.Phenotype; +import io.jenetics.util.ISeq; +import io.jenetics.util.RandomRegistry; +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.Dependent; +import javax.inject.Inject; +import javax.inject.Named; +import java.io.File; +import java.util.List; +import java.util.stream.Collectors; + +@Dependent +@Named("repair-with-training") +@Slf4j +public class TrainingRepairStrategy<G extends Gene<?, G>, C extends Comparable<? super C>> implements RepairStrategy<G, C> { + @Inject + private Blackboard board; + + @Inject + private CustomCodec codec; + + @Inject + @Named("genotype-specification") + private PropertiesSpecification sourceSpecification; + + @Inject + @Named("surrogate-target-properties-specification") + private PropertiesSpecification targetSpecification; + + private List<Properties> trainingData; + + @Override + public RepairStrategy init(final Instance configuration) { + final String filename = board.get(SurrogateBlackboardEntry.SURROGATE_TRAINING_DATA_FILE); + final File trainingFile = new File(filename); + + log.info("Using training data from {} for population.", filename); + + final PropertiesSpecification totalSpecification = + PropertiesSpecification.builder() + .add(sourceSpecification) + .add(targetSpecification) + .build(); + + final PropertiesStreamSupplier stream = new FileBasedPropertiesStreamSupplier(trainingFile, totalSpecification); + + trainingData = stream + .apply(totalSpecification) + .map(p -> new Properties(sourceSpecification).putAll(p)) + .unordered() + .collect(Collectors.toList()); + + return this; + } + + + @Override + public Phenotype apply(final Phenotype<G, C> individual, long generation) { + int index = RandomRegistry.random() + .nextInt(0, trainingData.size()); + + + final Genotype<G> newInstance = codec.encode(trainingData.get(index)); + + return Phenotype.of(newInstance, generation); + } +} -- GitLab