Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/Build.cmd
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/Build.cmd (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/Build.cmd (revision 12807)
@@ -0,0 +1,104 @@
+@ECHO OFF
+
+SET CLEANBEFOREBUILD=
+
+SET SELECTED=
+SET CONFIGURATION=
+SET PLATFORM=
+
+IF "%~1"=="" GOTO :prompt_solution
+
+SET SELECTED=%1
+IF NOT EXIST %SELECTED% (
+ ECHO Solution file %SELECTED% could not be found.
+ GOTO :end
+)
+ECHO Building solution %SELECTED% ...
+GOTO :config_selection
+
+:prompt_solution
+SET /A COUNT=0
+FOR /F "tokens=*" %%A IN ('dir /B *.sln') DO (
+ CALL :forloopbody "%%A"
+)
+
+IF "%COUNT%"=="1" (
+ SET SELECTED=%SOLUTIONS.1%
+ ECHO Building %SOLUTIONS.1% as it is the only solution that was found ...
+ GOTO :config_selection
+)
+
+ECHO Found the following solutions:
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO ECHO %%A = %%B
+ECHO.
+SET /P SOLUTIONINDEX=Which solution to build? Type the number:
+
+SET SELECTED=""
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO (
+ IF "%%A"=="%SOLUTIONINDEX%" SET SELECTED=%%B
+)
+
+IF %SELECTED%=="" GOTO :eof
+
+:config_selection
+IF "%~2"=="" GOTO :prompt_config
+
+SET CONFIGURATION=%~2
+ECHO Building configuration %CONFIGURATION% ...
+GOTO :platform_selection
+
+:prompt_config
+SET /P CONFIGURATION=Which configuration to build [Release]:
+IF "%CONFIGURATION%"=="" SET CONFIGURATION=Release
+
+:platform_selection
+IF "%~3"=="" GOTO :prompt_platform
+
+SET PLATFORM=%~3
+ECHO Building platform %PLATFORM% ...
+GOTO :clean
+
+:prompt_platform
+SET /P PLATFORM=Which platform to build [Any CPU]:
+IF "%PLATFORM%"=="" SET PLATFORM=Any CPU
+
+:clean
+IF "%~4"=="" GOTO :prompt_clean
+
+SET CLEANBEFOREBUILD=%~4
+GOTO :main
+
+:prompt_clean
+SET /P CLEANBEFOREBUILD=Would you like to clean before building [n]:
+IF "%CLEANBEFOREBUILD%"=="" SET CLEANBEFOREBUILD=n
+
+:main
+REM First find the path to the msbuild.exe by performing a registry query
+FOR /F "tokens=1,3 delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0"') DO (
+ IF "%%A"=="MSBuildToolsPath" SET MSBUILDPATH=%%B)
+
+REM Then execute msbuild to clean and build the solution
+REM Disable that msbuild creates a cache file of the solution
+SET MSBuildUseNoSolutionCache=1
+REM Run msbuild to clean and then build
+IF "%CLEANBEFOREBUILD%" NEQ "n" (
+ ECHO Cleaning ...
+ %MSBUILDPATH%msbuild.exe %SELECTED% /target:Clean /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+)
+ECHO Building ...
+%MSBUILDPATH%msbuild.exe %SELECTED% /target:Build /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+
+ECHO.
+ECHO DONE.
+
+:end
+
+PAUSE
+
+GOTO :eof
+
+REM This workaround is necessary so that COUNT gets reevaluated
+:forloopbody
+SET /A COUNT+=1
+SET SOLUTIONS.%COUNT%=%1
+GOTO :eof
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.LinqExpressionTreeInterpreter.sln
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.LinqExpressionTreeInterpreter.sln (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.LinqExpressionTreeInterpreter.sln (revision 12807)
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.23107.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Symbolic-3.4", "HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj", "{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Debug|x64.ActiveCfg = Debug|x64
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Debug|x64.Build.0 = Debug|x64
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Debug|x86.ActiveCfg = Debug|x86
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Debug|x86.Build.0 = Debug|x86
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|x64.ActiveCfg = Release|x64
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|x64.Build.0 = Release|x64
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|x86.ActiveCfg = Release|x86
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisAlleleFrequencyAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisAlleleFrequencyAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisAlleleFrequencyAnalyzer.cs (revision 12807)
@@ -0,0 +1,111 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ [Item("SymbolicDataAnalysisAlleleFrequencyAnalyzer", "")]
+ [StorableClass]
+ public sealed class SymbolicDataAnalysisAlleleFrequencyAnalyzer : AlleleFrequencyAnalyzer, ISymbolicDataAnalysisAnalyzer {
+ private const string AlleleTreeDepthParameterName = "AlleleTreeDepth";
+
+ #region parameter properties
+ public IScopeTreeLookupParameter SymbolicExpressionTreeParameter {
+ get { return SolutionParameter; }
+ }
+
+ public ILookupParameter ResultCollectionParameter {
+ get { return ResultsParameter; }
+ }
+
+ public IFixedValueParameter AlleleTreeDepthParameter {
+ get { return (IFixedValueParameter)Parameters[AlleleTreeDepthParameterName]; }
+ }
+ #endregion
+ #region properties
+ public int AlleleTreeDepth {
+ get { return AlleleTreeDepthParameter.Value.Value; }
+ set { AlleleTreeDepthParameter.Value.Value = value; }
+ }
+ #endregion
+
+ [StorableConstructor]
+ private SymbolicDataAnalysisAlleleFrequencyAnalyzer(bool deserializing) : base(deserializing) { }
+ private SymbolicDataAnalysisAlleleFrequencyAnalyzer(SymbolicDataAnalysisAlleleFrequencyAnalyzer original, Cloner cloner) : base(original, cloner) { }
+ public SymbolicDataAnalysisAlleleFrequencyAnalyzer()
+ : base() {
+ Parameters.Add(new FixedValueParameter(AlleleTreeDepthParameterName, "The depth of subtrees that should be considered as allele", new IntValue(2)));
+ }
+
+ public override IDeepCloneable Clone(Cloner cloner) {
+ return new SymbolicDataAnalysisAlleleFrequencyAnalyzer(this, cloner);
+ }
+
+ protected override Allele[] CalculateAlleles(ISymbolicExpressionTree solution) {
+ return CalculateAlleles(solution, AlleleTreeDepth);
+ }
+
+ public static Allele[] CalculateAlleles(ISymbolicExpressionTree solution, int alleleTreedepth) {
+ return GetAllSubtreesOfDepth(solution, alleleTreedepth)
+ .Select(t => GetAlleleFromSubtreeOfDepth(t, alleleTreedepth))
+ .ToArray();
+ }
+
+ private static Allele GetAlleleFromSubtreeOfDepth(ISymbolicExpressionTreeNode tree, int d) {
+ string textualRepresentation = GetTextualRepresentationFromSubtreeOfDepth(tree, d);
+ return new Allele(textualRepresentation);
+ }
+
+ private static string GetTextualRepresentationFromSubtreeOfDepth(ISymbolicExpressionTreeNode tree, int d) {
+ if (d == 0) return "";
+ StringBuilder builder = new StringBuilder();
+ var varTreeNode = tree as VariableTreeNode;
+ var constTreeNode = tree as ConstantTreeNode;
+ if (varTreeNode != null) {
+ builder.Append("(var " + varTreeNode.VariableName);
+ } else if (constTreeNode != null) {
+ builder.Append("(const");
+ } else {
+ builder.Append("(" + tree.ToString());
+ }
+ for (int i = 0; i < tree.SubtreeCount; i++) {
+ builder.Append(" " + GetTextualRepresentationFromSubtreeOfDepth(tree.GetSubtree(i), d - 1));
+ }
+ builder.Append(")");
+ return builder.ToString();
+ }
+
+ private static IEnumerable GetAllSubtreesOfDepth(ISymbolicExpressionTree solution, int d) {
+ return from node in solution.IterateNodesPostfix()
+ where node.GetDepth() >= d
+ select node;
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisAnalyzer.cs (revision 12807)
@@ -0,0 +1,69 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// Abstract base class for symbolic data analysis analyzers.
+ ///
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisAnalyzer : SingleSuccessorOperator, ISymbolicDataAnalysisAnalyzer {
+ private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+ private const string ResultCollectionParameterName = "Results";
+
+ #region parameter properties
+ public IScopeTreeLookupParameter SymbolicExpressionTreeParameter {
+ get { return (IScopeTreeLookupParameter)Parameters[SymbolicExpressionTreeParameterName]; }
+ }
+ public ILookupParameter ResultCollectionParameter {
+ get { return (ILookupParameter)Parameters[ResultCollectionParameterName]; }
+ }
+ #endregion
+ #region properties
+ public virtual bool EnabledByDefault {
+ get { return true; }
+ }
+ public ItemArray SymbolicExpressionTree {
+ get { return SymbolicExpressionTreeParameter.ActualValue; }
+ }
+ public ResultCollection ResultCollection {
+ get { return ResultCollectionParameter.ActualValue; }
+ }
+ #endregion
+ [StorableConstructor]
+ protected SymbolicDataAnalysisAnalyzer(bool deserializing) : base(deserializing) { }
+ protected SymbolicDataAnalysisAnalyzer(SymbolicDataAnalysisAnalyzer original, Cloner cloner)
+ : base(original, cloner) {
+ }
+ public SymbolicDataAnalysisAnalyzer()
+ : base() {
+ Parameters.Add(new ScopeTreeLookupParameter(SymbolicExpressionTreeParameterName, "The symbolic expression trees that should be analyzed."));
+ Parameters.Add(new LookupParameter(ResultCollectionParameterName, "The result collection to store the analysis results."));
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisBottomUpDiversityAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisBottomUpDiversityAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisBottomUpDiversityAnalyzer.cs (revision 12807)
@@ -0,0 +1,48 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ [Item("SymbolicDataAnalysisBottomUpDiversityAnalyzer", "A diversity analyzer based on the bottom-up distance between trees.")]
+ [StorableClass]
+ public class SymbolicDataAnalysisBottomUpDiversityAnalyzer : PopulationSimilarityAnalyzer {
+ [StorableConstructor]
+ protected SymbolicDataAnalysisBottomUpDiversityAnalyzer(bool deserializing) : base(deserializing) { }
+
+ protected SymbolicDataAnalysisBottomUpDiversityAnalyzer(SymbolicDataAnalysisBottomUpDiversityAnalyzer original, Cloner cloner)
+ : base(original, cloner) {
+ }
+
+ public override IDeepCloneable Clone(Cloner cloner) {
+ return new SymbolicDataAnalysisBottomUpDiversityAnalyzer(this, cloner);
+ }
+
+ public SymbolicDataAnalysisBottomUpDiversityAnalyzer(SymbolicExpressionTreeBottomUpSimilarityCalculator similarityCalculator)
+ : base(new[] { similarityCalculator }) {
+ DiversityResultName = "Genotypic Diversity";
+ UpdateCounterParameter.ActualName = "GenotypicDiversityAnalyzerUpdateCounter";
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveAnalyzer.cs (revision 12807)
@@ -0,0 +1,76 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// Abstract base class for multi objective symbolic data analysis analyzers.
+ ///
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisMultiObjectiveAnalyzer : SymbolicDataAnalysisAnalyzer, ISymbolicDataAnalysisMultiObjectiveAnalyzer {
+ private const string QualitiesParameterName = "Qualities";
+ private const string MaximizationParameterName = "Maximization";
+ private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+ #region parameter properties
+ public IScopeTreeLookupParameter QualitiesParameter {
+ get { return (IScopeTreeLookupParameter)Parameters[QualitiesParameterName]; }
+ }
+ public ILookupParameter MaximizationParameter {
+ get { return (ILookupParameter)Parameters[MaximizationParameterName]; }
+ }
+ public ILookupParameter ApplyLinearScalingParameter {
+ get { return (ILookupParameter)Parameters[ApplyLinearScalingParameterName]; }
+ }
+ #endregion
+ #region properties
+ public ItemArray Qualities {
+ get { return QualitiesParameter.ActualValue; }
+ }
+ public BoolArray Maximization {
+ get { return MaximizationParameter.ActualValue; }
+ }
+ #endregion
+ [StorableConstructor]
+ protected SymbolicDataAnalysisMultiObjectiveAnalyzer(bool deserializing) : base(deserializing) { }
+ protected SymbolicDataAnalysisMultiObjectiveAnalyzer(SymbolicDataAnalysisMultiObjectiveAnalyzer original, Cloner cloner)
+ : base(original, cloner) {
+ }
+ public SymbolicDataAnalysisMultiObjectiveAnalyzer()
+ : base() {
+ Parameters.Add(new ScopeTreeLookupParameter(QualitiesParameterName, "The qualities of the trees that should be analyzed."));
+ Parameters.Add(new LookupParameter(MaximizationParameterName, "The directions of optimization for each dimension."));
+ Parameters.Add(new LookupParameter(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+ }
+
+ [StorableHook(HookType.AfterDeserialization)]
+ private void AfterDeserialization() {
+ if (Parameters.ContainsKey(ApplyLinearScalingParameterName) && Parameters[ApplyLinearScalingParameterName] is LookupParameter)
+ Parameters.Remove(ApplyLinearScalingParameterName);
+ if (!Parameters.ContainsKey(ApplyLinearScalingParameterName))
+ Parameters.Add(new LookupParameter(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer.cs (revision 12807)
@@ -0,0 +1,184 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// An operator that analyzes the training best symbolic data analysis solution for multi objective symbolic data analysis problems.
+ ///
+ [Item("SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer", "An operator that analyzes the training best symbolic data analysis solution for multi objective symbolic data analysis problems.")]
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisMultiObjectiveAnalyzer
+ where T : class, ISymbolicDataAnalysisSolution {
+ private const string TrainingBestSolutionsParameterName = "Best training solutions";
+ private const string TrainingBestSolutionQualitiesParameterName = "Best training solution qualities";
+ private const string UpdateAlwaysParameterName = "Always update best solutions";
+
+ #region parameter properties
+ public ILookupParameter> TrainingBestSolutionsParameter {
+ get { return (ILookupParameter>)Parameters[TrainingBestSolutionsParameterName]; }
+ }
+ public ILookupParameter> TrainingBestSolutionQualitiesParameter {
+ get { return (ILookupParameter>)Parameters[TrainingBestSolutionQualitiesParameterName]; }
+ }
+ public IFixedValueParameter UpdateAlwaysParameter {
+ get { return (IFixedValueParameter)Parameters[UpdateAlwaysParameterName]; }
+ }
+ #endregion
+ #region properties
+ public ItemList TrainingBestSolutions {
+ get { return TrainingBestSolutionsParameter.ActualValue; }
+ set { TrainingBestSolutionsParameter.ActualValue = value; }
+ }
+ public ItemList TrainingBestSolutionQualities {
+ get { return TrainingBestSolutionQualitiesParameter.ActualValue; }
+ set { TrainingBestSolutionQualitiesParameter.ActualValue = value; }
+ }
+ public BoolValue UpdateAlways {
+ get { return UpdateAlwaysParameter.Value; }
+ }
+ #endregion
+
+ [StorableConstructor]
+ protected SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+ protected SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer(SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+ public SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer()
+ : base() {
+ Parameters.Add(new LookupParameter>(TrainingBestSolutionsParameterName, "The training best (Pareto-optimal) symbolic data analysis solutions."));
+ Parameters.Add(new LookupParameter>(TrainingBestSolutionQualitiesParameterName, "The qualities of the training best (Pareto-optimal) solutions."));
+ Parameters.Add(new FixedValueParameter(UpdateAlwaysParameterName, "Determines if the best training solutions should always be updated regardless of its quality.", new BoolValue(false)));
+ UpdateAlwaysParameter.Hidden = true;
+ }
+
+ [StorableHook(HookType.AfterDeserialization)]
+ private void AfterDeserialization() {
+ if (!Parameters.ContainsKey(UpdateAlwaysParameterName)) {
+ Parameters.Add(new FixedValueParameter(UpdateAlwaysParameterName, "Determines if the best training solutions should always be updated regardless of its quality.", new BoolValue(false)));
+ UpdateAlwaysParameter.Hidden = true;
+ }
+ }
+
+ public override IOperation Apply() {
+ var results = ResultCollection;
+ // create empty parameter and result values
+ if (TrainingBestSolutions == null) {
+ TrainingBestSolutions = new ItemList();
+ TrainingBestSolutionQualities = new ItemList();
+ results.Add(new Result(TrainingBestSolutionQualitiesParameter.Name, TrainingBestSolutionQualitiesParameter.Description, TrainingBestSolutionQualities));
+ results.Add(new Result(TrainingBestSolutionsParameter.Name, TrainingBestSolutionsParameter.Description, TrainingBestSolutions));
+ }
+
+ //if the pareto front of best solutions shall be updated regardless of the quality, the list initialized empty to discard old solutions
+ IList trainingBestQualities;
+ if (UpdateAlways.Value) {
+ trainingBestQualities = new List();
+ } else {
+ trainingBestQualities = TrainingBestSolutionQualities.Select(x => x.ToArray()).ToList();
+ }
+
+ #region find best trees
+ IList nonDominatedIndexes = new List();
+ ISymbolicExpressionTree[] tree = SymbolicExpressionTree.ToArray();
+ List qualities = Qualities.Select(x => x.ToArray()).ToList();
+ bool[] maximization = Maximization.ToArray();
+ List newNonDominatedQualities = new List();
+ for (int i = 0; i < tree.Length; i++) {
+ if (IsNonDominated(qualities[i], trainingBestQualities, maximization) &&
+ IsNonDominated(qualities[i], qualities, maximization)) {
+ if (!newNonDominatedQualities.Contains(qualities[i], new DoubleArrayComparer())) {
+ newNonDominatedQualities.Add(qualities[i]);
+ nonDominatedIndexes.Add(i);
+ }
+ }
+ }
+ #endregion
+ #region update Pareto-optimal solution archive
+ if (nonDominatedIndexes.Count > 0) {
+ ItemList nonDominatedQualities = new ItemList();
+ ItemList nonDominatedSolutions = new ItemList();
+ // add all new non-dominated solutions to the archive
+ foreach (var index in nonDominatedIndexes) {
+ T solution = CreateSolution(tree[index], qualities[index]);
+ nonDominatedSolutions.Add(solution);
+ nonDominatedQualities.Add(new DoubleArray(qualities[index]));
+ }
+ // add old non-dominated solutions only if they are not dominated by one of the new solutions
+ for (int i = 0; i < trainingBestQualities.Count; i++) {
+ if (IsNonDominated(trainingBestQualities[i], newNonDominatedQualities, maximization)) {
+ if (!newNonDominatedQualities.Contains(trainingBestQualities[i], new DoubleArrayComparer())) {
+ nonDominatedSolutions.Add(TrainingBestSolutions[i]);
+ nonDominatedQualities.Add(TrainingBestSolutionQualities[i]);
+ }
+ }
+ }
+
+ results[TrainingBestSolutionsParameter.Name].Value = nonDominatedSolutions;
+ results[TrainingBestSolutionQualitiesParameter.Name].Value = nonDominatedQualities;
+ }
+ #endregion
+ return base.Apply();
+ }
+
+ private class DoubleArrayComparer : IEqualityComparer {
+ public bool Equals(double[] x, double[] y) {
+ if (y.Length != x.Length) throw new ArgumentException();
+ for (int i = 0; i < x.Length; i++) {
+ if (!x[i].IsAlmost(y[i])) return false;
+ }
+ return true;
+ }
+
+ public int GetHashCode(double[] obj) {
+ int c = obj.Length;
+ for (int i = 0; i < obj.Length; i++)
+ c ^= obj[i].GetHashCode();
+ return c;
+ }
+ }
+
+ protected abstract T CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality);
+
+ private bool IsNonDominated(double[] point, IList points, bool[] maximization) {
+ foreach (var refPoint in points) {
+ bool refPointDominatesPoint = true;
+ for (int i = 0; i < point.Length; i++) {
+ refPointDominatesPoint &= IsBetterOrEqual(refPoint[i], point[i], maximization[i]);
+ }
+ if (refPointDominatesPoint) return false;
+ }
+ return true;
+ }
+ private bool IsBetterOrEqual(double lhs, double rhs, bool maximization) {
+ if (maximization) return lhs > rhs;
+ else return lhs < rhs;
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveValidationAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveValidationAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveValidationAnalyzer.cs (revision 12807)
@@ -0,0 +1,98 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// Abstract base class for symbolic data analysis analyzers that validate a solution on a separate data partition using the evaluator.
+ ///
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisMultiObjectiveValidationAnalyzer : SymbolicDataAnalysisMultiObjectiveAnalyzer,
+ ISymbolicDataAnalysisValidationAnalyzer
+ where T : class, ISymbolicDataAnalysisMultiObjectiveEvaluator
+ where U : class, IDataAnalysisProblemData {
+ private const string RandomParameterName = "Random";
+ private const string ProblemDataParameterName = "ProblemData";
+ private const string EvaluatorParameterName = "Evaluator";
+ private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
+ private const string ValidationPartitionParameterName = "ValidationPartition";
+ private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
+
+ #region parameter properties
+ public ILookupParameter RandomParameter {
+ get { return (ILookupParameter)Parameters[RandomParameterName]; }
+ }
+ public ILookupParameter ProblemDataParameter {
+ get { return (ILookupParameter)Parameters[ProblemDataParameterName]; }
+ }
+ public ILookupParameter EvaluatorParameter {
+ get { return (ILookupParameter)Parameters[EvaluatorParameterName]; }
+ }
+ public ILookupParameter SymbolicDataAnalysisTreeInterpreterParameter {
+ get { return (ILookupParameter)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
+ }
+ public IValueLookupParameter ValidationPartitionParameter {
+ get { return (IValueLookupParameter)Parameters[ValidationPartitionParameterName]; }
+ }
+ public IValueLookupParameter RelativeNumberOfEvaluatedSamplesParameter {
+ get { return (IValueLookupParameter)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; }
+ }
+ #endregion
+
+ [StorableConstructor]
+ protected SymbolicDataAnalysisMultiObjectiveValidationAnalyzer(bool deserializing) : base(deserializing) { }
+ protected SymbolicDataAnalysisMultiObjectiveValidationAnalyzer(SymbolicDataAnalysisMultiObjectiveValidationAnalyzer original, Cloner cloner)
+ : base(original, cloner) {
+ }
+ public SymbolicDataAnalysisMultiObjectiveValidationAnalyzer()
+ : base() {
+ Parameters.Add(new ValueLookupParameter(RandomParameterName, "The random generator to use."));
+ Parameters.Add(new LookupParameter(ProblemDataParameterName, "The problem data of the symbolic data analysis problem."));
+ Parameters.Add(new LookupParameter(EvaluatorParameterName, "The operator to use for fitness evaluation on the validation partition."));
+ Parameters.Add(new LookupParameter(SymbolicDataAnalysisTreeInterpreterParameterName, "The interpreter for symbolic data analysis expression trees."));
+ Parameters.Add(new ValueLookupParameter(ValidationPartitionParameterName, "The validation partition."));
+ Parameters.Add(new ValueLookupParameter(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index."));
+ }
+
+ protected IEnumerable GenerateRowsToEvaluate() {
+ int seed = RandomParameter.ActualValue.Next();
+ int samplesStart = ValidationPartitionParameter.ActualValue.Start;
+ int samplesEnd = ValidationPartitionParameter.ActualValue.End;
+ int testPartitionStart = ProblemDataParameter.ActualValue.TestPartition.Start;
+ int testPartitionEnd = ProblemDataParameter.ActualValue.TestPartition.End;
+
+ if (samplesEnd < samplesStart) throw new ArgumentException("Start value is larger than end value.");
+ int count = (int)((samplesEnd - samplesStart) * RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value);
+ if (count == 0) count = 1;
+ return RandomEnumerable.SampleRandomNumbers(seed, samplesStart, samplesEnd, count)
+ .Where(i => i < testPartitionStart || testPartitionEnd <= i);
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer.cs (revision 12807)
@@ -0,0 +1,197 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// An operator that analyzes the validation best symbolic data analysis solution for multi objective symbolic data analysis problems.
+ ///
+ [Item("SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer", "An operator that analyzes the validation best symbolic data analysis solution for multi objective symbolic data analysis problems.")]
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisMultiObjectiveValidationAnalyzer,
+ ISymbolicDataAnalysisMultiObjectiveAnalyzer
+ where S : class, ISymbolicDataAnalysisSolution
+ where T : class, ISymbolicDataAnalysisMultiObjectiveEvaluator
+ where U : class, IDataAnalysisProblemData {
+ private const string ValidationBestSolutionsParameterName = "Best validation solutions";
+ private const string ValidationBestSolutionQualitiesParameterName = "Best validation solution qualities";
+ private const string UpdateAlwaysParameterName = "Always update best solutions";
+
+ #region parameter properties
+ public ILookupParameter> ValidationBestSolutionsParameter {
+ get { return (ILookupParameter>)Parameters[ValidationBestSolutionsParameterName]; }
+ }
+ public ILookupParameter> ValidationBestSolutionQualitiesParameter {
+ get { return (ILookupParameter>)Parameters[ValidationBestSolutionQualitiesParameterName]; }
+ }
+ public IFixedValueParameter UpdateAlwaysParameter {
+ get { return (IFixedValueParameter)Parameters[UpdateAlwaysParameterName]; }
+ }
+ #endregion
+ #region properties
+ public ItemList ValidationBestSolutions {
+ get { return ValidationBestSolutionsParameter.ActualValue; }
+ set { ValidationBestSolutionsParameter.ActualValue = value; }
+ }
+ public ItemList ValidationBestSolutionQualities {
+ get { return ValidationBestSolutionQualitiesParameter.ActualValue; }
+ set { ValidationBestSolutionQualitiesParameter.ActualValue = value; }
+ }
+ public BoolValue UpdateAlways {
+ get { return UpdateAlwaysParameter.Value; }
+ }
+ #endregion
+
+ [StorableConstructor]
+ protected SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+ protected SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer(SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+ public SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer()
+ : base() {
+ Parameters.Add(new LookupParameter>(ValidationBestSolutionsParameterName, "The validation best (Pareto-optimal) symbolic data analysis solutions."));
+ Parameters.Add(new LookupParameter>(ValidationBestSolutionQualitiesParameterName, "The qualities of the validation best (Pareto-optimal) solutions."));
+ Parameters.Add(new FixedValueParameter(UpdateAlwaysParameterName, "Determines if the best validation solutions should always be updated regardless of its quality.", new BoolValue(false)));
+ UpdateAlwaysParameter.Hidden = true;
+ }
+
+ [StorableHook(HookType.AfterDeserialization)]
+ private void AfterDeserialization() {
+ if (!Parameters.ContainsKey(UpdateAlwaysParameterName)) {
+ Parameters.Add(new FixedValueParameter(UpdateAlwaysParameterName, "Determines if the best training solutions should always be updated regardless of its quality.", new BoolValue(false)));
+ UpdateAlwaysParameter.Hidden = true;
+ }
+ }
+
+ public override IOperation Apply() {
+ IEnumerable rows = GenerateRowsToEvaluate();
+ if (!rows.Any()) return base.Apply();
+
+ var results = ResultCollection;
+ // create empty parameter and result values
+ if (ValidationBestSolutions == null) {
+ ValidationBestSolutions = new ItemList();
+ ValidationBestSolutionQualities = new ItemList();
+ results.Add(new Result(ValidationBestSolutionQualitiesParameter.Name, ValidationBestSolutionQualitiesParameter.Description, ValidationBestSolutionQualities));
+ results.Add(new Result(ValidationBestSolutionsParameter.Name, ValidationBestSolutionsParameter.Description, ValidationBestSolutions));
+ }
+
+ //if the pareto front of best solutions shall be updated regardless of the quality, the list initialized empty to discard old solutions
+ IList trainingBestQualities;
+ if (UpdateAlways.Value) {
+ trainingBestQualities = new List();
+ } else {
+ trainingBestQualities = ValidationBestSolutionQualities.Select(x => x.ToArray()).ToList();
+ }
+
+ #region find best trees
+ IList nonDominatedIndexes = new List();
+ ISymbolicExpressionTree[] tree = SymbolicExpressionTree.ToArray();
+ bool[] maximization = Maximization.ToArray();
+ List newNonDominatedQualities = new List();
+ var evaluator = EvaluatorParameter.ActualValue;
+ var problemData = ProblemDataParameter.ActualValue;
+ IExecutionContext childContext = (IExecutionContext)ExecutionContext.CreateChildOperation(evaluator);
+
+ var qualities = tree
+ .Select(t => evaluator.Evaluate(childContext, t, problemData, rows))
+ .ToArray();
+ for (int i = 0; i < tree.Length; i++) {
+ if (IsNonDominated(qualities[i], trainingBestQualities, maximization) &&
+ IsNonDominated(qualities[i], qualities, maximization)) {
+ if (!newNonDominatedQualities.Contains(qualities[i], new DoubleArrayComparer())) {
+ newNonDominatedQualities.Add(qualities[i]);
+ nonDominatedIndexes.Add(i);
+ }
+ }
+ }
+ #endregion
+ #region update Pareto-optimal solution archive
+ if (nonDominatedIndexes.Count > 0) {
+ ItemList nonDominatedQualities = new ItemList();
+ ItemList nonDominatedSolutions = new ItemList();
+ // add all new non-dominated solutions to the archive
+ foreach (var index in nonDominatedIndexes) {
+ S solution = CreateSolution(tree[index], qualities[index]);
+ nonDominatedSolutions.Add(solution);
+ nonDominatedQualities.Add(new DoubleArray(qualities[index]));
+ }
+ // add old non-dominated solutions only if they are not dominated by one of the new solutions
+ for (int i = 0; i < trainingBestQualities.Count; i++) {
+ if (IsNonDominated(trainingBestQualities[i], newNonDominatedQualities, maximization)) {
+ if (!newNonDominatedQualities.Contains(trainingBestQualities[i], new DoubleArrayComparer())) {
+ nonDominatedSolutions.Add(ValidationBestSolutions[i]);
+ nonDominatedQualities.Add(ValidationBestSolutionQualities[i]);
+ }
+ }
+ }
+
+ results[ValidationBestSolutionsParameter.Name].Value = nonDominatedSolutions;
+ results[ValidationBestSolutionQualitiesParameter.Name].Value = nonDominatedQualities;
+ }
+ #endregion
+ return base.Apply();
+ }
+
+ protected abstract S CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality);
+
+ private bool IsNonDominated(double[] point, IList points, bool[] maximization) {
+ foreach (var refPoint in points) {
+ bool refPointDominatesPoint = true;
+ for (int i = 0; i < point.Length; i++) {
+ refPointDominatesPoint &= IsBetter(refPoint[i], point[i], maximization[i]);
+ }
+ if (refPointDominatesPoint) return false;
+ }
+ return true;
+ }
+ private bool IsBetter(double lhs, double rhs, bool maximization) {
+ if (maximization) return lhs > rhs;
+ else return lhs < rhs;
+ }
+
+ private class DoubleArrayComparer : IEqualityComparer {
+ public bool Equals(double[] x, double[] y) {
+ if (y.Length != x.Length) throw new ArgumentException();
+ for (int i = 0; i < x.Length; i++) {
+ if (!x[i].IsAlmost(y[i])) return false;
+ }
+ return true;
+ }
+
+ public int GetHashCode(double[] obj) {
+ int c = obj.Length;
+ for (int i = 0; i < obj.Length; i++)
+ c ^= obj[i].GetHashCode();
+ return c;
+ }
+ }
+
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveAnalyzer.cs (revision 12807)
@@ -0,0 +1,77 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// Abstract base class for single objective symbolic data analysis analyzers.
+ ///
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisSingleObjectiveAnalyzer : SymbolicDataAnalysisAnalyzer, ISymbolicDataAnalysisSingleObjectiveAnalyzer {
+ private const string QualityParameterName = "Quality";
+ private const string MaximizationParameterName = "Maximization";
+ private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+
+ #region parameter properties
+ public IScopeTreeLookupParameter QualityParameter {
+ get { return (IScopeTreeLookupParameter)Parameters[QualityParameterName]; }
+ }
+ public ILookupParameter MaximizationParameter {
+ get { return (ILookupParameter)Parameters[MaximizationParameterName]; }
+ }
+ public ILookupParameter ApplyLinearScalingParameter {
+ get { return (ILookupParameter)Parameters[ApplyLinearScalingParameterName]; }
+ }
+ #endregion
+ #region properties
+ public ItemArray Quality {
+ get { return QualityParameter.ActualValue; }
+ }
+ public BoolValue Maximization {
+ get { return MaximizationParameter.ActualValue; }
+ }
+ #endregion
+ [StorableConstructor]
+ protected SymbolicDataAnalysisSingleObjectiveAnalyzer(bool deserializing) : base(deserializing) { }
+ protected SymbolicDataAnalysisSingleObjectiveAnalyzer(SymbolicDataAnalysisSingleObjectiveAnalyzer original, Cloner cloner)
+ : base(original, cloner) {
+ }
+ public SymbolicDataAnalysisSingleObjectiveAnalyzer()
+ : base() {
+ Parameters.Add(new ScopeTreeLookupParameter(QualityParameterName, "The qualities of the trees that should be analyzed."));
+ Parameters.Add(new LookupParameter(MaximizationParameterName, "The direction of optimization."));
+ Parameters.Add(new LookupParameter(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+ }
+
+ [StorableHook(HookType.AfterDeserialization)]
+ private void AfterDeserialization() {
+ if (Parameters.ContainsKey(ApplyLinearScalingParameterName) && !(Parameters[ApplyLinearScalingParameterName] is LookupParameter))
+ Parameters.Remove(ApplyLinearScalingParameterName);
+ if (!Parameters.ContainsKey(ApplyLinearScalingParameterName))
+ Parameters.Add(new LookupParameter(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs (revision 12807)
@@ -0,0 +1,276 @@
+#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ [StorableClass]
+ [Item("SymbolicDataAnalysisSingleObjectivePruningAnalyzer", "An analyzer that prunes introns from trees in single objective symbolic data analysis problems.")]
+ public abstract class SymbolicDataAnalysisSingleObjectivePruningAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer {
+ #region parameter names
+ private const string ProblemDataParameterName = "ProblemData";
+ private const string UpdateIntervalParameterName = "UpdateInverval";
+ private const string UpdateCounterParameterName = "UpdateCounter";
+ private const string PopulationSliceParameterName = "PopulationSlice";
+ private const string PruningProbabilityParameterName = "PruningProbability";
+ private const string TotalNumberOfPrunedSubtreesParameterName = "Number of pruned subtrees";
+ private const string TotalNumberOfPrunedTreesParameterName = "Number of pruned trees";
+ private const string TotalNumberOfPrunedNodesParameterName = "Number of pruned nodes";
+ private const string RandomParameterName = "Random";
+ private const string ResultsParameterName = "Results";
+ private const string PopulationSizeParameterName = "PopulationSize";
+ #endregion
+
+ #region private members
+ private DataReducer prunedNodesReducer;
+ private DataReducer prunedSubtreesReducer;
+ private DataReducer prunedTreesReducer;
+ private DataTableValuesCollector valuesCollector;
+ private ResultsCollector resultsCollector;
+ #endregion
+
+ #region parameter properties
+ public ILookupParameter RandomParameter {
+ get { return (ILookupParameter)Parameters[RandomParameterName]; }
+ }
+ public IFixedValueParameter UpdateIntervalParameter {
+ get { return (IFixedValueParameter)Parameters[UpdateIntervalParameterName]; }
+ }
+ public IFixedValueParameter UpdateCounterParameter {
+ get { return (IFixedValueParameter)Parameters[UpdateCounterParameterName]; }
+ }
+ public IFixedValueParameter PopulationSliceParameter {
+ get { return (IFixedValueParameter)Parameters[PopulationSliceParameterName]; }
+ }
+ public IFixedValueParameter PruningProbabilityParameter {
+ get { return (IFixedValueParameter)Parameters[PruningProbabilityParameterName]; }
+ }
+ public ILookupParameter PopulationSizeParameter {
+ get { return (ILookupParameter)Parameters[PopulationSizeParameterName]; }
+ }
+ #endregion
+
+ #region properties
+ protected abstract SymbolicDataAnalysisExpressionPruningOperator PruningOperator { get; }
+ protected int UpdateInterval { get { return UpdateIntervalParameter.Value.Value; } }
+
+ protected int UpdateCounter {
+ get { return UpdateCounterParameter.Value.Value; }
+ set { UpdateCounterParameter.Value.Value = value; }
+ }
+
+ protected double PopulationSliceStart {
+ get { return PopulationSliceParameter.Value.Start; }
+ set { PopulationSliceParameter.Value.Start = value; }
+ }
+
+ protected double PopulationSliceEnd {
+ get { return PopulationSliceParameter.Value.End; }
+ set { PopulationSliceParameter.Value.End = value; }
+ }
+
+ protected double PruningProbability {
+ get { return PruningProbabilityParameter.Value.Value; }
+ set { PruningProbabilityParameter.Value.Value = value; }
+ }
+ #endregion
+
+ #region IStatefulItem members
+ public override void InitializeState() {
+ base.InitializeState();
+ UpdateCounter = 0;
+ }
+ public override void ClearState() {
+ base.ClearState();
+ UpdateCounter = 0;
+ }
+ #endregion
+
+ [StorableConstructor]
+ protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(bool deserializing) : base(deserializing) { }
+
+ protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(SymbolicDataAnalysisSingleObjectivePruningAnalyzer original, Cloner cloner)
+ : base(original, cloner) {
+ if (original.prunedNodesReducer != null)
+ this.prunedNodesReducer = (DataReducer)original.prunedNodesReducer.Clone();
+ if (original.prunedSubtreesReducer != null)
+ this.prunedSubtreesReducer = (DataReducer)original.prunedSubtreesReducer.Clone();
+ if (original.prunedTreesReducer != null)
+ this.prunedTreesReducer = (DataReducer)original.prunedTreesReducer.Clone();
+ if (original.valuesCollector != null)
+ this.valuesCollector = (DataTableValuesCollector)original.valuesCollector.Clone();
+ if (original.resultsCollector != null)
+ this.resultsCollector = (ResultsCollector)original.resultsCollector.Clone();
+ }
+
+ [StorableHook(HookType.AfterDeserialization)]
+ private void AfterDeserialization() {
+ if (!Parameters.ContainsKey(PopulationSizeParameterName)) {
+ Parameters.Add(new LookupParameter(PopulationSizeParameterName, "The population of individuals."));
+ }
+ if (Parameters.ContainsKey(UpdateCounterParameterName)) {
+ var fixedValueParameter = Parameters[UpdateCounterParameterName] as FixedValueParameter;
+ if (fixedValueParameter == null) {
+ var valueParameter = (ValueParameter)Parameters[UpdateCounterParameterName];
+ Parameters.Remove(UpdateCounterParameterName);
+ Parameters.Add(new FixedValueParameter(UpdateCounterParameterName, valueParameter.Value));
+ }
+ }
+ if (Parameters.ContainsKey(UpdateIntervalParameterName)) {
+ var fixedValueParameter = Parameters[UpdateIntervalParameterName] as FixedValueParameter;
+ if (fixedValueParameter == null) {
+ var valueParameter = (ValueParameter)Parameters[UpdateIntervalParameterName];
+ Parameters.Remove(UpdateIntervalParameterName);
+ Parameters.Add(new FixedValueParameter(UpdateIntervalParameterName, valueParameter.Value));
+ }
+ }
+ if (Parameters.ContainsKey(PopulationSliceParameterName)) {
+ var fixedValueParameter = Parameters[PopulationSliceParameterName] as FixedValueParameter;
+ if (fixedValueParameter == null) {
+ var valueParameter = (ValueParameter)Parameters[PopulationSliceParameterName];
+ Parameters.Remove(PopulationSliceParameterName);
+ Parameters.Add(new FixedValueParameter(PopulationSliceParameterName, valueParameter.Value));
+ }
+ }
+ if (Parameters.ContainsKey(PruningProbabilityParameterName)) {
+ var fixedValueParameter = Parameters[PruningProbabilityParameterName] as FixedValueParameter;
+ if (fixedValueParameter == null) {
+ var valueParameter = (ValueParameter)Parameters[PruningProbabilityParameterName];
+ Parameters.Remove(PruningProbabilityParameterName);
+ Parameters.Add(new FixedValueParameter(PruningProbabilityParameterName, valueParameter.Value));
+ }
+ }
+ }
+
+ protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer() {
+ #region add parameters
+ Parameters.Add(new FixedValueParameter(PopulationSliceParameterName, "The slice of the population where pruning should be applied.", new DoubleRange(0.75, 1)));
+ Parameters.Add(new FixedValueParameter(PruningProbabilityParameterName, "The probability for pruning an individual.", new DoubleValue(0.5)));
+ Parameters.Add(new FixedValueParameter(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
+ Parameters.Add(new FixedValueParameter(UpdateCounterParameterName, "The value which counts how many times the operator was called", new IntValue(0)));
+ Parameters.Add(new LookupParameter(RandomParameterName, "The random number generator."));
+ Parameters.Add(new LookupParameter(ProblemDataParameterName, "The problem data."));
+ Parameters.Add(new LookupParameter(PopulationSizeParameterName, "The population of individuals."));
+ #endregion
+ }
+
+ //
+ ///
+ /// Computes the closed interval bounding the portion of the population that is to be pruned.
+ ///
+ /// Returns an int range [start, end]
+ private IntRange GetSliceBounds() {
+ if (PopulationSliceStart < 0 || PopulationSliceEnd < 0) throw new ArgumentOutOfRangeException("The slice bounds cannot be negative.");
+ if (PopulationSliceStart > 1 || PopulationSliceEnd > 1) throw new ArgumentOutOfRangeException("The slice bounds should be expressed as unit percentages.");
+ var count = PopulationSizeParameter.ActualValue.Value;
+ var start = (int)Math.Round(PopulationSliceStart * count);
+ var end = (int)Math.Round(PopulationSliceEnd * count);
+ if (end > count) end = count;
+
+ if (start >= end) throw new ArgumentOutOfRangeException("Invalid PopulationSlice bounds.");
+ return new IntRange(start, end);
+ }
+
+ private IOperation CreatePruningOperation() {
+ var operations = new OperationCollection { Parallel = true };
+ var range = GetSliceBounds();
+ var qualities = Quality.Select(x => x.Value).ToArray();
+ var indices = Enumerable.Range(0, qualities.Length).ToArray();
+ indices.StableSort((a, b) => qualities[a].CompareTo(qualities[b]));
+
+ if (!Maximization.Value) Array.Reverse(indices);
+
+ var subscopes = ExecutionContext.Scope.SubScopes;
+ var random = RandomParameter.ActualValue;
+
+ var empty = new EmptyOperator();
+
+ for (int i = 0; i < indices.Length; ++i) {
+ IOperator @operator;
+ if (range.Start <= i && i < range.End && random.NextDouble() <= PruningProbability)
+ @operator = PruningOperator;
+ else @operator = empty;
+ var index = indices[i];
+ var subscope = subscopes[index];
+ operations.Add(ExecutionContext.CreateChildOperation(@operator, subscope));
+ }
+ return operations;
+ }
+
+ public override IOperation Apply() {
+ UpdateCounter++;
+ if (UpdateCounter != UpdateInterval) return base.Apply();
+ UpdateCounter = 0;
+
+ if (prunedNodesReducer == null || prunedSubtreesReducer == null || prunedTreesReducer == null || valuesCollector == null || resultsCollector == null) { InitializeOperators(); }
+
+ var prune = CreatePruningOperation();
+ var reducePrunedNodes = ExecutionContext.CreateChildOperation(prunedNodesReducer);
+ var reducePrunedSubtrees = ExecutionContext.CreateChildOperation(prunedSubtreesReducer);
+ var reducePrunedTrees = ExecutionContext.CreateChildOperation(prunedTreesReducer);
+ var collectValues = ExecutionContext.CreateChildOperation(valuesCollector);
+ var collectResults = ExecutionContext.CreateChildOperation(resultsCollector);
+
+ return new OperationCollection { prune, reducePrunedNodes, reducePrunedSubtrees, reducePrunedTrees, collectValues, collectResults, base.Apply() };
+ }
+
+ private void InitializeOperators() {
+ prunedNodesReducer = new DataReducer();
+ prunedNodesReducer.ParameterToReduce.ActualName = PruningOperator.PrunedNodesParameter.ActualName;
+ prunedNodesReducer.ReductionOperation.Value = new ReductionOperation(ReductionOperations.Sum); // sum all the pruned subtrees parameter values
+ prunedNodesReducer.TargetOperation.Value = new ReductionOperation(ReductionOperations.Assign); // asign the sum to the target parameter
+ prunedNodesReducer.TargetParameter.ActualName = TotalNumberOfPrunedNodesParameterName;
+
+ prunedSubtreesReducer = new DataReducer();
+ prunedSubtreesReducer.ParameterToReduce.ActualName = PruningOperator.PrunedSubtreesParameter.ActualName;
+ prunedSubtreesReducer.ReductionOperation.Value = new ReductionOperation(ReductionOperations.Sum); // sum all the pruned subtrees parameter values
+ prunedSubtreesReducer.TargetOperation.Value = new ReductionOperation(ReductionOperations.Assign); // asign the sum to the target parameter
+ prunedSubtreesReducer.TargetParameter.ActualName = TotalNumberOfPrunedSubtreesParameterName;
+
+ prunedTreesReducer = new DataReducer();
+ prunedTreesReducer.ParameterToReduce.ActualName = PruningOperator.PrunedTreesParameter.ActualName;
+ prunedTreesReducer.ReductionOperation.Value = new ReductionOperation(ReductionOperations.Sum);
+ prunedTreesReducer.TargetOperation.Value = new ReductionOperation(ReductionOperations.Assign);
+ prunedTreesReducer.TargetParameter.ActualName = TotalNumberOfPrunedTreesParameterName;
+
+ valuesCollector = new DataTableValuesCollector();
+ valuesCollector.CollectedValues.Add(new LookupParameter(TotalNumberOfPrunedNodesParameterName));
+ valuesCollector.CollectedValues.Add(new LookupParameter(TotalNumberOfPrunedSubtreesParameterName));
+ valuesCollector.CollectedValues.Add(new LookupParameter(TotalNumberOfPrunedTreesParameterName));
+ valuesCollector.DataTableParameter.ActualName = "Population pruning";
+
+ resultsCollector = new ResultsCollector();
+ resultsCollector.CollectedValues.Add(new LookupParameter("Population pruning"));
+ resultsCollector.ResultsParameter.ActualName = ResultsParameterName;
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs (revision 12807)
@@ -0,0 +1,154 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// An operator that analyzes the training best symbolic data analysis solution for single objective symbolic data analysis problems.
+ ///
+ [Item("SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer", "An operator that analyzes the training best symbolic data analysis solution for single objective symbolic data analysis problems.")]
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer, IIterationBasedOperator
+
+ where T : class, ISymbolicDataAnalysisSolution {
+ private const string TrainingBestSolutionParameterName = "Best training solution";
+ private const string TrainingBestSolutionQualityParameterName = "Best training solution quality";
+ private const string TrainingBestSolutionGenerationParameterName = "Best training solution generation";
+ private const string UpdateAlwaysParameterName = "Always update best solution";
+ private const string IterationsParameterName = "Iterations";
+ private const string MaximumIterationsParameterName = "Maximum Iterations";
+
+ #region parameter properties
+ public ILookupParameter TrainingBestSolutionParameter {
+ get { return (ILookupParameter)Parameters[TrainingBestSolutionParameterName]; }
+ }
+ public ILookupParameter TrainingBestSolutionQualityParameter {
+ get { return (ILookupParameter)Parameters[TrainingBestSolutionQualityParameterName]; }
+ }
+ public ILookupParameter TrainingBestSolutionGenerationParameter {
+ get { return (ILookupParameter)Parameters[TrainingBestSolutionGenerationParameterName]; }
+ }
+ public IFixedValueParameter UpdateAlwaysParameter {
+ get { return (IFixedValueParameter)Parameters[UpdateAlwaysParameterName]; }
+ }
+ public ILookupParameter IterationsParameter {
+ get { return (ILookupParameter)Parameters[IterationsParameterName]; }
+ }
+ public IValueLookupParameter MaximumIterationsParameter {
+ get { return (IValueLookupParameter)Parameters[MaximumIterationsParameterName]; }
+ }
+ #endregion
+ #region properties
+ public T TrainingBestSolution {
+ get { return TrainingBestSolutionParameter.ActualValue; }
+ set { TrainingBestSolutionParameter.ActualValue = value; }
+ }
+ public DoubleValue TrainingBestSolutionQuality {
+ get { return TrainingBestSolutionQualityParameter.ActualValue; }
+ set { TrainingBestSolutionQualityParameter.ActualValue = value; }
+ }
+ public BoolValue UpdateAlways {
+ get { return UpdateAlwaysParameter.Value; }
+ }
+ #endregion
+
+ [StorableConstructor]
+ protected SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+ protected SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer(SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+ public SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer()
+ : base() {
+ Parameters.Add(new LookupParameter(TrainingBestSolutionParameterName, "The training best symbolic data analyis solution."));
+ Parameters.Add(new LookupParameter(TrainingBestSolutionQualityParameterName, "The quality of the training best symbolic data analysis solution."));
+ Parameters.Add(new LookupParameter(TrainingBestSolutionGenerationParameterName, "The generation in which the best training solution was found."));
+ Parameters.Add(new FixedValueParameter(UpdateAlwaysParameterName, "Determines if the best training solution should always be updated regardless of its quality.", new BoolValue(false)));
+ Parameters.Add(new LookupParameter(IterationsParameterName, "The number of performed iterations."));
+ Parameters.Add(new ValueLookupParameter(MaximumIterationsParameterName, "The maximum number of performed iterations.") { Hidden = true });
+ UpdateAlwaysParameter.Hidden = true;
+ }
+
+ [StorableHook(HookType.AfterDeserialization)]
+ private void AfterDeserialization() {
+ if (!Parameters.ContainsKey(UpdateAlwaysParameterName)) {
+ Parameters.Add(new FixedValueParameter(UpdateAlwaysParameterName, "Determines if the best training solution should always be updated regardless of its quality.", new BoolValue(false)));
+ UpdateAlwaysParameter.Hidden = true;
+ }
+ if (!Parameters.ContainsKey(TrainingBestSolutionGenerationParameterName))
+ Parameters.Add(new LookupParameter(TrainingBestSolutionGenerationParameterName, "The generation in which the best training solution was found."));
+ if (!Parameters.ContainsKey(IterationsParameterName))
+ Parameters.Add(new LookupParameter(IterationsParameterName, "The number of performed iterations."));
+ if (!Parameters.ContainsKey(MaximumIterationsParameterName))
+ Parameters.Add(new ValueLookupParameter(MaximumIterationsParameterName, "The maximum number of performed iterations.") { Hidden = true });
+ }
+
+ public override IOperation Apply() {
+ #region find best tree
+ double bestQuality = Maximization.Value ? double.NegativeInfinity : double.PositiveInfinity;
+ ISymbolicExpressionTree bestTree = null;
+ ISymbolicExpressionTree[] tree = SymbolicExpressionTree.ToArray();
+ double[] quality = Quality.Select(x => x.Value).ToArray();
+ for (int i = 0; i < tree.Length; i++) {
+ if (IsBetter(quality[i], bestQuality, Maximization.Value)) {
+ bestQuality = quality[i];
+ bestTree = tree[i];
+ }
+ }
+ #endregion
+
+ var results = ResultCollection;
+ if (bestTree != null && (UpdateAlways.Value || TrainingBestSolutionQuality == null ||
+ IsBetter(bestQuality, TrainingBestSolutionQuality.Value, Maximization.Value))) {
+ TrainingBestSolution = CreateSolution(bestTree, bestQuality);
+ TrainingBestSolutionQuality = new DoubleValue(bestQuality);
+ if (IterationsParameter.ActualValue != null)
+ TrainingBestSolutionGenerationParameter.ActualValue = new IntValue(IterationsParameter.ActualValue.Value);
+
+ if (!results.ContainsKey(TrainingBestSolutionParameter.Name)) {
+ results.Add(new Result(TrainingBestSolutionParameter.Name, TrainingBestSolutionParameter.Description, TrainingBestSolution));
+ results.Add(new Result(TrainingBestSolutionQualityParameter.Name, TrainingBestSolutionQualityParameter.Description, TrainingBestSolutionQuality));
+ if (TrainingBestSolutionGenerationParameter.ActualValue != null)
+ results.Add(new Result(TrainingBestSolutionGenerationParameter.Name, TrainingBestSolutionGenerationParameter.Description, TrainingBestSolutionGenerationParameter.ActualValue));
+ } else {
+ results[TrainingBestSolutionParameter.Name].Value = TrainingBestSolution;
+ results[TrainingBestSolutionQualityParameter.Name].Value = TrainingBestSolutionQuality;
+ if (TrainingBestSolutionGenerationParameter.ActualValue != null)
+ results[TrainingBestSolutionGenerationParameter.Name].Value = TrainingBestSolutionGenerationParameter.ActualValue;
+
+ }
+ }
+ return base.Apply();
+ }
+
+ protected abstract T CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality);
+
+ private bool IsBetter(double lhs, double rhs, bool maximization) {
+ if (maximization) return lhs > rhs;
+ else return lhs < rhs;
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs (revision 12807)
@@ -0,0 +1,191 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// An operator that collects the Pareto-best symbolic data analysis solutions for single objective symbolic data analysis problems.
+ ///
+ [Item("SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer", "An operator that analyzes the Pareto-best symbolic data analysis solution for single objective symbolic data analysis problems.")]
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer, ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator
+ where T : class, ISymbolicDataAnalysisSolution
+ where S : class, IDataAnalysisProblemData {
+ private const string ProblemDataParameterName = "ProblemData";
+ private const string TrainingBestSolutionsParameterName = "Best training solutions";
+ private const string TrainingBestSolutionQualitiesParameterName = "Best training solution qualities";
+ private const string ComplexityParameterName = "Complexity";
+ private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
+ private const string EstimationLimitsParameterName = "EstimationLimits";
+
+ public override bool EnabledByDefault {
+ get { return false; }
+ }
+
+ #region parameter properties
+ public ILookupParameter> TrainingBestSolutionsParameter {
+ get { return (ILookupParameter>)Parameters[TrainingBestSolutionsParameterName]; }
+ }
+ public ILookupParameter> TrainingBestSolutionQualitiesParameter {
+ get { return (ILookupParameter>)Parameters[TrainingBestSolutionQualitiesParameterName]; }
+ }
+ public IScopeTreeLookupParameter ComplexityParameter {
+ get { return (IScopeTreeLookupParameter)Parameters[ComplexityParameterName]; }
+ }
+ public ILookupParameter SymbolicDataAnalysisTreeInterpreterParameter {
+ get { return (ILookupParameter)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
+ }
+ public ILookupParameter ProblemDataParameter {
+ get { return (ILookupParameter)Parameters[ProblemDataParameterName]; }
+ }
+ public IValueLookupParameter EstimationLimitsParameter {
+ get { return (IValueLookupParameter)Parameters[EstimationLimitsParameterName]; }
+ }
+ #endregion
+ #region properties
+ public ItemList TrainingBestSolutions {
+ get { return TrainingBestSolutionsParameter.ActualValue; }
+ set { TrainingBestSolutionsParameter.ActualValue = value; }
+ }
+ public ItemList TrainingBestSolutionQualities {
+ get { return TrainingBestSolutionQualitiesParameter.ActualValue; }
+ set { TrainingBestSolutionQualitiesParameter.ActualValue = value; }
+ }
+ #endregion
+
+ [StorableConstructor]
+ protected SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+ protected SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer(SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+ public SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer()
+ : base() {
+ Parameters.Add(new LookupParameter(ProblemDataParameterName, "The problem data for the symbolic data analysis solution."));
+ Parameters.Add(new LookupParameter>(TrainingBestSolutionsParameterName, "The training best (Pareto-optimal) symbolic data analysis solutions."));
+ Parameters.Add(new LookupParameter>(TrainingBestSolutionQualitiesParameterName, "The qualities of the training best (Pareto-optimal) solutions."));
+ Parameters.Add(new ScopeTreeLookupParameter(ComplexityParameterName, "The complexity of each tree."));
+ Parameters.Add(new LookupParameter(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
+ Parameters.Add(new ValueLookupParameter(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic classification model."));
+ }
+
+ public override IOperation Apply() {
+ var results = ResultCollection;
+ // create empty parameter and result values
+ if (TrainingBestSolutions == null) {
+ TrainingBestSolutions = new ItemList();
+ TrainingBestSolutionQualities = new ItemList();
+ results.Add(new Result(TrainingBestSolutionQualitiesParameter.Name, TrainingBestSolutionQualitiesParameter.Description, TrainingBestSolutionQualities));
+ results.Add(new Result(TrainingBestSolutionsParameter.Name, TrainingBestSolutionsParameter.Description, TrainingBestSolutions));
+ }
+
+ IList> trainingBestQualities = TrainingBestSolutionQualities
+ .Select(x => Tuple.Create(x[0], x[1]))
+ .ToList();
+
+ #region find best trees
+ IList nonDominatedIndexes = new List();
+ ISymbolicExpressionTree[] tree = SymbolicExpressionTree.ToArray();
+ List qualities = Quality.Select(x => x.Value).ToList();
+
+ List complexities;
+ if (ComplexityParameter.ActualValue != null && ComplexityParameter.ActualValue.Length == qualities.Count) {
+ complexities = ComplexityParameter.ActualValue.Select(x => x.Value).ToList();
+ } else {
+ complexities = tree.Select(t => (double)t.Length).ToList();
+ }
+ List> fitness = new List>();
+ for (int i = 0; i < qualities.Count; i++)
+ fitness.Add(Tuple.Create(qualities[i], complexities[i]));
+ var maximization = Tuple.Create(Maximization.Value, false);// complexity must be minimized
+ List> newNonDominatedQualities = new List>();
+ for (int i = 0; i < tree.Length; i++) {
+ if (IsNonDominated(fitness[i], trainingBestQualities, maximization) &&
+ IsNonDominated(fitness[i], newNonDominatedQualities, maximization) &&
+ IsNonDominated(fitness[i], fitness.Skip(i + 1), maximization)) {
+ if (!newNonDominatedQualities.Contains(fitness[i])) {
+ newNonDominatedQualities.Add(fitness[i]);
+ nonDominatedIndexes.Add(i);
+ }
+ }
+ }
+ #endregion
+
+ #region update Pareto-optimal solution archive
+ if (nonDominatedIndexes.Count > 0) {
+ ItemList nonDominatedQualities = new ItemList();
+ ItemList nonDominatedSolutions = new ItemList();
+ // add all new non-dominated solutions to the archive
+ foreach (var index in nonDominatedIndexes) {
+ T solution = CreateSolution(tree[index]);
+ nonDominatedSolutions.Add(solution);
+ nonDominatedQualities.Add(new DoubleArray(new double[] { fitness[index].Item1, fitness[index].Item2 }));
+ }
+ // add old non-dominated solutions only if they are not dominated by one of the new solutions
+ for (int i = 0; i < trainingBestQualities.Count; i++) {
+ if (IsNonDominated(trainingBestQualities[i], newNonDominatedQualities, maximization)) {
+ if (!newNonDominatedQualities.Contains(trainingBestQualities[i])) {
+ nonDominatedSolutions.Add(TrainingBestSolutions[i]);
+ nonDominatedQualities.Add(TrainingBestSolutionQualities[i]);
+ }
+ }
+ }
+
+ // make sure solutions and qualities are ordered in the results
+ var orderedIndexes =
+ nonDominatedSolutions.Select((s, i) => i).OrderBy(i => nonDominatedQualities[i][0]).ToArray();
+
+ var orderedNonDominatedSolutions = new ItemList();
+ var orderedNonDominatedQualities = new ItemList();
+ foreach (var i in orderedIndexes) {
+ orderedNonDominatedQualities.Add(nonDominatedQualities[i]);
+ orderedNonDominatedSolutions.Add(nonDominatedSolutions[i]);
+ }
+
+ TrainingBestSolutions = orderedNonDominatedSolutions;
+ TrainingBestSolutionQualities = orderedNonDominatedQualities;
+
+ results[TrainingBestSolutionsParameter.Name].Value = orderedNonDominatedSolutions;
+ results[TrainingBestSolutionQualitiesParameter.Name].Value = orderedNonDominatedQualities;
+ }
+ #endregion
+ return base.Apply();
+ }
+
+ protected abstract T CreateSolution(ISymbolicExpressionTree bestTree);
+
+ private bool IsNonDominated(Tuple point, IEnumerable> points, Tuple maximization) {
+ return !points.Any(p => IsBetterOrEqual(p.Item1, point.Item1, maximization.Item1) &&
+ IsBetterOrEqual(p.Item2, point.Item2, maximization.Item2));
+ }
+ private bool IsBetterOrEqual(double lhs, double rhs, bool maximization) {
+ if (maximization) return lhs >= rhs;
+ else return lhs <= rhs;
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveValidationAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveValidationAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveValidationAnalyzer.cs (revision 12807)
@@ -0,0 +1,112 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// Abstract base class for symbolic data analysis analyzers that validate a solution on a separate data partition using the evaluator.
+ ///
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisSingleObjectiveValidationAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer,
+ ISymbolicDataAnalysisValidationAnalyzer, IStochasticOperator
+ where T : class, ISymbolicDataAnalysisSingleObjectiveEvaluator
+ where U : class, IDataAnalysisProblemData {
+ private const string RandomParameterName = "Random";
+ private const string ProblemDataParameterName = "ProblemData";
+ private const string EvaluatorParameterName = "Evaluator";
+ private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
+ private const string ValidationPartitionParameterName = "ValidationPartition";
+ private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
+ private const string PercentageOfBestSolutionsParameterName = "PercentageOfBestSolutions";
+
+ #region parameter properties
+ public ILookupParameter RandomParameter {
+ get { return (ILookupParameter)Parameters[RandomParameterName]; }
+ }
+ public ILookupParameter ProblemDataParameter {
+ get { return (ILookupParameter)Parameters[ProblemDataParameterName]; }
+ }
+ public ILookupParameter EvaluatorParameter {
+ get { return (ILookupParameter)Parameters[EvaluatorParameterName]; }
+ }
+ public ILookupParameter SymbolicDataAnalysisTreeInterpreterParameter {
+ get { return (ILookupParameter)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
+ }
+ public IValueLookupParameter ValidationPartitionParameter {
+ get { return (IValueLookupParameter)Parameters[ValidationPartitionParameterName]; }
+ }
+ public IValueLookupParameter RelativeNumberOfEvaluatedSamplesParameter {
+ get { return (IValueLookupParameter)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; }
+ }
+ public IValueLookupParameter PercentageOfBestSolutionsParameter {
+ get { return (IValueLookupParameter)Parameters[PercentageOfBestSolutionsParameterName]; }
+ }
+ #endregion
+
+ [StorableConstructor]
+ protected SymbolicDataAnalysisSingleObjectiveValidationAnalyzer(bool deserializing) : base(deserializing) { }
+ protected SymbolicDataAnalysisSingleObjectiveValidationAnalyzer(SymbolicDataAnalysisSingleObjectiveValidationAnalyzer original, Cloner cloner)
+ : base(original, cloner) {
+ }
+
+ protected SymbolicDataAnalysisSingleObjectiveValidationAnalyzer(): base() {
+ Parameters.Add(new LookupParameter(RandomParameterName, "The random generator."));
+ Parameters.Add(new LookupParameter(ProblemDataParameterName, "The problem data of the symbolic data analysis problem."));
+ Parameters.Add(new LookupParameter(EvaluatorParameterName, "The operator to use for fitness evaluation on the validation partition."));
+ Parameters.Add(new LookupParameter(SymbolicDataAnalysisTreeInterpreterParameterName, "The interpreter for symbolic data analysis expression trees."));
+ Parameters.Add(new ValueLookupParameter(ValidationPartitionParameterName, "The validation partition."));
+ Parameters.Add(new ValueLookupParameter(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index."));
+ Parameters.Add(new ValueLookupParameter(PercentageOfBestSolutionsParameterName,
+ "The percentage of the top solutions which should be analyzed.", new PercentValue(0.1)));
+ }
+
+ [StorableHook(HookType.AfterDeserialization)]
+ private void AfterDeserialization() {
+ if (!Parameters.ContainsKey(PercentageOfBestSolutionsParameterName))
+ Parameters.Add(new ValueLookupParameter(PercentageOfBestSolutionsParameterName,
+ "The percentage of the top solutions which should be analyzed.", new PercentValue(1)));
+ }
+
+ protected IEnumerable GenerateRowsToEvaluate() {
+ int seed = RandomParameter.ActualValue.Next();
+ int samplesStart = ValidationPartitionParameter.ActualValue.Start;
+ int samplesEnd = ValidationPartitionParameter.ActualValue.End;
+ int testPartitionStart = ProblemDataParameter.ActualValue.TestPartition.Start;
+ int testPartitionEnd = ProblemDataParameter.ActualValue.TestPartition.End;
+
+ if (samplesEnd < samplesStart) throw new ArgumentException("Start value is larger than end value.");
+ int count = (int)((samplesEnd - samplesStart) * RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value);
+ if (count == 0) count = 1;
+ return RandomEnumerable.SampleRandomNumbers(seed, samplesStart, samplesEnd, count)
+ .Where(i => i < testPartitionStart || testPartitionEnd <= i);
+ }
+ }
+}
Index: /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer.cs (revision 12807)
+++ /branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer.cs (revision 12807)
@@ -0,0 +1,185 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ ///
+ /// An operator that analyzes the validation best symbolic data analysis solution for single objective symbolic data analysis problems.
+ ///
+ [Item("SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer", "An operator that analyzes the validation best symbolic data analysis solution for single objective symbolic data analysis problems.")]
+ [StorableClass]
+ public abstract class SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationAnalyzer, IIterationBasedOperator
+ where S : class, ISymbolicDataAnalysisSolution
+ where T : class, ISymbolicDataAnalysisSingleObjectiveEvaluator
+ where U : class, IDataAnalysisProblemData {
+ private const string ValidationBestSolutionParameterName = "Best validation solution";
+ private const string ValidationBestSolutionQualityParameterName = "Best validation solution quality";
+ private const string ValidationBestSolutionGenerationParameterName = "Best validation solution generation";
+ private const string UpdateAlwaysParameterName = "Always update best solution";
+ private const string IterationsParameterName = "Iterations";
+ private const string MaximumIterationsParameterName = "Maximum Iterations";
+
+ #region parameter properties
+ public ILookupParameter ValidationBestSolutionParameter {
+ get { return (ILookupParameter