source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs @ 10375

Last change on this file since 10375 was 10375, checked in by bburlacu, 8 years ago

#2143: Fixed incorrect accessibility levels of constructors for the pruning analyzers.

File size: 4.8 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Operators;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
33namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
34  [StorableClass]
35  [Item("SymbolicExpressionTreePruningOperator", "An operator that replaces introns with constant values in a symbolic expression tree.")]
36  public class SymbolicDataAnalysisExpressionPruningOperator : SingleSuccessorOperator {
37    private const string NumberOfPrunedSubtreesParameterName = "PrunedSubtrees";
38    private const string NumberOfPrunedTreesParameterName = "PrunedTrees";
39    #region parameter properties
40    public ILookupParameter<DoubleValue> NumberOfPrunedSubtreesParameter {
41      get { return (ILookupParameter<DoubleValue>)Parameters[NumberOfPrunedSubtreesParameterName]; }
42    }
43    public ILookupParameter<DoubleValue> NumberOfPrunedTreesParameter {
44      get { return (ILookupParameter<DoubleValue>)Parameters[NumberOfPrunedTreesParameterName]; }
45    }
46    #endregion
47    #region properties
48    private DoubleValue PrunedSubtrees { get { return NumberOfPrunedSubtreesParameter.ActualValue; } }
49    private DoubleValue PrunedTrees { get { return NumberOfPrunedTreesParameter.ActualValue; } }
50    #endregion
51
52    [StorableConstructor]
53    private SymbolicDataAnalysisExpressionPruningOperator(bool deserializing) : base(deserializing) { }
54    public override IDeepCloneable Clone(Cloner cloner) {
55      return new SymbolicDataAnalysisExpressionPruningOperator(this, cloner);
56    }
57    protected SymbolicDataAnalysisExpressionPruningOperator(SymbolicDataAnalysisExpressionPruningOperator original, Cloner cloner)
58      : base(original, cloner) {
59    }
60
61    public SymbolicDataAnalysisExpressionPruningOperator() {
62      Parameters.Add(new LookupParameter<DoubleValue>(NumberOfPrunedSubtreesParameterName));
63      Parameters.Add(new LookupParameter<DoubleValue>(NumberOfPrunedTreesParameterName));
64    }
65
66    public ISymbolicDataAnalysisModel Model { get; set; }
67    public IDataAnalysisProblemData ProblemData { get; set; }
68    public ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactsCalculator { get; set; }
69    public IRandom Random { get; set; }
70
71    public bool PruneOnlyZeroImpactNodes { get; set; }
72    public double NodeImpactThreshold { get; set; }
73
74    public override IOperation Apply() {
75      int prunedSubtrees = 0;
76
77      var nodes = Model.SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
78
79      for (int j = 0; j < nodes.Count; ++j) {
80        var node = nodes[j];
81        if (node is ConstantTreeNode) continue;
82
83        var impact = ImpactsCalculator.CalculateImpactValue(Model, node, ProblemData, ProblemData.TrainingIndices);
84
85        if (PruneOnlyZeroImpactNodes) {
86          if (!impact.IsAlmost(0.0)) continue;
87        } else {
88          if (NodeImpactThreshold < impact) continue;
89        }
90
91        var replacementValue = ImpactsCalculator.CalculateReplacementValue(Model, node, ProblemData, ProblemData.TrainingIndices);
92        var constantNode = new ConstantTreeNode(new Constant()) { Value = replacementValue };
93        ReplaceWithConstant(node, constantNode);
94        j += node.GetLength() - 1; // skip subtrees under the node that was folded
95
96        prunedSubtrees++;
97      }
98
99      if (prunedSubtrees > 0) {
100        lock (PrunedSubtrees) { PrunedSubtrees.Value += prunedSubtrees; }
101        lock (PrunedTrees) { PrunedTrees.Value += 1; }
102      }
103      return base.Apply();
104    }
105    private static void ReplaceWithConstant(ISymbolicExpressionTreeNode original, ISymbolicExpressionTreeNode replacement) {
106      var parent = original.Parent;
107      var i = parent.IndexOfSubtree(original);
108      parent.RemoveSubtree(i);
109      parent.InsertSubtree(i, replacement);
110    }
111  }
112}
Note: See TracBrowser for help on using the repository browser.