Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionSymbolFrequencyAnalyzer.cs @ 5809

Last change on this file since 5809 was 5809, checked in by mkommend, 13 years ago

#1418: Reintegrated branch into trunk.

File size: 5.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Collections.Generic;
23using System.Linq;
24using HeuristicLab.Analysis;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Operators;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
33  /// <summary>
34  /// An operator that tracks the frequencies of distinct symbols in symbolic expression trees.
35  /// </summary>
36  [Item("SymbolicExpressionSymbolFrequencyAnalyzer", "An operator that tracks frequencies of symbols in symbolic expression trees.")]
37  [StorableClass]
38  public class SymbolicExpressionSymbolFrequencyAnalyzer : SingleSuccessorOperator, ISymbolicExpressionTreeAnalyzer {
39    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
40    private const string ResultsParameterName = "Results";
41    private const string SymbolFrequenciesParameterName = "SymbolFrequencies";
42
43    #region parameter properties
44    public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
45      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
46    }
47    public ILookupParameter<DataTable> SymbolFrequenciesParameter {
48      get { return (ILookupParameter<DataTable>)Parameters[SymbolFrequenciesParameterName]; }
49    }
50    public ILookupParameter<ResultCollection> ResultsParameter {
51      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
52    }
53    #endregion
54    #region properties
55    public DataTable SymbolFrequencies {
56      get { return SymbolFrequenciesParameter.ActualValue; }
57      set { SymbolFrequenciesParameter.ActualValue = value; }
58    }
59    #endregion
60
61    [StorableConstructor]
62    protected SymbolicExpressionSymbolFrequencyAnalyzer(bool deserializing) : base(deserializing) { }
63    protected SymbolicExpressionSymbolFrequencyAnalyzer(SymbolicExpressionSymbolFrequencyAnalyzer original, Cloner cloner) : base(original, cloner) { }
64    public SymbolicExpressionSymbolFrequencyAnalyzer()
65      : base() {
66      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
67      Parameters.Add(new ValueLookupParameter<DataTable>(SymbolFrequenciesParameterName, "The data table to store the symbol frequencies."));
68      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The result collection where the symbol frequencies should be stored."));
69    }
70    public override IDeepCloneable Clone(Cloner cloner) {
71      return new SymbolicExpressionSymbolFrequencyAnalyzer(this, cloner);
72    }
73
74    public override IOperation Apply() {
75      ItemArray<ISymbolicExpressionTree> expressions = SymbolicExpressionTreeParameter.ActualValue;
76      ResultCollection results = ResultsParameter.ActualValue;
77
78      if (SymbolFrequencies == null) {
79        SymbolFrequencies = new DataTable("Symbol frequencies", "Relative frequency of symbols aggregated over the whole population.");
80        SymbolFrequencies.VisualProperties.YAxisTitle = "Relative Symbol Frequency";
81        results.Add(new Result("Symbol frequencies", SymbolFrequencies));
82      }
83
84      // all rows must have the same number of values so we can just take the first
85      int numberOfValues = SymbolFrequencies.Rows.Select(r => r.Values.Count).DefaultIfEmpty().First();
86
87      foreach (var pair in SymbolicExpressionSymbolFrequencyAnalyzer.CalculateSymbolFrequencies(expressions)) {
88        if (!SymbolFrequencies.Rows.ContainsKey(pair.Key)) {
89          // initialize a new row for the symbol and pad with zeros
90          DataRow row = new DataRow(pair.Key, "", Enumerable.Repeat(0.0, numberOfValues));
91          row.VisualProperties.StartIndexZero = true;
92          SymbolFrequencies.Rows.Add(row);
93        }
94        SymbolFrequencies.Rows[pair.Key].Values.Add(pair.Value);
95      }
96
97      // add a zero for each data row that was not modified in the previous loop
98      foreach (var row in SymbolFrequencies.Rows.Where(r => r.Values.Count != numberOfValues + 1))
99        row.Values.Add(0.0);
100
101      return base.Apply();
102    }
103
104    public static IEnumerable<KeyValuePair<string, double>> CalculateSymbolFrequencies(IEnumerable<ISymbolicExpressionTree> trees) {
105      Dictionary<string, double> symbolFrequencies = new Dictionary<string, double>();
106      int totalNumberOfSymbols = 0;
107
108      foreach (var tree in trees) {
109        foreach (var node in tree.IterateNodesPrefix()) {
110          if (symbolFrequencies.ContainsKey(node.Symbol.Name)) symbolFrequencies[node.Symbol.Name] += 1;
111          else symbolFrequencies.Add(node.Symbol.Name, 1);
112          totalNumberOfSymbols++;
113        }
114      }
115
116      foreach (var pair in symbolFrequencies)
117        yield return new KeyValuePair<string, double>(pair.Key, pair.Value / totalNumberOfSymbols);
118    }
119  }
120}
Note: See TracBrowser for help on using the repository browser.