#region License Information /* HeuristicLab * Copyright (C) 2002-2010 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 HeuristicLab.Analysis; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Optimization.Operators; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.DataAnalysis.Symbolic; using System.Collections.Generic; using HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols; namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Analyzers { /// /// An operator that analyzes the population diversity using fine grained structural tree similarity estimation. /// [Item("FineGrainedStructuralPopulationDiversityAnalyzer", "An operator that analyzes the population diversity using fine grained structural tree similarity estimation.")] [StorableClass] public sealed class FineGrainedStructuralPopulationDiversityAnalyzer : SymbolicRegressionPopulationDiversityAnalyzer { #region Properties and Parameters private const string FunctionTreeGrammarParameterName = "FunctionTreeGrammar"; private const string MinimumLevelDeltaParameterName = "MinimumLevelDelta"; private const string MaximumLevelDeltaParameterName = "MaximumLevelDelta"; private const string PreventMultipleComparisonContributionParameterName = "PreventMultipleComparisonContribution"; private const string MaximumExpressionDepthParameterName = "MaxExpressionDepth"; private const string LevelDifferenceCoefficientParameterName = "LevelDifferenceCoefficient"; private const string AncestorIndexCoefficientParameterName = "AncestorIndexCoefficient"; private const string ConstantValueCoefficientParameterName = "ConstantValueCoefficient"; private const string VariableWeightCoefficientParameterName = "VariableWeightCoefficient"; private const string TimeOffsetCoefficientParameterName = "TimeOffsetCoefficient"; private const string VariableIndexCoefficientParameterName = "VariableIndexCoefficient"; private const string AdditiveSimilarityCalculationParameterName = "AdditiveSimilarityCalculation"; public IValueLookupParameter FunctionTreeGrammarParameter { get { return (IValueLookupParameter)Parameters[FunctionTreeGrammarParameterName]; } } public GlobalSymbolicExpressionGrammar FunctionTreeGrammar { get { return FunctionTreeGrammarParameter.ActualValue; } } public IValueLookupParameter MaximumExpressionDepthParameter { get { return (IValueLookupParameter)Parameters[MaximumExpressionDepthParameterName]; } } public int MaximumExpressionDepth { get { return MaximumExpressionDepthParameter.ActualValue.Value; } } public IValueParameter MinimumLevelDeltaParameter { get { return (IValueParameter)Parameters[MinimumLevelDeltaParameterName]; } } public int MinimumLevelDelta { get { return MinimumLevelDeltaParameter.Value.Value; } } public IValueParameter MaximumLevelDeltaParameter { get { return (IValueParameter)Parameters[MaximumLevelDeltaParameterName]; } } public int MaximumLevelDelta { get { return MaximumLevelDeltaParameter.Value.Value; } } public IValueParameter PreventMultipleComparisonContributionParameter { get { return (IValueParameter)Parameters[PreventMultipleComparisonContributionParameterName]; } } public bool PreventMultipleComparisonContribution { get { return PreventMultipleComparisonContributionParameter.Value.Value; } } public IValueParameter LevelDifferenceCoefficientParameter { get { return (IValueParameter)Parameters[LevelDifferenceCoefficientParameterName]; } } public double LevelDifferenceCoefficient { get { return LevelDifferenceCoefficientParameter.Value.Value; } } public IValueParameter AncestorIndexCoefficientParameter { get { return (IValueParameter)Parameters[AncestorIndexCoefficientParameterName]; } } public double AncestorIndexCoefficient { get { return AncestorIndexCoefficientParameter.Value.Value; } } public IValueParameter ConstantValueCoefficientParameter { get { return (IValueParameter)Parameters[ConstantValueCoefficientParameterName]; } } public double ConstantValueCoefficient { get { return ConstantValueCoefficientParameter.Value.Value; } } public IValueParameter VariableWeightCoefficientParameter { get { return (IValueParameter)Parameters[VariableWeightCoefficientParameterName]; } } public double VariableWeightCoefficient { get { return VariableWeightCoefficientParameter.Value.Value; } } public IValueParameter TimeOffsetCoefficientParameter { get { return (IValueParameter)Parameters[TimeOffsetCoefficientParameterName]; } } public double TimeOffsetCoefficientCoefficient { get { return TimeOffsetCoefficientParameter.Value.Value; } } public IValueParameter VariableIndexCoefficientParameter { get { return (IValueParameter)Parameters[VariableIndexCoefficientParameterName]; } } public double VariableIndexCoefficient { get { return VariableIndexCoefficientParameter.Value.Value; } } public IValueParameter AdditiveSimilarityCalculationParameter { get { return (IValueParameter)Parameters[AdditiveSimilarityCalculationParameterName]; } } public bool AdditiveSimilarityCalculation { get { return AdditiveSimilarityCalculationParameter.Value.Value; } } #endregion [StorableConstructor] private FineGrainedStructuralPopulationDiversityAnalyzer(bool deserializing) : base(deserializing) { } private FineGrainedStructuralPopulationDiversityAnalyzer(FineGrainedStructuralPopulationDiversityAnalyzer original, Cloner cloner) : base(original, cloner) { } public FineGrainedStructuralPopulationDiversityAnalyzer() : base() { Parameters.Add(new ValueLookupParameter(FunctionTreeGrammarParameterName, "The grammar that is used for symbolic regression models.")); Parameters.Add(new ValueLookupParameter(MaximumExpressionDepthParameterName, "Maximal depth of the analyzed symbolic expressions.")); Parameters.Add(new ValueParameter(MinimumLevelDeltaParameterName, "Minimum value for the level delta of the analyzed genetic information items.", new IntValue(0))); Parameters.Add(new ValueParameter(MaximumLevelDeltaParameterName, "Maximum value for the level delta of the analyzed genetic information items.", new IntValue(int.MaxValue))); Parameters.Add(new ValueParameter(PreventMultipleComparisonContributionParameterName, "Flag that denotes whether genetic information items are hindered from contributing to the similarity function multiple times.", new BoolValue(false))); Parameters.Add(new ValueParameter(LevelDifferenceCoefficientParameterName, "Weighting coefficient for level differences.", new DoubleValue(0.2))); Parameters.Add(new ValueParameter(AncestorIndexCoefficientParameterName, "Weighting coefficient for ancestor index differences.", new DoubleValue(0.2))); Parameters.Add(new ValueParameter(ConstantValueCoefficientParameterName, "Weighting coefficient for constant value differences.", new DoubleValue(0.2))); Parameters.Add(new ValueParameter(VariableWeightCoefficientParameterName, "Weighting coefficient for variable weight differences.", new DoubleValue(0.2))); Parameters.Add(new ValueParameter(TimeOffsetCoefficientParameterName, "Weighting coefficient for time lag differences.", new DoubleValue(0.2))); Parameters.Add(new ValueParameter(VariableIndexCoefficientParameterName, "Weighting coefficient for variable index differences.", new DoubleValue(0.2))); Parameters.Add(new ValueParameter(AdditiveSimilarityCalculationParameterName, "Flag that denotes whether the similarity of genetic information items shall be calculated using additive calculation.", new BoolValue(true))); } public override IDeepCloneable Clone(Cloner cloner) { return new FineGrainedStructuralPopulationDiversityAnalyzer(this, cloner); } protected override double[,] CalculateSimilarities(SymbolicExpressionTree[] solutions) { // collect information stored int the problem's parameters double variableWeightSigma = 0; double constantMinimumValue = 0; double constantMaximumValue = 0; int minimumTimeOffset = 0; int maximumTimeOffset = 0; foreach (Symbol symbol in FunctionTreeGrammar.Symbols) { Constant constant = symbol as Constant; if (constant !=null) { constantMinimumValue = constant.MinValue; constantMaximumValue = constant.MaxValue; } DataAnalysis.Symbolic.Symbols.Variable variable = symbol as DataAnalysis.Symbolic.Symbols.Variable; if (variable != null) variableWeightSigma = variable.WeightSigma; LaggedVariable laggedVariable = symbol as LaggedVariable; if (laggedVariable !=null) { minimumTimeOffset = laggedVariable.MinLag; maximumTimeOffset = laggedVariable.MaxLag; } } int n = solutions.Length; List variableNames = new List(); foreach (StringValue variableName in ProblemData.InputVariables) { variableNames.Add(variableName.Value); } variableNames.Add(ProblemData.TargetVariable.Value); // collect genetic information item lists and store them also in dictionaries IList[] geneticInformationItemsLists = new List[n]; IDictionary>[] geneticInformationItemsListsDictionaries = new IDictionary>[n]; for (int i = 0; i < n; i++) { geneticInformationItemsLists[i] = GeneticInformationItem.GetGeneticInformationItems(solutions[i].Root, variableNames, MinimumLevelDelta, MaximumLevelDelta); geneticInformationItemsListsDictionaries[i] = GeneticInformationItem.GetDictionary(geneticInformationItemsLists[i]); } // calculate solution similarities double[,] similarities = new double[n, n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) similarities[i, j] = 1; else { IList solution1GeneticItems = geneticInformationItemsLists[i]; IDictionary> solution2GeneticItemsDictionary = GeneticInformationItem.CopyDictionary(geneticInformationItemsListsDictionaries[j]); double similarity = 0; for (int k = 0; k < solution1GeneticItems.Count; k++) { double bestPendantSimilarity = 0; GeneticInformationItem item = solution1GeneticItems[k]; GeneticInformationItem bestPendant = null; IList geneticInformationItemsList = null; string key = GeneticInformationItem.GetKey(item); if (solution2GeneticItemsDictionary.ContainsKey(key)) { geneticInformationItemsList = solution2GeneticItemsDictionary[GeneticInformationItem.GetKey(item)]; bestPendant = GeneticInformationItem.FindBestPendant(item, geneticInformationItemsList, constantMinimumValue, constantMaximumValue, variableWeightSigma, MaximumExpressionDepth, minimumTimeOffset, maximumTimeOffset, LevelDifferenceCoefficient, AncestorIndexCoefficient, ConstantValueCoefficient, VariableWeightCoefficient, TimeOffsetCoefficientCoefficient, VariableIndexCoefficient, AdditiveSimilarityCalculation, out bestPendantSimilarity); } if (bestPendant != null) { similarity += bestPendantSimilarity; if (PreventMultipleComparisonContribution) geneticInformationItemsList.Remove(bestPendant); } } similarities[i, j] = similarity / solution1GeneticItems.Count; } } } return similarities; } } }