Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2988_ModelsOfModels2/HeuristicLab.Algorithms.EMM/EMMAlgorithm/EMMBaseAlgorithm.cs @ 18242

Last change on this file since 18242 was 17134, checked in by msemenki, 5 years ago

#2988:

  1. The file system was changed, folders was added and part of files was transferred in these folders.
  2. HelpFunctions class was divided on 2 parts: HelpFuctions for common purposes static functions and SelfConfiguration that include functions for self-configuration mechanism realization (is used in EMMSucsessMap).
  3. Parts of self-configuration mechanism was transferred from EMMSucsessMap.cs to SelfConfiguration.cs. Now EMMSucsessMap used SelfConfiguration like one of data member. Other parts of project was adopted for this changing.
  4. FileComunication class was added. It include the majority of functions for printing to files or reading from files. Here were realized possibility to write and read to hl files.
  5. ModelTreeNode.cs has additional possibility - to write sub-model in string (then it is possible to write it in file).
  6. InfixExpressionFormatter.cs can work with TreeModelNode.
  7. Possibility for different map types to be readable from files was extended and cheeked.
  8. Such parameters like - ClusterNumbers, ClusterNumbersShow, NegbourNumber, NegbourType (that is used only in several maps) was transferred from EMMAlgorithm to Map Parameters. Now EMMBaseMap class inherited from ParameterizedNamedItem (not from Item). And EMMIslandMap and EMMNetworkMap contains their parameters (constructors was modified). CreationMap calls functions were simplified.
  9. Functions for different distance metric calculation was added. Now, it is possible to calculate different types of distances between models (with different random values of constants).
  10. DistanceParametr was added. Now maps can be created according different types of distance calculations.
  11. The class EMMClustering has new name KMeansClusterizationAlgorithm. On KMeansClusterizationAlgorithm bug with bloating of centroids list was fixed. Algorithm was adopted for working with different type of distance metric and get maximum number of iterations.
  12. Possibilities for constants optimization in sub-models an whole tree was added. EMMAlgorithm get new function for evaluation of individuals (and some additional technical stuff for that). Function for trees with model in usual tree transformation and back was added.
  13. EMMAlgorithm was divided on 2 parts:
  • EMMAlgorithm, that contain evolutionary algorithm working with sub-models, and use ready to use maps;
  • ModelSetPreparation, that contain distance calculation, model set simplification and map creation.
