Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 17571 was 17571, checked in by mkommend, 4 years ago

#2521: Changed parameters to use readonly only for GUI manipulation.

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