#region License Information /* HeuristicLab * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.PluginInfrastructure; namespace HeuristicLab.Encodings.BinaryVectorEncoding { [Item("BinaryVectorEncoding", "Describes a binary vector encoding.")] [StorableType("9BE0D561-3A83-4F7D-A51C-D6B8E6C1E9B7")] public sealed class BinaryVectorEncoding : Encoding { #region Encoding Parameters [Storable] private IFixedValueParameter lengthParameter; public IFixedValueParameter LengthParameter { get { return lengthParameter; } set { if (value == null) throw new ArgumentNullException("Length parameter must not be null."); if (value.Value == null) throw new ArgumentNullException("Length parameter value must not be null."); if (lengthParameter == value) return; if (lengthParameter != null) Parameters.Remove(lengthParameter); lengthParameter = value; Parameters.Add(lengthParameter); OnLengthParameterChanged(); } } #endregion public int Length { get { return LengthParameter.Value.Value; } set { LengthParameter.Value.Value = value; } } [StorableConstructor] private BinaryVectorEncoding(bool deserializing) : base(deserializing) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { RegisterParameterEvents(); DiscoverOperators(); } public override IDeepCloneable Clone(Cloner cloner) { return new BinaryVectorEncoding(this, cloner); } private BinaryVectorEncoding(BinaryVectorEncoding original, Cloner cloner) : base(original, cloner) { lengthParameter = cloner.Clone(original.lengthParameter); RegisterParameterEvents(); } public BinaryVectorEncoding() : this("BinaryVector", 10) { } public BinaryVectorEncoding(string name) : this(name, 10) { } public BinaryVectorEncoding(int length) : this("BinaryVector", length) { } public BinaryVectorEncoding(string name, int length) : base(name) { lengthParameter = new FixedValueParameter(Name + ".Length", new IntValue(length)); Parameters.Add(lengthParameter); SolutionCreator = new RandomBinaryVectorCreator(); RegisterParameterEvents(); DiscoverOperators(); } private void OnLengthParameterChanged() { RegisterLengthParameterEvents(); ConfigureOperators(Operators); } private void RegisterParameterEvents() { RegisterLengthParameterEvents(); } private void RegisterLengthParameterEvents() { LengthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators); LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators); } #region Operator Discovery private static readonly IEnumerable encodingSpecificOperatorTypes; static BinaryVectorEncoding() { encodingSpecificOperatorTypes = new List() { typeof (IBinaryVectorOperator), typeof (IBinaryVectorCreator), typeof (IBinaryVectorCrossover), typeof (IBinaryVectorManipulator), typeof (IBinaryVectorMoveOperator), typeof (IBinaryVectorMultiNeighborhoodShakingOperator), }; } private void DiscoverOperators() { var assembly = typeof(IBinaryVectorOperator).Assembly; var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, assembly, true, false, false); var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t)); var newOperators = operators.Except(Operators, new TypeEqualityComparer()).ToList(); ConfigureOperators(newOperators); foreach (var @operator in newOperators) AddOperator(@operator); } #endregion public override void ConfigureOperators(IEnumerable operators) { ConfigureCreators(operators.OfType()); ConfigureCrossovers(operators.OfType()); ConfigureManipulators(operators.OfType()); ConfigureMoveOperators(operators.OfType()); ConfigureBitFlipMoveOperators(operators.OfType()); ConfigureShakingOperators(operators.OfType()); } #region Specific Operator Wiring private void ConfigureCreators(IEnumerable creators) { foreach (var creator in creators) { creator.BinaryVectorParameter.ActualName = Name; creator.LengthParameter.ActualName = LengthParameter.Name; } } private void ConfigureCrossovers(IEnumerable crossovers) { foreach (var crossover in crossovers) { crossover.ParentsParameter.ActualName = Name; crossover.ChildParameter.ActualName = Name; } } private void ConfigureManipulators(IEnumerable manipulators) { foreach (var manipulator in manipulators) { manipulator.BinaryVectorParameter.ActualName = Name; } } private void ConfigureMoveOperators(IEnumerable moveOperators) { foreach (var moveOperator in moveOperators) { moveOperator.BinaryVectorParameter.ActualName = Name; } } private void ConfigureBitFlipMoveOperators(IEnumerable oneBitflipMoveOperators) { foreach (var oneBitFlipMoveOperator in oneBitflipMoveOperators) { oneBitFlipMoveOperator.OneBitflipMoveParameter.ActualName = Name + "_OneBitFlipMove"; } } private void ConfigureShakingOperators(IEnumerable shakingOperators) { foreach (var shakingOperator in shakingOperators) { shakingOperator.BinaryVectorParameter.ActualName = Name; } } #endregion } public static class IndividualExtensionMethods { public static BinaryVector BinaryVector(this Individual individual) { var encoding = individual.GetEncoding(); return individual.BinaryVector(encoding.Name); } public static BinaryVector BinaryVector(this Individual individual, string name) { return (BinaryVector)individual[name]; } } }