#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 = CreateInialization(); 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 CreateInialization() { 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"; seq.AddSubOperator(subScopesCreater); seq.AddSubOperator(subScopesProc); 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 = "ValidationMapeEvaluator"; 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 } }