Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 11550 was 11550, checked in by mkommend, 10 years ago

#2174: Updated IEncoding interface, adapted problems and refactored operator discovery in realencoding

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