Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Encodings.RealVectorEncoding/3.3/RealVectorEncoding.cs @ 17695

Last change on this file since 17695 was 17614, checked in by abeham, 4 years ago

#2521: work in progress (removed solution creator parameter from encoding), OrienteeringProblem and test functions are broken

File size: 12.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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 HEAL.Attic;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.PluginInfrastructure;
32
33namespace HeuristicLab.Encodings.RealVectorEncoding {
34  [Item("RealVectorEncoding", "Describes a real vector encoding.")]
35  [StorableType("155FFE02-931F-457D-AC95-A0389B0BFECD")]
36  public sealed class RealVectorEncoding : VectorEncoding<RealVector> {
37    [Storable] public IValueParameter<DoubleMatrix> BoundsParameter { get; private set; }
38
39    public DoubleMatrix Bounds {
40      get { return BoundsParameter.Value; }
41      set {
42        if (value == null) throw new ArgumentNullException("Bounds parameter must not be null.");
43        if (Bounds == value) return;
44        BoundsParameter.Value = value;
45      }
46    }
47
48    [StorableConstructor]
49    private RealVectorEncoding(StorableConstructorFlag _) : base(_) { }
50    [StorableHook(HookType.AfterDeserialization)]
51    private void AfterDeserialization() {
52      DiscoverOperators();
53      RegisterParameterEvents();
54    }
55
56    public override IDeepCloneable Clone(Cloner cloner) { return new RealVectorEncoding(this, cloner); }
57    private RealVectorEncoding(RealVectorEncoding original, Cloner cloner)
58      : base(original, cloner) {
59      BoundsParameter = cloner.Clone(original.BoundsParameter);
60      RegisterParameterEvents();
61    }
62
63    public RealVectorEncoding() : this("RealVector", 10) { }
64    public RealVectorEncoding(string name) : this(name, 10) { }
65    public RealVectorEncoding(int length) : this("RealVector", length) { }
66    public RealVectorEncoding(string name, int length, double min = -1000, double max = 1000)
67      : base(name, length) {
68      if (min >= max) throw new ArgumentException("min must be less than max", "min");
69
70      var bounds = new DoubleMatrix(1, 2);
71      bounds[0, 0] = min;
72      bounds[0, 1] = max;
73
74      BoundsParameter = new ValueParameter<DoubleMatrix>(Name + ".Bounds", bounds);
75      Parameters.Add(BoundsParameter);
76
77      RegisterParameterEvents();
78      DiscoverOperators();
79    }
80
81    public RealVectorEncoding(string name, int length, IList<double> min, IList<double> max)
82      : base(name, length) {
83      if (min.Count == 0) throw new ArgumentException("Bounds must be given for the real parameters.");
84      if (min.Count != max.Count) throw new ArgumentException("min must be of the same length as max", "min");
85      if (min.Zip(max, (mi, ma) => mi >= ma).Any(x => x)) throw new ArgumentException("min must be less than max in each dimension", "min");
86
87      var bounds = new DoubleMatrix(min.Count, 2);
88      for (int i = 0; i < min.Count; i++) {
89        bounds[i, 0] = min[i];
90        bounds[i, 1] = max[i];
91      }
92      BoundsParameter = new ValueParameter<DoubleMatrix>(Name + ".Bounds", bounds);
93      Parameters.Add(BoundsParameter);
94
95      DiscoverOperators();
96      RegisterParameterEvents();
97    }
98
99    private void RegisterParameterEvents() {
100      DoubleMatrixParameterChangeHandler.Create(BoundsParameter, () => {
101        ConfigureOperators(Operators);
102        OnBoundsChanged();
103      });
104    }
105
106    #region Operator Discovery
107    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
108    static RealVectorEncoding() {
109      encodingSpecificOperatorTypes = new List<Type>() {
110          typeof (IRealVectorOperator),
111          typeof (IRealVectorCreator),
112          typeof (IRealVectorCrossover),
113          typeof (IRealVectorManipulator),
114          typeof (IRealVectorStdDevStrategyParameterOperator),
115          typeof (IRealVectorSwarmUpdater),
116          typeof (IRealVectorParticleCreator),
117          typeof (IRealVectorParticleUpdater),
118          typeof (IRealVectorMultiNeighborhoodShakingOperator),
119          typeof (IRealVectorBoundsChecker),
120          typeof (IRealVectorMoveOperator),
121          typeof (IRealVectorMoveGenerator),
122          typeof (IRealVectorSolutionOperator),
123          typeof (IRealVectorSolutionsOperator),
124          typeof (IRealVectorBoundedOperator)
125      };
126    }
127    private void DiscoverOperators() {
128      var assembly = typeof(IRealVectorOperator).Assembly;
129      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, assembly, true, false, false);
130      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
131      var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
132
133      ConfigureOperators(newOperators);
134      foreach (var @operator in newOperators)
135        AddOperator(@operator);
136
137      foreach (var strategyVectorCreator in Operators.OfType<IRealVectorStdDevStrategyParameterCreator>())
138        strategyVectorCreator.BoundsParameter.ValueChanged += strategyVectorCreator_BoundsParameter_ValueChanged;
139    }
140    #endregion
141
142
143    private void strategyVectorCreator_BoundsParameter_ValueChanged(object sender, EventArgs e) {
144      var boundsParameter = (IValueLookupParameter<DoubleMatrix>)sender;
145      if (boundsParameter.Value == null) return;
146      foreach (var strategyVectorManipulator in Operators.OfType<IRealVectorStdDevStrategyParameterManipulator>())
147        strategyVectorManipulator.BoundsParameter.Value = (DoubleMatrix)boundsParameter.Value.Clone();
148    }
149
150    public override void ConfigureOperators(IEnumerable<IItem> operators) {
151      base.ConfigureOperators(operators);
152      ConfigureCreators(operators.OfType<IRealVectorCreator>());
153      ConfigureCrossovers(operators.OfType<IRealVectorCrossover>());
154      ConfigureManipulators(operators.OfType<IRealVectorManipulator>());
155      ConfigureStdDevStrategyParameterOperators(operators.OfType<IRealVectorStdDevStrategyParameterOperator>());
156      ConfigureSwarmUpdaters(operators.OfType<IRealVectorSwarmUpdater>());
157      ConfigureParticleCreators(operators.OfType<IRealVectorParticleCreator>());
158      ConfigureParticleUpdaters(operators.OfType<IRealVectorParticleUpdater>());
159      ConfigureShakingOperators(operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>());
160      ConfigureBoundsCheckers(operators.OfType<IRealVectorBoundsChecker>());
161      ConfigureMoveGenerators(operators.OfType<IRealVectorMoveGenerator>());
162      ConfigureMoveOperators(operators.OfType<IRealVectorMoveOperator>());
163      ConfigureAdditiveMoveOperator(operators.OfType<IRealVectorAdditiveMoveOperator>());
164      ConfigureRealVectorSolutionOperators(operators.OfType<IRealVectorSolutionOperator>());
165      ConfigureRealVectorSolutionsOperators(operators.OfType<IRealVectorSolutionsOperator>());
166      ConfigureRealVectorBoundedOperators(operators.OfType<IRealVectorBoundedOperator>());
167    }
168
169    #region Specific Operator Wiring
170    private void ConfigureCreators(IEnumerable<IRealVectorCreator> creators) {
171      foreach (var creator in creators) {
172        creator.LengthParameter.ActualName = LengthParameter.Name;
173      }
174    }
175    private void ConfigureCrossovers(IEnumerable<IRealVectorCrossover> crossovers) {
176      foreach (var crossover in crossovers) {
177        crossover.ChildParameter.ActualName = Name;
178        crossover.ParentsParameter.ActualName = Name;
179      }
180    }
181    private void ConfigureManipulators(IEnumerable<IRealVectorManipulator> manipulators) {
182      foreach (var manipulator in manipulators) {
183        var sm = manipulator as ISelfAdaptiveManipulator;
184        if (sm != null) {
185          var p = sm.StrategyParameterParameter as ILookupParameter;
186          if (p != null) {
187            p.ActualName = Name + ".Strategy";
188          }
189        }
190      }
191    }
192    private void ConfigureStdDevStrategyParameterOperators(IEnumerable<IRealVectorStdDevStrategyParameterOperator> strategyOperators) {
193      var bounds = new DoubleMatrix(Bounds.Rows, Bounds.Columns);
194      for (var i = 0; i < Bounds.Rows; i++) {
195        bounds[i, 0] = 0;
196        bounds[i, 1] = 0.1 * (Bounds[i, 1] - Bounds[i, 0]);
197      }
198      foreach (var s in strategyOperators) {
199        var c = s as IRealVectorStdDevStrategyParameterCreator;
200        if (c != null) {
201          c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
202          c.LengthParameter.ActualName = LengthParameter.Name;
203          c.StrategyParameterParameter.ActualName = Name + ".Strategy";
204        }
205        var m = s as IRealVectorStdDevStrategyParameterManipulator;
206        if (m != null) {
207          m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
208          m.StrategyParameterParameter.ActualName = Name + ".Strategy";
209        }
210        var mm = s as StdDevStrategyVectorManipulator;
211        if (mm != null) {
212          mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Length));
213          mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(Length)));
214        }
215        var x = s as IRealVectorStdDevStrategyParameterCrossover;
216        if (x != null) {
217          x.ParentsParameter.ActualName = Name + ".Strategy";
218          x.StrategyParameterParameter.ActualName = Name + ".Strategy";
219        }
220      }
221    }
222    private void ConfigureSwarmUpdaters(IEnumerable<IRealVectorSwarmUpdater> swarmUpdaters) {
223      // swarm updaters don't have additional parameters besides the solution parameter
224    }
225    private void ConfigureParticleCreators(IEnumerable<IRealVectorParticleCreator> particleCreators) {
226      foreach (var particleCreator in particleCreators) {
227      }
228    }
229    private void ConfigureParticleUpdaters(IEnumerable<IRealVectorParticleUpdater> particleUpdaters) {
230      // particle updaters don't have additional parameters besides solution and bounds parameter
231    }
232    private void ConfigureShakingOperators(IEnumerable<IRealVectorMultiNeighborhoodShakingOperator> shakingOperators) {
233      // shaking operators don't have additional parameters besides solution and bounds parameter
234    }
235    private void ConfigureBoundsCheckers(IEnumerable<IRealVectorBoundsChecker> boundsCheckers) {
236      foreach (var boundsChecker in boundsCheckers) {
237        boundsChecker.RealVectorParameter.ActualName = Name;
238        boundsChecker.BoundsParameter.ActualName = BoundsParameter.Name;
239      }
240    }
241    private void ConfigureMoveOperators(IEnumerable<IRealVectorMoveOperator> moveOperators) {
242      // move operators don't have additional parameters besides the solution parameter
243    }
244    private void ConfigureMoveGenerators(IEnumerable<IRealVectorMoveGenerator> moveGenerators) {
245      // move generators don't have additional parameters besides solution and bounds parameter
246    }
247    private void ConfigureAdditiveMoveOperator(IEnumerable<IRealVectorAdditiveMoveOperator> additiveMoveOperators) {
248      foreach (var additiveMoveOperator in additiveMoveOperators) {
249        additiveMoveOperator.AdditiveMoveParameter.ActualName = Name + ".AdditiveMove";
250      }
251    }
252    private void ConfigureRealVectorSolutionOperators(IEnumerable<IRealVectorSolutionOperator> solutionOperators) {
253      foreach (var solutionOperator in solutionOperators)
254        solutionOperator.RealVectorParameter.ActualName = Name;
255    }
256    private void ConfigureRealVectorSolutionsOperators(IEnumerable<IRealVectorSolutionsOperator> solutionsOperators) {
257      foreach (var solutionsOperator in solutionsOperators)
258        solutionsOperator.RealVectorParameter.ActualName = Name;
259    }
260    private void ConfigureRealVectorBoundedOperators(IEnumerable<IRealVectorBoundedOperator> boundedOperators) {
261      foreach (var boundedOperator in boundedOperators) {
262        boundedOperator.BoundsParameter.ActualName = BoundsParameter.Name;
263      }
264    }
265    #endregion
266
267    protected override void OnLengthChanged() {
268      ConfigureOperators(Operators);
269      base.OnLengthChanged();
270    }
271
272    public event EventHandler BoundsChanged;
273    private void OnBoundsChanged() {
274      BoundsChanged?.Invoke(this, EventArgs.Empty);
275    }
276  }
277}
Note: See TracBrowser for help on using the repository browser.