Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs @ 8694

Last change on this file since 8694 was 8213, checked in by bburlacu, 12 years ago

#1772: Performance improvements for the GenealogyGraph. Minor refactoring to VisualGenealogyGraphArc and VisualGenealogyGraphNode classes. Added new functionality to the SymbolicExpressionTreeFragmentsAnalyzer, minor refactoring in the other two analyzers. Refactored View code. Updated project references and plugin dependencies and added HeuristicLab.Problems.DataAnalysis.Symbolic to the branch.

File size: 10.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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 System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
33namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
34  /// <summary>
35  /// An operator that collects the Pareto-best symbolic data analysis solutions for single objective symbolic data analysis problems.
36  /// </summary>
37  [Item("SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer", "An operator that analyzes the Pareto-best symbolic data analysis solution for single objective symbolic data analysis problems.")]
38  [StorableClass]
39  public abstract class SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer<S, T> : SymbolicDataAnalysisSingleObjectiveAnalyzer, ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator
40    where T : class, ISymbolicDataAnalysisSolution
41    where S : class, IDataAnalysisProblemData {
42    private const string ProblemDataParameterName = "ProblemData";
43    private const string TrainingBestSolutionsParameterName = "Best training solutions";
44    private const string TrainingBestSolutionQualitiesParameterName = "Best training solution qualities";
45    private const string ComplexityParameterName = "Complexity";
46    private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
47    private const string EstimationLimitsParameterName = "EstimationLimits";
48
49    public override bool EnabledByDefault {
50      get { return false; }
51    }
52
53    #region parameter properties
54    public ILookupParameter<ItemList<T>> TrainingBestSolutionsParameter {
55      get { return (ILookupParameter<ItemList<T>>)Parameters[TrainingBestSolutionsParameterName]; }
56    }
57    public ILookupParameter<ItemList<DoubleArray>> TrainingBestSolutionQualitiesParameter {
58      get { return (ILookupParameter<ItemList<DoubleArray>>)Parameters[TrainingBestSolutionQualitiesParameterName]; }
59    }
60    public IScopeTreeLookupParameter<DoubleValue> ComplexityParameter {
61      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters[ComplexityParameterName]; }
62    }
63    public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
64      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
65    }
66    public ILookupParameter<S> ProblemDataParameter {
67      get { return (ILookupParameter<S>)Parameters[ProblemDataParameterName]; }
68    }
69    public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
70      get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
71    }
72    #endregion
73    #region properties
74    public ItemList<T> TrainingBestSolutions {
75      get { return TrainingBestSolutionsParameter.ActualValue; }
76      set { TrainingBestSolutionsParameter.ActualValue = value; }
77    }
78    public ItemList<DoubleArray> TrainingBestSolutionQualities {
79      get { return TrainingBestSolutionQualitiesParameter.ActualValue; }
80      set { TrainingBestSolutionQualitiesParameter.ActualValue = value; }
81    }
82    #endregion
83
84    [StorableConstructor]
85    protected SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
86    protected SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer(SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer<S, T> original, Cloner cloner) : base(original, cloner) { }
87    public SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer()
88      : base() {
89      Parameters.Add(new LookupParameter<S>(ProblemDataParameterName, "The problem data for the symbolic data analysis solution."));
90      Parameters.Add(new LookupParameter<ItemList<T>>(TrainingBestSolutionsParameterName, "The training best (Pareto-optimal) symbolic data analysis solutions."));
91      Parameters.Add(new LookupParameter<ItemList<DoubleArray>>(TrainingBestSolutionQualitiesParameterName, "The qualities of the training best (Pareto-optimal) solutions."));
92      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(ComplexityParameterName, "The complexity of each tree."));
93      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
94      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic classification model."));
95    }
96
97    public override IOperation Apply() {
98      var results = ResultCollection;
99      // create empty parameter and result values
100      if (TrainingBestSolutions == null) {
101        TrainingBestSolutions = new ItemList<T>();
102        TrainingBestSolutionQualities = new ItemList<DoubleArray>();
103        results.Add(new Result(TrainingBestSolutionQualitiesParameter.Name, TrainingBestSolutionQualitiesParameter.Description, TrainingBestSolutionQualities));
104        results.Add(new Result(TrainingBestSolutionsParameter.Name, TrainingBestSolutionsParameter.Description, TrainingBestSolutions));
105      }
106
107      IList<Tuple<double, double>> trainingBestQualities = TrainingBestSolutionQualities
108        .Select(x => Tuple.Create(x[0], x[1]))
109        .ToList();
110
111      #region find best trees
112      IList<int> nonDominatedIndexes = new List<int>();
113      ISymbolicExpressionTree[] tree = SymbolicExpressionTree.ToArray();
114      List<double> qualities = Quality.Select(x => x.Value).ToList();
115
116      List<double> complexities;
117      if (ComplexityParameter.ActualValue != null && ComplexityParameter.ActualValue.Length == qualities.Count) {
118        complexities = ComplexityParameter.ActualValue.Select(x => x.Value).ToList();
119      } else {
120        complexities = tree.Select(t => (double)t.Length).ToList();
121      }
122      List<Tuple<double, double>> fitness = new List<Tuple<double, double>>();
123      for (int i = 0; i < qualities.Count; i++)
124        fitness.Add(Tuple.Create(qualities[i], complexities[i]));
125      var maximization = Tuple.Create(Maximization.Value, false);// complexity must be minimized
126      List<Tuple<double, double>> newNonDominatedQualities = new List<Tuple<double, double>>();
127      for (int i = 0; i < tree.Length; i++) {
128        if (IsNonDominated(fitness[i], trainingBestQualities, maximization) &&
129          IsNonDominated(fitness[i], newNonDominatedQualities, maximization) &&
130          IsNonDominated(fitness[i], fitness.Skip(i + 1), maximization)) {
131          if (!newNonDominatedQualities.Contains(fitness[i])) {
132            newNonDominatedQualities.Add(fitness[i]);
133            nonDominatedIndexes.Add(i);
134          }
135        }
136      }
137      #endregion
138
139      #region update Pareto-optimal solution archive
140      if (nonDominatedIndexes.Count > 0) {
141        ItemList<DoubleArray> nonDominatedQualities = new ItemList<DoubleArray>();
142        ItemList<T> nonDominatedSolutions = new ItemList<T>();
143        // add all new non-dominated solutions to the archive
144        foreach (var index in nonDominatedIndexes) {
145          T solution = CreateSolution(tree[index]);
146          nonDominatedSolutions.Add(solution);
147          nonDominatedQualities.Add(new DoubleArray(new double[] { fitness[index].Item1, fitness[index].Item2 }));
148        }
149        // add old non-dominated solutions only if they are not dominated by one of the new solutions
150        for (int i = 0; i < trainingBestQualities.Count; i++) {
151          if (IsNonDominated(trainingBestQualities[i], newNonDominatedQualities, maximization)) {
152            if (!newNonDominatedQualities.Contains(trainingBestQualities[i])) {
153              nonDominatedSolutions.Add(TrainingBestSolutions[i]);
154              nonDominatedQualities.Add(TrainingBestSolutionQualities[i]);
155            }
156          }
157        }
158
159        // make sure solutions and qualities are ordered in the results
160        var orderedIndexes =
161          nonDominatedSolutions.Select((s, i) => i).OrderBy(i => nonDominatedQualities[i][0]).ToArray();
162
163        var orderedNonDominatedSolutions = new ItemList<T>();
164        var orderedNonDominatedQualities = new ItemList<DoubleArray>();
165        foreach (var i in orderedIndexes) {
166          orderedNonDominatedQualities.Add(nonDominatedQualities[i]);
167          orderedNonDominatedSolutions.Add(nonDominatedSolutions[i]);
168        }
169
170        TrainingBestSolutions = orderedNonDominatedSolutions;
171        TrainingBestSolutionQualities = orderedNonDominatedQualities;
172
173        results[TrainingBestSolutionsParameter.Name].Value = orderedNonDominatedSolutions;
174        results[TrainingBestSolutionQualitiesParameter.Name].Value = orderedNonDominatedQualities;
175      }
176      #endregion
177      return base.Apply();
178    }
179
180    protected abstract T CreateSolution(ISymbolicExpressionTree bestTree);
181
182    private bool IsNonDominated(Tuple<double, double> point, IEnumerable<Tuple<double, double>> points, Tuple<bool, bool> maximization) {
183      return !points.Any(p => IsBetterOrEqual(p.Item1, point.Item1, maximization.Item1) &&
184                             IsBetterOrEqual(p.Item2, point.Item2, maximization.Item2));
185    }
186    private bool IsBetterOrEqual(double lhs, double rhs, bool maximization) {
187      if (maximization) return lhs >= rhs;
188      else return lhs <= rhs;
189    }
190  }
191}
Note: See TracBrowser for help on using the repository browser.