Free cookie consent management tool by TermsFeed Policy Generator

source: addons/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushProblemBase.cs @ 15945

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

#2665 Testet Problems, Testet error functions, Small fixes, Created HL files

File size: 6.1 KB
Line 
1using System;
2using System.Linq;
3
4namespace HeuristicLab.Problems.ProgramSynthesis.Push.Problem {
5  using HeuristicLab.Common;
6  using HeuristicLab.Core;
7  using HeuristicLab.Data;
8  using HeuristicLab.Optimization;
9  using HeuristicLab.Parameters;
10  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
11  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
12  using HeuristicLab.Problems.ProgramSynthesis.Push.Evaluator;
13  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
14  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
15  using HeuristicLab.Problems.ProgramSynthesis.Push.ObjectPools.Random;
16  using HeuristicLab.Problems.ProgramSynthesis.Push.Solution;
17  using HeuristicLab.Random;
18
19  [StorableClass]
20  public abstract class PushProblemBase<T> : SingleObjectiveBasicProblem<T> where T : class, IEncoding {
21    [Storable]
22    public readonly PushConfiguration Config;
23
24    protected PushInterpreterPool Pool;
25    protected readonly SeededRandomPool RandomPool = new SeededRandomPool();
26
27    [Storable]
28    protected readonly IPushEvaluator PushEvaluator;
29
30    private const string BEST_TRAINING_SOLUTION_RESULT_NAME = "Best Solution";
31    private const string TEST_QUALITY_RESULT_NAME = "Test Quality";
32    private const string PUSH_CONFIGURATION_PARAMETER_NAME = "PushConfiguration";
33
34    public const string CasesScopeParameterName = "CaseQualities";
35    public const string CaseQualitiesScopeParameterName = "CaseQualities";
36    public const string SeedScopeParameterName = "Seed";
37
38    protected PushProblemBase(IPushEvaluator evaluator) {
39      Config = new PushConfiguration();
40      PushEvaluator = evaluator;
41
42      InitData();
43      InitParameters();
44    }
45
46    [StorableConstructor]
47    protected PushProblemBase(bool deserializing)
48      : base(deserializing) {
49    }
50
51    protected PushProblemBase(PushProblemBase<T> original, Cloner cloner)
52      : base(original, cloner) {
53      Config = cloner.Clone(original.Config);
54      PushEvaluator = cloner.Clone(original.PushEvaluator);
55
56      InitData();
57    }
58
59    [StorableHook(HookType.AfterDeserialization)]
60    // ReSharper disable once UnusedMember.Local
61    private void AfterDeserialization() {
62      InitData();
63      InitParameters();
64    }
65
66    private void InitData() {
67      Pool = new PushInterpreterPool(Environment.ProcessorCount * 2, 4096, 1024, Config);
68    }
69
70    private void InitParameters() {
71      foreach (var paramater in Config.Parameters) {
72        if (!Parameters.ContainsKey(paramater.Name)) {
73          Parameters.Add(paramater);
74        }
75      }
76
77      if (!Parameters.ContainsKey(PUSH_CONFIGURATION_PARAMETER_NAME))
78        Parameters.Add(new ValueParameter<IReadOnlyPushConfiguration>(PUSH_CONFIGURATION_PARAMETER_NAME, Config) {
79          Hidden = true
80        });
81
82      if (!Parameters.ContainsKey(CasesScopeParameterName))
83        Parameters.Add(new LookupParameter<BoolArray>(CasesScopeParameterName, "The training cases that have been successfully executed."));
84
85      if (!Parameters.ContainsKey(CaseQualitiesScopeParameterName))
86        Parameters.Add(new LookupParameter<DoubleArray>(CaseQualitiesScopeParameterName, "The quality of every single training case for each individual"));
87    }
88
89    public override bool Maximization { get { return false; } }
90
91    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
92      var bestQuality = Maximization ? qualities.Max() : qualities.Min();
93      var bestIdx = Array.IndexOf(qualities, bestQuality);
94      var bestIndividual = individuals[bestIdx];
95      var seed = (IntValue)bestIndividual[SeedScopeParameterName];
96      var program = MapIndividual(bestIndividual);
97
98      var rand = new FastRandom(seed.Value);
99      var isIndividualBetter = AnalyzeBestTrainingSolution(program, bestQuality, results, rand);
100
101      if (isIndividualBetter) {
102        rand.Reset(seed.Value);
103        AnalyzeBestTestSolution(program, results, rand);
104      }
105    }
106
107    protected void AnalyzeBestTestSolution(PushProgram program, ResultCollection results, IRandom random) {
108      var testResult = PushEvaluator.EvaluateTest(Pool, program, random);
109
110      if (!results.ContainsKey(TEST_QUALITY_RESULT_NAME)) {
111        results.Add(new Result(TEST_QUALITY_RESULT_NAME, new DoubleValue(testResult.AvgQuality)));
112      } else {
113        ((DoubleValue)results[TEST_QUALITY_RESULT_NAME].Value).Value = testResult.AvgQuality;
114      }
115    }
116
117    protected bool AnalyzeBestTrainingSolution(PushProgram program, double bestQuality, ResultCollection results, IRandom random) {
118      var solution = CreatePushSolution(
119            program,
120            bestQuality,
121            random, // is already cloned
122            (IReadOnlyPushConfiguration)Config.Clone());
123
124      if (!results.ContainsKey(BEST_TRAINING_SOLUTION_RESULT_NAME)) {
125        results.Add(new Result(BEST_TRAINING_SOLUTION_RESULT_NAME, solution));
126        return true;
127      }
128
129      var currentBestQuality = ((PushSolution)results[BEST_TRAINING_SOLUTION_RESULT_NAME].Value).Quality;
130
131      if ((!Maximization && currentBestQuality > bestQuality) ||
132           (Maximization && currentBestQuality < bestQuality)) {
133        results[BEST_TRAINING_SOLUTION_RESULT_NAME].Value = solution;
134        return true;
135      }
136
137      return false;
138    }
139
140    public override double Evaluate(Individual individual, IRandom random) {
141      var program = MapIndividual(individual);
142      var seed = random.Next();
143      var rand = new FastRandom(seed);
144      var result = PushEvaluator.EvaluateTraining(Pool, program, rand);
145
146      individual[CaseQualitiesScopeParameterName] = new DoubleArray(result.ExampleQualities);
147      individual[SeedScopeParameterName] = new IntValue(seed);
148
149      return result.AvgQuality;
150    }
151
152    protected abstract PushProgram MapIndividual(Individual individual);
153
154    protected abstract PushSolution CreatePushSolution(
155      PushProgram program,
156      double bestQuality,
157      IRandom random,
158      IReadOnlyPushConfiguration config);
159  }
160}
Note: See TracBrowser for help on using the repository browser.