#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;
}
}
}