Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Mutators/NestedOptimizerSubVectorImprovementManipulator.cs @ 18229

Last change on this file since 18229 was 18229, checked in by pfleck, 2 years ago

#3040 Added mutation for optimizing aggregation window that uses a nested optimizer.

File size: 10.3 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using HEAL.Attic;
5using HeuristicLab.Algorithms.EvolutionStrategy;
6using HeuristicLab.Algorithms.GeneticAlgorithm;
7using HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm;
8using HeuristicLab.Algorithms.RandomSearch;
9using HeuristicLab.Common;
10using HeuristicLab.Core;
11using HeuristicLab.Data;
12using HeuristicLab.Encodings.IntegerVectorEncoding;
13using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
14using HeuristicLab.Optimization;
15using HeuristicLab.Parameters;
16using HeuristicLab.Random;
17using HeuristicLab.Selection;
18
19namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
20
21  [Item("NestedOptimizerSubVectorImprovementManipulator", "Mutator that optimizes the ranges for a subvector symbol by utilizing a nested optimizer.")]
22  [StorableType("32E58EEE-97B4-4396-98A8-B98AB897E3F0")]
23  public class NestedOptimizerSubVectorImprovementManipulator<T> : SymbolicDataAnalysisExpressionManipulator<T> where T : class, IDataAnalysisProblemData {
24    private const string BestSolutionParameterName = "BestSolution";
25
26    [Item("SubVectorOptimizationProblem", "")]
27    [StorableType("EA3D3221-B274-4F2F-8B58-23CB2D091FD7")]
28    private class SubVectorOptimizationProblem : SingleObjectiveBasicProblem<IntegerVectorEncoding> {
29      #region Fixed Problem Parameters
30      [Storable]
31      private ISymbolicDataAnalysisSingleObjectiveEvaluator<T> evaluator;
32      [Storable]
33      private T problemData;
34      [Storable]
35      private List<int> rows;
36      [Storable]
37      private IExecutionContext executionContext;
38      #endregion
39
40      #region Instance Parameters
41      [Storable]
42      private ISymbolicExpressionTree tree;
43      [Storable]
44      private IList<int> selectedSubVectorNodes;
45      #endregion
46
47      public override bool Maximization { get { return false; } }
48
49      public SubVectorOptimizationProblem() {
50        Encoding = new IntegerVectorEncoding("bounds");
51        Parameters.Add(new ResultParameter<IntegerVector>(BestSolutionParameterName, ""));
52      }
53      private SubVectorOptimizationProblem(SubVectorOptimizationProblem original, Cloner cloner)
54        : base(original, cloner) { }
55      public override IDeepCloneable Clone(Cloner cloner) {
56        return new SubVectorOptimizationProblem(this, cloner);
57      }
58      [StorableConstructor]
59      private SubVectorOptimizationProblem(StorableConstructorFlag _) : base(_) { }
60
61      public override double Evaluate(Individual individual, IRandom random) {
62        var solution = individual.IntegerVector(Encoding.Name);
63
64        var updatedTree = (ISymbolicExpressionTree)tree.Clone();
65        UpdateFromVector(updatedTree, selectedSubVectorNodes, solution, Encoding.Bounds[0, 1]);
66       
67        var quality = evaluator.Evaluate(executionContext, updatedTree, problemData, rows);
68        if (evaluator.Maximization)
69          quality = -quality;
70        return quality;
71      }
72
73      public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
74        var best = GetBestIndividual(individuals, qualities);
75        var vector = best.Item1.IntegerVector(Encoding.Name);
76
77        results.AddOrUpdateResult(BestSolutionParameterName, vector);
78      }
79
80      public void SetProblemData(ISymbolicDataAnalysisSingleObjectiveEvaluator<T> evaluator, T problemData, List<int> rows, IExecutionContext executionContext) {
81        this.evaluator = evaluator;
82        this.problemData = problemData;
83        this.rows = rows;
84        this.executionContext = executionContext;
85      }
86      public void SetInstanceData(ISymbolicExpressionTree tree, List<int> selectedSubVectorNodes, int vectorLength) {
87        this.tree = tree;
88        this.selectedSubVectorNodes = selectedSubVectorNodes;
89        Encoding.Length = selectedSubVectorNodes.Count * 2;
90        Encoding.Bounds = new IntMatrix(new int[,] { { 0, vectorLength } });
91      }
92    }
93
94
95    #region Parameter Properties
96    public IConstrainedValueParameter<IAlgorithm> NestedOptimizerParameter {
97      get { return (IConstrainedValueParameter<IAlgorithm>)Parameters["NestedOptimizer"]; }
98    }
99
100    public IFixedValueParameter<PercentValue> PercentOptimizedSubVectorNodesParameter {
101      get { return (IFixedValueParameter<PercentValue>)Parameters["PercentOptimizedSubVectorNodes"]; }
102    }
103    #endregion
104
105    #region Properties
106    public IOptimizer NestedOptimizer {
107      get { return NestedOptimizerParameter.Value; }
108    }
109
110    public PercentValue PercentOptimizedSubVectorNodes {
111      get { return PercentOptimizedSubVectorNodesParameter.Value; }
112    }
113    #endregion
114
115    public NestedOptimizerSubVectorImprovementManipulator() : base() {
116      var problem = new SubVectorOptimizationProblem();
117
118      #region Create nested Algorithms
119      var rs = new RandomSearchAlgorithm() {
120        Problem = problem,
121        BatchSize = 10,
122        MaximumEvaluatedSolutions = 100
123      };
124
125      var es = new EvolutionStrategy() {
126        Problem = problem,
127        PlusSelection = new BoolValue(true),
128        PopulationSize = new IntValue(1),
129        Children = new IntValue(10),
130        MaximumGenerations = new IntValue(100)
131      };
132      es.Mutator = es.MutatorParameter.ValidValues.OfType<UniformSomePositionsManipulator>().Single();
133
134      var ga = new GeneticAlgorithm() {
135        Problem = problem,
136        PopulationSize = new IntValue(10),
137        MutationProbability = new PercentValue(0.1),
138        MaximumGenerations = new IntValue(100)
139      };
140      ga.Selector = ga.SelectorParameter.ValidValues.OfType<TournamentSelector>().Single();
141      ga.Crossover = ga.CrossoverParameter.ValidValues.OfType<RoundedBlendAlphaBetaCrossover>().Single();
142      ga.Mutator = ga.MutatorParameter.ValidValues.OfType<UniformOnePositionManipulator>().Single();
143
144      var osga = new OffspringSelectionGeneticAlgorithm() {
145        Problem = problem,
146        PopulationSize = new IntValue(10),
147        ComparisonFactorLowerBound = new DoubleValue(1.0),
148        ComparisonFactorUpperBound = new DoubleValue(1.0),
149        MutationProbability = new PercentValue(0.1),
150        MaximumGenerations = new IntValue(100),
151        MaximumEvaluatedSolutions = new IntValue(1000)
152      };
153      osga.Selector = osga.SelectorParameter.ValidValues.OfType<TournamentSelector>().Single();
154      osga.Crossover = osga.CrossoverParameter.ValidValues.OfType<RoundedBlendAlphaBetaCrossover>().Single();
155      osga.Mutator = osga.MutatorParameter.ValidValues.OfType<UniformOnePositionManipulator>().Single();
156      #endregion
157
158      var optimizers = new ItemSet<IAlgorithm>() { rs, es, ga, osga };
159
160      Parameters.Add(new ConstrainedValueParameter<IAlgorithm>("NestedOptimizer", optimizers, rs));
161      Parameters.Add(new FixedValueParameter<PercentValue>("PercentOptimizedSubVectorNodes", new PercentValue(1.0)));
162    }
163
164    private NestedOptimizerSubVectorImprovementManipulator(NestedOptimizerSubVectorImprovementManipulator<T> original, Cloner cloner) : base(original, cloner) { }
165
166    public override IDeepCloneable Clone(Cloner cloner) {
167      return new NestedOptimizerSubVectorImprovementManipulator<T>(this, cloner);
168    }
169
170    [StorableConstructor]
171    private NestedOptimizerSubVectorImprovementManipulator(StorableConstructorFlag _) : base(_) { }
172
173    public override void Manipulate(IRandom random, ISymbolicExpressionTree symbolicExpressionTree) {
174      int vectorLengths = GetVectorLengths(ProblemDataParameter.ActualValue);
175     
176      var selectedSubVectorNodes = GetSelectedSubVectorNodes(symbolicExpressionTree, random);
177      if (selectedSubVectorNodes.Count == 0)
178        return;
179
180      var algorithm = (IAlgorithm)NestedOptimizer.Clone();
181      PrepareAlgorithm(algorithm, symbolicExpressionTree, selectedSubVectorNodes, vectorLengths);
182
183      algorithm.Start(CancellationToken);
184
185      if (algorithm.ExecutionState != ExecutionState.Stopped)
186        throw new InvalidOperationException("Nested Algorithm did not finish.");
187
188      var solution = (IntegerVector)algorithm.Results[BestSolutionParameterName].Value;
189      UpdateFromVector(symbolicExpressionTree, selectedSubVectorNodes, solution, vectorLengths);
190    }
191
192    private void PrepareAlgorithm(IAlgorithm algorithm, ISymbolicExpressionTree symbolicExpressionTree, List<int> selectedSubVectorNodes, int vectorLengths) {
193      var problem = (SubVectorOptimizationProblem)algorithm.Problem;
194      problem.SetProblemData(EvaluatorParameter.ActualValue, ProblemDataParameter.ActualValue, GenerateRowsToEvaluate().ToList(), ExecutionContext);
195      problem.SetInstanceData(symbolicExpressionTree, selectedSubVectorNodes, vectorLengths);
196    }
197
198    private List<int> GetSelectedSubVectorNodes(ISymbolicExpressionTree symbolicExpressionTree, IRandom random) {
199      var subVectorNodes = GetSubVectorNodes(symbolicExpressionTree).ToList();
200
201      int numSelect = (int)Math.Round(subVectorNodes.Count * PercentOptimizedSubVectorNodes.Value);
202      var selectedSubVectorNodes = Enumerable.Range(0, subVectorNodes.Count).SampleRandomWithoutRepetition(random, numSelect).ToList();
203      return selectedSubVectorNodes;
204    }
205
206    private static int GetVectorLengths(T problemData) {  // ToDo evaluate a tree to get vector length per node
207      var vectorLengths = problemData.Dataset.DoubleVectorVariables
208        .Select(v => problemData.Dataset.GetDoubleVectorValue(v, row: 0).Count)
209        .Distinct();
210      return vectorLengths.Single();
211    }
212
213    private static void UpdateFromVector(ISymbolicExpressionTree tree, IList<int> selectedNodes, IntegerVector solution, int vectorLength) {
214      var nodes = GetSubVectorNodes(tree).ToList();
215
216      int i = 0;
217      foreach (var nodeIdx in selectedNodes) {
218        var node = nodes[nodeIdx];
219        node.Offset = (double)solution[i++] / (vectorLength - 1);
220        node.Length = (double)solution[i++] / (vectorLength - 1);
221      }
222    }
223
224    private static IEnumerable<WindowedSymbolTreeNode> GetSubVectorNodes(ISymbolicExpressionTree tree) {
225      return ActualRoot(tree)
226        .IterateNodesBreadth()
227        .OfType<WindowedSymbolTreeNode>()
228        .Where(n => n.HasLocalParameters);
229    }
230    private static ISymbolicExpressionTreeNode ActualRoot(ISymbolicExpressionTree tree) {
231      return tree.Root.GetSubtree(0).GetSubtree(0);
232    }
233
234  }
235}
Note: See TracBrowser for help on using the repository browser.