#region License Information
/* HeuristicLab
* Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HeuristicLab.Core;
using System.Xml;
using System.Diagnostics;
using HeuristicLab.DataAnalysis;
using HeuristicLab.Operators;
using HeuristicLab.Random;
using HeuristicLab.Selection;
using HeuristicLab.Logging;
using HeuristicLab.Data;
using HeuristicLab.Operators.Programmable;
namespace HeuristicLab.GP.StructureIdentification {
public class StandardGP : ItemBase, IEditable {
private IntData maxGenerations = new IntData();
public int MaxGenerations {
get { return maxGenerations.Data; }
set { maxGenerations.Data = value; }
}
private IntData tournamentSize = new IntData();
public int TournamentSize {
get { return tournamentSize.Data; }
set { tournamentSize.Data = value; }
}
private DoubleData mutationRate = new DoubleData();
public double MutationRate {
get { return mutationRate.Data; }
set { mutationRate.Data = value; }
}
private IntData parents = new IntData();
private IntData populationSize = new IntData();
public int PopulationSize {
get { return populationSize.Data; }
set {
populationSize.Data = value;
parents.Data = value * 2;
}
}
private BoolData setSeedRandomly = new BoolData();
public bool SetSeedRandomly {
get { return setSeedRandomly.Data; }
set { setSeedRandomly.Data = value; }
}
private IntData seed = new IntData();
public int Seed {
get { return seed.Data; }
set { seed.Data = value; }
}
public IOperator ProblemInjector {
get { return algorithm.SubOperators[0]; }
set {
value.Name = "ProblemInjector";
algorithm.RemoveSubOperator(0);
algorithm.AddSubOperator(value, 0);
}
}
private IntData elites = new IntData();
public int Elites {
get { return elites.Data; }
set { elites.Data = value; }
}
private int maxTreeSize = 50;
public int MaxTreeSize {
get { return maxTreeSize; }
set { maxTreeSize = value; }
}
private int maxTreeHeight = 8;
public int MaxTreeHeight {
get { return maxTreeHeight; }
set { maxTreeHeight = value; }
}
private double punishmentFactor = 10.0;
private bool useEstimatedTargetValue = false;
private double fullTreeShakingFactor = 0.1;
private double onepointShakingFactor = 1.0;
private IOperator algorithm;
private SequentialEngine.SequentialEngine engine;
public IEngine Engine {
get { return engine; }
}
public StandardGP() {
PopulationSize = 10000;
MaxGenerations = 100;
TournamentSize = 7;
MutationRate = 0.15;
Elites = 1;
MaxTreeSize = 100;
MaxTreeHeight = 10;
engine = new SequentialEngine.SequentialEngine();
CombinedOperator algo = CreateAlgorithm();
engine.OperatorGraph.AddOperator(algo);
engine.OperatorGraph.InitialOperator = algo;
}
private CombinedOperator CreateAlgorithm() {
CombinedOperator algo = new CombinedOperator();
algo.Name = "StandardGP";
SequentialProcessor seq = new SequentialProcessor();
EmptyOperator problemInjectorPlaceholder = new EmptyOperator();
RandomInjector randomInjector = new RandomInjector();
randomInjector.GetVariable("SetSeedRandomly").Value = setSeedRandomly;
randomInjector.GetVariable("Seed").Value = seed;
randomInjector.Name = "Random Injector";
VariableInjector globalInjector = CreateGlobalInjector();
CombinedOperator initialization = CreateInitialization();
initialization.Name = "Initialization";
FunctionLibraryInjector funLibInjector = new FunctionLibraryInjector();
CombinedOperator mainLoop = CreateMainLoop();
mainLoop.Name = "Main loop";
ProbabilisticTreeCreator treeCreator = new ProbabilisticTreeCreator();
treeCreator.Name = "Tree generator";
treeCreator.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
treeCreator.GetVariableInfo("MinTreeSize").Local = true;
treeCreator.AddVariable(new HeuristicLab.Core.Variable("MinTreeSize", new IntData(3)));
MeanSquaredErrorEvaluator evaluator = new MeanSquaredErrorEvaluator();
evaluator.GetVariableInfo("MSE").ActualName = "Quality";
evaluator.GetVariableInfo("SamplesStart").ActualName = "TrainingSamplesStart";
evaluator.GetVariableInfo("SamplesEnd").ActualName = "TrainingSamplesEnd";
evaluator.Name = "Evaluator";
StandardCrossOver crossover = new StandardCrossOver();
crossover.Name = "Crossover";
crossover.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
CombinedOperator manipulator = CreateManipulator();
manipulator.Name = "Manipulator";
TournamentSelector selector = new TournamentSelector();
selector.Name = "Selector";
selector.GetVariableInfo("Selected").ActualName = "Parents";
selector.GetVariableInfo("GroupSize").Local = false;
selector.RemoveVariable("GroupSize");
selector.GetVariableInfo("GroupSize").ActualName = "TournamentSize";
LeftReducer cleanUp = new LeftReducer();
seq.AddSubOperator(problemInjectorPlaceholder);
seq.AddSubOperator(randomInjector);
seq.AddSubOperator(globalInjector);
seq.AddSubOperator(funLibInjector);
seq.AddSubOperator(initialization);
seq.AddSubOperator(mainLoop);
seq.AddSubOperator(cleanUp);
initialization.AddSubOperator(treeCreator);
initialization.AddSubOperator(evaluator);
mainLoop.AddSubOperator(selector);
mainLoop.AddSubOperator(crossover);
mainLoop.AddSubOperator(manipulator);
mainLoop.AddSubOperator(evaluator);
algo.OperatorGraph.AddOperator(seq);
algo.OperatorGraph.InitialOperator = seq;
this.algorithm = seq;
return algo;
}
private VariableInjector CreateGlobalInjector() {
VariableInjector injector = new VariableInjector();
injector.Name = "Global Injector";
injector.AddVariable(new HeuristicLab.Core.Variable("Generations", new IntData(0)));
injector.AddVariable(new HeuristicLab.Core.Variable("MaxGenerations", maxGenerations));
injector.AddVariable(new HeuristicLab.Core.Variable("MutationRate", mutationRate));
injector.AddVariable(new HeuristicLab.Core.Variable("PopulationSize", populationSize));
injector.AddVariable(new HeuristicLab.Core.Variable("Parents", parents));
injector.AddVariable(new HeuristicLab.Core.Variable("Elites", elites));
injector.AddVariable(new HeuristicLab.Core.Variable("TournamentSize", tournamentSize));
injector.AddVariable(new HeuristicLab.Core.Variable("Maximization", new BoolData(false)));
injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeHeight", new IntData(maxTreeHeight)));
injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeSize", new IntData(maxTreeSize)));
injector.AddVariable(new HeuristicLab.Core.Variable("EvaluatedSolutions", new IntData(0)));
injector.AddVariable(new HeuristicLab.Core.Variable("TotalEvaluatedNodes", new DoubleData(0)));
injector.AddVariable(new HeuristicLab.Core.Variable("PunishmentFactor", new DoubleData(punishmentFactor)));
injector.AddVariable(new HeuristicLab.Core.Variable("UseEstimatedTargetValue", new BoolData(useEstimatedTargetValue)));
return injector;
}
private CombinedOperator CreateManipulator() {
CombinedOperator manipulator = new CombinedOperator();
StochasticMultiBranch multibranch = new StochasticMultiBranch();
FullTreeShaker fullTreeShaker = new FullTreeShaker();
fullTreeShaker.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
fullTreeShaker.GetVariableInfo("ShakingFactor").Local = true;
fullTreeShaker.AddVariable(new HeuristicLab.Core.Variable("ShakingFactor", new DoubleData(fullTreeShakingFactor)));
OnePointShaker onepointShaker = new OnePointShaker();
onepointShaker.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
onepointShaker.GetVariableInfo("ShakingFactor").Local = true;
onepointShaker.AddVariable(new HeuristicLab.Core.Variable("ShakingFactor", new DoubleData(onepointShakingFactor)));
ChangeNodeTypeManipulation changeNodeTypeManipulation = new ChangeNodeTypeManipulation();
changeNodeTypeManipulation.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
CutOutNodeManipulation cutOutNodeManipulation = new CutOutNodeManipulation();
cutOutNodeManipulation.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
DeleteSubTreeManipulation deleteSubTreeManipulation = new DeleteSubTreeManipulation();
deleteSubTreeManipulation.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
SubstituteSubTreeManipulation substituteSubTreeManipulation = new SubstituteSubTreeManipulation();
substituteSubTreeManipulation.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
IOperator[] manipulators = new IOperator[] {
onepointShaker, fullTreeShaker,
changeNodeTypeManipulation,
cutOutNodeManipulation,
deleteSubTreeManipulation,
substituteSubTreeManipulation};
DoubleArrayData probabilities = new DoubleArrayData(new double[manipulators.Length]);
for (int i = 0; i < manipulators.Length; i++) {
probabilities.Data[i] = 1.0;
multibranch.AddSubOperator(manipulators[i]);
}
multibranch.GetVariableInfo("Probabilities").Local = true;
multibranch.AddVariable(new HeuristicLab.Core.Variable("Probabilities", probabilities));
manipulator.OperatorGraph.AddOperator(multibranch);
manipulator.OperatorGraph.InitialOperator = multibranch;
return manipulator;
}
private CombinedOperator CreateInitialization() {
CombinedOperator init = new CombinedOperator();
SequentialProcessor seq = new SequentialProcessor();
SubScopesCreater subScopesCreater = new SubScopesCreater();
subScopesCreater.GetVariableInfo("SubScopes").ActualName = "PopulationSize";
UniformSequentialSubScopesProcessor subScopesProc = new UniformSequentialSubScopesProcessor();
SequentialProcessor individualSeq = new SequentialProcessor();
OperatorExtractor treeCreater = new OperatorExtractor();
treeCreater.Name = "Tree generator (extr.)";
treeCreater.GetVariableInfo("Operator").ActualName = "Tree generator";
OperatorExtractor evaluator = new OperatorExtractor();
evaluator.Name = "Evaluator (extr.)";
evaluator.GetVariableInfo("Operator").ActualName = "Evaluator";
MeanSquaredErrorEvaluator validationEvaluator = new MeanSquaredErrorEvaluator();
validationEvaluator.GetVariableInfo("MSE").ActualName = "ValidationQuality";
validationEvaluator.GetVariableInfo("SamplesStart").ActualName = "ValidationSamplesStart";
validationEvaluator.GetVariableInfo("SamplesEnd").ActualName = "ValidationSamplesEnd";
Counter evalCounter = new Counter();
evalCounter.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
Sorter sorter = new Sorter();
sorter.GetVariableInfo("Descending").ActualName = "Maximization";
sorter.GetVariableInfo("Value").ActualName = "Quality";
seq.AddSubOperator(subScopesCreater);
seq.AddSubOperator(subScopesProc);
seq.AddSubOperator(sorter);
subScopesProc.AddSubOperator(individualSeq);
individualSeq.AddSubOperator(treeCreater);
individualSeq.AddSubOperator(evaluator);
individualSeq.AddSubOperator(validationEvaluator);
individualSeq.AddSubOperator(evalCounter);
init.OperatorGraph.AddOperator(seq);
init.OperatorGraph.InitialOperator = seq;
return init;
}
private CombinedOperator CreateMainLoop() {
CombinedOperator main = new CombinedOperator();
SequentialProcessor seq = new SequentialProcessor();
CombinedOperator childCreater = CreateChildCreater();
childCreater.Name = "Create children";
CombinedOperator replacement = CreateReplacement();
replacement.Name = "Replacement";
BestSolutionStorer solutionStorer = CreateBestSolutionStorer();
BestAverageWorstQualityCalculator qualityCalculator = new BestAverageWorstQualityCalculator();
BestAverageWorstQualityCalculator validationQualityCalculator = new BestAverageWorstQualityCalculator();
validationQualityCalculator.Name = "ValidationQualityCalculator";
validationQualityCalculator.GetVariableInfo("BestQuality").ActualName = "BestValidationQuality";
validationQualityCalculator.GetVariableInfo("AverageQuality").ActualName = "AverageValidationQuality";
validationQualityCalculator.GetVariableInfo("WorstQuality").ActualName = "WorstValidationQuality";
DataCollector collector = new DataCollector();
ItemList names = collector.GetVariable("VariableNames").GetValue>();
names.Add(new StringData("BestQuality"));
names.Add(new StringData("AverageQuality"));
names.Add(new StringData("WorstQuality"));
names.Add(new StringData("BestValidationQuality"));
names.Add(new StringData("AverageValidationQuality"));
names.Add(new StringData("WorstValidationQuality"));
LinechartInjector lineChartInjector = new LinechartInjector();
lineChartInjector.GetVariableInfo("Linechart").ActualName = "Quality Linechart";
lineChartInjector.GetVariable("NumberOfLines").GetValue().Data = 6;
QualityLogger qualityLogger = new QualityLogger();
QualityLogger validationQualityLogger = new QualityLogger();
validationQualityCalculator.Name = "ValidationQualityLogger";
validationQualityLogger.GetVariableInfo("Quality").ActualName = "ValidationQuality";
validationQualityLogger.GetVariableInfo("QualityLog").ActualName = "ValidationQualityLog";
Counter counter = new Counter();
counter.GetVariableInfo("Value").ActualName = "Generations";
LessThanComparator comparator = new LessThanComparator();
comparator.GetVariableInfo("LeftSide").ActualName = "Generations";
comparator.GetVariableInfo("RightSide").ActualName = "MaxGenerations";
comparator.GetVariableInfo("Result").ActualName = "GenerationsCondition";
ConditionalBranch cond = new ConditionalBranch();
cond.GetVariableInfo("Condition").ActualName = "GenerationsCondition";
seq.AddSubOperator(childCreater);
seq.AddSubOperator(replacement);
seq.AddSubOperator(solutionStorer);
seq.AddSubOperator(qualityCalculator);
seq.AddSubOperator(validationQualityCalculator);
seq.AddSubOperator(collector);
seq.AddSubOperator(lineChartInjector);
seq.AddSubOperator(qualityLogger);
seq.AddSubOperator(validationQualityLogger);
seq.AddSubOperator(counter);
seq.AddSubOperator(comparator);
seq.AddSubOperator(cond);
cond.AddSubOperator(seq);
main.OperatorGraph.AddOperator(seq);
main.OperatorGraph.InitialOperator = seq;
return main;
}
private BestSolutionStorer CreateBestSolutionStorer() {
BestSolutionStorer solutionStorer = new BestSolutionStorer();
solutionStorer.GetVariableInfo("Quality").ActualName = "ValidationQuality";
solutionStorer.GetVariableInfo("BestSolution").ActualName = "BestValidationSolution";
SequentialProcessor bestSolutionProcessor = new SequentialProcessor();
MeanAbsolutePercentageErrorEvaluator trainingMapeEvaluator = new MeanAbsolutePercentageErrorEvaluator();
trainingMapeEvaluator.Name = "TrainingMapeEvaluator";
trainingMapeEvaluator.GetVariableInfo("MAPE").ActualName = "TrainingMAPE";
trainingMapeEvaluator.GetVariableInfo("SamplesStart").ActualName = "TrainingSamplesStart";
trainingMapeEvaluator.GetVariableInfo("SamplesEnd").ActualName = "TrainingSamplesEnd";
MeanAbsolutePercentageErrorEvaluator validationMapeEvaluator = new MeanAbsolutePercentageErrorEvaluator();
validationMapeEvaluator.Name = "ValidationMapeEvaluator";
validationMapeEvaluator.GetVariableInfo("MAPE").ActualName = "ValidationMAPE";
validationMapeEvaluator.GetVariableInfo("SamplesStart").ActualName = "ValidationSamplesStart";
validationMapeEvaluator.GetVariableInfo("SamplesEnd").ActualName = "ValidationSamplesEnd";
ProgrammableOperator progOperator = new ProgrammableOperator();
progOperator.RemoveVariableInfo("Result");
progOperator.AddVariableInfo(new HeuristicLab.Core.VariableInfo("EvaluatedSolutions", "", typeof(IntData), VariableKind.In));
progOperator.Code = @"
int evalSolutions = EvaluatedSolutions.Data;
scope.AddVariable(new Variable(""EvaluatedSolutions"", new IntData(evalSolutions)));
";
solutionStorer.AddSubOperator(bestSolutionProcessor);
bestSolutionProcessor.AddSubOperator(trainingMapeEvaluator);
bestSolutionProcessor.AddSubOperator(validationMapeEvaluator);
bestSolutionProcessor.AddSubOperator(progOperator);
return solutionStorer;
}
private CombinedOperator CreateReplacement() {
CombinedOperator replacement = new CombinedOperator();
SequentialProcessor seq = new SequentialProcessor();
SequentialSubScopesProcessor seqScopeProc = new SequentialSubScopesProcessor();
SequentialProcessor selectedProc = new SequentialProcessor();
LeftSelector leftSelector = new LeftSelector();
leftSelector.GetVariableInfo("Selected").ActualName = "Elites";
RightReducer rightReducer = new RightReducer();
SequentialProcessor remainingProc = new SequentialProcessor();
RightSelector rightSelector = new RightSelector();
rightSelector.GetVariableInfo("Selected").ActualName = "Elites";
LeftReducer leftReducer = new LeftReducer();
MergingReducer mergingReducer = new MergingReducer();
Sorter sorter = new Sorter();
sorter.GetVariableInfo("Descending").ActualName = "Maximization";
sorter.GetVariableInfo("Value").ActualName = "Quality";
seq.AddSubOperator(seqScopeProc);
seqScopeProc.AddSubOperator(selectedProc);
selectedProc.AddSubOperator(leftSelector);
selectedProc.AddSubOperator(rightReducer);
seqScopeProc.AddSubOperator(remainingProc);
remainingProc.AddSubOperator(rightSelector);
remainingProc.AddSubOperator(leftReducer);
seq.AddSubOperator(mergingReducer);
seq.AddSubOperator(sorter);
replacement.OperatorGraph.AddOperator(seq);
replacement.OperatorGraph.InitialOperator = seq;
return replacement;
}
private CombinedOperator CreateChildCreater() {
CombinedOperator childCreater = new CombinedOperator();
SequentialProcessor seq = new SequentialProcessor();
OperatorExtractor selector = new OperatorExtractor();
selector.Name = "Selector (extr.)";
selector.GetVariableInfo("Operator").ActualName = "Selector";
SequentialSubScopesProcessor seqScopesProc = new SequentialSubScopesProcessor();
EmptyOperator emptyOpt = new EmptyOperator();
SequentialProcessor selectedProc = new SequentialProcessor();
OperatorExtractor crossover = new OperatorExtractor();
crossover.Name = "Crossover (extr.)";
crossover.GetVariableInfo("Operator").ActualName = "Crossover";
UniformSequentialSubScopesProcessor individualProc = new UniformSequentialSubScopesProcessor();
SequentialProcessor individualSeqProc = new SequentialProcessor();
StochasticBranch cond = new StochasticBranch();
cond.GetVariableInfo("Probability").ActualName = "MutationRate";
OperatorExtractor manipulator = new OperatorExtractor();
manipulator.Name = "Manipulator (extr.)";
manipulator.GetVariableInfo("Operator").ActualName = "Manipulator";
OperatorExtractor evaluator = new OperatorExtractor();
evaluator.Name = "Evaluator (extr.)";
evaluator.GetVariableInfo("Operator").ActualName = "Evaluator";
MeanSquaredErrorEvaluator validationEvaluator = new MeanSquaredErrorEvaluator();
validationEvaluator.GetVariableInfo("MSE").ActualName = "ValidationQuality";
validationEvaluator.GetVariableInfo("SamplesStart").ActualName = "ValidationSamplesStart";
validationEvaluator.GetVariableInfo("SamplesEnd").ActualName = "ValidationSamplesEnd";
Counter evalCounter = new Counter();
evalCounter.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
Sorter sorter = new Sorter();
sorter.GetVariableInfo("Descending").ActualName = "Maximization";
sorter.GetVariableInfo("Value").ActualName = "Quality";
seq.AddSubOperator(selector);
seq.AddSubOperator(seqScopesProc);
seqScopesProc.AddSubOperator(emptyOpt);
seqScopesProc.AddSubOperator(selectedProc);
selectedProc.AddSubOperator(crossover);
selectedProc.AddSubOperator(individualProc);
individualProc.AddSubOperator(individualSeqProc);
individualSeqProc.AddSubOperator(cond);
cond.AddSubOperator(manipulator);
individualSeqProc.AddSubOperator(evaluator);
individualSeqProc.AddSubOperator(validationEvaluator);
individualSeqProc.AddSubOperator(evalCounter);
selectedProc.AddSubOperator(sorter);
childCreater.OperatorGraph.AddOperator(seq);
childCreater.OperatorGraph.InitialOperator = seq;
return childCreater;
}
public IEditor CreateEditor() {
return new StandardGpEditor(this);
}
public override IView CreateView() {
return new StandardGpEditor(this);
}
public override object Clone(IDictionary clonedObjects) {
StandardGP clone = new StandardGP();
clonedObjects.Add(Guid, clone);
clone.engine = (SequentialEngine.SequentialEngine)Auxiliary.Clone(Engine, clonedObjects);
return clone;
}
#region SetReferences Method
private void SetReferences() {
// SGA
CombinedOperator co1 = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
// SequentialProcessor in SGA
algorithm = (SequentialProcessor)co1.OperatorGraph.InitialOperator;
// RandomInjector
RandomInjector ri = (RandomInjector)algorithm.SubOperators[1];
setSeedRandomly = ri.GetVariable("SetSeedRandomly").GetValue();
seed = ri.GetVariable("Seed").GetValue();
// VariableInjector
VariableInjector vi = (VariableInjector)algorithm.SubOperators[2];
populationSize = vi.GetVariable("PopulationSize").GetValue();
parents = vi.GetVariable("Parents").GetValue();
maxGenerations = vi.GetVariable("MaxGenerations").GetValue();
mutationRate = vi.GetVariable("MutationRate").GetValue();
elites = vi.GetVariable("Elites").GetValue();
}
#endregion
#region Persistence Methods
public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary persistedObjects) {
XmlNode node = base.GetXmlNode(name, document, persistedObjects);
node.AppendChild(PersistenceManager.Persist("Engine", Engine, document, persistedObjects));
return node;
}
public override void Populate(XmlNode node, IDictionary restoredObjects) {
base.Populate(node, restoredObjects);
engine = (SequentialEngine.SequentialEngine)PersistenceManager.Restore(node.SelectSingleNode("Engine"), restoredObjects);
SetReferences();
}
#endregion
}
}