source: branches/StackingProblems/HeuristicLab.Encodings.MoveVectorEncoding/3.3/MoveVectorEncoding.cs @ 14278

Last change on this file since 14278 was 14278, checked in by mzehetho, 5 years ago

Initial Commit for ticket #2605

Implemented:

  • Encoding
  • Moves
  • Views
  • Blocks World Problem
  • Blocks Relocation Problem
  • Stacking Problem
File size: 9.5 KB
Line 
1using HeuristicLab.Optimization;
2using System;
3using System.Collections.Generic;
4using System.Linq;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Encodings.MoveVectorEncoding.Interfaces;
8using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
9using HeuristicLab.Data;
10using HeuristicLab.PluginInfrastructure;
11using HeuristicLab.Parameters;
12using HeuristicLab.Encodings.MoveVectorEncoding.Creators;
13using HeuristicLab.Data.MoveVectorData;
14
15namespace HeuristicLab.Encodings.MoveVectorEncoding
16{
17    [Item("MoveVectorEncoding", "Describes a Move Vector encoding.")]
18    [StorableClass]
19    public sealed class MoveVectorEncoding : Encoding<IMoveVectorCreator>
20    {
21        #region Parameter Properties
22        [Storable]
23        private IFixedValueParameter<IntValue> lengthParameter;
24        public IFixedValueParameter<IntValue> LengthParameter
25        {
26            get { return lengthParameter; }
27            set
28            {
29                if (value == null) throw new ArgumentNullException("Length parameter must not be null.");
30                if (value.Value == null) throw new ArgumentNullException("Length parameter value must not be null.");
31                if (lengthParameter == value) return;
32
33                if (lengthParameter != null) Parameters.Remove(lengthParameter);
34                lengthParameter = value;
35                Parameters.Add(lengthParameter);
36                OnLengthParameterChanged();
37            }
38        }
39        [Storable]
40        private IValueParameter<IntMatrix> boundsParameter;
41        public IValueParameter<IntMatrix> BoundsParameter
42        {
43            get { return boundsParameter; }
44            set
45            {
46                if (value == null) throw new ArgumentNullException("Bounds parameter must not be null.");
47                if (boundsParameter == value) return;
48
49                if (boundsParameter != null) Parameters.Remove(boundsParameter);
50                boundsParameter = value;
51                Parameters.Add(boundsParameter);
52                OnBoundsParameterChanged();
53            }
54        }
55        #endregion
56
57        #region Properties
58        public int Length
59        {
60            get { return LengthParameter.Value.Value; }
61            set { LengthParameter.Value.Value = value; }
62        }
63        public IntMatrix Bounds
64        {
65            get { return BoundsParameter.Value; }
66            set { BoundsParameter.Value = value; }
67        }
68        #endregion
69
70        #region Cloning
71        [StorableConstructor]
72        private MoveVectorEncoding(bool deserializing) : base(deserializing) { }
73        [StorableHook(HookType.AfterDeserialization)]
74        private void AfterDeserialization()
75        {
76            RegisterParameterEvents();
77            DiscoverOperators();
78        }
79
80        public override IDeepCloneable Clone(Cloner cloner)
81        {
82            return new MoveVectorEncoding(this, cloner);
83        }
84        private MoveVectorEncoding(MoveVectorEncoding original, Cloner cloner) : base(original, cloner) {
85            lengthParameter = cloner.Clone(original.lengthParameter);
86            boundsParameter = cloner.Clone(original.boundsParameter);
87            RegisterParameterEvents();
88        }
89
90        #endregion
91
92        public MoveVectorEncoding() : this("MoveVector", 10) { }
93        public MoveVectorEncoding(string name) : this(name, 10) { }
94        public MoveVectorEncoding(int length, int min, int max) : this("MoveVector", length, min, max) { }
95        public MoveVectorEncoding(string name, int length, int min = int.MinValue, int max = int.MaxValue, int? step = null)
96            : base(name)
97        {
98            if (min >= max) throw new ArgumentException("min must be less than max", "min");
99            if (step.HasValue && step.Value <= 0) throw new ArgumentException("step must be greater than zero or null", "step");
100
101            var bounds = new IntMatrix(1, step.HasValue ? 3 : 2);
102            bounds[0, 0] = min;
103            bounds[0, 1] = max;
104            if (step.HasValue) bounds[0, 2] = step.Value;
105
106            lengthParameter = new FixedValueParameter<IntValue>(Name + ".Length", new IntValue(length));
107            boundsParameter = new ValueParameter<IntMatrix>(Name + ".Bounds", bounds);
108            Parameters.Add(lengthParameter);
109            Parameters.Add(boundsParameter);
110
111            SolutionCreator = new RandomMoveVectorCreator();
112            RegisterParameterEvents();
113            DiscoverOperators();
114        }
115
116        #region Operators
117        private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
118        static MoveVectorEncoding()
119        {
120            encodingSpecificOperatorTypes = new List<Type>() {
121                typeof(IMoveVectorOperator),
122                typeof(IMoveVectorCreator),
123                typeof(IMoveVectorCrossover),
124                typeof(IMoveVectorManipulator)
125            };
126        }
127        private void DiscoverOperators()
128        {
129            var assembly = typeof(IMoveVectorOperator).Assembly;
130            var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, assembly, true, false, false);
131            var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
132            var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
133
134            ConfigureOperators(newOperators);
135            foreach (var @operator in newOperators)
136                AddOperator(@operator);
137        }
138        public override void ConfigureOperators(IEnumerable<IOperator> operators)
139        {
140            ConfigureBoundedOperators(operators.OfType<IBoundedMoveVectorOperator>());
141            ConfigureCreators(operators.OfType<IMoveVectorCreator>());
142            ConfigureCrossovers(operators.OfType<IMoveVectorCrossover>());
143            ConfigureManipulators(operators.OfType<IMoveVectorManipulator>());
144            ConfigureShakingOperators(operators.OfType<IMoveVectorMultiNeighborhoodShakingOperator>());
145        }
146
147        private void ConfigureBoundedOperators(IEnumerable<IBoundedMoveVectorOperator> boundedOperators)
148        {
149            foreach (var boundedOperator in boundedOperators)
150            {
151                boundedOperator.BoundsParameter.ActualName = BoundsParameter.Name;
152            }
153        }
154        private void ConfigureCreators(IEnumerable<IMoveVectorCreator> creators)
155        {
156            foreach (var creator in creators)
157            {
158                creator.MoveVectorParameter.ActualName = Name;
159                creator.BoundsParameter.ActualName = BoundsParameter.Name;
160                creator.LengthParameter.ActualName = LengthParameter.Name;
161            }
162        }
163        private void ConfigureCrossovers(IEnumerable<IMoveVectorCrossover> crossovers)
164        {
165            foreach (var crossover in crossovers)
166            {
167                crossover.ChildParameter.ActualName = Name;
168                crossover.ParentsParameter.ActualName = Name;
169            }
170        }
171
172        private void ConfigureManipulators(IEnumerable<IMoveVectorManipulator> manipulators)
173        {
174            foreach (var manipulator in manipulators)
175            {
176                manipulator.MoveVectorParameter.ActualName = Name;
177                manipulator.MoveVectorParameter.Hidden = true;
178                var sm = manipulator as ISelfAdaptiveManipulator;
179                if (sm != null)
180                {
181                    var p = sm.StrategyParameterParameter as ILookupParameter;
182                    if (p != null)
183                    {
184                        p.ActualName = Name + "Strategy";
185                    }
186                }
187            }
188        }
189
190        private void ConfigureShakingOperators(IEnumerable<IMoveVectorMultiNeighborhoodShakingOperator> shakingOperators)
191        {
192            foreach (var shakingOperator in shakingOperators)
193            {
194                shakingOperator.MoveVectorParameter.ActualName = Name;
195            }
196        }
197        #endregion
198
199        #region Events
200        private void RegisterParameterEvents()
201        {
202            RegisterLengthParameterEvents();
203            RegisterBoundsParameterEvents();
204        }
205        private void OnLengthParameterChanged()
206        {
207            RegisterLengthParameterEvents();
208            ConfigureOperators(Operators);
209        }
210        private void OnBoundsParameterChanged()
211        {
212            RegisterBoundsParameterEvents();
213            ConfigureOperators(Operators);
214        }
215        private void RegisterLengthParameterEvents()
216        {
217            LengthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
218            LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
219        }
220        private void RegisterBoundsParameterEvents()
221        {
222            BoundsParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
223            boundsParameter.Value.ToStringChanged += (o, s) => ConfigureOperators(Operators);
224        }
225        #endregion
226    }
227
228    public static class IndividualExtensionMethods
229    {
230        public static MoveVector MoveVector(this Individual individual)
231        {
232            var encoding = individual.GetEncoding<MoveVectorEncoding>();
233            return individual.MoveVector(encoding.Name);
234        }
235
236        public static MoveVector MoveVector(this Individual individual, string name)
237        {
238            return (MoveVector)individual[name];
239        }
240    }
241}
Note: See TracBrowser for help on using the repository browser.