source: branches/2994-AutoDiffForIntervals/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEncoding.cs @ 17209

Last change on this file since 17209 was 17209, checked in by gkronber, 5 weeks ago

#2994: merged r17132:17198 from trunk to branch

File size: 10.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
30using HEAL.Attic;
31using HeuristicLab.PluginInfrastructure;
32
33namespace HeuristicLab.Encodings.PermutationEncoding {
34  [Item("PermutationEncoding", "Describes a permutation encoding.")]
35  [StorableType("E30E7507-44BA-4021-8F56-C3FC5569A6FE")]
36  public sealed class PermutationEncoding : Encoding<IPermutationCreator> {
37    #region encoding parameters
38    [Storable]
39    private IFixedValueParameter<IntValue> lengthParameter;
40    public IFixedValueParameter<IntValue> LengthParameter {
41      get { return lengthParameter; }
42      set {
43        if (value == null) throw new ArgumentNullException("Length parameter must not be null.");
44        if (value.Value == null) throw new ArgumentNullException("Length parameter value must not be null.");
45        if (lengthParameter == value) return;
46
47        if (lengthParameter != null) Parameters.Remove(lengthParameter);
48        lengthParameter = value;
49        Parameters.Add(lengthParameter);
50        OnLengthParameterChanged();
51      }
52    }
53
54    [Storable]
55    private IFixedValueParameter<PermutationType> permutationTypeParameter;
56    public IFixedValueParameter<PermutationType> PermutationTypeParameter {
57      get { return permutationTypeParameter; }
58      set {
59        if (value == null) throw new ArgumentNullException("Permutation type parameter must not be null.");
60        if (value.Value == null) throw new ArgumentNullException("Permutation type parameter value must not be null.");
61        if (permutationTypeParameter == value) return;
62
63        if (permutationTypeParameter != null) Parameters.Remove(permutationTypeParameter);
64        permutationTypeParameter = value;
65        Parameters.Add(permutationTypeParameter);
66        OnPermutationTypeParameterChanged();
67      }
68    }
69    #endregion
70
71    public int Length {
72      get { return LengthParameter.Value.Value; }
73      set { LengthParameter.Value.Value = value; }
74    }
75
76    public PermutationTypes Type {
77      get { return PermutationTypeParameter.Value.Value; }
78      set { PermutationTypeParameter.Value.Value = value; }
79    }
80
81    [StorableConstructor]
82    private PermutationEncoding(StorableConstructorFlag _) : base(_) { }
83    [StorableHook(HookType.AfterDeserialization)]
84    private void AfterDeserialization() {
85      RegisterParameterEvents();
86      DiscoverOperators();
87    }
88
89    public override IDeepCloneable Clone(Cloner cloner) { return new PermutationEncoding(this, cloner); }
90    private PermutationEncoding(PermutationEncoding original, Cloner cloner)
91      : base(original, cloner) {
92      lengthParameter = cloner.Clone(original.lengthParameter);
93      permutationTypeParameter = cloner.Clone(original.permutationTypeParameter);
94      RegisterParameterEvents();
95    }
96
97
98    public PermutationEncoding() : this("Permutation", 10, PermutationTypes.Absolute) { }
99    public PermutationEncoding(string name) : this(name, 10, PermutationTypes.Absolute) { }
100    public PermutationEncoding(int length) : this("Permutation", length, PermutationTypes.Absolute) { }
101    public PermutationEncoding(string name, int length, PermutationTypes type)
102      : base(name) {
103      lengthParameter = new FixedValueParameter<IntValue>(Name + ".Length", new IntValue(length));
104      permutationTypeParameter = new FixedValueParameter<PermutationType>(Name + ".Type", new PermutationType(type));
105      Parameters.Add(lengthParameter);
106      Parameters.Add(permutationTypeParameter);
107
108      SolutionCreator = new RandomPermutationCreator();
109      RegisterParameterEvents();
110      DiscoverOperators();
111    }
112
113    private void OnLengthParameterChanged() {
114      RegisterLengthParameterEvents();
115      ConfigureOperators(Operators);
116    }
117
118    private void OnPermutationTypeParameterChanged() {
119      RegisterPermutationTypeParameterEvents();
120      ConfigureOperators(Operators);
121    }
122
123    private void RegisterParameterEvents() {
124      RegisterLengthParameterEvents();
125      RegisterPermutationTypeParameterEvents();
126    }
127    private void RegisterLengthParameterEvents() {
128      LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
129    }
130    private void RegisterPermutationTypeParameterEvents() {
131      PermutationTypeParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
132    }
133
134    #region Operator Discovery
135    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
136    static PermutationEncoding() {
137      encodingSpecificOperatorTypes = new List<Type>() {
138          typeof (IPermutationOperator),
139          typeof (IPermutationCreator),
140          typeof (IPermutationCrossover),
141          typeof (IPermutationManipulator),
142          typeof (IPermutationMultiNeighborhoodShakingOperator),
143          typeof (IPermutationMoveOperator),
144          typeof (IPermutationInversionMoveOperator),
145          typeof (IPermutationScrambleMoveOperator),
146          typeof (IPermutationSwap2MoveOperator),                   
147          typeof (IPermutationTranslocationMoveOperator)
148      };
149    }
150    private void DiscoverOperators() {
151      var assembly = typeof(IPermutationOperator).Assembly;
152      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, assembly, true, false, false);
153      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
154      var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
155
156      ConfigureOperators(newOperators);
157      foreach (var @operator in newOperators)
158        AddOperator(@operator);
159    }
160    #endregion
161
162    public override void ConfigureOperators(IEnumerable<IOperator> operators) {
163      ConfigureCreators(operators.OfType<IPermutationCreator>());
164      ConfigureCrossovers(operators.OfType<IPermutationCrossover>());
165      ConfigureManipulators(operators.OfType<IPermutationManipulator>());
166      ConfigureShakingOperators(operators.OfType<IPermutationMultiNeighborhoodShakingOperator>());
167      ConfigureMoveOperators(operators.OfType<IPermutationMoveOperator>());
168      ConfigureInversionMoveOperators(operators.OfType<IPermutationInversionMoveOperator>());
169      ConfigureScrambleMoveOperators(operators.OfType<IPermutationScrambleMoveOperator>());
170      ConfigureSwap2MoveOperators(operators.OfType<IPermutationSwap2MoveOperator>());
171      ConfigureTranslocationMoveOperators(operators.OfType<IPermutationTranslocationMoveOperator>());
172    }
173
174    #region specific operator wiring
175    private void ConfigureCreators(IEnumerable<IPermutationCreator> creators) {
176      foreach (var creator in creators) {
177        creator.LengthParameter.ActualName = LengthParameter.Name;
178        creator.PermutationParameter.ActualName = Name;
179        creator.PermutationTypeParameter.Value.Value = Type;
180      }
181    }
182    private void ConfigureCrossovers(IEnumerable<IPermutationCrossover> crossovers) {
183      foreach (var crossover in crossovers) {
184        crossover.ChildParameter.ActualName = Name;
185        crossover.ParentsParameter.ActualName = Name;
186      }
187    }
188    private void ConfigureManipulators(IEnumerable<IPermutationManipulator> manipulators) {
189      foreach (var manipulator in manipulators) {
190        manipulator.PermutationParameter.ActualName = Name;
191      }
192    }
193    private void ConfigureShakingOperators(IEnumerable<IPermutationMultiNeighborhoodShakingOperator> shakingOperators) {
194      foreach (var shakingOperator in shakingOperators) {
195        shakingOperator.PermutationParameter.ActualName = Name;
196      }
197    }
198    private void ConfigureMoveOperators(IEnumerable<IPermutationMoveOperator> moveOperators) {
199      foreach (var moveOperator in moveOperators) {
200        moveOperator.PermutationParameter.ActualName = Name;
201      }
202    }
203    private void ConfigureInversionMoveOperators(IEnumerable<IPermutationInversionMoveOperator> inversionMoveOperators) {
204      foreach (var inversionMoveOperator in inversionMoveOperators) {
205        inversionMoveOperator.InversionMoveParameter.ActualName = Name + ".InversionMove";
206      }
207    }
208    private void ConfigureScrambleMoveOperators(IEnumerable<IPermutationScrambleMoveOperator> scrambleMoveOperators) {
209      foreach (var scrambleMoveOperator in scrambleMoveOperators) {
210        scrambleMoveOperator.ScrambleMoveParameter.ActualName = Name + ".ScrambleMove";
211      }
212    }
213    private void ConfigureSwap2MoveOperators(IEnumerable<IPermutationSwap2MoveOperator> swap2MoveOperators) {
214      foreach (var swap2MoveOperator in swap2MoveOperators) {
215        swap2MoveOperator.Swap2MoveParameter.ActualName = Name + ".Swap2Move";
216      }
217    }
218    private void ConfigureTranslocationMoveOperators(IEnumerable<IPermutationTranslocationMoveOperator> translocationMoveOperators) {
219      foreach (var translocationMoveOperator in translocationMoveOperators) {
220        translocationMoveOperator.TranslocationMoveParameter.ActualName = Name + ".TranslocationMove";
221      }
222    }
223
224    #endregion
225  }
226
227  public static class IndividualExtensionMethods {
228    public static Permutation Permutation(this Individual individual) {
229      var encoding = individual.GetEncoding<PermutationEncoding>();
230      return individual.Permutation(encoding.Name);
231    }
232    public static Permutation Permutation(this Individual individual, string name) {
233      return (Permutation)individual[name];
234    }
235  }
236}
Note: See TracBrowser for help on using the repository browser.