Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2174: Adapted IntegerEncoding to include the wiring code of operators.

File size: 32.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.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 IntegerVector Creator
204      var intEnc = encoding as IntegerEncoding;
205      if (intEnc != null) {
206        DynamicEncodingParameters.AddRange(intEnc.Parameters);
207        return intEnc.DefaultSolutionCreator;
208      }
209      #endregion
210      #region Configure MultiEncoding Creator
211      var multiEncoding = encoding as MultiEncoding;
212      if (multiEncoding != null) {
213        var creator = new MultiEncodingCreator();
214        foreach (var enc in multiEncoding.Encodings) {
215          if (enc is MultiEncoding) throw new InvalidOperationException("MultiEncoding within a MultiEncoding is not supported.");
216          creator.Operators.Add(ConfigureCreator(enc));
217        }
218        return creator;
219      }
220      #endregion
221      #region Configure Permutation Creator
222      var permEnc = encoding as PermutationEncoding;
223      if (permEnc != null) {
224        var l = new ValueParameter<IntValue>(permEnc.Name + "Length", permEnc.Length);
225        DynamicEncodingParameters.Add(l);
226
227        var creator = new RandomPermutationCreator();
228        creator.PermutationParameter.ActualName = permEnc.Name;
229        creator.LengthParameter.ActualName = l.Name;
230        creator.PermutationTypeParameter.Value = permEnc.Type;
231        return creator;
232      }
233      #endregion
234      throw new ArgumentException(string.Format("Encoding {0} is unknown.", encoding != null ? encoding.GetType().FullName : "(null)"));
235    }
236
237
238    private IEnumerable<IOperator> GetDiscoveredOperators<T>() where T : class,IOperator {
239      return ApplicationManager.Manager.GetInstances<T>()
240          .Except(Operators.OfType<T>(), new TypeEqualityComparer<T>());
241    }
242    protected virtual void ConfigureSingleEncodingOperators(ISolutionCreator newCreator, IEncoding encoding) {
243      // remove all multiencoding operators
244      Operators.RemoveAll(x => x is MultiEncodingCrossover
245                            || x is MultiEncodingManipulator
246                            || x is MultiEncodingCreator);
247
248      #region Configure Operators for RealVectorEncoding
249      var realEncoding = encoding as RealEncoding;
250      if (realEncoding != null) {
251        // do not replace a real vector creator that was manually set
252        if (!(SolutionCreator is IRealVectorCreator)
253            || ((IRealVectorCreator)SolutionCreator).RealVectorParameter.ActualName != realEncoding.Name) {
254          Operators.Remove(SolutionCreator);
255          SolutionCreator = newCreator;
256        }
257
258        foreach (var su in realEncoding.Operators.OfType<IRealVectorSwarmUpdater>()) {
259          su.MaximizationParameter.ActualName = MaximizationParameter.Name;
260        }
261      }
262      #endregion
263      #region Configure Operators for BinaryVectorEncoding
264      var binEncoding = encoding as BinaryEncoding;
265      if (binEncoding != null) {
266        // do not replace a binary vector creator that was manually set
267        if (!(SolutionCreator is IBinaryVectorCreator) || ((IBinaryVectorCreator)SolutionCreator).BinaryVectorParameter.ActualName != binEncoding.Name) {
268          Operators.Remove(SolutionCreator);
269          SolutionCreator = newCreator;
270        }
271      }
272      #endregion
273      #region Configure Operators for IntegerVectorEncoding
274      var intEncoding = encoding as IntegerEncoding;
275      if (intEncoding != null) {
276        // do not replace an integer vector creator that was manually set
277        if (!(SolutionCreator is IIntegerVectorCreator)
278          || ((IIntegerVectorCreator)SolutionCreator).IntegerVectorParameter.ActualName != intEncoding.Name) {
279          Operators.Remove(SolutionCreator);
280          SolutionCreator = newCreator;
281        }
282      }
283      #endregion
284      #region Configure Operators for PermutationEncoding
285      var permCreator = newCreator as IPermutationCreator;
286      if (permCreator != null) {
287        var paramName = permCreator.PermutationParameter.ActualName;
288        // do not replace a permutation creator that was manually set
289        if (!(SolutionCreator is IPermutationCreator)
290            || ((IPermutationCreator)SolutionCreator).PermutationParameter.ActualName != permCreator.PermutationParameter.ActualName) {
291          Operators.Remove(SolutionCreator);
292          SolutionCreator = newCreator;
293          Operators.Add(SolutionCreator);
294        }
295
296        #region Wire Permutation Crossovers
297        var crossovers = Operators.OfType<IPermutationCrossover>()
298          .Union(ApplicationManager.Manager.GetInstances<IPermutationCrossover>(), new TypeEqualityComparer<IPermutationCrossover>())
299          .ToList();
300        foreach (var xo in crossovers) {
301          xo.ChildParameter.ActualName = permCreator.PermutationParameter.ActualName;
302          xo.ChildParameter.Hidden = true;
303          xo.ParentsParameter.ActualName = permCreator.PermutationParameter.ActualName;
304          xo.ParentsParameter.Hidden = true;
305        }
306        Operators.AddRange(crossovers.Except(Operators.OfType<IPermutationCrossover>()));
307        #endregion
308        #region Wire Permutation Manipulators
309        var manipulators = Operators.OfType<IPermutationManipulator>()
310          .Union(ApplicationManager.Manager.GetInstances<IPermutationManipulator>(), new TypeEqualityComparer<IPermutationManipulator>())
311          .ToList();
312        foreach (var m in manipulators) {
313          m.PermutationParameter.ActualName = permCreator.PermutationParameter.ActualName;
314          m.PermutationParameter.Hidden = true;
315        }
316        Operators.AddRange(manipulators.Except(Operators.OfType<IPermutationManipulator>()));
317        #endregion
318        #region Wire Permutation ShakingOperators
319        var shakingOperators = Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()
320          .Union(ApplicationManager.Manager.GetInstances<IPermutationMultiNeighborhoodShakingOperator>(), new TypeEqualityComparer<IPermutationMultiNeighborhoodShakingOperator>())
321          .ToList();
322        foreach (var op in shakingOperators) {
323          op.PermutationParameter.ActualName = paramName;
324          op.PermutationParameter.Hidden = true;
325        }
326        Operators.AddRange(shakingOperators.Except(Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()));
327        #endregion
328      } else {
329        Operators.RemoveAll(x => x is IPermutationCrossover
330          || x is IPermutationManipulator
331          || x is IPermutationMultiNeighborhoodShakingOperator);
332      }
333      #endregion
334    }
335
336    protected virtual void ConfigureMultiVectorEncodingOperators(MultiEncodingCreator newCreator, MultiEncoding encoding) {
337      var newBinParams = new HashSet<string>(newCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
338      var newIntParams = new HashSet<string>(newCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
339      var newRealParams = new HashSet<string>(newCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
340      var newPermParams = new HashSet<string>(newCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
341
342      var oldCreator = SolutionCreator as MultiEncodingCreator;
343      if (oldCreator == null) SolutionCreator = newCreator;
344      else {
345        #region Configure BinaryVector Creator
346        var oldBinParams = new HashSet<string>(oldCreator.Operators.OfType<IBinaryVectorCreator>().Select(x => x.BinaryVectorParameter.ActualName));
347        foreach (var toAdd in newBinParams.Except(oldBinParams)) {
348          oldCreator.Operators.Add(newCreator.Operators.OfType<IBinaryVectorCreator>().Single(x => x.BinaryVectorParameter.ActualName == toAdd));
349        }
350        foreach (var toRemove in oldBinParams.Except(newBinParams)) {
351          var op = oldCreator.Operators.OfType<IBinaryVectorCreator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
352          if (op != null) oldCreator.Operators.Remove(op);
353        }
354        #endregion
355
356        #region Configure IntegerVector Creator
357        var oldIntParams = new HashSet<string>(oldCreator.Operators.OfType<IIntegerVectorCreator>().Select(x => x.IntegerVectorParameter.ActualName));
358        foreach (var toAdd in newIntParams.Except(oldIntParams)) {
359          oldCreator.Operators.Add(newCreator.Operators.OfType<IIntegerVectorCreator>().Single(x => x.IntegerVectorParameter.ActualName == toAdd));
360        }
361        foreach (var toRemove in oldIntParams.Except(newIntParams)) {
362          var op = oldCreator.Operators.OfType<IIntegerVectorCreator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
363          if (op != null) oldCreator.Operators.Remove(op);
364        }
365        #endregion
366
367        #region Configure RealVector Creator
368        var oldRealParams = new HashSet<string>(oldCreator.Operators.OfType<IRealVectorCreator>().Select(x => x.RealVectorParameter.ActualName));
369        foreach (var toAdd in newRealParams.Except(oldRealParams)) {
370          oldCreator.Operators.Add(newCreator.Operators.OfType<IRealVectorCreator>().Single(x => x.RealVectorParameter.ActualName == toAdd));
371        }
372        foreach (var toRemove in oldRealParams.Except(newRealParams)) {
373          var op = oldCreator.Operators.OfType<IRealVectorCreator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
374          if (op != null) oldCreator.Operators.Remove(op);
375        }
376        #endregion
377
378        #region Configure Permutation Creator
379        var oldPermParams = new HashSet<string>(oldCreator.Operators.OfType<IPermutationCreator>().Select(x => x.PermutationParameter.ActualName));
380        foreach (var toAdd in newPermParams.Except(oldPermParams)) {
381          oldCreator.Operators.Add(newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == toAdd));
382        }
383        foreach (var toRemove in oldPermParams.Except(newPermParams)) {
384          var op = oldCreator.Operators.OfType<IPermutationCreator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
385          if (op != null) oldCreator.Operators.Remove(op);
386        }
387        // we also have to sync the permutation type (in case this changes, as it is a value parameter)
388        foreach (var intersect in newPermParams.Intersect(oldPermParams)) {
389          var oldPermCreator = oldCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
390          var newPermCreator = newCreator.Operators.OfType<IPermutationCreator>().Single(x => x.PermutationParameter.ActualName == intersect);
391          oldPermCreator.PermutationTypeParameter.Value = newPermCreator.PermutationTypeParameter.Value;
392        }
393        #endregion
394
395      }
396
397      // crossover and manipulator for multi-vector encoding
398      // the condition checks if a multi-vector encoding is to be updated (there already exists ParameterVectorCrossover and ParameterVectorManipulator)
399      if (Operators.OfType<MultiEncodingCrossover>().Any() && Operators.OfType<MultiEncodingManipulator>().Any()) {
400        #region Update existing multi-vector encoding
401        #region Update ParameterVector Crossover ...
402        foreach (var oldXo in Operators.OfType<MultiEncodingCrossover>()) {
403          #region ... for binary parameters
404          var oldBinParams = new HashSet<string>(oldXo.Operators.OfType<IBinaryVectorCrossover>().Select(x => x.ChildParameter.ActualName));
405          foreach (var toAdd in newBinParams.Except(oldBinParams))
406            oldXo.Operators.Add(GetDefaultBinaryCrossover(toAdd, encoding));
407          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
408            var op = oldXo.Operators.OfType<IBinaryVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
409            if (op != null) oldXo.Operators.Remove(op);
410          }
411          #endregion
412          #region ... for integer parameters
413          var oldIntParams = new HashSet<string>(oldXo.Operators.OfType<IIntegerVectorCrossover>().Select(x => x.ChildParameter.ActualName));
414          foreach (var toAdd in newIntParams.Except(oldIntParams))
415            oldXo.Operators.Add(GetDefaultIntegerCrossover(toAdd, encoding));
416          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
417            var op = oldXo.Operators.OfType<IIntegerVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
418            if (op != null) oldXo.Operators.Remove(op);
419          }
420          #endregion
421          #region ... for real parameters
422          var oldRealParams = new HashSet<string>(oldXo.Operators.OfType<IRealVectorCrossover>().Select(x => x.ChildParameter.ActualName));
423          foreach (var toAdd in newRealParams.Except(oldRealParams))
424            oldXo.Operators.Add(GetDefaultRealCrossover(toAdd, encoding));
425          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
426            var op = oldXo.Operators.OfType<IRealVectorCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
427            if (op != null) oldXo.Operators.Remove(op);
428          }
429          #endregion
430          #region ... for permutation parameters
431          var oldPermParams = new HashSet<string>(oldXo.Operators.OfType<IPermutationCrossover>().Select(x => x.ChildParameter.ActualName));
432          foreach (var toAdd in newPermParams.Except(oldPermParams))
433            oldXo.Operators.Add(GetDefaultPermutationCrossover(toAdd, encoding));
434          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
435            var op = oldXo.Operators.OfType<IPermutationCrossover>().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove);
436            if (op != null) oldXo.Operators.Remove(op);
437          }
438          #endregion
439        }
440        #endregion
441        #region Update ParameterVector Manipulator ...
442        foreach (var oldM in Operators.OfType<MultiEncodingManipulator>()) {
443          #region ... for binary parameters
444          var oldBinParams = new HashSet<string>(oldM.Operators.OfType<IBinaryVectorManipulator>().Select(x => x.BinaryVectorParameter.ActualName));
445          foreach (var toAdd in newBinParams.Except(oldBinParams))
446            oldM.Operators.Add(GetDefaultBinaryManipulator(toAdd, encoding));
447          foreach (var toRemove in oldBinParams.Except(newBinParams)) {
448            var op = oldM.Operators.OfType<IBinaryVectorManipulator>().SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove);
449            if (op != null) oldM.Operators.Remove(op);
450          }
451          #endregion
452          #region ... for integer parameters
453          var oldIntParams = new HashSet<string>(oldM.Operators.OfType<IIntegerVectorManipulator>().Select(x => x.IntegerVectorParameter.ActualName));
454          foreach (var toAdd in newIntParams.Except(oldIntParams))
455            oldM.Operators.Add(GetDefaultIntegerManipulator(toAdd, encoding));
456          foreach (var toRemove in oldIntParams.Except(newIntParams)) {
457            var op = oldM.Operators.OfType<IIntegerVectorManipulator>().SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove);
458            if (op != null) oldM.Operators.Remove(op);
459          }
460          #endregion
461          #region ... for real parameters
462          var oldRealParams = new HashSet<string>(oldM.Operators.OfType<IRealVectorManipulator>().Select(x => x.RealVectorParameter.ActualName));
463          foreach (var toAdd in newRealParams.Except(oldRealParams))
464            oldM.Operators.Add(GetDefaultRealManipulator(toAdd, encoding));
465          foreach (var toRemove in oldRealParams.Except(newRealParams)) {
466            var op = oldM.Operators.OfType<IRealVectorManipulator>().SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove);
467            if (op != null) oldM.Operators.Remove(op);
468          }
469          #endregion
470          #region ... for permutation parameters
471          var oldPermParams = new HashSet<string>(oldM.Operators.OfType<IPermutationManipulator>().Select(x => x.PermutationParameter.ActualName));
472          foreach (var toAdd in newPermParams.Except(oldPermParams))
473            oldM.Operators.Add(GetDefaultPermutationManipulator(toAdd, encoding));
474          foreach (var toRemove in oldPermParams.Except(newPermParams)) {
475            var op = oldM.Operators.OfType<IPermutationManipulator>().SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove);
476            if (op != null) oldM.Operators.Remove(op);
477          }
478          #endregion
479        }
480        #endregion
481        #endregion
482      } else {
483        #region Handle transition from single-vector to multi-vector encoding
484        Operators.RemoveAll(x => x is ICrossover);
485        Operators.RemoveAll(x => x is IManipulator);
486        Operators.RemoveAll(x => x is IStrategyParameterCreator || x is IStrategyParameterManipulator || x is IStrategyParameterCrossover);
487        Operators.RemoveAll(x => x is IParticleCreator);
488        Operators.RemoveAll(x => x is IParticleUpdater);
489        Operators.RemoveAll(x => x is ISwarmUpdater);
490        Operators.RemoveAll(x => x is IMultiNeighborhoodShakingOperator);
491
492        var crossover = new MultiEncodingCrossover();
493        var manipulator = new MultiEncodingManipulator();
494        foreach (var enc in encoding.Encodings) {
495          if (enc is BinaryEncoding) {
496            crossover.Operators.Add(GetDefaultBinaryCrossover(enc.Name, encoding));
497            manipulator.Operators.Add(GetDefaultBinaryManipulator(enc.Name, encoding));
498            continue;
499          }
500          var intConfig = enc as IntegerEncoding;
501          if (intConfig != null) {
502            crossover.Operators.Add(GetDefaultIntegerCrossover(enc.Name, encoding));
503            manipulator.Operators.Add(GetDefaultIntegerManipulator(enc.Name, encoding));
504            continue;
505          }
506          var realConfig = enc as RealEncoding;
507          if (realConfig != null) {
508            crossover.Operators.Add(GetDefaultRealCrossover(enc.Name, encoding));
509            manipulator.Operators.Add(GetDefaultRealManipulator(enc.Name, encoding));
510            continue;
511          }
512          var permConfig = enc as PermutationEncoding;
513          if (permConfig != null) {
514            crossover.Operators.Add(GetDefaultPermutationCrossover(enc.Name, encoding));
515            manipulator.Operators.Add(GetDefaultPermutationManipulator(enc.Name, encoding));
516            continue;
517          }
518          throw new InvalidOperationException("Unknown type for parameter " + enc.Name);
519        }
520        Operators.Add(crossover);
521        Operators.Add(manipulator);
522        #endregion
523      }
524    }
525
526    protected virtual void UpdateImprovementOperators() {
527      if (!Operators.Any(x => x is SingleObjectiveImprover))
528        Operators.Add(new SingleObjectiveImprover());
529      foreach (var improver in Operators.OfType<SingleObjectiveImprover>()) {
530        improver.EncodingParameter.ActualName = EncodingParameter.Name;
531        improver.MaximizationParameter.ActualName = MaximizationParameter.Name;
532        improver.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
533        improver.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
534      }
535    }
536    protected virtual void UpdateMoveOperators() {
537      if (!Operators.Any(x => x is SingleObjectiveMoveGenerator))
538        Operators.Add(new SingleObjectiveMoveGenerator());
539      if (!Operators.Any(x => x is SingleObjectiveMoveEvaluator))
540        Operators.Add(new SingleObjectiveMoveEvaluator());
541      if (!Operators.Any(x => x is SingleObjectiveMoveMaker))
542        Operators.Add(new SingleObjectiveMoveMaker());
543
544      foreach (var generator in Operators.OfType<SingleObjectiveMoveGenerator>()) {
545        generator.EncodingParameter.ActualName = EncodingParameter.Name;
546        generator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
547      }
548      foreach (var evaluator in Operators.OfType<SingleObjectiveMoveEvaluator>()) {
549        evaluator.EncodingParameter.ActualName = EncodingParameter.Name;
550        evaluator.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
551        evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
552      }
553      foreach (var maker in Operators.OfType<SingleObjectiveMoveMaker>()) {
554        maker.EncodingParameter.ActualName = EncodingParameter.Name;
555        maker.MoveQualityParameter.ActualName = Operators.OfType<SingleObjectiveMoveEvaluator>().First().MoveQualityParameter.ActualName;
556        maker.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
557      }
558    }
559
560    #region GetDefaultOperators for Crossovers and Manipulators
561    // ReSharper disable RedundantNameQualifier
562    protected virtual IBinaryVectorCrossover GetDefaultBinaryCrossover(string paramName, MultiEncoding config) {
563      var binConfig = (BinaryEncoding)config.Encodings[paramName];
564      IBinaryVectorCrossover binXo;
565      if (binConfig.Length > 3) binXo = new Encodings.BinaryVectorEncoding.SinglePointCrossover();
566      else binXo = new Encodings.BinaryVectorEncoding.UniformCrossover();
567      binXo.ChildParameter.ActualName = paramName;
568      binXo.ParentsParameter.ActualName = paramName;
569      return binXo;
570    }
571
572    protected virtual IBinaryVectorManipulator GetDefaultBinaryManipulator(string paramName, MultiEncoding config) {
573      var binM = new Encodings.BinaryVectorEncoding.SomePositionsBitflipManipulator();
574      binM.BinaryVectorParameter.ActualName = paramName;
575      binM.MutationProbabilityParameter.Value = new DoubleValue(0.1);
576      return binM;
577    }
578
579    protected virtual IIntegerVectorCrossover GetDefaultIntegerCrossover(string paramName, MultiEncoding config) {
580      var intXo = new Encodings.IntegerVectorEncoding.RoundedBlendAlphaBetaCrossover();
581      intXo.ChildParameter.ActualName = paramName;
582      intXo.ParentsParameter.ActualName = paramName;
583      intXo.BoundsParameter.ActualName = paramName + "Bounds";
584      intXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
585      intXo.MaximizationParameter.ActualName = MaximizationParameter.Name;
586      return intXo;
587    }
588
589    protected virtual IIntegerVectorManipulator GetDefaultIntegerManipulator(string paramName, MultiEncoding configuration) {
590      var intM = new Encodings.IntegerVectorEncoding.UniformSomePositionsManipulator();
591      intM.IntegerVectorParameter.ActualName = paramName;
592      intM.BoundsParameter.ActualName = paramName + "Bounds";
593      intM.ProbabilityParameter.Value = new DoubleValue(0.1);
594      return intM;
595    }
596
597    protected virtual IRealVectorCrossover GetDefaultRealCrossover(string paramName, MultiEncoding configuration) {
598      var realXo = new Encodings.RealVectorEncoding.BlendAlphaBetaCrossover();
599      realXo.ChildParameter.ActualName = paramName;
600      realXo.ParentsParameter.ActualName = paramName;
601      realXo.BoundsParameter.ActualName = paramName + "Bounds";
602      realXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
603      realXo.MaximizationParameter.ActualName = MaximizationParameter.Name;
604      return realXo;
605    }
606
607    protected virtual IRealVectorManipulator GetDefaultRealManipulator(string paramName, MultiEncoding configuration) {
608      var realM = new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator();
609      realM.RealVectorParameter.ActualName = paramName;
610      realM.BoundsParameter.ActualName = paramName + "Bounds";
611      return realM;
612    }
613
614    protected virtual IPermutationCrossover GetDefaultPermutationCrossover(string paramName, MultiEncoding configuration) {
615      var permXo = new Encodings.PermutationEncoding.PartiallyMatchedCrossover();
616      permXo.ChildParameter.ActualName = paramName;
617      permXo.ParentsParameter.ActualName = paramName;
618      return permXo;
619    }
620
621    protected virtual IPermutationManipulator GetDefaultPermutationManipulator(string paramName, MultiEncoding configuration) {
622      var permM = new Encodings.PermutationEncoding.Swap2Manipulator();
623      permM.PermutationParameter.ActualName = paramName;
624      return permM;
625    }
626    // ReSharper restore RedundantNameQualifier
627    #endregion
628  }
629}
Note: See TracBrowser for help on using the repository browser.