Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProgrammableProblem.cs @ 11484

Last change on this file since 11484 was 11484, checked in by abeham, 8 years ago

#2174: Major refactoring

  • Removed ProblemDefinitionHosts
  • Renamed ParameterVector to Individual
  • Renamed Configuration to Encoding
  • Changed handling of existing operators that they will not be removed and recreated, but only rewired
File size: 44.5 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.Drawing;
25using System.Linq;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.BinaryVectorEncoding;
30using HeuristicLab.Encodings.IntegerVectorEncoding;
31using HeuristicLab.Encodings.PermutationEncoding;
32using HeuristicLab.Encodings.RealVectorEncoding;
33using HeuristicLab.Optimization;
34using HeuristicLab.Parameters;
35using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
36using HeuristicLab.PluginInfrastructure;
37
38namespace HeuristicLab.Problems.Programmable {
39  [Item("Programmable Problem (multi-objective)", "Represents a multi-objective problem that can be programmed.")]
40  [Creatable("Problems")]
41  [StorableClass]
42  public class MultiObjectiveProgrammableProblem : MultiObjectiveHeuristicOptimizationProblem<IMultiObjectiveProgrammableProblemEvaluator, ISolutionCreator>, IParameterizedNamedItem, IStorableContent {
43    public string Filename { get; set; }
44
45    public static new Image StaticItemImage {
46      get { return Common.Resources.VSImageLibrary.Script; }
47    }
48
49    public new ParameterCollection Parameters {
50      get { return base.Parameters; }
51    }
52    IKeyedItemCollection<string, IParameter> IParameterizedItem.Parameters {
53      get { return Parameters; }
54    }
55
56    public IValueParameter<IMultiObjectiveProblemDefinition> ProblemDefinitionParameter {
57      get { return (IValueParameter<IMultiObjectiveProblemDefinition>)Parameters["ProblemDefinition"]; }
58    }
59
60    protected IValueParameter<Encoding> EncodingParameter {
61      get { return (IValueParameter<Encoding>)Parameters["Encoding"]; }
62    }
63
64    public IMultiObjectiveProblemDefinition ProblemDefinition {
65      get { return ProblemDefinitionParameter.Value; }
66      set { ProblemDefinitionParameter.Value = value; }
67    }
68
69    [Storable]
70    protected List<IParameter> DynamicEncodingParameters;
71
72    [StorableConstructor]
73    protected MultiObjectiveProgrammableProblem(bool deserializing) : base(deserializing) { }
74    protected MultiObjectiveProgrammableProblem(MultiObjectiveProgrammableProblem original, Cloner cloner)
75      : base(original, cloner) {
76      DynamicEncodingParameters = original.DynamicEncodingParameters.Select(cloner.Clone).ToList();
77      RegisterEventHandlers();
78    }
79    public MultiObjectiveProgrammableProblem()
80      : base(new MultiObjectiveEvaluator(), new MultiEncodingCreator()) {
81      Parameters.Add(new ValueParameter<IMultiObjectiveProblemDefinition>("ProblemDefinition", "Defines the problem.", new MultiObjectiveProblemScript() { Name = Name }));
82      Parameters.Add(new ValueParameter<Encoding>("Encoding", "Describes which parameters exist, what they're called, what type they are and their bounds if any."));
83
84      DynamicEncodingParameters = new List<IParameter>();
85
86      Operators.Add(new MultiObjectiveAnalyzer());
87      Operators.Add(Evaluator);
88      Operators.Add(SolutionCreator);
89
90      RegisterEventHandlers();
91    }
92
93    public override IDeepCloneable Clone(Cloner cloner) {
94      return new MultiObjectiveProgrammableProblem(this, cloner);
95    }
96
97    [StorableHook(HookType.AfterDeserialization)]
98    // ReSharper disable UnusedMember.Local
99    private void AfterDeserialization() {
100      RegisterEventHandlers();
101    }
102    // ReSharper restore UnusedMember.Local
103
104    private void RegisterEventHandlers() {
105      ProblemDefinitionParameter.ValueChanged += ProblemDefinitionParameterOnValueChanged;
106      RegisterHostInstanceChanges();
107    }
108
109    private void ProblemDefinitionParameterOnValueChanged(object sender, EventArgs eventArgs) {
110      RegisterHostInstanceChanges();
111      Parameterize();
112    }
113
114    private void RegisterHostInstanceChanges() {
115      ProblemDefinitionParameter.Value.ProblemDefinitionChanged += ProblemDefinitionChanged;
116      ProblemDefinitionParameter.Value.NameChanged += ProblemDefinitionHostOnNameChanged;
117    }
118
119    private void ProblemDefinitionHostOnNameChanged(object sender, EventArgs eventArgs) {
120      if (sender != ProblemDefinitionParameter.Value) return;
121      Name = ProblemDefinitionParameter.Value.Name;
122    }
123
124    protected override void OnNameChanged() {
125      base.OnNameChanged();
126      ProblemDefinitionParameter.Value.Name = Name;
127    }
128
129    protected override void OnEvaluatorChanged() {
130      base.OnEvaluatorChanged();
131      Parameterize();
132    }
133
134    protected virtual void ProblemDefinitionChanged(object sender, EventArgs eventArgs) {
135      Parameterize();
136    }
137
138    protected virtual void Parameterize() {
139      var definition = ProblemDefinitionParameter.Value;
140      if (definition == null) return;
141
142      Encoding encoding;
143      try {
144        encoding = definition.Encoding;
145      } catch { return; }
146      EncodingParameter.Value = encoding;
147      Maximization = new BoolArray(definition.Maximization);
148
149      Evaluator.EncodingParameter.ActualName = EncodingParameter.Name;
150      Evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
151      foreach (var evalOp in Operators.OfType<IMultiObjectiveProgrammableProblemEvaluator>()) {
152        evalOp.EncodingParameter.ActualName = EncodingParameter.Name;
153        evalOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
154      }
155      foreach (var analyzeOp in Operators.OfType<IMultiObjectiveProgrammableProblemAnalyzer>()) {
156        analyzeOp.EncodingParameter.ActualName = EncodingParameter.Name;
157        analyzeOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
158        analyzeOp.QualitiesParameter.ActualName = Evaluator.QualitiesParameter.ActualName;
159      }
160
161      foreach (var param in DynamicEncodingParameters)
162        if (Parameters.Contains(param)) Parameters.Remove(param);
163      DynamicEncodingParameters.Clear();
164
165      var creator = ConfigureCreator(encoding);
166
167      foreach (var param in DynamicEncodingParameters) {
168        param.Hidden = true;
169        Parameters.Add(param);
170      }
171
172      var multiEncoding = encoding as MultiEncoding;
173      if (multiEncoding != null) {
174        ConfigureMultiVectorEncodingOperators((MultiEncodingCreator)creator, multiEncoding);
175      } else {
176        ConfigureSingleEncodingOperators(creator, encoding);
177      }
178    }
179
180    protected virtual ISolutionCreator ConfigureCreator(Encoding encoding) {
181      #region Configure MultiEncoding Creator
182      var multiEncoding = encoding as MultiEncoding;
183      if (multiEncoding != null) {
184        var creator = new MultiEncodingCreator();
185        foreach (var enc in multiEncoding.Encodings) {
186          if (enc is MultiEncoding) throw new InvalidOperationException("MultiEncoding within a MultiEncoding is not supported.");
187          creator.Operators.Add(ConfigureCreator(enc));
188        }
189        return creator;
190      }
191      #endregion
192      #region Configure BinaryVector Creator
193      var binEnc = encoding as BinaryEncoding;
194      if (binEnc != null) {
195        var p = new ValueParameter<IntValue>(binEnc.Name + "Length", binEnc.Length);
196        DynamicEncodingParameters.Add(p);
197
198        var creator = new RandomBinaryVectorCreator();
199        creator.BinaryVectorParameter.ActualName = binEnc.Name;
200        creator.LengthParameter.ActualName = p.Name;
201        return creator;
202      }
203      #endregion
204      #region Configure IntegerVector Creator
205      var intEnc = encoding as IntegerEncoding;
206      if (intEnc != null) {
207        var l = new ValueParameter<IntValue>(intEnc.Name + "Length", intEnc.Length);
208        var b = new ValueParameter<IntMatrix>(intEnc.Name + "Bounds", intEnc.Bounds);
209        DynamicEncodingParameters.Add(l);
210        DynamicEncodingParameters.Add(b);
211
212        var creator = new UniformRandomIntegerVectorCreator();
213        creator.IntegerVectorParameter.ActualName = intEnc.Name;
214        creator.LengthParameter.ActualName = l.Name;
215        creator.BoundsParameter.ActualName = b.Name;
216        return creator;
217      }
218      #endregion
219      #region Configure RealVector Creator
220      var realEnc = encoding as RealEncoding;
221      if (realEnc != null) {
222        var l = new ValueParameter<IntValue>(realEnc.Name + "Length", realEnc.Length);
223        var b = new ValueParameter<DoubleMatrix>(realEnc.Name + "Bounds", realEnc.Bounds);
224        DynamicEncodingParameters.Add(l);
225        DynamicEncodingParameters.Add(b);
226
227        var creator = new UniformRandomRealVectorCreator();
228        creator.RealVectorParameter.ActualName = realEnc.Name;
229        creator.LengthParameter.ActualName = l.Name;
230        creator.BoundsParameter.ActualName = b.Name;
231        return creator;
232      }
233      #endregion
234      #region Configure Permutation Creator
235      var permEnc = encoding as PermutationEncoding;
236      if (permEnc != null) {
237        var l = new ValueParameter<IntValue>(permEnc.Name + "Length", permEnc.Length);
238        DynamicEncodingParameters.Add(l);
239
240        var creator = new RandomPermutationCreator();
241        creator.PermutationParameter.ActualName = permEnc.Name;
242        creator.LengthParameter.ActualName = l.Name;
243        creator.PermutationTypeParameter.Value = permEnc.Type;
244        return creator;
245      }
246      #endregion
247      throw new ArgumentException(string.Format("Encoding {0} is unknown.", encoding != null ? encoding.GetType().FullName : "(null)"));
248    }
249
250    protected virtual void ConfigureSingleEncodingOperators(ISolutionCreator newCreator, Encoding encoding) {
251      // remove all multiencoding operators
252      Operators.RemoveAll(x => x is MultiEncodingCrossover
253                            || x is MultiEncodingManipulator
254                            || x is MultiEncodingCreator);
255
256      #region Configure Operators for BinaryVectorEncoding
257      var binCreator = newCreator as IBinaryVectorCreator;
258      if (binCreator != null) {
259        var paramName = binCreator.BinaryVectorParameter.ActualName;
260        // do not replace a binary vector creator that was manually set
261        if (!(SolutionCreator is IBinaryVectorCreator) || ((IBinaryVectorCreator)SolutionCreator).BinaryVectorParameter.ActualName != paramName) {
262          Operators.Remove(SolutionCreator);
263          SolutionCreator = newCreator;
264          Operators.Add(SolutionCreator);
265        }
266
267        #region Wire BinaryVector Crossovers
268        var crossovers = Operators.OfType<IBinaryVectorCrossover>()
269          .Union(ApplicationManager.Manager.GetInstances<IBinaryVectorCrossover>(), new TypeEqualityComparer<IBinaryVectorCrossover>())
270          .ToList();
271        foreach (var xo in crossovers) {
272          xo.ChildParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
273          xo.ChildParameter.Hidden = true;
274          xo.ParentsParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
275          xo.ParentsParameter.Hidden = true;
276        }
277        Operators.AddRange(crossovers.Except(Operators.OfType<IBinaryVectorCrossover>()));
278        #endregion
279        #region Wire BinaryVector Manipulators
280        var manipulators = Operators.OfType<IBinaryVectorManipulator>()
281          .Union(ApplicationManager.Manager.GetInstances<IBinaryVectorManipulator>(), new TypeEqualityComparer<IBinaryVectorManipulator>())
282          .ToList();
283        foreach (var m in manipulators) {
284          m.BinaryVectorParameter.ActualName = binCreator.BinaryVectorParameter.ActualName;
285          m.BinaryVectorParameter.Hidden = true;
286        }
287        Operators.AddRange(manipulators.Except(Operators.OfType<IBinaryVectorManipulator>()));
288        #endregion
289        #region Wire BinaryVector ShakingOperators
290        var shakingOperators = Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>()
291          .Union(ApplicationManager.Manager.GetInstances<IBinaryVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IBinaryVectorMultiNeighborhoodShakingOperator>())
292          .ToList();
293        foreach (var so in shakingOperators) {
294          so.BinaryVectorParameter.ActualName = paramName;
295          so.BinaryVectorParameter.Hidden = true;
296        }
297        Operators.AddRange(shakingOperators.Except(Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>()));
298        #endregion
299      } else {
300        Operators.RemoveAll(x => x is IBinaryVectorCrossover
301          || x is IBinaryVectorManipulator
302          || x is IBinaryVectorMultiNeighborhoodShakingOperator);
303      }
304      #endregion
305      #region Configure Operators for IntegerVectorEncoding
306      var intCreator = newCreator as IIntegerVectorCreator;
307      if (intCreator != null) {
308        var paramName = intCreator.IntegerVectorParameter.ActualName;
309        // do not replace an integer vector creator that was manually set
310        if (!(SolutionCreator is IIntegerVectorCreator)
311          || ((IIntegerVectorCreator)SolutionCreator).IntegerVectorParameter.ActualName != intCreator.IntegerVectorParameter.ActualName) {
312          Operators.Remove(SolutionCreator);
313          SolutionCreator = newCreator;
314          Operators.Add(SolutionCreator);
315        }
316
317        #region Wire IntegerVector Crossovers
318        var crossovers = Operators.OfType<IIntegerVectorCrossover>()
319          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorCrossover>(), new TypeEqualityComparer<IIntegerVectorCrossover>())
320          .ToList();
321        foreach (var xo in crossovers) {
322          xo.ChildParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
323          xo.ChildParameter.Hidden = true;
324          xo.ParentsParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
325          xo.ParentsParameter.Hidden = true;
326          var bx = xo as IBoundedIntegerVectorOperator;
327          if (bx != null) {
328            bx.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName;
329            bx.BoundsParameter.Hidden = true;
330          }
331        }
332        Operators.AddRange(crossovers.Except(Operators.OfType<IIntegerVectorCrossover>()));
333        #endregion
334        #region Wire IntegerVector Manipulators
335        var manipulators = Operators.OfType<IIntegerVectorManipulator>()
336          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorManipulator>(), new TypeEqualityComparer<IIntegerVectorManipulator>())
337          .ToList();
338        foreach (var m in manipulators) {
339          m.IntegerVectorParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
340          m.IntegerVectorParameter.Hidden = true;
341          var sm = m as ISelfAdaptiveManipulator;
342          if (sm != null) {
343            var p = sm.StrategyParameterParameter as ILookupParameter;
344            if (p != null) {
345              p.ActualName = paramName + "Strategy";
346              p.Hidden = true;
347            }
348          }
349          var bm = m as IBoundedIntegerVectorOperator;
350          if (bm != null) {
351            bm.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName;
352            bm.BoundsParameter.Hidden = true;
353          }
354        }
355        Operators.AddRange(manipulators.Except(Operators.OfType<IIntegerVectorManipulator>()));
356        #region Wire IntegerVector StrategyParameters for SelfAdaptiveManipulators
357        var strategyOperators = Operators.OfType<IIntegerVectorStdDevStrategyParameterOperator>()
358          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorStdDevStrategyParameterOperator>(), new TypeEqualityComparer<IIntegerVectorStdDevStrategyParameterOperator>())
359          .ToList();
360        var problemSize = ((IntegerEncoding)encoding).Length.Value;
361        var b = ((IntegerEncoding)encoding).Bounds;
362        var bounds = new DoubleMatrix(b.Rows, b.Columns);
363        for (var i = 0; i < bounds.Rows; i++) {
364          bounds[i, 1] = (int)Math.Ceiling(0.33 * (b[i, 1] - b[i, 0]));
365          bounds[i, 0] = 0;
366          if (bounds.Columns > 2) bounds[i, 2] = b[i, 2];
367        }
368        foreach (var s in strategyOperators) {
369          var c = s as IIntegerVectorStdDevStrategyParameterCreator;
370          if (c != null) {
371            c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
372            c.LengthParameter.ActualName = intCreator.LengthParameter.ActualName;
373            c.StrategyParameterParameter.ActualName = paramName + "Strategy";
374          }
375          var m = s as IIntegerVectorStdDevStrategyParameterManipulator;
376          if (m != null) {
377            m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
378            m.StrategyParameterParameter.ActualName = paramName + "Strategy";
379          }
380          var mm = s as Encodings.IntegerVectorEncoding.StdDevStrategyVectorManipulator;
381          if (mm != null) {
382            mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * problemSize));
383            mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(problemSize)));
384          }
385          var x = s as IIntegerVectorStdDevStrategyParameterCrossover;
386          if (x != null) {
387            x.ParentsParameter.ActualName = paramName + "Strategy";
388            x.StrategyParameterParameter.ActualName = paramName + "Strategy";
389          }
390        }
391        Operators.AddRange(strategyOperators.Except(Operators.OfType<IIntegerVectorStdDevStrategyParameterOperator>()));
392        #endregion
393        #endregion
394        #region Wire IntegerVector ShakingOperators
395        var shakingOperators = Operators.OfType<IIntegerVectorMultiNeighborhoodShakingOperator>()
396          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IIntegerVectorMultiNeighborhoodShakingOperator>())
397          .ToList();
398        foreach (var so in shakingOperators) {
399          so.IntegerVectorParameter.ActualName = paramName;
400          so.IntegerVectorParameter.Hidden = true;
401        }
402        Operators.AddRange(shakingOperators.Except(Operators.OfType<IIntegerVectorMultiNeighborhoodShakingOperator>()));
403        #endregion
404      } else {
405        Operators.RemoveAll(x => x is IIntegerVectorCrossover
406          || x is IIntegerVectorManipulator
407          || x is IIntegerVectorStdDevStrategyParameterOperator
408          || x is IIntegerVectorMultiNeighborhoodShakingOperator);
409      }
410      #endregion
411      #region Configure Operators for RealVectorEncoding
412      var realCreator = newCreator as IRealVectorCreator;
413      if (realCreator != null) {
414        var paramName = realCreator.RealVectorParameter.ActualName;
415        // do not replace a real vector creator that was manually set
416        if (!(SolutionCreator is IRealVectorCreator)
417            || ((IRealVectorCreator)SolutionCreator).RealVectorParameter.ActualName != realCreator.RealVectorParameter.ActualName) {
418          Operators.Remove(SolutionCreator);
419          SolutionCreator = newCreator;
420          Operators.Add(SolutionCreator);
421        }
422
423        #region Wire RealVector Crossovers
424        var crossovers = Operators.OfType<IRealVectorCrossover>()
425          .Union(ApplicationManager.Manager.GetInstances<IRealVectorCrossover>(), new TypeEqualityComparer<IRealVectorCrossover>())
426          .ToList();
427        foreach (var xo in crossovers) {
428          xo.ChildParameter.ActualName = paramName;
429          xo.ChildParameter.Hidden = true;
430          xo.ParentsParameter.ActualName = paramName;
431          xo.ParentsParameter.Hidden = true;
432          xo.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
433          xo.BoundsParameter.Hidden = true;
434        }
435        Operators.AddRange(crossovers.Except(Operators.OfType<IRealVectorCrossover>()));
436        #endregion
437        #region Wire RealVector Manipulators
438        var manipulators = Operators.OfType<IRealVectorManipulator>()
439          .Union(ApplicationManager.Manager.GetInstances<IRealVectorManipulator>(), new TypeEqualityComparer<IRealVectorManipulator>())
440          .ToList();
441        foreach (var m in manipulators) {
442          m.RealVectorParameter.ActualName = paramName;
443          m.RealVectorParameter.Hidden = true;
444          m.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
445          m.BoundsParameter.Hidden = true;
446          var sm = m as ISelfAdaptiveManipulator;
447          if (sm != null) {
448            var p = sm.StrategyParameterParameter as ILookupParameter;
449            if (p != null) {
450              p.ActualName = paramName + "Strategy";
451              p.Hidden = true;
452            }
453          }
454        }
455        Operators.AddRange(manipulators.Except(Operators.OfType<IRealVectorManipulator>()));
456        #region Wire RealVector Strategy Parameters for SelfAdaptiveManipulators
457        var strategyOperators = Operators.OfType<IRealVectorStdDevStrategyParameterOperator>()
458          .Union(ApplicationManager.Manager.GetInstances<IRealVectorStdDevStrategyParameterOperator>(), new TypeEqualityComparer<IRealVectorStdDevStrategyParameterOperator>())
459          .ToList();
460        var problemSize = ((RealEncoding)encoding).Length.Value;
461        var bounds = (DoubleMatrix)((RealEncoding)encoding).Bounds.Clone();
462        for (var i = 0; i < bounds.Rows; i++) {
463          bounds[i, 1] = 0.1 * (bounds[i, 1] - bounds[i, 0]);
464          bounds[i, 0] = 0;
465        }
466        foreach (var s in strategyOperators) {
467          var c = s as IRealVectorStdDevStrategyParameterCreator;
468          if (c != null) {
469            c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
470            c.LengthParameter.ActualName = realCreator.LengthParameter.ActualName;
471            c.StrategyParameterParameter.ActualName = paramName + "Strategy";
472          }
473          var m = s as IRealVectorStdDevStrategyParameterManipulator;
474          if (m != null) {
475            m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
476            m.StrategyParameterParameter.ActualName = paramName + "Strategy";
477          }
478          var mm = s as Encodings.RealVectorEncoding.StdDevStrategyVectorManipulator;
479          if (mm != null) {
480            mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * problemSize));
481            mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(problemSize)));
482          }
483          var x = s as IRealVectorStdDevStrategyParameterCrossover;
484          if (x != null) {
485            x.ParentsParameter.ActualName = paramName + "Strategy";
486            x.StrategyParameterParameter.ActualName = paramName + "Strategy";
487          }
488        }
489        Operators.AddRange(strategyOperators.Except(Operators.OfType<IRealVectorStdDevStrategyParameterOperator>()));
490        #endregion
491        #endregion
492        #region Wire RealVector ParticleCreators
493        var particleCreators = Operators.OfType<IRealVectorParticleCreator>()
494          .Union(ApplicationManager.Manager.GetInstances<IRealVectorParticleCreator>(), new TypeEqualityComparer<IRealVectorParticleCreator>())
495          .ToList();
496        foreach (var pc in particleCreators) {
497          pc.RealVectorParameter.ActualName = paramName;
498          pc.RealVectorParameter.Hidden = true;
499          pc.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
500          pc.BoundsParameter.Hidden = true;
501          pc.ProblemSizeParameter.ActualName = realCreator.LengthParameter.ActualName;
502          pc.ProblemSizeParameter.Hidden = true;
503        }
504        Operators.AddRange(particleCreators.Except(Operators.OfType<IRealVectorParticleCreator>()));
505        #endregion
506        #region Wire RealVector ParticleUpdaters
507        var particleUpdaters = Operators.OfType<IRealVectorParticleUpdater>()
508          .Union(ApplicationManager.Manager.GetInstances<IRealVectorParticleUpdater>(), new TypeEqualityComparer<IRealVectorParticleUpdater>())
509          .ToList();
510        foreach (var pu in particleUpdaters) {
511          pu.RealVectorParameter.ActualName = paramName;
512          pu.RealVectorParameter.Hidden = true;
513          pu.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName;
514          pu.BoundsParameter.Hidden = true;
515        }
516        Operators.AddRange(particleUpdaters.Except(Operators.OfType<IRealVectorParticleUpdater>()));
517        #endregion
518        #region Wire RealVector SwarmUpdaters
519        var swarmUpdaters = Operators.OfType<IRealVectorSwarmUpdater>()
520          .Union(ApplicationManager.Manager.GetInstances<IRealVectorSwarmUpdater>(), new TypeEqualityComparer<IRealVectorSwarmUpdater>())
521          .ToList();
522        foreach (var su in swarmUpdaters) {
523          su.RealVectorParameter.ActualName = paramName;
524          su.RealVectorParameter.Hidden = true;
525          su.MaximizationParameter.ActualName = MaximizationParameter.Name;
526          su.MaximizationParameter.Hidden = true;
527        }
528        Operators.AddRange(swarmUpdaters.Except(Operators.OfType<IRealVectorSwarmUpdater>()));
529        #endregion
530        #region Wire RealVector ShakingOperators
531        var shakingOperators = Operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>()
532          .Union(ApplicationManager.Manager.GetInstances<IRealVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IRealVectorMultiNeighborhoodShakingOperator>())
533          .ToList();
534        foreach (var so in shakingOperators) {
535          so.RealVectorParameter.ActualName = paramName;
536          so.RealVectorParameter.Hidden = true;
537        }
538        Operators.AddRange(shakingOperators.Except(Operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>()));
539        #endregion
540      } else {
541        Operators.RemoveAll(x => x is IRealVectorCrossover
542          || x is IRealVectorManipulator
543          || x is IRealVectorStdDevStrategyParameterOperator
544          || x is IRealVectorParticleCreator
545          || x is IRealVectorParticleUpdater
546          || x is IRealVectorSwarmUpdater
547          || x is IRealVectorMultiNeighborhoodShakingOperator);
548      }
549      #endregion
550      #region Configure Operators for PermutationEncoding
551      var permCreator = newCreator as IPermutationCreator;
552      if (permCreator != null) {
553        var paramName = permCreator.PermutationParameter.ActualName;
554        // do not replace a permutation creator that was manually set
555        if (!(SolutionCreator is IPermutationCreator)
556            || ((IPermutationCreator)SolutionCreator).PermutationParameter.ActualName != permCreator.PermutationParameter.ActualName) {
557          Operators.Remove(SolutionCreator);
558          SolutionCreator = newCreator;
559          Operators.Add(SolutionCreator);
560        }
561
562        #region Wire Permutation Crossovers
563        var crossovers = Operators.OfType<IPermutationCrossover>()
564          .Union(ApplicationManager.Manager.GetInstances<IPermutationCrossover>(), new TypeEqualityComparer<IPermutationCrossover>())
565          .ToList();
566        foreach (var xo in crossovers) {
567          xo.ChildParameter.ActualName = permCreator.PermutationParameter.ActualName;
568          xo.ChildParameter.Hidden = true;
569          xo.ParentsParameter.ActualName = permCreator.PermutationParameter.ActualName;
570          xo.ParentsParameter.Hidden = true;
571        }
572        Operators.AddRange(crossovers.Except(Operators.OfType<IPermutationCrossover>()));
573        #endregion
574        #region Wire Permutation Manipulators
575        var manipulators = Operators.OfType<IPermutationManipulator>()
576          .Union(ApplicationManager.Manager.GetInstances<IPermutationManipulator>(), new TypeEqualityComparer<IPermutationManipulator>())
577          .ToList();
578        foreach (var m in manipulators) {
579          m.PermutationParameter.ActualName = permCreator.PermutationParameter.ActualName;
580          m.PermutationParameter.Hidden = true;
581        }
582        Operators.AddRange(manipulators.Except(Operators.OfType<IPermutationManipulator>()));
583        #endregion
584        #region Wire Permutation ShakingOperators
585        var shakingOperators = Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()
586          .Union(ApplicationManager.Manager.GetInstances<IPermutationMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IPermutationMultiNeighborhoodShakingOperator>())
587          .ToList();
588        foreach (var op in shakingOperators) {
589          op.PermutationParameter.ActualName = paramName;
590          op.PermutationParameter.Hidden = true;
591        }
592        Operators.AddRange(shakingOperators.Except(Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()));
593        #endregion
594      } else {
595        Operators.RemoveAll(x => x is IPermutationCrossover
596          || x is IPermutationManipulator
597          || x is IPermutationMultiNeighborhoodShakingOperator);
598      }
599      #endregion
600    }
601
602    protected virtual void ConfigureMultiVectorEncodingOperators(MultiEncodingCreator newCreator, MultiEncoding encoding) {
603      var newBinParams = new HashSet<string>(newCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
604      var newIntParams = new HashSet<string>(newCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
605      var newRealParams = new HashSet<string>(newCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
606      var newPermParams = new HashSet<string>(newCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
607
608      var oldCreator = SolutionCreator as MultiEncodingCreator;
609      if (oldCreator == null) SolutionCreator = newCreator;
610      else {
611        #region Configure BinaryVector Creator
612        var oldBinParams = new HashSet<string>(oldCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
613        foreach (var toAdd in newBinParams.Except(oldBinParams)) {
614          oldCreator.Operators.Add(newCreator.Operators.OfType<IBinaryVectorCreator>().Single(x => x.BinaryVectorParameter.ActualName == toAdd));
615        }
616        foreach (var toRemove in oldBinParams.Except(newBinParams)) {
617          var op = oldCreator.Operators.OfType<IBinaryVectorCreator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
618          if (op != null) oldCreator.Operators.Remove(op);
619        }
620        #endregion
621
622        #region Configure IntegerVector Creator
623        var oldIntParams = new HashSet<string>(oldCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
624        foreach (var toAdd in newIntParams.Except(oldIntParams)) {
625          oldCreator.Operators.Add(newCreator.Operators.OfType<IIntegerVectorCreator>().Single(x => x.IntegerVectorParameter.ActualName == toAdd));
626        }
627        foreach (var toRemove in oldIntParams.Except(newIntParams)) {
628          var op = oldCreator.Operators.OfType<IIntegerVectorCreator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
629          if (op != null) oldCreator.Operators.Remove(op);
630        }
631        #endregion
632
633        #region Configure RealVector Creator
634        var oldRealParams = new HashSet<string>(oldCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
635        foreach (var toAdd in newRealParams.Except(oldRealParams)) {
636          oldCreator.Operators.Add(newCreator.Operators.OfType<IRealVectorCreator>().Single(x => x.RealVectorParameter.ActualName == toAdd));
637        }
638        foreach (var toRemove in oldRealParams.Except(newRealParams)) {
639          var op = oldCreator.Operators.OfType<IRealVectorCreator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
640          if (op != null) oldCreator.Operators.Remove(op);
641        }
642        #endregion
643
644        #region Configure Permutation Creator
645        var oldPermParams = new HashSet<string>(oldCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
646        foreach (var toAdd in newPermParams.Except(oldPermParams)) {
647          oldCreator.Operators.Add(newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == toAdd));
648        }
649        foreach (var toRemove in oldPermParams.Except(newPermParams)) {
650          var op = oldCreator.Operators.OfType<IPermutationCreator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
651          if (op != null) oldCreator.Operators.Remove(op);
652        }
653        // we also have to sync the permutation type (in case this changes, as it is a value parameter)
654        foreach (var intersect in newPermParams.Intersect(oldPermParams)) {
655          var oldPermCreator = oldCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
656          var newPermCreator = newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
657          oldPermCreator.PermutationTypeParameter.Value = newPermCreator.PermutationTypeParameter.Value;
658        }
659        #endregion
660
661      }
662
663      // crossover and manipulator for multi-vector encoding
664      // the condition checks if a multi-vector encoding is to be updated (there already exists ParameterVectorCrossover and ParameterVectorManipulator)
665      if (Operators.OfType<MultiEncodingCrossover>().Any() && Operators.OfType<MultiEncodingManipulator>().Any()) {
666        #region Update existing multi-vector encoding
667        #region Update ParameterVector Crossover ...
668        foreach (var oldXo in Operators.OfType<MultiEncodingCrossover>()) {
669          #region ... for binary parameters
670          var oldBinParams = new HashSet<string>(oldXo.Operators.OfType<IBinaryVectorCrossover>().Select(x => x.ChildParameter.ActualName));
671          foreach (var toAdd in newBinParams.Except(oldBinParams))
672            oldXo.Operators.Add(GetDefaultBinaryCrossover(toAdd, encoding));
673          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
674            var op = oldXo.Operators.OfType<IBinaryVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
675            if (op != null) oldXo.Operators.Remove(op);
676          }
677          #endregion
678          #region ... for integer parameters
679          var oldIntParams = new HashSet<string>(oldXo.Operators.OfType<IIntegerVectorCrossover>().Select(x => x.ChildParameter.ActualName));
680          foreach (var toAdd in newIntParams.Except(oldIntParams))
681            oldXo.Operators.Add(GetDefaultIntegerCrossover(toAdd, encoding));
682          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
683            var op = oldXo.Operators.OfType<IIntegerVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
684            if (op != null) oldXo.Operators.Remove(op);
685          }
686          #endregion
687          #region ... for real parameters
688          var oldRealParams = new HashSet<string>(oldXo.Operators.OfType<IRealVectorCrossover>().Select(x => x.ChildParameter.ActualName));
689          foreach (var toAdd in newRealParams.Except(oldRealParams))
690            oldXo.Operators.Add(GetDefaultRealCrossover(toAdd, encoding));
691          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
692            var op = oldXo.Operators.OfType<IRealVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
693            if (op != null) oldXo.Operators.Remove(op);
694          }
695          #endregion
696          #region ... for permutation parameters
697          var oldPermParams = new HashSet<string>(oldXo.Operators.OfType<IPermutationCrossover>().Select(x => x.ChildParameter.ActualName));
698          foreach (var toAdd in newPermParams.Except(oldPermParams))
699            oldXo.Operators.Add(GetDefaultPermutationCrossover(toAdd, encoding));
700          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
701            var op = oldXo.Operators.OfType<IPermutationCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
702            if (op != null) oldXo.Operators.Remove(op);
703          }
704          #endregion
705        }
706        #endregion
707        #region Update ParameterVector Manipulator ...
708        foreach (var oldM in Operators.OfType<MultiEncodingManipulator>()) {
709          #region ... for binary parameters
710          var oldBinParams = new HashSet<string>(oldM.Operators.OfType<IBinaryVectorManipulator>().Select(x => x.BinaryVectorParameter.ActualName));
711          foreach (var toAdd in newBinParams.Except(oldBinParams))
712            oldM.Operators.Add(GetDefaultBinaryManipulator(toAdd, encoding));
713          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
714            var op = oldM.Operators.OfType<IBinaryVectorManipulator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
715            if (op != null) oldM.Operators.Remove(op);
716          }
717          #endregion
718          #region ... for integer parameters
719          var oldIntParams = new HashSet<string>(oldM.Operators.OfType<IIntegerVectorManipulator>().Select(x => x.IntegerVectorParameter.ActualName));
720          foreach (var toAdd in newIntParams.Except(oldIntParams))
721            oldM.Operators.Add(GetDefaultIntegerManipulator(toAdd, encoding));
722          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
723            var op = oldM.Operators.OfType<IIntegerVectorManipulator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
724            if (op != null) oldM.Operators.Remove(op);
725          }
726          #endregion
727          #region ... for real parameters
728          var oldRealParams = new HashSet<string>(oldM.Operators.OfType<IRealVectorManipulator>().Select(x => x.RealVectorParameter.ActualName));
729          foreach (var toAdd in newRealParams.Except(oldRealParams))
730            oldM.Operators.Add(GetDefaultRealManipulator(toAdd, encoding));
731          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
732            var op = oldM.Operators.OfType<IRealVectorManipulator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
733            if (op != null) oldM.Operators.Remove(op);
734          }
735          #endregion
736          #region ... for permutation parameters
737          var oldPermParams = new HashSet<string>(oldM.Operators.OfType<IPermutationManipulator>().Select(x => x.PermutationParameter.ActualName));
738          foreach (var toAdd in newPermParams.Except(oldPermParams))
739            oldM.Operators.Add(GetDefaultPermutationManipulator(toAdd, encoding));
740          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
741            var op = oldM.Operators.OfType<IPermutationManipulator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
742            if (op != null) oldM.Operators.Remove(op);
743          }
744          #endregion
745        }
746        #endregion
747        #endregion
748      } else {
749        #region Handle transition from single-vector to multi-vector encoding
750        Operators.RemoveAll(x => x is ICrossover);
751        Operators.RemoveAll(x => x is IManipulator);
752        Operators.RemoveAll(x => x is IStrategyParameterCreator || x is IStrategyParameterManipulator || x is IStrategyParameterCrossover);
753        Operators.RemoveAll(x => x is IParticleCreator);
754        Operators.RemoveAll(x => x is IParticleUpdater);
755        Operators.RemoveAll(x => x is ISwarmUpdater);
756        Operators.RemoveAll(x => x is IMultiNeighborhoodShakingOperator);
757
758        var crossover = new MultiEncodingCrossover();
759        var manipulator = new MultiEncodingManipulator();
760        foreach (var enc in encoding.Encodings) {
761          if (enc is BinaryEncoding) {
762            crossover.Operators.Add(GetDefaultBinaryCrossover(enc.Name, encoding));
763            manipulator.Operators.Add(GetDefaultBinaryManipulator(enc.Name, encoding));
764            continue;
765          }
766          var intConfig = enc as IntegerEncoding;
767          if (intConfig != null) {
768            crossover.Operators.Add(GetDefaultIntegerCrossover(enc.Name, encoding));
769            manipulator.Operators.Add(GetDefaultIntegerManipulator(enc.Name, encoding));
770            continue;
771          }
772          var realConfig = enc as RealEncoding;
773          if (realConfig != null) {
774            crossover.Operators.Add(GetDefaultRealCrossover(enc.Name, encoding));
775            manipulator.Operators.Add(GetDefaultRealManipulator(enc.Name, encoding));
776            continue;
777          }
778          var permConfig = enc as PermutationEncoding;
779          if (permConfig != null) {
780            crossover.Operators.Add(GetDefaultPermutationCrossover(enc.Name, encoding));
781            manipulator.Operators.Add(GetDefaultPermutationManipulator(enc.Name, encoding));
782            continue;
783          }
784          throw new InvalidOperationException("Unknown type for parameter " + enc.Name);
785        }
786        Operators.Add(crossover);
787        Operators.Add(manipulator);
788        #endregion
789      }
790    }
791
792    #region GetDefaultOperators for Crossovers and Manipulators
793    // ReSharper disable RedundantNameQualifier
794    protected virtual IBinaryVectorCrossover GetDefaultBinaryCrossover(string paramName, MultiEncoding config) {
795      var binConfig = (BinaryEncoding)config.Encodings[paramName];
796      IBinaryVectorCrossover binXo;
797      if (binConfig.Length.Value > 3) binXo = new Encodings.BinaryVectorEncoding.SinglePointCrossover();
798      else binXo = new Encodings.BinaryVectorEncoding.UniformCrossover();
799      binXo.ChildParameter.ActualName = paramName;
800      binXo.ParentsParameter.ActualName = paramName;
801      return binXo;
802    }
803
804    protected virtual IBinaryVectorManipulator GetDefaultBinaryManipulator(string paramName, MultiEncoding config) {
805      var binM = new Encodings.BinaryVectorEncoding.SomePositionsBitflipManipulator();
806      binM.BinaryVectorParameter.ActualName = paramName;
807      binM.MutationProbabilityParameter.Value = new DoubleValue(0.1);
808      return binM;
809    }
810
811    protected virtual IIntegerVectorCrossover GetDefaultIntegerCrossover(string paramName, MultiEncoding config) {
812      var intXo = new Encodings.IntegerVectorEncoding.RoundedBlendAlphaCrossover();
813      intXo.ChildParameter.ActualName = paramName;
814      intXo.ParentsParameter.ActualName = paramName;
815      intXo.BoundsParameter.ActualName = paramName + "Bounds";
816      return intXo;
817    }
818
819    protected virtual IIntegerVectorManipulator GetDefaultIntegerManipulator(string paramName, MultiEncoding configuration) {
820      var intM = new Encodings.IntegerVectorEncoding.UniformSomePositionsManipulator();
821      intM.IntegerVectorParameter.ActualName = paramName;
822      intM.BoundsParameter.ActualName = paramName + "Bounds";
823      intM.ProbabilityParameter.Value = new DoubleValue(0.1);
824      return intM;
825    }
826
827    protected virtual IRealVectorCrossover GetDefaultRealCrossover(string paramName, MultiEncoding configuration) {
828      var realXo = new Encodings.RealVectorEncoding.BlendAlphaCrossover();
829      realXo.ChildParameter.ActualName = paramName;
830      realXo.ParentsParameter.ActualName = paramName;
831      realXo.BoundsParameter.ActualName = paramName + "Bounds";
832      return realXo;
833    }
834
835    protected virtual IRealVectorManipulator GetDefaultRealManipulator(string paramName, MultiEncoding configuration) {
836      var realM = new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator();
837      realM.RealVectorParameter.ActualName = paramName;
838      realM.BoundsParameter.ActualName = paramName + "Bounds";
839      return realM;
840    }
841
842    protected virtual IPermutationCrossover GetDefaultPermutationCrossover(string paramName, MultiEncoding configuration) {
843      var permXo = new Encodings.PermutationEncoding.PartiallyMatchedCrossover();
844      permXo.ChildParameter.ActualName = paramName;
845      permXo.ParentsParameter.ActualName = paramName;
846      return permXo;
847    }
848
849    protected virtual IPermutationManipulator GetDefaultPermutationManipulator(string paramName, MultiEncoding configuration) {
850      var permM = new Encodings.PermutationEncoding.Swap2Manipulator();
851      permM.PermutationParameter.ActualName = paramName;
852      return permM;
853    }
854    // ReSharper restore RedundantNameQualifier
855    #endregion
856  }
857}
Note: See TracBrowser for help on using the repository browser.