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

Last change on this file since 10470 was 10470, checked in by bburlacu, 7 years ago

#2143: Fixed deep cloning error and assembly plugin reference.

File size: 10.6 KB
Line 
1using System;
2using System.Linq;
3using HeuristicLab.Analysis;
4using HeuristicLab.Common;
5using HeuristicLab.Core;
6using HeuristicLab.Data;
7using HeuristicLab.Operators;
8using HeuristicLab.Optimization.Operators;
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    #region parameter names
17    private const string ProblemDataParameterName = "ProblemData";
18    private const string UpdateIntervalParameterName = "UpdateInverval";
19    private const string UpdateCounterParameterName = "UpdateCounter";
20    private const string PopulationSliceParameterName = "PopulationSlice";
21    private const string PruningProbabilityParameterName = "PruningProbability";
22    private const string TotalNumberOfPrunedSubtreesParameterName = "Number of pruned subtrees";
23    private const string TotalNumberOfPrunedTreesParameterName = "Number of pruned trees";
24    private const string RandomParameterName = "Random";
25    private const string PruneOnlyZeroImpactNodesParameterName = "PruneOnlyZeroImpactNodes";
26    private const string NodeImpactThresholdParameterName = "ImpactThreshold";
27    private const string PruningOperatorParameterName = "PruningOperator";
28    private const string ResultsParameterName = "Results";
29    #endregion
30    #region private members
31    private DataReducer prunedSubtreesReducer;
32    private DataReducer prunedTreesReducer;
33    private DataTableValuesCollector valuesCollector;
34    private ResultsCollector resultsCollector;
35    private EmptyOperator emptyOp;
36    #endregion
37    #region parameter properties
38    public IValueParameter<SymbolicDataAnalysisExpressionPruningOperator> PruningOperatorParameter {
39      get { return (IValueParameter<SymbolicDataAnalysisExpressionPruningOperator>)Parameters[PruningOperatorParameterName]; }
40    }
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<IRandom> RandomParameter {
48      get { return (ILookupParameter<IRandom>)Parameters[RandomParameterName]; }
49    }
50    private ILookupParameter<IDataAnalysisProblemData> ProblemDataParameter {
51      get { return (ILookupParameter<IDataAnalysisProblemData>)Parameters[ProblemDataParameterName]; }
52    }
53    public IValueParameter<IntValue> UpdateIntervalParameter {
54      get { return (IValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
55    }
56    public IValueParameter<IntValue> UpdateCounterParameter {
57      get { return (IValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
58    }
59    public IValueParameter<DoubleRange> PopulationSliceParameter {
60      get { return (IValueParameter<DoubleRange>)Parameters[PopulationSliceParameterName]; }
61    }
62    public IValueParameter<DoubleValue> PruningProbabilityParameter {
63      get { return (IValueParameter<DoubleValue>)Parameters[PruningProbabilityParameterName]; }
64    }
65    #endregion
66    #region properties
67    protected SymbolicDataAnalysisExpressionPruningOperator PruningOperator { get { return PruningOperatorParameter.Value; } }
68    protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
69    protected IntValue UpdateInterval { get { return UpdateIntervalParameter.Value; } }
70    protected IntValue UpdateCounter { get { return UpdateCounterParameter.Value; } }
71    protected DoubleRange PopulationSlice { get { return PopulationSliceParameter.Value; } }
72    protected DoubleValue PruningProbability { get { return PruningProbabilityParameter.Value; } }
73    protected IRandom Random { get { return RandomParameter.ActualValue; } }
74    protected DoubleValue NodeImpactThreshold { get { return NodeImpactThresholdParameter.Value; } }
75    protected BoolValue PruneOnlyZeroImpactNodes { get { return PruneOnlyZeroImpactNodesParameter.Value; } }
76    #endregion
77    #region IStatefulItem members
78    public override void InitializeState() {
79      base.InitializeState();
80      UpdateCounter.Value = 0;
81    }
82    public override void ClearState() {
83      base.ClearState();
84      UpdateCounter.Value = 0;
85    }
86    #endregion
87
88    [StorableConstructor]
89    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(bool deserializing) : base(deserializing) { }
90    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(SymbolicDataAnalysisSingleObjectivePruningAnalyzer original, Cloner cloner)
91      : base(original, cloner) {
92      if (original.prunedSubtreesReducer != null)
93        this.prunedSubtreesReducer = (DataReducer)original.prunedSubtreesReducer.Clone();
94      if (original.prunedTreesReducer != null)
95        this.prunedTreesReducer = (DataReducer)original.prunedTreesReducer.Clone();
96      if (original.valuesCollector != null)
97        this.valuesCollector = (DataTableValuesCollector)original.valuesCollector.Clone();
98      if (original.resultsCollector != null)
99        this.resultsCollector = (ResultsCollector)original.resultsCollector.Clone();
100    }
101    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer() {
102      #region add parameters
103      Parameters.Add(new ValueParameter<DoubleRange>(PopulationSliceParameterName, new DoubleRange(0.75, 1)));
104      Parameters.Add(new ValueParameter<DoubleValue>(PruningProbabilityParameterName, new DoubleValue(0.5)));
105      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
106      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called", new IntValue(0)));
107      Parameters.Add(new LookupParameter<IRandom>(RandomParameterName));
108      Parameters.Add(new LookupParameter<IDataAnalysisProblemData>(ProblemDataParameterName));
109      Parameters.Add(new FixedValueParameter<DoubleValue>(NodeImpactThresholdParameterName, new DoubleValue(0.0)));
110      Parameters.Add(new FixedValueParameter<BoolValue>(PruneOnlyZeroImpactNodesParameterName, new BoolValue(false)));
111      #endregion
112    }
113
114    private void InitializeOperators() {
115      prunedSubtreesReducer = new DataReducer();
116      prunedSubtreesReducer.ParameterToReduce.ActualName = PruningOperator.PrunedSubtreesParameter.ActualName;
117      prunedSubtreesReducer.ReductionOperation.Value = new ReductionOperation(ReductionOperations.Sum); // sum all the pruned subtrees parameter values
118      prunedSubtreesReducer.TargetOperation.Value = new ReductionOperation(ReductionOperations.Assign); // asign the sum to the target parameter
119      prunedSubtreesReducer.TargetParameter.ActualName = TotalNumberOfPrunedSubtreesParameterName;
120
121      prunedTreesReducer = new DataReducer();
122      prunedTreesReducer.ParameterToReduce.ActualName = PruningOperator.PrunedTreesParameter.ActualName;
123      prunedTreesReducer.ReductionOperation.Value = new ReductionOperation(ReductionOperations.Sum);
124      prunedTreesReducer.TargetOperation.Value = new ReductionOperation(ReductionOperations.Assign);
125      prunedTreesReducer.TargetParameter.ActualName = TotalNumberOfPrunedTreesParameterName;
126
127      valuesCollector = new DataTableValuesCollector();
128      valuesCollector.CollectedValues.Add(new LookupParameter<IntValue>(TotalNumberOfPrunedSubtreesParameterName));
129      valuesCollector.CollectedValues.Add(new LookupParameter<IntValue>(TotalNumberOfPrunedTreesParameterName));
130      valuesCollector.DataTableParameter.ActualName = "Population pruning";
131
132      resultsCollector = new ResultsCollector();
133      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>("Population pruning"));
134      resultsCollector.ResultsParameter.ActualName = ResultsParameterName;
135
136      emptyOp = new EmptyOperator();
137    }
138
139    //
140    /// <summary>
141    /// Computes the closed interval bounding the portion of the population that is to be pruned.
142    /// </summary>
143    /// <returns>Returns an int range [start, end]</returns>
144    private IntRange GetSliceBounds() {
145      var count = ExecutionContext.Scope.SubScopes.Count;
146      var start = (int)Math.Round(PopulationSlice.Start * count);
147      var end = (int)Math.Round(PopulationSlice.End * count);
148      if (end > count) end = count;
149
150      if (start >= end) throw new ArgumentOutOfRangeException("Invalid PopulationSlice bounds.");
151      return new IntRange(start, end);
152    }
153
154    private IOperation CreatePruningOperation() {
155      var oc = new OperationCollection { Parallel = true };
156      var range = GetSliceBounds();
157      var qualities = Quality.Select(x => x.Value).ToArray();
158      var indices = Enumerable.Range(0, qualities.Length).ToArray();
159      Array.Sort(qualities, indices);
160      if (!Maximization.Value) Array.Reverse(indices);
161
162      var subscopes = ExecutionContext.Scope.SubScopes;
163
164      for (int i = 0; i < subscopes.Count; ++i) {
165        IOperator op;
166        if (range.Start <= i && i < range.End && Random.NextDouble() <= PruningProbability.Value)
167          op = PruningOperator;
168        else op = emptyOp;
169        var index = indices[i];
170        var subscope = subscopes[index];
171        oc.Add(ExecutionContext.CreateChildOperation(op, subscope));
172      }
173      return oc;
174    }
175
176    public override IOperation Apply() {
177      UpdateCounter.Value++;
178      if (UpdateCounter.Value != UpdateInterval.Value) return base.Apply();
179      UpdateCounter.Value = 0;
180
181      if (prunedSubtreesReducer == null || prunedTreesReducer == null || valuesCollector == null || resultsCollector == null) { InitializeOperators(); }
182
183      var prune = CreatePruningOperation();
184      var reducePrunedSubtrees = ExecutionContext.CreateChildOperation(prunedSubtreesReducer);
185      var reducePrunedTrees = ExecutionContext.CreateChildOperation(prunedTreesReducer);
186      var collectValues = ExecutionContext.CreateChildOperation(valuesCollector);
187      var collectResults = ExecutionContext.CreateChildOperation(resultsCollector);
188
189      return new OperationCollection { prune, reducePrunedSubtrees, reducePrunedTrees, collectValues, collectResults, base.Apply() };
190    }
191  }
192}
Note: See TracBrowser for help on using the repository browser.