Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Analyzer/PushExpressionFrequencyAnalyzer.cs @ 15273

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

#2665 Started Plush Encoding, Added Zero Error Individual Count Analyzer

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