#region License Information /* HeuristicLab * Copyright (C) 2002-2019 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 HEAL.Attic; using HeuristicLab.PluginInfrastructure; namespace HeuristicLab.Encodings.LinearLinkageEncoding { [Item("Linear Linkage Encoding", "Describes a linear linkage (LLE) encoding.")] [StorableType("7AE11F39-E6BD-4FC7-8112-0A5EDCBFBDB6")] public sealed class LinearLinkageEncoding : 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 LinearLinkageEncoding(StorableConstructorFlag _) : base(_) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { RegisterParameterEvents(); DiscoverOperators(); } public override IDeepCloneable Clone(Cloner cloner) { return new LinearLinkageEncoding(this, cloner); } private LinearLinkageEncoding(LinearLinkageEncoding original, Cloner cloner) : base(original, cloner) { lengthParameter = cloner.Clone(original.lengthParameter); RegisterParameterEvents(); } public LinearLinkageEncoding() : this("LLE", 10) { } public LinearLinkageEncoding(string name) : this(name, 10) { } public LinearLinkageEncoding(int length) : this("LLE", length) { } public LinearLinkageEncoding(string name, int length) : base(name) { lengthParameter = new FixedValueParameter(Name + ".Length", new IntValue(length)); Parameters.Add(lengthParameter); SolutionCreator = new RandomLinearLinkageCreator(); RegisterParameterEvents(); DiscoverOperators(); } private void OnLengthParameterChanged() { RegisterLengthParameterEvents(); ConfigureOperators(Operators); } private void RegisterParameterEvents() { RegisterLengthParameterEvents(); } private void RegisterLengthParameterEvents() { LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators); } #region Operator Discovery private static readonly IEnumerable encodingSpecificOperatorTypes; static LinearLinkageEncoding() { encodingSpecificOperatorTypes = new List() { typeof (ILinearLinkageOperator), typeof (ILinearLinkageCreator), typeof (ILinearLinkageCrossover), typeof (ILinearLinkageManipulator), typeof (ILinearLinkageShakingOperator), typeof (ILinearLinkageMoveOperator) }; } private void DiscoverOperators() { var assembly = typeof(ILinearLinkageOperator).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()); ConfigureShakingOperators(operators.OfType()); ConfigureMoveOperators(operators.OfType()); ConfigureSwap2MoveOperators(operators.OfType()); } #region specific operator wiring private void ConfigureCreators(IEnumerable creators) { foreach (var creator in creators) { creator.LengthParameter.ActualName = LengthParameter.Name; creator.LLEParameter.ActualName = Name; } } private void ConfigureCrossovers(IEnumerable crossovers) { foreach (var crossover in crossovers) { crossover.ChildParameter.ActualName = Name; crossover.ParentsParameter.ActualName = Name; } } private void ConfigureManipulators(IEnumerable manipulators) { foreach (var manipulator in manipulators) { manipulator.LLEParameter.ActualName = Name; } } private void ConfigureShakingOperators(IEnumerable shakingOperators) { foreach (var shakingOperator in shakingOperators) { shakingOperator.LLEParameter.ActualName = Name; } } private void ConfigureMoveOperators(IEnumerable moveOperators) { foreach (var moveOperator in moveOperators) { moveOperator.LLEParameter.ActualName = Name; } } private void ConfigureSwap2MoveOperators(IEnumerable swap2MoveOperators) { foreach (var swap2MoveOperator in swap2MoveOperators) { swap2MoveOperator.Swap2MoveParameter.ActualName = Name + ".Swap2Move"; } } #endregion } public static class IndividualExtensionMethods { public static LinearLinkage LinearLinkage(this Individual individual) { var encoding = individual.GetEncoding(); return individual.LinearLinkage(encoding.Name); } public static LinearLinkage LinearLinkage(this Individual individual, string name) { return (LinearLinkage)individual[name]; } } }