Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer.cs @ 17334

Last change on this file since 17334 was 17181, checked in by swagner, 5 years ago

#2875: Merged r17180 from trunk to stable

File size: 9.5 KB
RevLine 
[5557]1#region License Information
2/* HeuristicLab
[17181]3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[5557]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 System.Collections.Generic;
23using System.Linq;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
[17097]30using HEAL.Attic;
[5557]31
32namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
33  /// <summary>
34  /// An operator that analyzes the training best symbolic data analysis solution for multi objective symbolic data analysis problems.
35  /// </summary>
36  [Item("SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer", "An operator that analyzes the training best symbolic data analysis solution for multi objective symbolic data analysis problems.")]
[17097]37  [StorableType("D43D38D1-EEA8-4DEF-AA95-6E941194D708")]
[5557]38  public abstract class SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer<T> : SymbolicDataAnalysisMultiObjectiveAnalyzer
[5607]39    where T : class, ISymbolicDataAnalysisSolution {
[5557]40    private const string TrainingBestSolutionsParameterName = "Best training solutions";
41    private const string TrainingBestSolutionQualitiesParameterName = "Best training solution qualities";
[9152]42    private const string UpdateAlwaysParameterName = "Always update best solutions";
[13310]43    private const string TrainingBestSolutionParameterName = "Best training solution";
[5557]44
45    #region parameter properties
46    public ILookupParameter<ItemList<T>> TrainingBestSolutionsParameter {
47      get { return (ILookupParameter<ItemList<T>>)Parameters[TrainingBestSolutionsParameterName]; }
48    }
49    public ILookupParameter<ItemList<DoubleArray>> TrainingBestSolutionQualitiesParameter {
50      get { return (ILookupParameter<ItemList<DoubleArray>>)Parameters[TrainingBestSolutionQualitiesParameterName]; }
51    }
[9152]52    public IFixedValueParameter<BoolValue> UpdateAlwaysParameter {
53      get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateAlwaysParameterName]; }
54    }
[5557]55    #endregion
56    #region properties
[13310]57    private ItemList<T> TrainingBestSolutions {
[5557]58      get { return TrainingBestSolutionsParameter.ActualValue; }
59      set { TrainingBestSolutionsParameter.ActualValue = value; }
60    }
[13310]61    private ItemList<DoubleArray> TrainingBestSolutionQualities {
[5557]62      get { return TrainingBestSolutionQualitiesParameter.ActualValue; }
63      set { TrainingBestSolutionQualitiesParameter.ActualValue = value; }
64    }
[13310]65    public bool UpdateAlways {
66      get { return UpdateAlwaysParameter.Value.Value; }
67      set { UpdateAlwaysParameter.Value.Value = value; }
[9152]68    }
[5557]69    #endregion
70
71    [StorableConstructor]
[17097]72    protected SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer(StorableConstructorFlag _) : base(_) { }
[5557]73    protected SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer(SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer<T> original, Cloner cloner) : base(original, cloner) { }
74    public SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer()
75      : base() {
[5607]76      Parameters.Add(new LookupParameter<ItemList<T>>(TrainingBestSolutionsParameterName, "The training best (Pareto-optimal) symbolic data analysis solutions."));
[5557]77      Parameters.Add(new LookupParameter<ItemList<DoubleArray>>(TrainingBestSolutionQualitiesParameterName, "The qualities of the training best (Pareto-optimal) solutions."));
[9152]78      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateAlwaysParameterName, "Determines if the best training solutions should always be updated regardless of its quality.", new BoolValue(false)));
79      UpdateAlwaysParameter.Hidden = true;
[5557]80    }
81
[9152]82    [StorableHook(HookType.AfterDeserialization)]
83    private void AfterDeserialization() {
84      if (!Parameters.ContainsKey(UpdateAlwaysParameterName)) {
85        Parameters.Add(new FixedValueParameter<BoolValue>(UpdateAlwaysParameterName, "Determines if the best training solutions should always be updated regardless of its quality.", new BoolValue(false)));
86        UpdateAlwaysParameter.Hidden = true;
87      }
88    }
89
[5557]90    public override IOperation Apply() {
91      var results = ResultCollection;
92      // create empty parameter and result values
93      if (TrainingBestSolutions == null) {
94        TrainingBestSolutions = new ItemList<T>();
95        TrainingBestSolutionQualities = new ItemList<DoubleArray>();
[5747]96        results.Add(new Result(TrainingBestSolutionQualitiesParameter.Name, TrainingBestSolutionQualitiesParameter.Description, TrainingBestSolutionQualities));
97        results.Add(new Result(TrainingBestSolutionsParameter.Name, TrainingBestSolutionsParameter.Description, TrainingBestSolutions));
[5557]98      }
99
[13310]100      if (!results.ContainsKey(TrainingBestSolutionParameterName)) {
101        results.Add(new Result(TrainingBestSolutionParameterName, "", typeof(ISymbolicDataAnalysisSolution)));
102      }
103
[9152]104      //if the pareto front of best solutions shall be updated regardless of the quality, the list initialized empty to discard old solutions
[13310]105      List<double[]> trainingBestQualities;
106      if (UpdateAlways) {
[9152]107        trainingBestQualities = new List<double[]>();
108      } else {
109        trainingBestQualities = TrainingBestSolutionQualities.Select(x => x.ToArray()).ToList();
110      }
[5557]111
[13310]112      ISymbolicExpressionTree[] trees = SymbolicExpressionTree.ToArray();
[5557]113      List<double[]> qualities = Qualities.Select(x => x.ToArray()).ToList();
114      bool[] maximization = Maximization.ToArray();
[13310]115
116      var nonDominatedIndividuals = new[] { new { Tree = default(ISymbolicExpressionTree), Qualities = default(double[]) } }.ToList();
117      nonDominatedIndividuals.Clear();
118
119      // build list of new non-dominated solutions
120      for (int i = 0; i < trees.Length; i++) {
121        if (IsNonDominated(qualities[i], nonDominatedIndividuals.Select(ind => ind.Qualities), maximization) &&
122            IsNonDominated(qualities[i], trainingBestQualities, maximization)) {
123          for (int j = nonDominatedIndividuals.Count - 1; j >= 0; j--) {
124            if (IsBetterOrEqual(qualities[i], nonDominatedIndividuals[j].Qualities, maximization)) {
125              nonDominatedIndividuals.RemoveAt(j);
126            }
[5742]127          }
[13310]128          nonDominatedIndividuals.Add(new { Tree = trees[i], Qualities = qualities[i] });
[5557]129        }
130      }
[13310]131
132      var nonDominatedSolutions = nonDominatedIndividuals.Select(x => new { Solution = CreateSolution(x.Tree, x.Qualities), Qualities = x.Qualities }).ToList();
133      nonDominatedSolutions.ForEach(s => s.Solution.Name = string.Join(",", s.Qualities.Select(q => q.ToString())));
134
[5557]135      #region update Pareto-optimal solution archive
[13310]136      if (nonDominatedSolutions.Count > 0) {
137        //add old non-dominated solutions only if they are not dominated by one of the new solutions
[5557]138        for (int i = 0; i < trainingBestQualities.Count; i++) {
[13310]139          if (IsNonDominated(trainingBestQualities[i], nonDominatedSolutions.Select(x => x.Qualities), maximization)) {
140            nonDominatedSolutions.Add(new { Solution = TrainingBestSolutions[i], Qualities = TrainingBestSolutionQualities[i].ToArray() });
[5557]141          }
142        }
143
[13310]144        //assumes the the first objective is always the accuracy
145        var sortedNonDominatedSolutions = maximization[0]
146          ? nonDominatedSolutions.OrderByDescending(x => x.Qualities[0])
147          : nonDominatedSolutions.OrderBy(x => x.Qualities[0]);
148        var trainingBestSolution = sortedNonDominatedSolutions.Select(s => s.Solution).First();
149        results[TrainingBestSolutionParameterName].Value = trainingBestSolution;
150        TrainingBestSolutions = new ItemList<T>(sortedNonDominatedSolutions.Select(x => x.Solution));
151        results[TrainingBestSolutionsParameter.Name].Value = TrainingBestSolutions;
152        TrainingBestSolutionQualities = new ItemList<DoubleArray>(sortedNonDominatedSolutions.Select(x => new DoubleArray(x.Qualities)));
153        results[TrainingBestSolutionQualitiesParameter.Name].Value = TrainingBestSolutionQualities;
[5557]154      }
155      #endregion
156      return base.Apply();
157    }
158
159    protected abstract T CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality);
160
[13310]161    private bool IsNonDominated(double[] point, IEnumerable<double[]> points, bool[] maximization) {
[5557]162      foreach (var refPoint in points) {
[13310]163        bool refPointDominatesPoint = IsBetterOrEqual(refPoint, point, maximization);
[5557]164        if (refPointDominatesPoint) return false;
165      }
166      return true;
167    }
[13310]168
169    private bool IsBetterOrEqual(double[] lhs, double[] rhs, bool[] maximization) {
170      for (int i = 0; i < lhs.Length; i++) {
171        var result = IsBetterOrEqual(lhs[i], rhs[i], maximization[i]);
172        if (!result) return false;
173      }
174      return true;
175    }
176
[5742]177    private bool IsBetterOrEqual(double lhs, double rhs, bool maximization) {
[13310]178      if (maximization) return lhs >= rhs;
179      else return lhs <= rhs;
[5557]180    }
181  }
182}
Note: See TracBrowser for help on using the repository browser.