Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2174: Adapted binary encoding to new wiring method.

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