source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs @ 10428

Last change on this file since 10428 was 10428, checked in by bburlacu, 6 years ago

#2143: Reset the pruned subtrees/trees counters to zero on reinitialization.

File size: 11.1 KB
Line 
1using System;
2using System.Linq;
3using HeuristicLab.Analysis;
4using HeuristicLab.Common;
5using HeuristicLab.Core;
6using HeuristicLab.Data;
7using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
8using HeuristicLab.Optimization;
9using HeuristicLab.Parameters;
10using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
11
12namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
13  [StorableClass]
14  [Item("SymbolicDataAnalysisSingleObjectivePruningAnalyzer", "An analyzer that prunes introns from trees in single objective symbolic data analysis problems.")]
15  public abstract class SymbolicDataAnalysisSingleObjectivePruningAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer {
16    private const string ProblemDataParameterName = "ProblemData";
17    private const string InterpreterParameterName = "SymbolicExpressionTreeInterpreter";
18
19    private const string UpdateIntervalParameterName = "UpdateInverval";
20    private const string UpdateCounterParameterName = "UpdateCounter";
21
22    private const string PopulationSliceParameterName = "PopulationSlice";
23    private const string PruningProbabilityParameterName = "PruningProbability";
24
25    private const string NumberOfPrunedSubtreesParameterName = "PrunedSubtrees";
26    private const string NumberOfPrunedTreesParameterName = "PrunedTrees";
27
28    private const string RandomParameterName = "Random";
29    private const string EstimationLimitsParameterName = "EstimationLimits";
30
31    private const string PruneOnlyZeroImpactNodesParameterName = "PruneOnlyZeroImpactNodes";
32    private const string NodeImpactThresholdParameterName = "ImpactThreshold";
33
34    private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition";
35
36    private bool reentry;
37    [Storable]
38    protected ISymbolicDataAnalysisSolutionImpactValuesCalculator impactValuesCalculator;
39
40    #region parameter properties
41    public IFixedValueParameter<BoolValue> PruneOnlyZeroImpactNodesParameter {
42      get { return (IFixedValueParameter<BoolValue>)Parameters[PruneOnlyZeroImpactNodesParameterName]; }
43    }
44    public IFixedValueParameter<DoubleValue> NodeImpactThresholdParameter {
45      get { return (IFixedValueParameter<DoubleValue>)Parameters[NodeImpactThresholdParameterName]; }
46    }
47    public ILookupParameter<DoubleLimit> EstimationLimitsParameter {
48      get { return (ILookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
49    }
50    public ILookupParameter<IRandom> RandomParameter {
51      get { return (ILookupParameter<IRandom>)Parameters[RandomParameterName]; }
52    }
53    private ILookupParameter<IDataAnalysisProblemData> ProblemDataParameter {
54      get { return (ILookupParameter<IDataAnalysisProblemData>)Parameters[ProblemDataParameterName]; }
55    }
56    public ILookupParameter<IntRange> FitnessCalculationPartitionParameter {
57      get { return (ILookupParameter<IntRange>)Parameters[FitnessCalculationPartitionParameterName]; }
58    }
59    private ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> InterpreterParameter {
60      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[InterpreterParameterName]; }
61    }
62    public IValueParameter<IntValue> UpdateIntervalParameter {
63      get { return (IValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
64    }
65    public IValueParameter<IntValue> UpdateCounterParameter {
66      get { return (IValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
67    }
68    public IValueParameter<DoubleRange> PopulationSliceParameter {
69      get { return (IValueParameter<DoubleRange>)Parameters[PopulationSliceParameterName]; }
70    }
71    public IValueParameter<DoubleValue> PruningProbabilityParameter {
72      get { return (IValueParameter<DoubleValue>)Parameters[PruningProbabilityParameterName]; }
73    }
74    public IFixedValueParameter<DoubleValue> NumberOfPrunedSubtreesParameter {
75      get { return (IFixedValueParameter<DoubleValue>)Parameters[NumberOfPrunedSubtreesParameterName]; }
76    }
77    public IFixedValueParameter<DoubleValue> NumberOfPrunedTreesParameter {
78      get { return (IFixedValueParameter<DoubleValue>)Parameters[NumberOfPrunedTreesParameterName]; }
79    }
80    #endregion
81    #region properties
82    protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
83    protected IntRange FitnessCalculationPartition { get { return FitnessCalculationPartitionParameter.ActualValue; } }
84    protected ISymbolicDataAnalysisExpressionTreeInterpreter Interpreter { get { return InterpreterParameter.ActualValue; } }
85    protected IntValue UpdateInterval { get { return UpdateIntervalParameter.Value; } }
86    protected IntValue UpdateCounter { get { return UpdateCounterParameter.Value; } }
87    protected DoubleRange PopulationSlice { get { return PopulationSliceParameter.Value; } }
88    protected DoubleValue PruningProbability { get { return PruningProbabilityParameter.Value; } }
89    protected DoubleValue PrunedSubtrees { get { return NumberOfPrunedSubtreesParameter.Value; } }
90    protected DoubleValue PrunedTrees { get { return NumberOfPrunedTreesParameter.Value; } }
91    protected DoubleLimit EstimationLimits { get { return EstimationLimitsParameter.ActualValue; } }
92    protected IRandom Random { get { return RandomParameter.ActualValue; } }
93    protected DoubleValue NodeImpactThreshold { get { return NodeImpactThresholdParameter.Value; } }
94    protected BoolValue PruneOnlyZeroImpactNodes { get { return PruneOnlyZeroImpactNodesParameter.Value; } }
95    #endregion
96
97    #region IStatefulItem members
98    public override void InitializeState() {
99      base.InitializeState();
100      UpdateCounter.Value = 0;
101      PrunedSubtrees.Value = 0;
102      PrunedTrees.Value = 0;
103    }
104    public override void ClearState() {
105      base.ClearState();
106      UpdateCounter.Value = 0;
107      PrunedSubtrees.Value = 0;
108      PrunedTrees.Value = 0;
109    }
110    #endregion
111
112    [StorableConstructor]
113    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(bool deserializing) : base(deserializing) { }
114    [StorableHook(HookType.AfterDeserialization)]
115    private void AfterDeserialization() {
116      if (!Parameters.ContainsKey(FitnessCalculationPartitionParameterName))
117        Parameters.Add(new LookupParameter<IntRange>(FitnessCalculationPartitionParameterName, ""));
118    }
119    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(SymbolicDataAnalysisSingleObjectivePruningAnalyzer original, Cloner cloner)
120      : base(original, cloner) {
121      impactValuesCalculator = original.impactValuesCalculator;
122    }
123    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer() {
124      Parameters.Add(new ValueParameter<DoubleRange>(PopulationSliceParameterName, new DoubleRange(0.75, 1)));
125      Parameters.Add(new ValueParameter<DoubleValue>(PruningProbabilityParameterName, new DoubleValue(0.5)));
126      // analyzer parameters
127      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
128      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called", new IntValue(0)));
129      Parameters.Add(new LookupParameter<IRandom>(RandomParameterName));
130      Parameters.Add(new LookupParameter<IDataAnalysisProblemData>(ProblemDataParameterName));
131      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(InterpreterParameterName));
132
133      Parameters.Add(new FixedValueParameter<DoubleValue>(NumberOfPrunedSubtreesParameterName, new DoubleValue(0)));
134      Parameters.Add(new FixedValueParameter<DoubleValue>(NumberOfPrunedTreesParameterName, new DoubleValue(0)));
135      Parameters.Add(new LookupParameter<DoubleLimit>(EstimationLimitsParameterName));
136      Parameters.Add(new FixedValueParameter<DoubleValue>(NodeImpactThresholdParameterName, new DoubleValue(0.0)));
137      Parameters.Add(new FixedValueParameter<BoolValue>(PruneOnlyZeroImpactNodesParameterName, new BoolValue(false)));
138      Parameters.Add(new LookupParameter<IntRange>(FitnessCalculationPartitionParameterName, ""));
139    }
140
141    public override IOperation Apply() {
142      if (reentry) {
143        UpdateCounter.Value++;
144
145        if (UpdateCounter.Value != UpdateInterval.Value) return base.Apply();
146        UpdateCounter.Value = 0;
147
148        var trees = SymbolicExpressionTreeParameter.ActualValue.ToList();
149        var qualities = QualityParameter.ActualValue.ToList();
150
151        var population = trees.Zip(qualities, (tree, quality) => new { Tree = tree, Quality = quality }).ToList();
152        Func<double, double, int> compare = (a, b) => Maximization.Value ? a.CompareTo(b) : b.CompareTo(a);
153        population.Sort((a, b) => compare(a.Quality.Value, b.Quality.Value));
154
155        var start = (int)Math.Round(PopulationSlice.Start * trees.Count);
156        var end = (int)Math.Round(PopulationSlice.End * trees.Count);
157
158        if (end == population.Count) end--;
159
160        if (start >= end || end >= population.Count) throw new Exception("Invalid PopulationSlice bounds.");
161
162        PrunedSubtrees.Value = 0;
163        PrunedTrees.Value = 0;
164
165        reentry = false;
166
167        var operations = new OperationCollection { Parallel = true };
168        foreach (var p in population.Skip(start).Take(end)) {
169          if (Random.NextDouble() > PruningProbability.Value) continue;
170          var op = new SymbolicDataAnalysisExpressionPruningOperator {
171            Model = CreateModel(p.Tree, Interpreter, EstimationLimits.Lower, EstimationLimits.Upper),
172            ImpactsCalculator = impactValuesCalculator,
173            ProblemData = ProblemData,
174            Random = Random,
175            PruneOnlyZeroImpactNodes = PruneOnlyZeroImpactNodes.Value,
176            NodeImpactThreshold = NodeImpactThreshold.Value,
177            FitnessCalculationPartition = FitnessCalculationPartition
178          };
179          operations.Add(ExecutionContext.CreateChildOperation(op, ExecutionContext.Scope));
180        }
181        return new OperationCollection { operations, ExecutionContext.CreateOperation(this) };
182      }
183
184      DataTable table;
185
186      if (ResultCollection.ContainsKey("Population Pruning")) {
187        table = (DataTable)ResultCollection["Population Pruning"].Value;
188      } else {
189        table = new DataTable("Population Pruning");
190        table.Rows.Add(new DataRow("Pruned Trees") { VisualProperties = { StartIndexZero = true } });
191        table.Rows.Add(new DataRow("Pruned Subtrees") { VisualProperties = { StartIndexZero = true } });
192        ResultCollection.Add(new Result("Population Pruning", table));
193      }
194
195      table.Rows["Pruned Trees"].Values.Add(PrunedTrees.Value);
196      table.Rows["Pruned Subtrees"].Values.Add(PrunedSubtrees.Value);
197
198      reentry = true;
199
200      return base.Apply();
201    }
202
203    protected abstract ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
204      double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue);
205  }
206}
Note: See TracBrowser for help on using the repository browser.