Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisComplexityAnalyzer.cs @ 7726

Last change on this file since 7726 was 7726, checked in by gkronber, 12 years ago

#1823

  • added analyzer that calculates the complexity of symbolic data analysis trees (weighted symbols)
  • added analyzer that collects the Pareto-optimal solutions regarding complexity and accuracy
File size: 6.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Analysis;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.PluginInfrastructure;
34using HeuristicLab.PluginInfrastructure.Manager;
35
36namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
37  /// <summary>
38  /// Calculates the complexity of all trees in the population.
39  /// </summary>
40  [Item("SymbolicDataAnalysisComplexityAnalyzer", "Calculates the complexity of all trees in the population.")]
41  [StorableClass]
42  public sealed class SymbolicDataAnalysisComplexityAnalyzer : SymbolicDataAnalysisAnalyzer {
43    private const string ComplexityParameterName = "Complexity";
44    private const string WeightsParameterName = "Weights";
45
46
47    #region parameter properties
48    public IScopeTreeLookupParameter<DoubleValue> ComplexityParameter {
49      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters[ComplexityParameterName]; }
50    }
51    public IValueParameter<ItemDictionary<StringValue, DoubleValue>> WeightsParameter {
52      get { return (IValueParameter<ItemDictionary<StringValue, DoubleValue>>)Parameters[WeightsParameterName]; }
53    }
54    #endregion
55
56    [StorableConstructor]
57    private SymbolicDataAnalysisComplexityAnalyzer(bool deserializing) : base(deserializing) { }
58    private SymbolicDataAnalysisComplexityAnalyzer(SymbolicDataAnalysisComplexityAnalyzer original, Cloner cloner)
59      : base(original, cloner) {
60    }
61    public SymbolicDataAnalysisComplexityAnalyzer()
62      : base() {
63      var defaultWeights = new Dictionary<string, double>()
64                             {
65                                { "StartSymbol", 0.0},
66                                { "ProgramRootSymbol", 0.0},
67                                { "Addition", 1.0 },
68                                { "AiryA", 10.0 },
69                                { "AiryB", 10.0 },
70                                { "And", 2.0 },
71                                { "Average", 2.0 },
72                                { "Bessel", 10.0 },
73                                { "Constant", 1.0 },
74                                { "Cosine", 5.0 },
75                                { "CosineIntegral", 10.0 },
76                                { "Dawson", 10.0 },
77                                { "Derivative", 5.0 },
78                                { "Division", 2.0 },
79                                { "Erf", 10.0 },
80                                { "Exponential", 5.0 },
81                                { "ExponentialIntegralEi", 10.0 },
82                                { "FresnelCosineIntegral", 10.0 },
83                                { "FresnelSineIntegral", 10.0 },
84                                { "Gamma", 10.0 },
85                                { "GreaterThan", 2.0 },
86                                { "HyperbolicCosineIntegral", 10.0 },
87                                { "HyperbolicSineIntegral", 10.0 },
88                                { "IfThenElse", 3.0 },
89                                { "Integral", 5.0},
90                                { "LaggedVariable", 2.0 },
91                                { "LessThan", 2.0 },
92                                { "Logarithm", 5.0 },
93                                { "Multiplication", 2.0 },
94                                { "Norm", 10.0 },
95                                { "Not", 2.0 },
96                                { "Or", 1.0 },
97                                { "Power", 5.0 },
98                                { "Psi", 10.0 },
99                                { "Root", 5.0 },
100                                { "Sine", 5.0 },
101                                { "SineIntegral", 10.0 },
102                                { "Square", 2.0 },
103                                { "SquareRoot", 2.0 },
104                                { "Subtraction", 1.0 },
105                                { "Tangent", 3.0 },
106                                { "TimeLag", 3.0 },
107                                { "Variable", 1.0 },
108                                { "Variable Condition", 5.0 },
109                             };
110
111      var defaultWeightsTable = new ItemDictionary<StringValue, DoubleValue>();
112      foreach (var p in defaultWeights) {
113        defaultWeightsTable.Add(new StringValue(p.Key), new DoubleValue(p.Value));
114      }
115      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(ComplexityParameterName, "The complexity of the tree."));
116      Parameters.Add(new ValueParameter<ItemDictionary<StringValue, DoubleValue>>(WeightsParameterName, "A table with complexity weights for each symbol.", defaultWeightsTable));
117    }
118
119    public override IDeepCloneable Clone(Cloner cloner) {
120      return new SymbolicDataAnalysisComplexityAnalyzer(this, cloner);
121    }
122
123    public override IOperation Apply() {
124      ItemArray<ISymbolicExpressionTree> expressions = SymbolicExpressionTreeParameter.ActualValue;
125      var weightsTable = WeightsParameter.Value;
126      var weights = new Dictionary<string, double>();
127      foreach (var p in weightsTable)
128        weights.Add(p.Key.Value, p.Value.Value);
129      var complexities = from t in expressions
130                         select CalculateComplexity(t, weights);
131      ComplexityParameter.ActualValue = new ItemArray<DoubleValue>(complexities.Select(x => new DoubleValue(x)).ToArray());
132      return base.Apply();
133    }
134
135    private double CalculateComplexity(ISymbolicExpressionTree t, Dictionary<string, double> weights) {
136      double c = 0.0;
137      foreach (var n in t.Root.IterateNodesPrefix()) {
138        if (!weights.ContainsKey(n.Symbol.Name)) throw new ArgumentException("Weight for symbol " + n.Symbol.Name + " is not defined.");
139        c += weights[n.Symbol.Name];
140      }
141      return c;
142    }
143  }
144}
Note: See TracBrowser for help on using the repository browser.