File size: 21.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using HEAL.Attic;
23using HeuristicLab.Algorithms.DataAnalysis;
24using HeuristicLab.Analysis;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.PluginInfrastructure;
32using HeuristicLab.Problems.DataAnalysis;
33using HeuristicLab.Problems.DataAnalysis.Symbolic;
34using HeuristicLab.Random;
35using System;
36using System.Collections.Generic;
37using System.IO;
38using System.Linq;
39using CancellationToken = System.Threading.CancellationToken;
40using ExecutionContext = HeuristicLab.Core.ExecutionContext;
41
42namespace HeuristicLab.Algorithms.EvolvmentModelsOfModels {
43  [Item("EMMAlgorithmBase", "Base class for all EMM algorithm variants.")]
44  [StorableType("A56A396B-965A-4ADE-8A2B-AE3A45F9C239")]
45  public abstract class EvolvmentModelsOfModelsAlgorithmBase : FixedDataAnalysisAlgorithm<ISymbolicDataAnalysisSingleObjectiveProblem> {
46    #region data members
47    [Storable]
48    protected IList<IEMMSolution> Solutions;
49    [Storable]
50    protected List<IEMMSolution> Population;
51    [Storable]
52    protected int EvaluatedSolutions;
53    [Storable]
54    protected ExecutionContext executionContext;
55    [Storable]
56    protected IScope globalScope;
57    [Storable]
58    protected ExecutionState previousExecutionState;
59    [Storable]
60    protected IEnumerable<ISymbolicExpressionTree> trees;
61
62    [Storable]
63    protected ExecutionState currentExecutionState;
64    #endregion
65
66    #region parameters
67    private const string SeedParameterName = "Seed";
68    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
69    private const string PopulationSizeParameterName = "PopulationSize";
70    private const string SelectorParameterName = "Selector";
71    private const string GroupSizeParameterName = "GroupSize";
72    private const string CrossoverProbabilityParameterName = "CrossoverProbability";
73    private const string CrossoverParameterName = "Crossover";
74    private const string MutationProbabilityParameterName = "MutationProbability";
75    private const string MutatorParameterName = "Mutator";
76    private const string MaximumEvaluatedSolutionsParameterName = "MaximumEvaluatedSolutions";
77    private const string RandomParameterName = "Random";
78    private const string AnalyzerParameterName = "Analyzer";
79    private const string InputFileParameterName = "InputFile";
80    private const string AlgorithmImplementationTypeParameterName = "AlgorithmImplementationType";
81    private const string DistanceTypeParameterName = "DistanceType";
82    private const string MapParameterName = "Map";
83    public IValueParameter<MultiAnalyzer> AnalyzerParameter {
84      get { return (ValueParameter<MultiAnalyzer>)Parameters[AnalyzerParameterName]; }
85    }
86    public IFixedValueParameter<IntValue> SeedParameter {
87      get { return (IFixedValueParameter<IntValue>)Parameters[SeedParameterName]; }
88    }
89    public IConstrainedValueParameter<StringValue> AlgorithmImplementationTypeParameter {
90      get { return (IConstrainedValueParameter<StringValue>)Parameters[AlgorithmImplementationTypeParameterName]; }
91    }
92    public IConstrainedValueParameter<StringValue> DistanceTypeParameter {
93      get { return (IConstrainedValueParameter<StringValue>)Parameters[DistanceTypeParameterName]; }
94    }
95    public IConstrainedValueParameter<EMMMapBase<ISymbolicExpressionTree>> MapParameter {
96      get { return (IConstrainedValueParameter<EMMMapBase<ISymbolicExpressionTree>>)Parameters[MapParameterName]; }
97    }
98
99    public IFixedValueParameter<StringValue> InputFileParameter {
100      get { return (IFixedValueParameter<StringValue>)Parameters[InputFileParameterName]; }
101    }
102    public IFixedValueParameter<BoolValue> SetSeedRandomlyParameter {
103      get { return (IFixedValueParameter<BoolValue>)Parameters[SetSeedRandomlyParameterName]; }
104    }
105    private IValueParameter<IntValue> PopulationSizeParameter {
106      get { return (IValueParameter<IntValue>)Parameters[PopulationSizeParameterName]; }
107    }
108    public IValueParameter<PercentValue> CrossoverProbabilityParameter {
109      get { return (IValueParameter<PercentValue>)Parameters[CrossoverProbabilityParameterName]; }
110    }
111    public IValueParameter<IntValue> GroupSizeParameter {
112      get { return (IValueParameter<IntValue>)Parameters[GroupSizeParameterName]; }
113    }
114    public IConstrainedValueParameter<ICrossover> CrossoverParameter {
115      get { return (IConstrainedValueParameter<ICrossover>)Parameters[CrossoverParameterName]; }
116    }
117    public IConstrainedValueParameter<ISelector> SelectorParameter {
118      get { return (IConstrainedValueParameter<ISelector>)Parameters[SelectorParameterName]; }
119    }
120    public IValueParameter<PercentValue> MutationProbabilityParameter {
121      get { return (IValueParameter<PercentValue>)Parameters[MutationProbabilityParameterName]; }
122    }
123    public IConstrainedValueParameter<IManipulator> MutatorParameter {
124      get { return (IConstrainedValueParameter<IManipulator>)Parameters[MutatorParameterName]; }
125    }
126    public IValueParameter<IntValue> MaximumEvaluatedSolutionsParameter {
127      get { return (IValueParameter<IntValue>)Parameters[MaximumEvaluatedSolutionsParameterName]; }
128    }
129    public IValueParameter<IRandom> RandomParameter {
130      get { return (IValueParameter<IRandom>)Parameters[RandomParameterName]; }
131    }
132    #endregion
133
134    #region parameter properties
135    public ValueParameter<IntValue> ElitesParameter {
136      get { return (ValueParameter<IntValue>)Parameters["Elites"]; }
137    }
138    public int Seed {
139      get { return SeedParameter.Value.Value; }
140      set { SeedParameter.Value.Value = value; }
141    }
142    public StringValue AlgorithmImplemetationType {
143      get { return AlgorithmImplementationTypeParameter.Value; }
144      set { AlgorithmImplementationTypeParameter.Value.Value = value.Value; }
145    }
146    public StringValue DistanceType {
147      get { return DistanceTypeParameter.Value; }
148      set { DistanceTypeParameter.Value.Value = value.Value; }
149    }
150    public EMMMapBase<ISymbolicExpressionTree> Map {
151      get { return MapParameter.Value; }
152      set { MapParameter.Value = value; }
153    }
154    public StringValue InputFile {
155      get { return InputFileParameter.Value; }
156      set { InputFileParameter.Value.Value = value.Value; }
157    }
158    public bool SetSeedRandomly {
159      get { return SetSeedRandomlyParameter.Value.Value; }
160      set { SetSeedRandomlyParameter.Value.Value = value; }
161    }
162    public IntValue PopulationSize {
163      get { return PopulationSizeParameter.Value; }
164      set { PopulationSizeParameter.Value = value; }
165    }
166    public PercentValue CrossoverProbability {
167      get { return CrossoverProbabilityParameter.Value; }
168      set { CrossoverProbabilityParameter.Value = value; }
169    }
170    public IntValue GroupSize {
171      get { return GroupSizeParameter.Value; }
172      set { GroupSizeParameter.Value = value; }
173    }
174    public ICrossover Crossover {
175      get { return CrossoverParameter.Value; }
176      set { CrossoverParameter.Value = value; }
177    }
178    public ISelector Selector {
179      get { return SelectorParameter.Value; }
180      set { SelectorParameter.Value = value; }
181    }
182    public PercentValue MutationProbability {
183      get { return MutationProbabilityParameter.Value; }
184      set { MutationProbabilityParameter.Value = value; }
185    }
186    public IManipulator Mutator {
187      get { return MutatorParameter.Value; }
188      set { MutatorParameter.Value = value; }
189    }
190    public MultiAnalyzer Analyzer {
191      get { return AnalyzerParameter.Value; }
192      set { AnalyzerParameter.Value = value; }
193    }
194    public IntValue MaximumEvaluatedSolutions {
195      get { return MaximumEvaluatedSolutionsParameter.Value; }
196      set { MaximumEvaluatedSolutionsParameter.Value = value; }
197    }
198    public IntValue Elites {
199      get { return ElitesParameter.Value; }
200    }
201    #endregion
202
203    #region constructors
204    public EvolvmentModelsOfModelsAlgorithmBase() {
205
206      Parameters.Add(new FixedValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
207      Parameters.Add(new FixedValueParameter<StringValue>(InputFileParameterName, "The file with set of models that will be.", new StringValue("input.txt")));
208      Parameters.Add(new ConstrainedValueParameter<StringValue>(AlgorithmImplementationTypeParameterName, "The Type of possible algorithm, implementation, choose one: OnlyMap, Full, Read."));
209      Parameters.Add(new ConstrainedValueParameter<StringValue>(DistanceTypeParameterName, "The Type of possible distance calculator for case of only distance calculation."));
210      Parameters.Add(new ConstrainedValueParameter<EMMMapBase<ISymbolicExpressionTree>>(MapParameterName, "The type of map creation algorithm. Use one from: IslandMap, NetworkMap."));
211      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
212      Parameters.Add(new ValueParameter<IntValue>(PopulationSizeParameterName, "The size of the population of Solutions.", new IntValue(100)));
213      Parameters.Add(new ConstrainedValueParameter<ISelector>(SelectorParameterName, "The operator used to select parents."));
214      Parameters.Add(new ValueParameter<PercentValue>(CrossoverProbabilityParameterName, "The probability that the crossover operator is applied.", new PercentValue(0.9)));
215      Parameters.Add(new ValueParameter<IntValue>(GroupSizeParameterName, "The GoupSize that the Selector operator is applied.", new IntValue(3)));
216      Parameters.Add(new ConstrainedValueParameter<ICrossover>(CrossoverParameterName, "The operator used to cross Solutions."));
217      Parameters.Add(new ValueParameter<PercentValue>(MutationProbabilityParameterName, "The probability that the mutation operator is applied on a solution.", new PercentValue(0.25)));
218      Parameters.Add(new ConstrainedValueParameter<IManipulator>(MutatorParameterName, "The operator used to mutate Solutions."));
219      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer()));
220      Parameters.Add(new ValueParameter<IntValue>(MaximumEvaluatedSolutionsParameterName, "The maximum number of evaluated Solutions (approximately).", new IntValue(100_000)));
221      Parameters.Add(new ValueParameter<IRandom>(RandomParameterName, new MersenneTwister()));
222      Parameters.Add(new ValueParameter<IntValue>("Elites", "The number of elite Solutions which are kept in each generation.", new IntValue(1)));
223      foreach (ISelector selector in ApplicationManager.Manager.GetInstances<ISelector>().Where(x => !(x is IMultiObjectiveSelector)).OrderBy(x => x.Name))
224        SelectorParameter.ValidValues.Add(selector);
225      ISelector proportionalSelector = SelectorParameter.ValidValues.FirstOrDefault(x => x.GetType().Name.Equals("ProportionalSelector"));
226      if (proportionalSelector != null) SelectorParameter.Value = proportionalSelector;
227      ParameterizeSelectors();
228
229      //begin hack ...
230      InputFile.ValueChanged += InputFile_ValueChanged;
231      InfixExpressionParser parser = new InfixExpressionParser();
232      trees = File.ReadAllLines(InputFileParameter.Value.Value).Select(parser.Parse).ToArray();
233      // end hack
234
235      ProblemChanged += EvolvmentModelsOfModelsAlgorithmBase_ProblemChanged;
236      MapParameterUpdate();
237
238    }
239
240    // also hack vvvvvvvvv
241    private void InputFile_ValueChanged(object sender, EventArgs e) {
242      InfixExpressionParser parser = new InfixExpressionParser();
243      trees = File.ReadAllLines(InputFileParameter.Value.Value).Select(parser.Parse);
244    }
245    // remove again ^^^^^^^^^
246
247    private void EvolvmentModelsOfModelsAlgorithmBase_ProblemChanged(object sender, EventArgs e) {
248      if (Problem != null) {
249        Problem.SymbolicExpressionTreeInterpreter = new SymbolicDataAnalysisExpressionTreeBatchInterpreter();
250      }
251    }
252    protected void MapParameterUpdate() {
253      var mapTypes = new EMMMapBase<ISymbolicExpressionTree>[]
254      {
255        new EMMIslandMap(),
256        new EMMNetworkMap(),
257        new EMMDisatanceMap(),
258        new EMMRankMap(),
259        new EMMSucsessMap (),
260        new EMMZeroMap ()
261      };
262      foreach (var t in mapTypes) {
263        MapParameter.ValidValues.Add(t);
264      }
265      var algorithmType = new StringValue[]
266        {
267          new StringValue("Full"),
268          new StringValue("Read"),
269        };
270      foreach (var t in algorithmType) {
271        AlgorithmImplementationTypeParameter.ValidValues.Add(t);
272      }
273      var distanceType = new StringValue[]
274        {
275          new StringValue("MSE"),
276          new StringValue("PearsonsRSquared"),
277          new StringValue ("Covariance"),
278          new StringValue ("MaxAbsoluteError"),
279          new StringValue ("MeanAbsoluteError"),
280          new StringValue ("Symbolic")
281        };
282      foreach (var t in distanceType) {
283        DistanceTypeParameter.ValidValues.Add(t);
284      }
285    }
286
287    protected EvolvmentModelsOfModelsAlgorithmBase(EvolvmentModelsOfModelsAlgorithmBase original, Cloner cloner) : base(original, cloner) {
288      EvaluatedSolutions = original.EvaluatedSolutions;
289      previousExecutionState = original.previousExecutionState;
290
291      if (original.Solutions != null) {
292        Solutions = original.Solutions.Select(cloner.Clone).ToArray();
293      }
294
295      if (original.Population != null) {
296        Population = original.Population.Select(cloner.Clone).ToList();
297      }
298
299      if (original.executionContext != null) {
300        executionContext = cloner.Clone(original.executionContext);
301      }
302
303      if (original.globalScope != null) {
304        globalScope = cloner.Clone(original.globalScope);
305      }
306      // hack
307      if (original.trees != null) {
308        trees = original.trees.Select(x => cloner.Clone(x)).ToArray();
309      }
310    }
311
312    [StorableConstructor]
313    protected EvolvmentModelsOfModelsAlgorithmBase(StorableConstructorFlag _) : base(_) { }
314    #endregion
315
316
317    public override void Prepare() {
318      base.Prepare();
319    }
320
321    protected override void Initialize(CancellationToken cancellationToken) {
322      base.Initialize(cancellationToken);
323    }
324
325    public override bool SupportsPause => true;
326
327    // implements random number generation from https://en.wikipedia.org/wiki/Dirichlet_distribution#Random_number_generation
328
329    public IList<IEMMSolution> GetResult(IRandom random) {
330      return Population;
331    }
332
333    #region operator wiring and events
334    private void ParameterizeStochasticOperator(IOperator op) {
335      IStochasticOperator stochasticOp = op as IStochasticOperator;
336      if (stochasticOp != null) {
337        stochasticOp.RandomParameter.ActualName = "Random";
338        stochasticOp.RandomParameter.Hidden = true;
339      }
340    }
341    private void ParameterizeSelectors() {
342      foreach (ISelector selector in SelectorParameter.ValidValues) {
343        selector.CopySelected = new BoolValue(true);
344        selector.NumberOfSelectedSubScopesParameter.Value = new IntValue(2 * (PopulationSizeParameter.Value.Value - ElitesParameter.Value.Value));
345        selector.NumberOfSelectedSubScopesParameter.Hidden = true;
346        ParameterizeStochasticOperator(selector);
347      }
348      if (Problem != null) {
349        foreach (ISingleObjectiveSelector selector in SelectorParameter.ValidValues.OfType<ISingleObjectiveSelector>()) {
350          selector.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
351          selector.MaximizationParameter.Hidden = true;
352          selector.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
353          selector.QualityParameter.Hidden = true;
354        }
355      }
356    }
357    protected void ExecuteOperation(ExecutionContext executionContext, CancellationToken cancellationToken, IOperation operation) {
358      Stack<IOperation> executionStack = new Stack<IOperation>();
359      executionStack.Push(operation);
360      while (executionStack.Count > 0) {
361        cancellationToken.ThrowIfCancellationRequested();
362        IOperation next = executionStack.Pop();
363        if (next is OperationCollection) {
364          OperationCollection coll = (OperationCollection)next;
365          for (int i = coll.Count - 1; i >= 0; i--)
366            if (coll[i] != null) executionStack.Push(coll[i]);
367        } else if (next is IAtomicOperation) {
368          IAtomicOperation op = (IAtomicOperation)next;
369          next = op.Operator.Execute((IExecutionContext)op, cancellationToken);
370          if (next != null) executionStack.Push(next);
371        }
372      }
373    }
374
375    private void UpdateAnalyzers() {
376      Analyzer.Operators.Clear();
377      if (Problem != null) {
378        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>()) {
379          foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
380            param.Depth = 1;
381          Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
382        }
383      }
384    }
385
386    private void UpdateCrossovers() {
387      ICrossover oldCrossover = CrossoverParameter.Value;
388      CrossoverParameter.ValidValues.Clear();
389      ICrossover defaultCrossover = Problem.Operators.OfType<ICrossover>().FirstOrDefault();
390
391      foreach (ICrossover crossover in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name))
392        CrossoverParameter.ValidValues.Add(crossover);
393
394      if (oldCrossover != null) {
395        ICrossover crossover = CrossoverParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldCrossover.GetType());
396        if (crossover != null) CrossoverParameter.Value = crossover;
397        else oldCrossover = null;
398      }
399      if (oldCrossover == null && defaultCrossover != null)
400        CrossoverParameter.Value = defaultCrossover;
401    }
402
403    private void UpdateMutators() {
404      IManipulator oldMutator = MutatorParameter.Value;
405      MutatorParameter.ValidValues.Clear();
406      IManipulator defaultMutator = Problem.Operators.OfType<IManipulator>().FirstOrDefault();
407
408      foreach (IManipulator mutator in Problem.Operators.OfType<IManipulator>().OrderBy(x => x.Name))
409        MutatorParameter.ValidValues.Add(mutator);
410
411      if (oldMutator != null) {
412        IManipulator mutator = MutatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMutator.GetType());
413        if (mutator != null) MutatorParameter.Value = mutator;
414        else oldMutator = null;
415      }
416
417      if (oldMutator == null && defaultMutator != null)
418        MutatorParameter.Value = defaultMutator;
419    }
420    private void UpdateSelectors() {
421      ISelector oldSelector = SelectorParameter.Value;
422      SelectorParameter.ValidValues.Clear();
423      ISelector defaultSelector = Problem.Operators.OfType<ISelector>().FirstOrDefault();
424
425      foreach (ISelector selector in Problem.Operators.OfType<ISelector>().OrderBy(x => x.Name))
426        SelectorParameter.ValidValues.Add(selector);
427
428      if (oldSelector != null) {
429        ISelector selector = SelectorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldSelector.GetType());
430        if (selector != null) SelectorParameter.Value = selector;
431        else oldSelector = null;
432      }
433
434      if (oldSelector == null && defaultSelector != null)
435        SelectorParameter.Value = defaultSelector;
436    }
437    protected override void OnProblemChanged() {
438      UpdateCrossovers();
439      UpdateMutators();
440      UpdateAnalyzers();
441      base.OnProblemChanged();
442    }
443
444    protected override void OnExecutionStateChanged() {
445      previousExecutionState = currentExecutionState;
446      currentExecutionState = ExecutionState;
447      base.OnExecutionStateChanged();
448    }
449
450    protected override void OnStopped() {
451      if (Solutions != null) {
452        Solutions.Clear();
453      }
454      if (Population != null) {
455        Population.Clear();
456      }
457      //if (offspringPopulation != null) {
458      //  offspringPopulation.Clear();
459      //}
460      //if (jointPopulation != null) {
461      //  jointPopulation.Clear();
462      //}
463      executionContext.Scope.SubScopes.Clear();
464      base.OnStopped();
465    }
466    #endregion
467  }
468}
Note: See TracBrowser for help on using the repository browser.