Free cookie consent management tool by TermsFeed Policy Generator

source: addons/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Analyzer/PushExpressionFrequencyAnalyzer.cs

Last change on this file was 15289, checked in by pkimmesw, 7 years ago

#2665 Fixed analyzer, fixed Plush encoding + operators, adpated print evaluation according to McPhee

File size: 7.5 KB
Line 
1namespace HeuristicLab.Problems.ProgramSynthesis.Push.Analyzer {
2  using System;
3  using System.Collections.Generic;
4  using System.Linq;
5
6  using HeuristicLab.Analysis;
7  using HeuristicLab.Common;
8  using HeuristicLab.Core;
9  using HeuristicLab.Data;
10  using HeuristicLab.Encodings.IntegerVectorEncoding;
11  using HeuristicLab.Operators;
12  using HeuristicLab.Optimization;
13  using HeuristicLab.Parameters;
14  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
15  using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
16  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
17  using HeuristicLab.Problems.ProgramSynthesis.Push.Encoding;
18  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
19  using HeuristicLab.Problems.ProgramSynthesis.Push.Individual;
20
21  /// <summary>
22  /// An operater that tracks the frequencies of distinct push expressions in a push solution
23  /// </summary>
24  [Item("PushExpressionFrequencyAnalyzer", "An operater that tracks the frequencies of distinct push expressions in a push solution")]
25  [StorableClass]
26  public class PushExpressionFrequencyAnalyzer : SingleSuccessorOperator, IPushExpressionAnalyzer {
27
28    private const string PUSH_CONFIGURATION_PARAMETER_NAME = "PushConfiguration";
29    private const string INTEGER_VECTOR_PARAMETER_NAME = "IntegerVector";
30    private const string RESULTS_PARAMETER_NAME = "Results";
31    private const string EXPRESSION_FREQUENCIES_PARAMETER_NAME = "InstructionFrequencies";
32    private const string AGGREGATE_STACK_TYPES_PARAMETER_NAME = "Aggregate stack types";
33    private const string IN_EXPRESSION_GROUP_NAME = "IN";
34    private const string RANDOM_PARAMETER_NAME = "Random";
35    private const string RESULT_PARAMETER_NAME = "Instruction frequencies";
36    private const string RESULT_PARAMETER_DESCRIPTION = "Relative frequency of instructions aggregated over the whole population.";
37    private const string Y_AXIS_TITLE = "Relative Instruction Frequency";
38
39    public PushExpressionFrequencyAnalyzer() {
40      Parameters.Add(new LookupParameter<IReadOnlyPushConfiguration>(PUSH_CONFIGURATION_PARAMETER_NAME, "The current specified push configuration."));
41      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>(INTEGER_VECTOR_PARAMETER_NAME, "The integer vectors to analyze."));
42      Parameters.Add(new ScopeTreeLookupParameter<PlushVector>("Plush", "The plush vectors to analyze."));
43      Parameters.Add(new LookupParameter<DataTable>(EXPRESSION_FREQUENCIES_PARAMETER_NAME, "The data table to store the instruction frequencies."));
44      Parameters.Add(new LookupParameter<ResultCollection>(RESULTS_PARAMETER_NAME, "The result collection where the symbol frequencies should be stored."));
45
46      Parameters.Add(new FixedValueParameter<BoolValue>(AGGREGATE_STACK_TYPES_PARAMETER_NAME, "Determines if expressions should be aggregated by their primary stack type.", new BoolValue(true)));
47    }
48
49    [StorableConstructor]
50    public PushExpressionFrequencyAnalyzer(bool deserializing) : base(deserializing) { }
51
52    public PushExpressionFrequencyAnalyzer(PushExpressionFrequencyAnalyzer origin, Cloner cloner) : base(origin, cloner) { }
53
54    public override IDeepCloneable Clone(Cloner cloner) {
55      return new PushExpressionFrequencyAnalyzer(this, cloner);
56    }
57
58    public bool EnabledByDefault { get { return true; } }
59
60    public ILookupParameter<IReadOnlyPushConfiguration> PushConfigurationParameter
61    {
62      get { return (ILookupParameter<IReadOnlyPushConfiguration>)Parameters[PUSH_CONFIGURATION_PARAMETER_NAME]; }
63    }
64
65    public IScopeTreeLookupParameter<PlushVector> PlushVectorParameter
66    {
67      get { return (IScopeTreeLookupParameter<PlushVector>)Parameters["Plush"]; }
68    }
69
70    public IScopeTreeLookupParameter<IntegerVector> IntegerVectorParameter
71    {
72      get { return (IScopeTreeLookupParameter<IntegerVector>)Parameters[INTEGER_VECTOR_PARAMETER_NAME]; }
73    }
74
75    public ILookupParameter<DataTable> ExpressionFrequenciesParameter
76    {
77      get { return (ILookupParameter<DataTable>)Parameters[EXPRESSION_FREQUENCIES_PARAMETER_NAME]; }
78    }
79
80    public ILookupParameter<IRandom> RandomParameter
81    {
82      get { return (ILookupParameter<IRandom>)Parameters[RANDOM_PARAMETER_NAME]; }
83    }
84
85    public ILookupParameter<ResultCollection> ResultsParameter
86    {
87      get { return (ILookupParameter<ResultCollection>)Parameters[RESULTS_PARAMETER_NAME]; }
88    }
89
90    public IValueParameter<BoolValue> AggregateStackTypesParameter
91    {
92      get { return (IValueParameter<BoolValue>)Parameters[AGGREGATE_STACK_TYPES_PARAMETER_NAME]; }
93    }
94
95    public bool AggregateStackTypes
96    {
97      get { return AggregateStackTypesParameter.Value.Value; }
98      set { AggregateStackTypesParameter.Value.Value = value; }
99    }
100
101    public override IOperation Apply() {
102      var config = PushConfigurationParameter.ActualValue;
103
104      IReadOnlyList<PushProgram> pushPrograms = null;
105
106      if (IntegerVectorParameter.ActualValue.Length > 0) {
107        pushPrograms = IntegerVectorParameter.ActualValue.Select(iv => iv.ToPushProgram(config)).ToList();
108      } else if (PlushVectorParameter.ActualValue.Length > 0) {
109        pushPrograms = PlushVectorParameter.ActualValue.Select(pv => pv.PushProgram).ToList();
110      } else {
111        // nothing to do
112        return base.Apply();
113      }
114
115      var results = ResultsParameter.ActualValue;
116      var frequencies = ExpressionFrequenciesParameter.ActualValue;
117
118      if (frequencies == null) {
119        frequencies = new DataTable(
120          RESULT_PARAMETER_NAME,
121          RESULT_PARAMETER_DESCRIPTION) {
122          VisualProperties = {
123            YAxisTitle = Y_AXIS_TITLE
124          }
125        };
126
127        ExpressionFrequenciesParameter.ActualValue = frequencies;
128        results.Add(new Result(RESULT_PARAMETER_NAME, frequencies));
129      }
130
131      var allExpressions = pushPrograms
132        .SelectMany(p => p.DepthLast())
133        .Select(e => new {
134          Expression = e,
135          Attribute = ExpressionTable.TypeToAttributeTable[e.GetType()]
136        });
137
138      var expressionFrequencies = allExpressions
139        .GroupBy(x => GetGroupName(x.Attribute, AggregateStackTypes))
140        .ToDictionary(
141          group => group.Key,
142          group => group.Count());
143
144      var totalNumberOfExpressions = Math.Max(1.0, expressionFrequencies.Values.Sum());
145
146      // all rows must have the same number of values so we can just take the first
147      var numberOfValues = frequencies.Rows.Select(r => r.Values.Count).FirstOrDefault();
148
149      foreach (var pair in expressionFrequencies) {
150        if (!frequencies.Rows.ContainsKey(pair.Key)) {
151          var row = new DataRow(pair.Key, string.Empty, Enumerable.Repeat(0.0, numberOfValues)) {
152            VisualProperties = {
153              StartIndexZero = true,
154            }
155          };
156
157          frequencies.Rows.Add(row);
158        }
159
160        frequencies.Rows[pair.Key].Values.Add(Math.Round(pair.Value / totalNumberOfExpressions, 3));
161      }
162
163      // add a zero for each data row that was not modified in the previous loop
164      foreach (var row in frequencies.Rows.Where(r => r.Values.Count != numberOfValues + 1))
165        row.Values.Add(0.0);
166
167      return base.Apply();
168    }
169
170    private string GetGroupName(PushExpressionAttribute attribute, bool aggregateStackTypes) {
171      if (aggregateStackTypes) {
172        return attribute.IsInExpression
173         ? IN_EXPRESSION_GROUP_NAME
174         : attribute.StackType.ToString();
175      }
176
177      return attribute.Name;
178    }
179  }
180}
Note: See TracBrowser for help on using the repository browser.