Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushProblem.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: 8.0 KB
Line 
1using System;
2
3namespace HeuristicLab.Problems.ProgramSynthesis.Push.Problem {
4  using System.Linq;
5
6  using Common;
7  using Configuration;
8  using Core;
9  using HeuristicLab.Data;
10  using HeuristicLab.Encodings.IntegerVectorEncoding;
11  using HeuristicLab.Problems.ProgramSynthesis.Push.Analyzer;
12  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
13  using HeuristicLab.Problems.ProgramSynthesis.Push.Individual;
14  using HeuristicLab.Problems.ProgramSynthesis.Push.ObjectPools.Random;
15  using HeuristicLab.Problems.ProgramSynthesis.Push.SolutionCreator;
16
17  using Interpreter;
18  using Optimization;
19  using Parameters;
20  using Persistence.Default.CompositeSerializers.Storable;
21
22  [StorableClass]
23  public abstract class PushProblem : SingleObjectiveBasicProblem<IntegerVectorEncoding> {
24    [Storable]
25    protected readonly PushConfigurationParameterCollection Config;
26
27    protected PushInterpreterPool Pool;
28    protected readonly SeededRandomPool RandomPool = new SeededRandomPool();
29
30    [Storable]
31    protected readonly IPushEvaluator PushEvaluator;
32
33    private const string BEST_TRAINING_SOLUTION_RESULT_NAME = "Best Solution";
34    private const string TEST_QUALITY_RESULT_NAME = "Test Quality";
35
36    protected PushProblem(IPushEvaluator evaluator) {
37      Config = new PushConfigurationParameterCollection();
38      PushEvaluator = evaluator;
39
40      InitData();
41      InitEvents();
42      InitParameters();
43      InitEncoding();
44      InitOperators();
45    }
46
47    [StorableConstructor]
48    protected PushProblem(bool deserializing)
49      : base(deserializing) {
50    }
51
52    protected PushProblem(PushProblem original, Cloner cloner)
53      : base(original, cloner) {
54      Config = cloner.Clone(original.Config);
55      PushEvaluator = cloner.Clone(original.PushEvaluator);
56
57      InitData();
58      InitEvents();
59    }
60
61    [StorableHook(HookType.AfterDeserialization)]
62    // ReSharper disable once UnusedMember.Local
63    private void AfterDeserialization() {
64      InitData();
65      InitEvents();
66      InitParameters();
67    }
68
69    private void InitData() {
70      Pool = new PushInterpreterPool(Environment.ProcessorCount * 2, 4096, 1024, Config);
71    }
72
73    private void InitEvents() {
74      Config.EnabledExpressionsChanged += EnabledExpressionsChanged;
75      Reset += PushProblemReset;
76    }
77
78    private void EnabledExpressionsChanged(object sender, EnabledExpressionsChangedEventArgs e) {
79      Encoding.Bounds[0, 1] = Config.EnabledExpressions.Count;
80      Encoding.BoundsParameter.Value[0, 1] = Config.EnabledExpressions.Count;
81    }
82
83    private const string PUSH_CONFIGURATION_PARAMETER_NAME = "PushConfiguration";
84
85    public const string CasesScopeParameterName = "CaseQualities";
86    public const string CaseQualitiesScopeParameterName = "CaseQualities";
87
88    private void InitParameters() {
89      foreach (var paramater in Config.Parameters) {
90        if (!Parameters.ContainsKey(paramater.Name)) {
91          Parameters.Add(paramater);
92        }
93      }
94
95      if (!Parameters.ContainsKey(PUSH_CONFIGURATION_PARAMETER_NAME))
96        Parameters.Add(new ValueParameter<IReadOnlyPushConfiguration>(PUSH_CONFIGURATION_PARAMETER_NAME, Config) {
97          Hidden = true
98        });
99
100      if (!Parameters.ContainsKey(CasesScopeParameterName))
101        Parameters.Add(new LookupParameter<BoolArray>(CasesScopeParameterName, "The training cases that have been successfully executed."));
102
103      if (!Parameters.ContainsKey(CaseQualitiesScopeParameterName))
104        Parameters.Add(new LookupParameter<DoubleArray>(CaseQualitiesScopeParameterName, "The quality of every single training case for each individual"));
105    }
106
107    private void PushProblemReset(object sender, EventArgs e) {
108      // clear pools and free reserved memory
109      Pool.Clear();
110      IndividualMapper.Clear();
111      RandomPool.Clear();
112
113      // reset seed
114      Config.Seed = 0;
115    }
116
117    protected override void OnReset() {
118      base.OnReset();
119
120      // clear pools and free reserved memory
121      Pool.Clear();
122      IndividualMapper.Clear();
123      RandomPool.Clear();
124      Config.Seed = 0;
125    }
126
127    private void InitEncoding() {
128      Encoding.Bounds[0, 0] = 0;
129      Encoding.Bounds[0, 1] = Config.EnabledExpressions.Count;
130      Encoding.Length = Config.MaxPointsInProgram;
131    }
132
133    private void InitOperators() {
134
135      var solutionCreator = Operators.OfType<PushSolutionCreator>().FirstOrDefault();
136
137      if (solutionCreator == null) {
138        solutionCreator = new PushSolutionCreator();
139        Operators.Add(solutionCreator);
140      }
141
142      solutionCreator.ErcOptions = Config.ErcOptions;
143
144      if (!Operators.OfType<PushExpressionFrequencyAnalyzer>().Any()) {
145        Operators.Add(new PushExpressionFrequencyAnalyzer());
146      }
147
148      SolutionCreator = solutionCreator;
149    }
150
151    public override bool Maximization { get { return false; } }
152
153    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
154      IndividualMapper.Reset();
155
156      var bestQuality = Maximization ? qualities.Max() : qualities.Min();
157      var bestIdx = Array.IndexOf(qualities, bestQuality);
158      var vector = individuals[bestIdx].IntegerVector();
159
160      var rand = RandomPool.ResetAndAllocate();
161      var program = (PushProgram)vector.ToPushProgram(Config, rand).Clone();
162      RandomPool.Free(rand);
163
164      rand = RandomPool.ResetAndAllocate();
165      var isIndividualBetter = AnalyzeBestTrainingSolution(program, bestQuality, results, rand);
166      RandomPool.Free(rand);
167
168      if (isIndividualBetter) {
169        rand = RandomPool.ResetAndAllocate();
170        AnalyzeBestTestSolution(program, results, rand);
171        RandomPool.Free(rand);
172      }
173    }
174
175    private void AnalyzeBestTestSolution(PushProgram program, ResultCollection results, IRandom random) {
176      var testResult = PushEvaluator.EvaluateTraining(Pool, program, random);
177
178      if (!results.ContainsKey(TEST_QUALITY_RESULT_NAME)) {
179        results.Add(new Result(TEST_QUALITY_RESULT_NAME, new DoubleValue(testResult.AvgQuality)));
180      } else {
181        ((DoubleValue)results[TEST_QUALITY_RESULT_NAME].Value).Value = testResult.AvgQuality;
182      }
183    }
184
185    private bool AnalyzeBestTrainingSolution(PushProgram program, double bestQuality, ResultCollection results, IRandom random) {
186      if (!results.ContainsKey(BEST_TRAINING_SOLUTION_RESULT_NAME)) {
187        var solution = CreatePushSolution(
188            program,
189            bestQuality,
190            (IRandom)random.Clone(),
191            (IReadOnlyPushConfiguration)Config.Clone());
192
193        results.Add(new Result(BEST_TRAINING_SOLUTION_RESULT_NAME, solution));
194        return true;
195      }
196
197      var currentBestQuality = ((PushSolution)results[BEST_TRAINING_SOLUTION_RESULT_NAME].Value).Quality;
198
199      if ((!Maximization && currentBestQuality > bestQuality) ||
200           (Maximization && currentBestQuality < bestQuality)) {
201        results[BEST_TRAINING_SOLUTION_RESULT_NAME].Value = CreatePushSolution(
202            program,
203            bestQuality,
204            random,
205            Config);
206        return true;
207      }
208
209      return false;
210    }
211
212    protected abstract PushSolution CreatePushSolution(
213      PushProgram program,
214      double bestQuality,
215      IRandom random,
216      IReadOnlyPushConfiguration config);
217
218    public override double Evaluate(Individual individual, IRandom random) {
219      // init seed of random pool
220      //Interlocked.CompareExchange(ref RandomPool.Seed, random.Next(), 0);
221      //Config.Seed = RandomPool.Seed;
222
223      //var rand = RandomPool.ResetAndAllocate();
224      var program = individual.ToPushProgram(Config, random);
225      //RandomPool.Free(rand);
226
227      //rand = RandomPool.ResetAndAllocate();
228      var result = PushEvaluator.EvaluateTraining(Pool, program, random);
229      //RandomPool.Free(rand);
230
231      individual[CaseQualitiesScopeParameterName] = new DoubleArray(result.ExampleQualities);
232
233      return result.AvgQuality;
234    }
235  }
236}
Note: See TracBrowser for help on using the repository browser.