Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2895_PushGP_GenealogyAnalysis/HeuristicLab.Problems.ProgramSynthesis/Push/Analyzer/PushExpressionFrequencyAnalyzer.cs @ 16099

Last change on this file since 16099 was 15771, checked in by bburlacu, 7 years ago

#2895: Add solution skeleton for PushGP with genealogy analysis.

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