Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2174: Adapted binary encoding to new wiring method.

File size: 37.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using HeuristicLab.Analysis;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Encodings.BinaryVectorEncoding;
31using HeuristicLab.Encodings.IntegerVectorEncoding;
32using HeuristicLab.Encodings.PermutationEncoding;
33using HeuristicLab.Encodings.RealVectorEncoding;
34using HeuristicLab.Optimization;
35using HeuristicLab.Parameters;
36using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
37using HeuristicLab.PluginInfrastructure;
38
39namespace HeuristicLab.Problems.Programmable {
40  [Item("Programmable Problem (single-objective)", "Represents a single-objective problem that can be programmed.")]
41  [Creatable("Problems")]
42  [StorableClass]
43  public class SingleObjectiveProgrammableProblem : SingleObjectiveHeuristicOptimizationProblem<ISingleObjectiveProgrammableProblemEvaluator, ISolutionCreator>, IParameterizedNamedItem, IStorableContent {
44    public string Filename { get; set; }
45
46    public static new Image StaticItemImage {
47      get { return Common.Resources.VSImageLibrary.Script; }
48    }
49
50    public new ParameterCollection Parameters {
51      get { return base.Parameters; }
52    }
53    IKeyedItemCollection<string, IParameter> IParameterizedItem.Parameters {
54      get { return Parameters; }
55    }
56
57    public IValueParameter<ISingleObjectiveProblemDefinition> ProblemDefinitionParameter {
58      get { return (IValueParameter<ISingleObjectiveProblemDefinition>)Parameters["ProblemDefinition"]; }
59    }
60
61    protected IValueParameter<IEncoding> EncodingParameter {
62      get { return (IValueParameter<IEncoding>)Parameters["Encoding"]; }
63    }
64
65
66    public ISingleObjectiveProblemDefinition ProblemDefinition {
67      get { return ProblemDefinitionParameter.Value; }
68      set { ProblemDefinitionParameter.Value = value; }
69    }
70
71    [Storable]
72    protected List<IParameter> DynamicEncodingParameters;
73
74    protected override IEnumerable<IItem> GetOperators() {
75      return base.GetOperators().Concat(ProblemDefinition.Encoding.Operators);
76    }
77
78    [StorableConstructor]
79    protected SingleObjectiveProgrammableProblem(bool deserializing) : base(deserializing) { }
80
81    protected SingleObjectiveProgrammableProblem(SingleObjectiveProgrammableProblem original, Cloner cloner)
82      : base(original, cloner) {
83      DynamicEncodingParameters = original.DynamicEncodingParameters.Select(cloner.Clone).ToList();
84      RegisterEventHandlers();
85    }
86    public SingleObjectiveProgrammableProblem()
87      : base(new SingleObjectiveEvaluator(), new MultiEncodingCreator()) {
88      Parameters.Add(new ValueParameter<ISingleObjectiveProblemDefinition>("ProblemDefinition", "Defines the problem.", new SingleObjectiveProblemScript() { Name = Name }));
89      Parameters.Add(new ValueParameter<IEncoding>("Encoding", "Describes the configuration of the encoding, what the variables are called, what type they are and their bounds if any."));
90
91      DynamicEncodingParameters = new List<IParameter>();
92
93      Operators.Add(new BestScopeSolutionAnalyzer());
94      Operators.Add(new SingleObjectiveAnalyzer());
95      Operators.Add(Evaluator);
96      Operators.Add(SolutionCreator);
97
98      RegisterEventHandlers();
99    }
100
101    public override IDeepCloneable Clone(Cloner cloner) {
102      return new SingleObjectiveProgrammableProblem(this, cloner);
103    }
104
105    [StorableHook(HookType.AfterDeserialization)]
106    // ReSharper disable UnusedMember.Local
107    private void AfterDeserialization() {
108      RegisterEventHandlers();
109    }
110    // ReSharper restore UnusedMember.Local
111
112    private void RegisterEventHandlers() {
113      ProblemDefinitionParameter.ValueChanged += ProblemDefinitionParameterOnValueChanged;
114      RegisterProblemDefinitionEventHandlers();
115    }
116
117    private void ProblemDefinitionParameterOnValueChanged(object sender, EventArgs eventArgs) {
118      RegisterProblemDefinitionEventHandlers();
119      Parameterize();
120    }
121
122    private void RegisterProblemDefinitionEventHandlers() {
123      ProblemDefinitionParameter.Value.ProblemDefinitionChanged += ProblemDefinitionChanged;
124      ProblemDefinitionParameter.Value.NameChanged += ProblemDefinitionNameChanged;
125    }
126
127    private void ProblemDefinitionNameChanged(object sender, EventArgs eventArgs) {
128      if (sender != ProblemDefinitionParameter.Value) return;
129      Name = ProblemDefinitionParameter.Value.Name;
130    }
131
132    protected override void OnNameChanged() {
133      base.OnNameChanged();
134      ProblemDefinitionParameter.Value.Name = Name;
135    }
136
137    protected override void OnEvaluatorChanged() {
138      base.OnEvaluatorChanged();
139      Parameterize();
140    }
141
142    protected virtual void ProblemDefinitionChanged(object sender, EventArgs eventArgs) {
143      Parameterize();
144    }
145
146    protected virtual void Parameterize() {
147      var definition = ProblemDefinitionParameter.Value;
148      if (definition == null) return;
149
150      IEncoding encoding = definition.Encoding;
151
152      EncodingParameter.Value = encoding;
153      Maximization.Value = definition.IsMaximizationProblem;
154
155      Evaluator.EncodingParameter.ActualName = EncodingParameter.Name;
156      Evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
157      foreach (var evalOp in Operators.OfType<ISingleObjectiveProgrammableProblemEvaluator>()) {
158        evalOp.EncodingParameter.ActualName = EncodingParameter.Name;
159        evalOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
160      }
161      foreach (var analyzeOp in Operators.OfType<ISingleObjectiveProgrammableProblemAnalyzer>()) {
162        analyzeOp.EncodingParameter.ActualName = EncodingParameter.Name;
163        analyzeOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
164        analyzeOp.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
165      }
166
167      foreach (var param in DynamicEncodingParameters)
168        if (Parameters.Contains(param)) Parameters.Remove(param);
169      DynamicEncodingParameters.Clear();
170
171      var creator = ConfigureCreator(encoding);
172
173      foreach (var param in DynamicEncodingParameters) {
174        param.Hidden = true;
175        Parameters.Add(param);
176      }
177
178      var multiEncoding = encoding as MultiEncoding;
179      if (multiEncoding != null) {
180        ConfigureMultiVectorEncodingOperators((MultiEncodingCreator)creator, multiEncoding);
181      } else {
182        ConfigureSingleEncodingOperators(creator, encoding);
183      }
184      UpdateImprovementOperators();
185      UpdateMoveOperators();
186    }
187
188    protected virtual ISolutionCreator ConfigureCreator(IEncoding encoding) {
189      #region Configure RealVector Creator
190      var realEnc = encoding as RealEncoding;
191      if (realEnc != null) {
192        DynamicEncodingParameters.AddRange(realEnc.Parameters);
193        return realEnc.DefaultSolutionCreator;
194      }
195      #endregion
196      #region Configure BinaryVector Creator
197      var binEnc = encoding as BinaryEncoding;
198      if (binEnc != null) {
199        DynamicEncodingParameters.AddRange(binEnc.Parameters);
200        return binEnc.DefaultSolutionCreator;
201      }
202      #endregion
203      #region Configure MultiEncoding Creator
204      var multiEncoding = encoding as MultiEncoding;
205      if (multiEncoding != null) {
206        var creator = new MultiEncodingCreator();
207        foreach (var enc in multiEncoding.Encodings) {
208          if (enc is MultiEncoding) throw new InvalidOperationException("MultiEncoding within a MultiEncoding is not supported.");
209          creator.Operators.Add(ConfigureCreator(enc));
210        }
211        return creator;
212      }
213      #endregion
214      #region Configure IntegerVector Creator
215      var intEnc = encoding as IntegerEncoding;
216      if (intEnc != null) {
217        var l = new ValueParameter<IntValue>(intEnc.Name + "Length", intEnc.Length);
218        var b = new ValueParameter<IntMatrix>(intEnc.Name + "Bounds", intEnc.Bounds);
219        DynamicEncodingParameters.Add(l);
220        DynamicEncodingParameters.Add(b);
221
222        var creator = new UniformRandomIntegerVectorCreator();
223        creator.IntegerVectorParameter.ActualName = intEnc.Name;
224        creator.LengthParameter.ActualName = l.Name;
225        creator.BoundsParameter.ActualName = b.Name;
226        return creator;
227      }
228      #endregion
229      #region Configure Permutation Creator
230      var permEnc = encoding as PermutationEncoding;
231      if (permEnc != null) {
232        var l = new ValueParameter<IntValue>(permEnc.Name + "Length", permEnc.Length);
233        DynamicEncodingParameters.Add(l);
234
235        var creator = new RandomPermutationCreator();
236        creator.PermutationParameter.ActualName = permEnc.Name;
237        creator.LengthParameter.ActualName = l.Name;
238        creator.PermutationTypeParameter.Value = permEnc.Type;
239        return creator;
240      }
241      #endregion
242      throw new ArgumentException(string.Format("Encoding {0} is unknown.", encoding != null ? encoding.GetType().FullName : "(null)"));
243    }
244
245
246    private IEnumerable<IOperator> GetDiscoveredOperators<T>() where T : class,IOperator {
247      return ApplicationManager.Manager.GetInstances<T>()
248          .Except(Operators.OfType<T>(), new TypeEqualityComparer<T>());
249    }
250    protected virtual void ConfigureSingleEncodingOperators(ISolutionCreator newCreator, IEncoding 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 RealVectorEncoding
257      var realEncoding = encoding as RealEncoding;
258      if (realEncoding != null) {
259        // do not replace a real vector creator that was manually set
260        if (!(SolutionCreator is IRealVectorCreator)
261            || ((IRealVectorCreator)SolutionCreator).RealVectorParameter.ActualName != realEncoding.Name) {
262          Operators.Remove(SolutionCreator);
263          SolutionCreator = newCreator;
264        }
265
266        foreach (var su in realEncoding.Operators.OfType<IRealVectorSwarmUpdater>()) {
267          su.MaximizationParameter.ActualName = MaximizationParameter.Name;
268        }
269      }
270      #endregion
271      #region Configure Operators for BinaryVectorEncoding
272      var binEncoding = encoding as BinaryEncoding;
273      if (binEncoding != null) {
274        // do not replace a binary vector creator that was manually set
275        if (!(SolutionCreator is IBinaryVectorCreator) || ((IBinaryVectorCreator)SolutionCreator).BinaryVectorParameter.ActualName != binEncoding.Name) {
276          Operators.Remove(SolutionCreator);
277          SolutionCreator = newCreator;
278        }
279      }
280      #endregion
281      #region Configure Operators for IntegerVectorEncoding
282      var intCreator = newCreator as IIntegerVectorCreator;
283      if (intCreator != null) {
284        var paramName = intCreator.IntegerVectorParameter.ActualName;
285        // do not replace an integer vector creator that was manually set
286        if (!(SolutionCreator is IIntegerVectorCreator)
287          || ((IIntegerVectorCreator)SolutionCreator).IntegerVectorParameter.ActualName != intCreator.IntegerVectorParameter.ActualName) {
288          Operators.Remove(SolutionCreator);
289          SolutionCreator = newCreator;
290          Operators.Add(SolutionCreator);
291        }
292
293        #region Wire IntegerVector Crossovers
294        var crossovers = Operators.OfType<IIntegerVectorCrossover>()
295          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorCrossover>(), new TypeEqualityComparer<IIntegerVectorCrossover>())
296          .ToList();
297        foreach (var xo in crossovers) {
298          xo.ChildParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
299          xo.ChildParameter.Hidden = true;
300          xo.ParentsParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
301          xo.ParentsParameter.Hidden = true;
302          var bx = xo as IBoundedIntegerVectorOperator;
303          if (bx != null) {
304            bx.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName;
305            bx.BoundsParameter.Hidden = true;
306          }
307        }
308        Operators.AddRange(crossovers.Except(Operators.OfType<IIntegerVectorCrossover>()));
309        #endregion
310        #region Wire IntegerVector Manipulators
311        var manipulators = Operators.OfType<IIntegerVectorManipulator>()
312          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorManipulator>(), new TypeEqualityComparer<IIntegerVectorManipulator>())
313          .ToList();
314        foreach (var m in manipulators) {
315          m.IntegerVectorParameter.ActualName = intCreator.IntegerVectorParameter.ActualName;
316          m.IntegerVectorParameter.Hidden = true;
317          var sm = m as ISelfAdaptiveManipulator;
318          if (sm != null) {
319            var p = sm.StrategyParameterParameter as ILookupParameter;
320            if (p != null) {
321              p.ActualName = paramName + "Strategy";
322              p.Hidden = true;
323            }
324          }
325          var bm = m as IBoundedIntegerVectorOperator;
326          if (bm != null) {
327            bm.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName;
328            bm.BoundsParameter.Hidden = true;
329          }
330        }
331        Operators.AddRange(manipulators.Except(Operators.OfType<IIntegerVectorManipulator>()));
332        #region Wire IntegerVector StrategyParameters for SelfAdaptiveManipulators
333        var strategyOperators = Operators.OfType<IIntegerVectorStdDevStrategyParameterOperator>()
334          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorStdDevStrategyParameterOperator>(), new TypeEqualityComparer<IIntegerVectorStdDevStrategyParameterOperator>())
335          .ToList();
336        var problemSize = ((IntegerEncoding)encoding).Length.Value;
337        var b = ((IntegerEncoding)encoding).Bounds;
338        var bounds = new DoubleMatrix(b.Rows, b.Columns);
339        for (var i = 0; i < bounds.Rows; i++) {
340          bounds[i, 1] = (int)Math.Ceiling(0.33 * (b[i, 1] - b[i, 0]));
341          bounds[i, 0] = 0;
342          if (bounds.Columns > 2) bounds[i, 2] = b[i, 2];
343        }
344        foreach (var s in strategyOperators) {
345          var c = s as IIntegerVectorStdDevStrategyParameterCreator;
346          if (c != null) {
347            c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
348            c.LengthParameter.ActualName = intCreator.LengthParameter.ActualName;
349            c.StrategyParameterParameter.ActualName = paramName + "Strategy";
350          }
351          var m = s as IIntegerVectorStdDevStrategyParameterManipulator;
352          if (m != null) {
353            m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone();
354            m.StrategyParameterParameter.ActualName = paramName + "Strategy";
355          }
356          var mm = s as Encodings.IntegerVectorEncoding.StdDevStrategyVectorManipulator;
357          if (mm != null) {
358            mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * problemSize));
359            mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(problemSize)));
360          }
361          var x = s as IIntegerVectorStdDevStrategyParameterCrossover;
362          if (x != null) {
363            x.ParentsParameter.ActualName = paramName + "Strategy";
364            x.StrategyParameterParameter.ActualName = paramName + "Strategy";
365          }
366        }
367        Operators.AddRange(strategyOperators.Except(Operators.OfType<IIntegerVectorStdDevStrategyParameterOperator>()));
368        #endregion
369        #endregion
370        #region Wire IntegerVector ShakingOperators
371        var shakingOperators = Operators.OfType<IIntegerVectorMultiNeighborhoodShakingOperator>()
372          .Union(ApplicationManager.Manager.GetInstances<IIntegerVectorMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IIntegerVectorMultiNeighborhoodShakingOperator>())
373          .ToList();
374        foreach (var so in shakingOperators) {
375          so.IntegerVectorParameter.ActualName = paramName;
376          so.IntegerVectorParameter.Hidden = true;
377        }
378        Operators.AddRange(shakingOperators.Except(Operators.OfType<IIntegerVectorMultiNeighborhoodShakingOperator>()));
379        #endregion
380      } else {
381        Operators.RemoveAll(x => x is IIntegerVectorCrossover
382          || x is IIntegerVectorManipulator
383          || x is IIntegerVectorStdDevStrategyParameterOperator
384          || x is IIntegerVectorMultiNeighborhoodShakingOperator);
385      }
386      #endregion
387      #region Configure Operators for PermutationEncoding
388      var permCreator = newCreator as IPermutationCreator;
389      if (permCreator != null) {
390        var paramName = permCreator.PermutationParameter.ActualName;
391        // do not replace a permutation creator that was manually set
392        if (!(SolutionCreator is IPermutationCreator)
393            || ((IPermutationCreator)SolutionCreator).PermutationParameter.ActualName != permCreator.PermutationParameter.ActualName) {
394          Operators.Remove(SolutionCreator);
395          SolutionCreator = newCreator;
396          Operators.Add(SolutionCreator);
397        }
398
399        #region Wire Permutation Crossovers
400        var crossovers = Operators.OfType<IPermutationCrossover>()
401          .Union(ApplicationManager.Manager.GetInstances<IPermutationCrossover>(), new TypeEqualityComparer<IPermutationCrossover>())
402          .ToList();
403        foreach (var xo in crossovers) {
404          xo.ChildParameter.ActualName = permCreator.PermutationParameter.ActualName;
405          xo.ChildParameter.Hidden = true;
406          xo.ParentsParameter.ActualName = permCreator.PermutationParameter.ActualName;
407          xo.ParentsParameter.Hidden = true;
408        }
409        Operators.AddRange(crossovers.Except(Operators.OfType<IPermutationCrossover>()));
410        #endregion
411        #region Wire Permutation Manipulators
412        var manipulators = Operators.OfType<IPermutationManipulator>()
413          .Union(ApplicationManager.Manager.GetInstances<IPermutationManipulator>(), new TypeEqualityComparer<IPermutationManipulator>())
414          .ToList();
415        foreach (var m in manipulators) {
416          m.PermutationParameter.ActualName = permCreator.PermutationParameter.ActualName;
417          m.PermutationParameter.Hidden = true;
418        }
419        Operators.AddRange(manipulators.Except(Operators.OfType<IPermutationManipulator>()));
420        #endregion
421        #region Wire Permutation ShakingOperators
422        var shakingOperators = Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()
423          .Union(ApplicationManager.Manager.GetInstances<IPermutationMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IPermutationMultiNeighborhoodShakingOperator>())
424          .ToList();
425        foreach (var op in shakingOperators) {
426          op.PermutationParameter.ActualName = paramName;
427          op.PermutationParameter.Hidden = true;
428        }
429        Operators.AddRange(shakingOperators.Except(Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()));
430        #endregion
431      } else {
432        Operators.RemoveAll(x => x is IPermutationCrossover
433          || x is IPermutationManipulator
434          || x is IPermutationMultiNeighborhoodShakingOperator);
435      }
436      #endregion
437    }
438
439    protected virtual void ConfigureMultiVectorEncodingOperators(MultiEncodingCreator newCreator, MultiEncoding encoding) {
440      var newBinParams = new HashSet<string>(newCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
441      var newIntParams = new HashSet<string>(newCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
442      var newRealParams = new HashSet<string>(newCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
443      var newPermParams = new HashSet<string>(newCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
444
445      var oldCreator = SolutionCreator as MultiEncodingCreator;
446      if (oldCreator == null) SolutionCreator = newCreator;
447      else {
448        #region Configure BinaryVector Creator
449        var oldBinParams = new HashSet<string>(oldCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
450        foreach (var toAdd in newBinParams.Except(oldBinParams)) {
451          oldCreator.Operators.Add(newCreator.Operators.OfType<IBinaryVectorCreator>().Single(x => x.BinaryVectorParameter.ActualName == toAdd));
452        }
453        foreach (var toRemove in oldBinParams.Except(newBinParams)) {
454          var op = oldCreator.Operators.OfType<IBinaryVectorCreator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
455          if (op != null) oldCreator.Operators.Remove(op);
456        }
457        #endregion
458
459        #region Configure IntegerVector Creator
460        var oldIntParams = new HashSet<string>(oldCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
461        foreach (var toAdd in newIntParams.Except(oldIntParams)) {
462          oldCreator.Operators.Add(newCreator.Operators.OfType<IIntegerVectorCreator>().Single(x => x.IntegerVectorParameter.ActualName == toAdd));
463        }
464        foreach (var toRemove in oldIntParams.Except(newIntParams)) {
465          var op = oldCreator.Operators.OfType<IIntegerVectorCreator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
466          if (op != null) oldCreator.Operators.Remove(op);
467        }
468        #endregion
469
470        #region Configure RealVector Creator
471        var oldRealParams = new HashSet<string>(oldCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
472        foreach (var toAdd in newRealParams.Except(oldRealParams)) {
473          oldCreator.Operators.Add(newCreator.Operators.OfType<IRealVectorCreator>().Single(x => x.RealVectorParameter.ActualName == toAdd));
474        }
475        foreach (var toRemove in oldRealParams.Except(newRealParams)) {
476          var op = oldCreator.Operators.OfType<IRealVectorCreator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
477          if (op != null) oldCreator.Operators.Remove(op);
478        }
479        #endregion
480
481        #region Configure Permutation Creator
482        var oldPermParams = new HashSet<string>(oldCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
483        foreach (var toAdd in newPermParams.Except(oldPermParams)) {
484          oldCreator.Operators.Add(newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == toAdd));
485        }
486        foreach (var toRemove in oldPermParams.Except(newPermParams)) {
487          var op = oldCreator.Operators.OfType<IPermutationCreator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
488          if (op != null) oldCreator.Operators.Remove(op);
489        }
490        // we also have to sync the permutation type (in case this changes, as it is a value parameter)
491        foreach (var intersect in newPermParams.Intersect(oldPermParams)) {
492          var oldPermCreator = oldCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
493          var newPermCreator = newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
494          oldPermCreator.PermutationTypeParameter.Value = newPermCreator.PermutationTypeParameter.Value;
495        }
496        #endregion
497
498      }
499
500      // crossover and manipulator for multi-vector encoding
501      // the condition checks if a multi-vector encoding is to be updated (there already exists ParameterVectorCrossover and ParameterVectorManipulator)
502      if (Operators.OfType<MultiEncodingCrossover>().Any() && Operators.OfType<MultiEncodingManipulator>().Any()) {
503        #region Update existing multi-vector encoding
504        #region Update ParameterVector Crossover ...
505        foreach (var oldXo in Operators.OfType<MultiEncodingCrossover>()) {
506          #region ... for binary parameters
507          var oldBinParams = new HashSet<string>(oldXo.Operators.OfType<IBinaryVectorCrossover>().Select(x => x.ChildParameter.ActualName));
508          foreach (var toAdd in newBinParams.Except(oldBinParams))
509            oldXo.Operators.Add(GetDefaultBinaryCrossover(toAdd, encoding));
510          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
511            var op = oldXo.Operators.OfType<IBinaryVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
512            if (op != null) oldXo.Operators.Remove(op);
513          }
514          #endregion
515          #region ... for integer parameters
516          var oldIntParams = new HashSet<string>(oldXo.Operators.OfType<IIntegerVectorCrossover>().Select(x => x.ChildParameter.ActualName));
517          foreach (var toAdd in newIntParams.Except(oldIntParams))
518            oldXo.Operators.Add(GetDefaultIntegerCrossover(toAdd, encoding));
519          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
520            var op = oldXo.Operators.OfType<IIntegerVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
521            if (op != null) oldXo.Operators.Remove(op);
522          }
523          #endregion
524          #region ... for real parameters
525          var oldRealParams = new HashSet<string>(oldXo.Operators.OfType<IRealVectorCrossover>().Select(x => x.ChildParameter.ActualName));
526          foreach (var toAdd in newRealParams.Except(oldRealParams))
527            oldXo.Operators.Add(GetDefaultRealCrossover(toAdd, encoding));
528          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
529            var op = oldXo.Operators.OfType<IRealVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
530            if (op != null) oldXo.Operators.Remove(op);
531          }
532          #endregion
533          #region ... for permutation parameters
534          var oldPermParams = new HashSet<string>(oldXo.Operators.OfType<IPermutationCrossover>().Select(x => x.ChildParameter.ActualName));
535          foreach (var toAdd in newPermParams.Except(oldPermParams))
536            oldXo.Operators.Add(GetDefaultPermutationCrossover(toAdd, encoding));
537          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
538            var op = oldXo.Operators.OfType<IPermutationCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
539            if (op != null) oldXo.Operators.Remove(op);
540          }
541          #endregion
542        }
543        #endregion
544        #region Update ParameterVector Manipulator ...
545        foreach (var oldM in Operators.OfType<MultiEncodingManipulator>()) {
546          #region ... for binary parameters
547          var oldBinParams = new HashSet<string>(oldM.Operators.OfType<IBinaryVectorManipulator>().Select(x => x.BinaryVectorParameter.ActualName));
548          foreach (var toAdd in newBinParams.Except(oldBinParams))
549            oldM.Operators.Add(GetDefaultBinaryManipulator(toAdd, encoding));
550          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
551            var op = oldM.Operators.OfType<IBinaryVectorManipulator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
552            if (op != null) oldM.Operators.Remove(op);
553          }
554          #endregion
555          #region ... for integer parameters
556          var oldIntParams = new HashSet<string>(oldM.Operators.OfType<IIntegerVectorManipulator>().Select(x => x.IntegerVectorParameter.ActualName));
557          foreach (var toAdd in newIntParams.Except(oldIntParams))
558            oldM.Operators.Add(GetDefaultIntegerManipulator(toAdd, encoding));
559          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
560            var op = oldM.Operators.OfType<IIntegerVectorManipulator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
561            if (op != null) oldM.Operators.Remove(op);
562          }
563          #endregion
564          #region ... for real parameters
565          var oldRealParams = new HashSet<string>(oldM.Operators.OfType<IRealVectorManipulator>().Select(x => x.RealVectorParameter.ActualName));
566          foreach (var toAdd in newRealParams.Except(oldRealParams))
567            oldM.Operators.Add(GetDefaultRealManipulator(toAdd, encoding));
568          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
569            var op = oldM.Operators.OfType<IRealVectorManipulator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
570            if (op != null) oldM.Operators.Remove(op);
571          }
572          #endregion
573          #region ... for permutation parameters
574          var oldPermParams = new HashSet<string>(oldM.Operators.OfType<IPermutationManipulator>().Select(x => x.PermutationParameter.ActualName));
575          foreach (var toAdd in newPermParams.Except(oldPermParams))
576            oldM.Operators.Add(GetDefaultPermutationManipulator(toAdd, encoding));
577          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
578            var op = oldM.Operators.OfType<IPermutationManipulator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
579            if (op != null) oldM.Operators.Remove(op);
580          }
581          #endregion
582        }
583        #endregion
584        #endregion
585      } else {
586        #region Handle transition from single-vector to multi-vector encoding
587        Operators.RemoveAll(x => x is ICrossover);
588        Operators.RemoveAll(x => x is IManipulator);
589        Operators.RemoveAll(x => x is IStrategyParameterCreator || x is IStrategyParameterManipulator || x is IStrategyParameterCrossover);
590        Operators.RemoveAll(x => x is IParticleCreator);
591        Operators.RemoveAll(x => x is IParticleUpdater);
592        Operators.RemoveAll(x => x is ISwarmUpdater);
593        Operators.RemoveAll(x => x is IMultiNeighborhoodShakingOperator);
594
595        var crossover = new MultiEncodingCrossover();
596        var manipulator = new MultiEncodingManipulator();
597        foreach (var enc in encoding.Encodings) {
598          if (enc is BinaryEncoding) {
599            crossover.Operators.Add(GetDefaultBinaryCrossover(enc.Name, encoding));
600            manipulator.Operators.Add(GetDefaultBinaryManipulator(enc.Name, encoding));
601            continue;
602          }
603          var intConfig = enc as IntegerEncoding;
604          if (intConfig != null) {
605            crossover.Operators.Add(GetDefaultIntegerCrossover(enc.Name, encoding));
606            manipulator.Operators.Add(GetDefaultIntegerManipulator(enc.Name, encoding));
607            continue;
608          }
609          var realConfig = enc as RealEncoding;
610          if (realConfig != null) {
611            crossover.Operators.Add(GetDefaultRealCrossover(enc.Name, encoding));
612            manipulator.Operators.Add(GetDefaultRealManipulator(enc.Name, encoding));
613            continue;
614          }
615          var permConfig = enc as PermutationEncoding;
616          if (permConfig != null) {
617            crossover.Operators.Add(GetDefaultPermutationCrossover(enc.Name, encoding));
618            manipulator.Operators.Add(GetDefaultPermutationManipulator(enc.Name, encoding));
619            continue;
620          }
621          throw new InvalidOperationException("Unknown type for parameter " + enc.Name);
622        }
623        Operators.Add(crossover);
624        Operators.Add(manipulator);
625        #endregion
626      }
627    }
628
629    protected virtual void UpdateImprovementOperators() {
630      if (!Operators.Any(x => x is SingleObjectiveImprover))
631        Operators.Add(new SingleObjectiveImprover());
632      foreach (var improver in Operators.OfType<SingleObjectiveImprover>()) {
633        improver.EncodingParameter.ActualName = EncodingParameter.Name;
634        improver.MaximizationParameter.ActualName = MaximizationParameter.Name;
635        improver.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
636        improver.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
637      }
638    }
639    protected virtual void UpdateMoveOperators() {
640      if (!Operators.Any(x => x is SingleObjectiveMoveGenerator))
641        Operators.Add(new SingleObjectiveMoveGenerator());
642      if (!Operators.Any(x => x is SingleObjectiveMoveEvaluator))
643        Operators.Add(new SingleObjectiveMoveEvaluator());
644      if (!Operators.Any(x => x is SingleObjectiveMoveMaker))
645        Operators.Add(new SingleObjectiveMoveMaker());
646
647      foreach (var generator in Operators.OfType<SingleObjectiveMoveGenerator>()) {
648        generator.EncodingParameter.ActualName = EncodingParameter.Name;
649        generator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
650      }
651      foreach (var evaluator in Operators.OfType<SingleObjectiveMoveEvaluator>()) {
652        evaluator.EncodingParameter.ActualName = EncodingParameter.Name;
653        evaluator.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
654        evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
655      }
656      foreach (var maker in Operators.OfType<SingleObjectiveMoveMaker>()) {
657        maker.EncodingParameter.ActualName = EncodingParameter.Name;
658        maker.MoveQualityParameter.ActualName = Operators.OfType<SingleObjectiveMoveEvaluator>().First().MoveQualityParameter.ActualName;
659        maker.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
660      }
661    }
662
663    #region GetDefaultOperators for Crossovers and Manipulators
664    // ReSharper disable RedundantNameQualifier
665    protected virtual IBinaryVectorCrossover GetDefaultBinaryCrossover(string paramName, MultiEncoding config) {
666      var binConfig = (BinaryEncoding)config.Encodings[paramName];
667      IBinaryVectorCrossover binXo;
668      if (binConfig.Length > 3) binXo = new Encodings.BinaryVectorEncoding.SinglePointCrossover();
669      else binXo = new Encodings.BinaryVectorEncoding.UniformCrossover();
670      binXo.ChildParameter.ActualName = paramName;
671      binXo.ParentsParameter.ActualName = paramName;
672      return binXo;
673    }
674
675    protected virtual IBinaryVectorManipulator GetDefaultBinaryManipulator(string paramName, MultiEncoding config) {
676      var binM = new Encodings.BinaryVectorEncoding.SomePositionsBitflipManipulator();
677      binM.BinaryVectorParameter.ActualName = paramName;
678      binM.MutationProbabilityParameter.Value = new DoubleValue(0.1);
679      return binM;
680    }
681
682    protected virtual IIntegerVectorCrossover GetDefaultIntegerCrossover(string paramName, MultiEncoding config) {
683      var intXo = new Encodings.IntegerVectorEncoding.RoundedBlendAlphaBetaCrossover();
684      intXo.ChildParameter.ActualName = paramName;
685      intXo.ParentsParameter.ActualName = paramName;
686      intXo.BoundsParameter.ActualName = paramName + "Bounds";
687      intXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
688      intXo.MaximizationParameter.ActualName = MaximizationParameter.Name;
689      return intXo;
690    }
691
692    protected virtual IIntegerVectorManipulator GetDefaultIntegerManipulator(string paramName, MultiEncoding configuration) {
693      var intM = new Encodings.IntegerVectorEncoding.UniformSomePositionsManipulator();
694      intM.IntegerVectorParameter.ActualName = paramName;
695      intM.BoundsParameter.ActualName = paramName + "Bounds";
696      intM.ProbabilityParameter.Value = new DoubleValue(0.1);
697      return intM;
698    }
699
700    protected virtual IRealVectorCrossover GetDefaultRealCrossover(string paramName, MultiEncoding configuration) {
701      var realXo = new Encodings.RealVectorEncoding.BlendAlphaBetaCrossover();
702      realXo.ChildParameter.ActualName = paramName;
703      realXo.ParentsParameter.ActualName = paramName;
704      realXo.BoundsParameter.ActualName = paramName + "Bounds";
705      realXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
706      realXo.MaximizationParameter.ActualName = MaximizationParameter.Name;
707      return realXo;
708    }
709
710    protected virtual IRealVectorManipulator GetDefaultRealManipulator(string paramName, MultiEncoding configuration) {
711      var realM = new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator();
712      realM.RealVectorParameter.ActualName = paramName;
713      realM.BoundsParameter.ActualName = paramName + "Bounds";
714      return realM;
715    }
716
717    protected virtual IPermutationCrossover GetDefaultPermutationCrossover(string paramName, MultiEncoding configuration) {
718      var permXo = new Encodings.PermutationEncoding.PartiallyMatchedCrossover();
719      permXo.ChildParameter.ActualName = paramName;
720      permXo.ParentsParameter.ActualName = paramName;
721      return permXo;
722    }
723
724    protected virtual IPermutationManipulator GetDefaultPermutationManipulator(string paramName, MultiEncoding configuration) {
725      var permM = new Encodings.PermutationEncoding.Swap2Manipulator();
726      permM.PermutationParameter.ActualName = paramName;
727      return permM;
728    }
729    // ReSharper restore RedundantNameQualifier
730    #endregion
731  }
732}
Note: See TracBrowser for help on using the repository browser.