#region License Information /* HeuristicLab * Copyright (C) 2002-2014 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.Encodings.BinaryVectorEncoding; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.PluginInfrastructure; namespace HeuristicLab.Problems.Programmable { [Item("BinaryEncoding", "Describes a binary vector encoding.")] [StorableClass] public sealed class BinaryEncoding : 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 (lengthParameter == value) return; lengthParameter = value; OnLengthParameterChanged(); } } public override IEnumerable Parameters { get { return base.Parameters.Concat(new IValueParameter[] { LengthParameter }); } } #endregion public int Length { get { return LengthParameter.Value.Value; } set { LengthParameter.Value.Value = value; } } [StorableConstructor] private BinaryEncoding(bool deserializing) : base(deserializing) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { RegisterParameterEvents(); DiscoverOperators(); } public override IDeepCloneable Clone(Cloner cloner) { return new BinaryEncoding(this, cloner); } private BinaryEncoding(BinaryEncoding original, Cloner cloner) : base(original, cloner) { lengthParameter = cloner.Clone(original.lengthParameter); RegisterParameterEvents(); } public BinaryEncoding(string name, int length) : base(name) { lengthParameter = new FixedValueParameter(Name + "Length", new IntValue(length)); } 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 BinaryEncoding() { encodingSpecificOperatorTypes = new List() { typeof (IBinaryVectorOperator), typeof (IBinaryVectorCreator), typeof (IBinaryVectorCrossover), typeof (IBinaryVectorManipulator), typeof (IBinaryVectorMoveOperator), typeof (IBinaryVectorMultiNeighborhoodShakingOperator), }; } private void DiscoverOperators() { var pluginDescription = ApplicationManager.Manager.GetDeclaringPlugin(typeof(IBinaryVectorOperator)); var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, pluginDescription, true, false, false); var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t)); var newOperators = operators.Except(encodingOperators, new TypeEqualityComparer()).ToList(); ConfigureOperators(newOperators); encodingOperators.AddRange(newOperators); } #endregion public override void ConfigureOperators(IEnumerable operators) { ConfigureCreators(operators.OfType()); ConfigureCrossovers(operators.OfType()); ConfigureManipulators(operators.OfType()); ConfigureMoveOperators(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 ConfigureShakingOperators(IEnumerable shakingOperators) { foreach (var shakingOperator in shakingOperators) { shakingOperator.BinaryVectorParameter.ActualName = Name; } } #endregion } }