Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Encodings/RealEncoding.cs @ 11582

Last change on this file since 11582 was 11582, checked in by mkommend, 9 years ago

#2174: Configured solution creator in single encodings.

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