Commit 7dddb9e0 authored by Christian Reuschling's avatar Christian Reuschling
Browse files

version to 1.1 | added eliteVectorMetadata for fitness functions |

some more config possibilities  |  fitness function call data over stdIn
parent 339d058b
Pipeline #15124 passed with stages
in 46 seconds
......@@ -54,6 +54,9 @@ constantRandomSeed=true
# proportionate, helps to avoid early dominance of one/two fit candidates. Amplifies minor fitness differences in more mature populations)
selectionStrategy=SigmaScaling
# The probability a vector value will mutate to another random value from its value range when a vector is created from its parents
mutationProbability=0.01
# The size of the first population. After the first population, the evolution goes further with the specified population size. This is to start wide
# spreaded and to evolve the best candidates more focused afterwards. Can be relevant if you have huge fitness calculation runtimes where every
# calculation counts.
......@@ -123,10 +126,18 @@ firstGenerationParentMetadata=
initialMetadataAtt_2=initVal_2
}
# The fitness function call for a candidate vector recieves the metadata of the top N candidate vectors from its parent population for information.
# This can e.g. be used for population based training. Here you can specify the count for the top N list. This value has NO influence to the genetic
# optimization, it is just about metadata for the fitness function
eliteMetadataCount=3
# For using GenIe standalone, you can specify an exec call for the fitness function. This executable will be called for each candidate vector
# evaluation, receiving the candidate vector values as invocation arguments. The last invocation argument will be the parents metadata as Json string.
# GenIe will wait for the process to terminate, looking for a calculation result in its output. This calculation result must follow this example Json
# structure, and should be somewhere at the end of the processes output:
# evaluation, receiving the candidate vector values as invocation arguments (just strings from the configured value range), or over stdIn if enabled.
# The forelast invocation argument will be the parents metadata (json), the last argument the metadata from the top N candidate vectors of the parent
# population, also as Json string, simply as returned from the parents fitness function invocation.
# GenIe will wait for the process to terminate, looking for a calculation result in its output (stdOut). This calculation result have to be like
# the following example Json structure, and should be somewhere at the end of the processes output. GenIe have a look the tail of the output only for
# performance purposes. Configure the tail length with consideredTailLength.
# {
# "fitness":0.0,
# "metadata":{
......@@ -135,6 +146,24 @@ firstGenerationParentMetadata=
# }
# }
fitnessFunctionExecPath=sum23TestFitnessFunction.sh
consideredTailLength=10000
# It true, all input to the fitness function process will be given over standard input as json instead of process arguments. The format given to stdIn is as follows
# {
# "candidateVectorParamNames":[“paramName1”, “paramName2”, “paramName3”,..],
# "candidateVector":[“value1”, “value2”, “value3”,..],
# "parentsMetadata":[
# {"someMetadataKeyParent1_1":"someMetadataValue", "someMetadataKeyParent1_N":"someMetadataValue"},
# {"someMetadataKeyParent2_1":"someMetadataValue", "someMetadataKeyParent2_N":"someMetadataValue"},
# ],
# "eliteMetadata":[
# {"someMetadataKeyElite1_1":"someMetadataValue", "someMetadataKeyElite1_N":"someMetadataValue"},
# {"someMetadataKeyElite2_1":"someMetadataValue", "someMetadataKeyElite2_N":"someMetadataValue"},
# ...
# ]
# }
inputOverStdIn=false
# The tail of the fitness function output should be logged
logExecOutputTail=true
......
......@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.dfki.sds</groupId>
<artifactId>genIe</artifactId>
<version>1.0</version>
<version>1.1</version>
<packaging>jar</packaging>
<name>genIe</name>
<url>http://leechcrawler.github.com/leech/</url>
......
......@@ -2,70 +2,39 @@ package de.dfki.sds.genie;
import javax.print.*;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.JobSheets;
import javax.print.attribute.standard.MediaSizeName;
import java.io.IOException;
import de.dfki.inquisitor.streams.StreamUtilz;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
public class FeldWaldWiese
{
public static void main(String[] args)
{
DocFlavor[] docFlavorsAccepted =
{DocFlavor.INPUT_STREAM.JPEG, DocFlavor.INPUT_STREAM.JPEG, DocFlavor.INPUT_STREAM.PNG, DocFlavor.INPUT_STREAM.GIF, DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST,
DocFlavor.INPUT_STREAM.TEXT_HTML_HOST, DocFlavor.INPUT_STREAM.TEXT_HTML_HOST, DocFlavor.INPUT_STREAM.POSTSCRIPT,//7
DocFlavor.INPUT_STREAM.PDF};
int iFlavour = 7;
StreamPrintServiceFactory[] prservFactories =
StreamPrintServiceFactory.lookupStreamPrintServiceFactories(null, null);
if (null == prservFactories || 0 >= prservFactories.length)
{
System.err.println("sErrNoPrintService");
System.exit(2);
}
DocFlavor flavor = docFlavorsAccepted[iFlavour];
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(MediaSizeName.ISO_A4);
StreamPrintService streamPrintService = prservFactories[0].getPrintService(new OutputStream()
{
@Override
public void write(int b) throws IOException
public static void main(String[] args) throws Exception
{
LinkedList<String> lCommand = new LinkedList<>();
lCommand.add("/home/reuschling/muell/test.sh");
lCommand.add("bla");
}
});
JobSheets jobSheets = (JobSheets) streamPrintService.getDefaultAttributeValue(JobSheets.class);
System.out.println(jobSheets);
ProcessBuilder builder = new ProcessBuilder(lCommand);
Process process = builder.start();
// TODO anstatt alles über Aufrufargumente mitzugeben, die Daten in stdIn schieben
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(process.getOutputStream());
outputStreamWriter.write("'mein gepipter input mit\nleerzeichen'");
outputStreamWriter.close();
PrintService[] pservices = PrintServiceLookup.lookupPrintServices(flavor, aset);
if (pservices.length > 0)
{
PrintService service = pservices[0];
DocPrintJob pj = service.createPrintJob();
int returnCode = process.waitFor();
if (returnCode != 0)
throw new Exception(String.format("Fitness function exec call returned not '0' but '%s'", returnCode));
boolean mNoJobSheet = false;
JobSheets js = (JobSheets) (service.getDefaultAttributeValue(JobSheets.class));
if (js != null && js.equals(JobSheets.NONE))
{
mNoJobSheet = true;
}
System.out.println(mNoJobSheet);
}
int iTailLength = 10000;
String strOutputTail = StreamUtilz.getStreamTail(process.getInputStream(), iTailLength);
System.out.println(strOutputTail + "'");
}
}
......@@ -11,12 +11,14 @@ import de.dfki.inquisitor.streams.StreamUtilz;
import de.dfki.sds.genie.genetic.CandidateVectorWithMetadata;
import de.dfki.sds.genie.genetic.GeneticParamOptimizer;
import de.dfki.sds.genie.genetic.GeneticRunConfig;
import lombok.Data;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;
import java.io.File;
import java.io.OutputStreamWriter;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.LinkedHashMap;
......@@ -34,16 +36,20 @@ public class GenIe extends GeneticParamOptimizer
public static void main(String[] args)
@Accessors(chain = true, prefix = {"m_d", "m_f", "m_str", "m_l", "m_hs", "m_s", "m_", "d", "f", "str", "l", "hs", "s", ""})
@Data
public static class FitnessFunctionStdInInput
{
List<String> candidateVectorParamNames;
List<String> candidateVector;
List<HashMap<String, String>> parentsMetadata;
List<HashMap<String, String>> eliteMetadata;
}
// TODO Joachim Projekt
// TODO Andreas fragen wg openSource, vorstellen in der Gruppe
// TODO Christoph zeigen, weitere Schritte
// TODO In meiner neuen HomePage referenzieren
public static void main(String[] args)
{
GenIe geneticOptimizer = new GenIe();
......@@ -65,10 +71,6 @@ public class GenIe extends GeneticParamOptimizer
@CommandLine.Option(names = {"-c", "--configFile"}, description = "The file path to the genIe configuration that should be used")
protected String m_strConfigPath = "geneticOptimization.conf";
@Setter
......@@ -100,7 +102,7 @@ public class GenIe extends GeneticParamOptimizer
return m_fitnessCalculator.calculateFitness(candidate, population);
// we invoke the configred exec call as default
// we invoke the configured exec call as default
LinkedList<String> lCommand = new LinkedList<>();
......@@ -108,22 +110,42 @@ public class GenIe extends GeneticParamOptimizer
strCommandPath = Path.of(strCommandPath).toAbsolutePath().toString();
lCommand.add(strCommandPath);
if (!m_geneticRunConfig.m_geneticConfig.getUniqueAsBoolean("inputOverStdIn"))
{
lCommand.addAll(candidate.getCandidateVector());
String strJson = JsonWriter.objectToJson(candidate.getParentMetadata(), CollectionUtilz.createHashMap(JsonWriter.TYPE, false, JsonWriter.PRETTY_PRINT, true));
lCommand.add(strJson);
// parents
String strJson4ParentMetadata =
JsonWriter.objectToJson(candidate.getParentMetadata(), CollectionUtilz.createHashMap(JsonWriter.TYPE, false, JsonWriter.PRETTY_PRINT, true));
lCommand.add(strJson4ParentMetadata);
// elite
String strJson4TopNMetadata =
JsonWriter.objectToJson(candidate.getTopNParentGenerationMetadata(), CollectionUtilz.createHashMap(JsonWriter.TYPE, false, JsonWriter.PRETTY_PRINT, true));
lCommand.add(strJson4TopNMetadata);
}
ProcessBuilder builder = new ProcessBuilder(lCommand);
Process process = builder.start();
String strOutputTail = StreamUtilz.getStreamTail(process.getInputStream(), 10000);
if (m_geneticRunConfig.m_geneticConfig.getUniqueAsBoolean("inputOverStdIn"))
{
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(process.getOutputStream());
FitnessFunctionStdInInput stdInInput =
new FitnessFunctionStdInInput().setCandidateVectorParamNames(candidate.getCandidateVectorParamNames()).setCandidateVector(candidate.getCandidateVector())
.setParentsMetadata(candidate.getParentMetadata()).setEliteMetadata(candidate.getTopNParentGenerationMetadata());
String strJson4StdInInput = JsonWriter.objectToJson(stdInInput, CollectionUtilz.createHashMap(JsonWriter.TYPE, false, JsonWriter.PRETTY_PRINT, true));
outputStreamWriter.write(strJson4StdInInput);
outputStreamWriter.close();
}
int returnCode = process.waitFor();
if (returnCode != 0)
throw new Exception(String.format("Fitness function exec call returned not '0' but '%s'", returnCode));
int iTailLength = m_geneticRunConfig.m_geneticConfig.getUniqueAsInteger("consideredTailLength");
String strOutputTail = StreamUtilz.getStreamTail(process.getInputStream(), iTailLength);
if (m_geneticRunConfig.m_geneticConfig.getUniqueAsBoolean("logExecOutputTail"))
LoggerFactory.getLogger(GenIe.class.getName()).info(String.format("Fitness exec call output tail (recognized length of %s):\n%s", iTailLength, strOutputTail));
// das wollen wir parsen {"fitness":0,"metadata":{"shellVar":"hier","shellVector":"2,15,30,0"}}
......
......@@ -18,40 +18,45 @@ import java.util.List;
public class CandidateVectorWithMetadata
{
public CandidateVectorWithMetadata(List<String> paramNames)
{
}
/**
* The vector that will be optimized
*/
List<String> m_lCandidateVector;
/**
* The names of the vector parameters, in the same order as the values inside the candidate
*/
List<String> m_lCandidateVectorParamNames;
/**
* TODO - wollen wir hier wirklich eine HashMap oder schleifen wir die einfach unverarbeitet durch
* Optional. Some arbitrary metadata given from the cost function (or maybe initially from the config for the first generation)
*/
HashMap<String, String> m_hsMetadata = new HashMap<>();
/**
* Optional. The metadata of the parents, will be given to the cost function for information
*/
List<HashMap<String, String>> m_lParentMetadata;
/**
* Optional. The metadata of the topN parent generation candidates, will be given to the cost function for information
*/
List<HashMap<String, String>> m_lTopNParentGenerationMetadata;
/**
* Optional. The scores of the parents in the same order as the parents metadata. Will be given to the cost function for information
*/
List<Double> m_lParentScores;
/**
* Optional. The scores of the topN parent generation candidates in the same order as the according metadata list. Will be given to the cost function for information
*/
List<Double> m_lTopNParentGenerationScores;
/**
* Will be set by the system
*/
Double m_dFitnessScore = Double.NaN;
public CandidateVectorWithMetadata(List<String> candidateVectorParamNames)
{
m_lCandidateVectorParamNames = candidateVectorParamNames;
}
public CandidateVectorWithMetadata cloneDeep()
......@@ -71,6 +76,15 @@ public class CandidateVectorWithMetadata
}
if (this.getParentScores() != null)
clone.setParentScores(new ArrayList<>(this.getParentScores()));
if (this.getTopNParentGenerationMetadata() != null)
{
List<HashMap<String, String>> lTopNMetadataNew = this.getParentMetadata().stream().map(HashMap::new).toList();
clone.setTopNParentGenerationMetadata(lTopNMetadataNew);
}
if (this.getTopNParentGenerationScores() != null)
clone.setTopNParentGenerationScores(new ArrayList<>(this.getTopNParentGenerationScores()));
clone.setFitnessScore(this.getFitnessScore());
return clone;
......
......@@ -81,6 +81,7 @@ public abstract class GeneticParamOptimizer
@Override
protected List<CandidateVectorWithMetadata> mate(CandidateVectorWithMetadata parent1, CandidateVectorWithMetadata parent2, int numberOfCrossoverPoints, Random rng)
{
......@@ -156,8 +157,6 @@ public abstract class GeneticParamOptimizer
{
lStartTime = System.currentTimeMillis();
// TODO hier wäre noch geil, wenn man zu der runtime auch noch die fitness anzeigen könnte, um einen Eindruck zu kriegen, wie sehr die Qualität leidet. Das
// wäre jetzt möglich, da wir den ins CandidateVectorWithMetadata mit reinschreiben
double dCalculatedFitness = GeneticParamOptimizer.this.calculateFitness(candidate, population);
candidate.setFitnessScore(dCalculatedFitness);
......@@ -748,7 +747,7 @@ public abstract class GeneticParamOptimizer
List<EvolutionaryOperator<CandidateVectorWithMetadata>> lEvolutionaryOperators = new LinkedList<>();
// hier werden einzelne Bestandteile eines Gewinners einer Population evtl. mutiert
lEvolutionaryOperators.add(new RecoParamMutation(new Probability(0.1)));
lEvolutionaryOperators.add(new RecoParamMutation(new Probability(m_geneticRunConfig.m_mutationProbability)));
// hier (er)zeugen die Gewinner einer Population ihre Nachkommen
lEvolutionaryOperators.add(new CandidateVectorWithMetadataCrossover());
// die Götter haben das letzte Wort
......
......@@ -39,9 +39,11 @@ public class GeneticRunConfig
public boolean m_bVerbose = false;
public boolean m_bWeakRefCache = false;
public int m_eliteCount;
public int m_eliteMetadataCount4Metadata;
public int m_epochLength;
public int m_firstPopulationSize;
public String m_selectionStrategy;
public float m_mutationProbability;
public MultiValueConfiguration m_geneticConfig;
public int m_iEvaluateLastWinnersCount;
public int m_islandCount;
......@@ -92,6 +94,7 @@ public class GeneticRunConfig
}
m_selectionStrategy = m_geneticConfig.getUniqueAsString("selectionStrategy");
m_mutationProbability = geneticConfig.getUniqueAsFloat("mutationProbability");
m_firstPopulationSize = geneticConfig.getUniqueAsInteger("firstPopulationSize");
m_populationSize = geneticConfig.getUniqueAsInteger("populationSize");
......@@ -112,6 +115,7 @@ public class GeneticRunConfig
m_geneticConfig.getUniqueAsConfiguration("firstGenerationParentMetadata").entryList()
.forEach(entry -> m_firstGenerationParentMetadata.put(entry.getKey(), entry.getValue().getAsString()));
m_eliteMetadataCount4Metadata = geneticConfig.getUniqueAsInteger("eliteMetadataCount");
return this;
......
......@@ -28,16 +28,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
public class NonShrinkingGenerationalEvolutionEngine extends GenerationalEvolutionEngine<CandidateVectorWithMetadata>
{
protected final GeneticParamOptimizer m_geneticParamOptimizer;
protected CandidateFactory<CandidateVectorWithMetadata> candidateFactory;
protected EvolutionaryOperator<CandidateVectorWithMetadata> evolutionScheme;
protected FitnessEvaluator<? super CandidateVectorWithMetadata> fitnessEvaluator;
protected CandidatesEntropyAnalyzer m_candidatesEntropyAnalyzer = new CandidatesEntropyAnalyzer();
protected final GeneticParamOptimizer m_geneticParamOptimizer;
protected int m_populationSize;
protected Set<EvolutionObserver<? super CandidateVectorWithMetadata>> observers = new CopyOnWriteArraySet<EvolutionObserver<? super CandidateVectorWithMetadata>>();
......@@ -50,8 +45,10 @@ public class NonShrinkingGenerationalEvolutionEngine extends GenerationalEvoluti
public NonShrinkingGenerationalEvolutionEngine(CandidateFactory<CandidateVectorWithMetadata> candidateFactory, EvolutionaryOperator<CandidateVectorWithMetadata> evolutionScheme,
FitnessEvaluator<? super CandidateVectorWithMetadata> fitnessEvaluator, SelectionStrategy<? super CandidateVectorWithMetadata> selectionStrategy, Random rng, int populationSize,
public NonShrinkingGenerationalEvolutionEngine(CandidateFactory<CandidateVectorWithMetadata> candidateFactory,
EvolutionaryOperator<CandidateVectorWithMetadata> evolutionScheme,
FitnessEvaluator<? super CandidateVectorWithMetadata> fitnessEvaluator,
SelectionStrategy<? super CandidateVectorWithMetadata> selectionStrategy, Random rng, int populationSize,
GeneticParamOptimizer geneticParamOptimizer)
{
super(candidateFactory, evolutionScheme, fitnessEvaluator, selectionStrategy, rng);
......@@ -70,8 +67,10 @@ public class NonShrinkingGenerationalEvolutionEngine extends GenerationalEvoluti
public NonShrinkingGenerationalEvolutionEngine(CandidateFactory<CandidateVectorWithMetadata> candidateFactory, EvolutionaryOperator<CandidateVectorWithMetadata> evolutionScheme,
InteractiveSelection<CandidateVectorWithMetadata> selectionStrategy, Random rng, int populationSize, GeneticParamOptimizer geneticParamOptimizer)
public NonShrinkingGenerationalEvolutionEngine(CandidateFactory<CandidateVectorWithMetadata> candidateFactory,
EvolutionaryOperator<CandidateVectorWithMetadata> evolutionScheme,
InteractiveSelection<CandidateVectorWithMetadata> selectionStrategy, Random rng, int populationSize,
GeneticParamOptimizer geneticParamOptimizer)
{
super(candidateFactory, evolutionScheme, selectionStrategy, rng);
......@@ -108,13 +107,14 @@ public class NonShrinkingGenerationalEvolutionEngine extends GenerationalEvoluti
/**
* {@inheritDoc}
*/
public List<EvaluatedCandidate<CandidateVectorWithMetadata>> evolvePopulation(int populationSize, int eliteCount, Collection<CandidateVectorWithMetadata> seedCandidates, TerminationCondition... conditions)
public List<EvaluatedCandidate<CandidateVectorWithMetadata>> evolvePopulation(int populationSize, int eliteCount, Collection<CandidateVectorWithMetadata> seedCandidates,
TerminationCondition... conditions)
{
if(eliteCount < 0 || eliteCount >= populationSize)
if (eliteCount < 0 || eliteCount >= populationSize)
{
throw new IllegalArgumentException("Elite count must be non-negative and less than population size.");
}
if(conditions.length == 0)
if (conditions.length == 0)
{
throw new IllegalArgumentException("At least one TerminationCondition must be specified.");
}
......@@ -131,7 +131,7 @@ public class NonShrinkingGenerationalEvolutionEngine extends GenerationalEvoluti
boolean bFirst = true;
while (satisfiedConditions == null)
{
if(bFirst)
if (bFirst)
{
evaluatedPopulation = evaluatePopulation(population);
bFirst = false;
......@@ -140,7 +140,8 @@ public class NonShrinkingGenerationalEvolutionEngine extends GenerationalEvoluti
evaluatedPopulation = nextEvolutionStep(evaluatedPopulation, eliteCount, rng);
EvolutionUtils.sortEvaluatedPopulation(evaluatedPopulation, fitnessEvaluator.isNatural());
PopulationData<CandidateVectorWithMetadata> data = EvolutionUtils.getPopulationData(evaluatedPopulation, fitnessEvaluator.isNatural(), eliteCount, currentGenerationIndex, startTime);
PopulationData<CandidateVectorWithMetadata> data =
EvolutionUtils.getPopulationData(evaluatedPopulation, fitnessEvaluator.isNatural(), eliteCount, currentGenerationIndex, startTime);
// Notify observers of the state of the population.
notifyPopulationChange(data);
......@@ -149,11 +150,11 @@ public class NonShrinkingGenerationalEvolutionEngine extends GenerationalEvoluti
if(m_geneticParamOptimizer.m_geneticRunConfig.m_bVerbose)
if (m_geneticParamOptimizer.m_geneticRunConfig.m_bVerbose)
{
String strMetadata = String.format(
"Analyzed set: Generation %s with population size %d, mean fitness: %.2f, fitness standard deviation %.2f, needed %s\nThe best vector in the set is "
+ "highlighted",
"Analyzed set: Generation %s with population size %d, mean fitness: %.2f, fitness standard deviation %.2f, needed %s\nThe best vector in the set is " +
"highlighted",
data.getGenerationNumber(), data.getPopulationSize(), data.getMeanFitness(), data.getFitnessStandardDeviation(),
StopWatch.formatTimeDistance(data.getElapsedTime()));
......@@ -200,7 +201,7 @@ public class NonShrinkingGenerationalEvolutionEngine extends GenerationalEvoluti
public List<TerminationCondition> getSatisfiedTerminationConditions()
{
if(satisfiedTerminationConditions == null)
if (satisfiedTerminationConditions == null)
{
throw new IllegalStateException("EvolutionEngine has not terminated.");
}
......@@ -216,25 +217,55 @@ public class NonShrinkingGenerationalEvolutionEngine extends GenerationalEvoluti
* {@inheritDoc}
*/
@Override
protected List<EvaluatedCandidate<CandidateVectorWithMetadata>> nextEvolutionStep(List<EvaluatedCandidate<CandidateVectorWithMetadata>> evaluatedPopulation, int eliteCount, Random rng)
protected List<EvaluatedCandidate<CandidateVectorWithMetadata>> nextEvolutionStep(List<EvaluatedCandidate<CandidateVectorWithMetadata>> evaluatedPopulation, int eliteCount,
Random rng)
{
List<CandidateVectorWithMetadata> population = new ArrayList<CandidateVectorWithMetadata>(evaluatedPopulation.size());
// First perform any elitist selection.
List<CandidateVectorWithMetadata> elite = new ArrayList<CandidateVectorWithMetadata>(eliteCount);
Iterator<EvaluatedCandidate<CandidateVectorWithMetadata>> iterator = evaluatedPopulation.iterator();
while (elite.size() < eliteCount)
List<CandidateVectorWithMetadata> lElite = new ArrayList<>(eliteCount);
int iEliteMetadataCount4Metadata = m_geneticParamOptimizer.m_geneticRunConfig.m_eliteMetadataCount4Metadata;
List<HashMap<String, String>> lEliteMetadata4Metadata = new ArrayList<>(iEliteMetadataCount4Metadata);
List<Double> lEliteScores4Metadata = new ArrayList<>(iEliteMetadataCount4Metadata);
// wir ermitteln die topN candidaten - einmal für die Elite die weiterleben darf, einmal für unsere KandidatenMetadaten
// evaluatedPopulation is sorted, fitnessEvaluator.isNatural() is considered
for (EvaluatedCandidate<CandidateVectorWithMetadata> elitistEvaluated : evaluatedPopulation)
{
CandidateVectorWithMetadata elitist = elitistEvaluated.getCandidate();
if (lElite.size() < eliteCount)
lElite.add(elitist);
if (lEliteMetadata4Metadata.size() < iEliteMetadataCount4Metadata)
{
elite.add(iterator.next().getCandidate());
lEliteMetadata4Metadata.add(new HashMap<>(elitist.getMetadata()));
lEliteScores4Metadata.add(elitistEvaluated.getFitness());
}
if (lElite.size() == eliteCount && lEliteMetadata4Metadata.size() == iEliteMetadataCount4Metadata)
break;
}
// Then select candidates that will be operated on to create the evolved portion of the next generation.
// We use the configured generation size instead of the current one to ensure fixed generation sizes
population.addAll(selectionStrategy.select(evaluatedPopulation, fitnessEvaluator.isNatural(), m_populationSize - eliteCount, rng));
// Then evolve the population.
population = evolutionScheme.apply(population, rng);
List<CandidateVectorWithMetadata> lSelectedParents =
new ArrayList<>(selectionStrategy.select(evaluatedPopulation, fitnessEvaluator.isNatural(), m_populationSize - eliteCount, rng));
// Then evolve the population (generate new candidate vectors out of the selected parents).
List<CandidateVectorWithMetadata> lChildren = evolutionScheme.apply(lSelectedParents, rng);
// When the evolution is finished, add the elite to the population.
population.addAll(elite);
return evaluatePopulation(population);
lChildren.addAll(lElite);
// topN Elite as information to the cost function
lChildren.forEach(child -> child.setTopNParentGenerationMetadata(lEliteMetadata4Metadata));
lChildren.forEach(child -> child.setTopNParentGenerationScores(lEliteScores4Metadata));
// finally, the fitness function will be performed on each generated candidate in this new population
List<EvaluatedCandidate<CandidateVectorWithMetadata>> lEvaluatedChildren = evaluatePopulation(lChildren);
return lEvaluatedChildren;
}
......
......@@ -18,16 +18,16 @@ public class Sum23Test
public static void main(String[] args)
{
CandidateVectorWithMetadata bestVector = new GenIe().setFitnessCalculator((candidate, population) -> {
int iSum = candidate.getCandidateVector().stream().mapToInt(Integer::valueOf).sum();
if (iSum == 23)
return 0.9d;
return 0d;
}).optimizeParams("src/test/java/de/dfki/sds/genie/geneticOptimization.conf");
// CandidateVectorWithMetadata bestVector = new GenIe().optimizeParams("src/test/java/de/dfki/sds/genie/geneticOptimization.conf");
// CandidateVectorWithMetadata bestVector = new GenIe().setFitnessCalculator((candidate, population) -> {
// int iSum = candidate.getCandidateVector().stream().mapToInt(Integer::valueOf).sum();
//
// if (iSum == 23)
// return 0.9d;
//
// return 0d;