#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.Drawing; using System.Linq; using HeuristicLab.Analysis; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.BinaryVectorEncoding; using HeuristicLab.Encodings.IntegerVectorEncoding; using HeuristicLab.Encodings.PermutationEncoding; using HeuristicLab.Encodings.RealVectorEncoding; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.PluginInfrastructure; namespace HeuristicLab.Problems.Programmable { [Item("Programmable Problem (single-objective)", "Represents a single-objective problem that can be programmed.")] [Creatable("Problems")] [StorableClass] public class SingleObjectiveProgrammableProblem : SingleObjectiveHeuristicOptimizationProblem, IParameterizedNamedItem, IStorableContent { public string Filename { get; set; } public static new Image StaticItemImage { get { return Common.Resources.VSImageLibrary.Script; } } public new ParameterCollection Parameters { get { return base.Parameters; } } IKeyedItemCollection IParameterizedItem.Parameters { get { return Parameters; } } public IValueParameter ProblemDefinitionParameter { get { return (IValueParameter)Parameters["ProblemDefinition"]; } } protected IValueParameter ConfigurationParameter { get { return (IValueParameter)Parameters["Configuration"]; } } public ISingleObjectiveProblemDefinitionHost ProblemDefinition { get { return ProblemDefinitionParameter.Value; } set { ProblemDefinitionParameter.Value = value; } } [Storable] protected List DynamicConfigurationParameters; [StorableConstructor] protected SingleObjectiveProgrammableProblem(bool deserializing) : base(deserializing) { } protected SingleObjectiveProgrammableProblem(SingleObjectiveProgrammableProblem original, Cloner cloner) : base(original, cloner) { DynamicConfigurationParameters = original.DynamicConfigurationParameters.Select(cloner.Clone).ToList(); RegisterEventHandlers(); } public SingleObjectiveProgrammableProblem() : base(new SingleObjectiveEvaluator(), new ParameterVectorCreater()) { Parameters.Add(new ValueParameter("ProblemDefinition", "Defines the problem.", new SingleObjectiveProblemDefinitionScript() { Name = Name })); Parameters.Add(new ValueParameter("Configuration", "Describes which parameters exist, what they're called, what type they are and their bounds if any.")); DynamicConfigurationParameters = new List(); Operators.Add(new BestScopeSolutionAnalyzer()); Operators.Add(new SingleObjectiveAnalyzer()); Operators.Add(Evaluator); Operators.Add(SolutionCreator); RegisterEventHandlers(); } public override IDeepCloneable Clone(Cloner cloner) { return new SingleObjectiveProgrammableProblem(this, cloner); } [StorableHook(HookType.AfterDeserialization)] // ReSharper disable UnusedMember.Local private void AfterDeserialization() { RegisterEventHandlers(); } // ReSharper restore UnusedMember.Local private void RegisterEventHandlers() { ProblemDefinitionParameter.ValueChanged += ProblemDefinitionParameterOnValueChanged; RegisterHostInstanceChanges(); } private void ProblemDefinitionParameterOnValueChanged(object sender, EventArgs eventArgs) { RegisterHostInstanceChanges(); Parameterize(); } private void RegisterHostInstanceChanges() { ProblemDefinitionParameter.Value.InstanceChanged += ProblemDefinitionHostOnInstanceChanged; ProblemDefinitionParameter.Value.NameChanged += ProblemDefinitionHostOnNameChanged; } private void ProblemDefinitionHostOnNameChanged(object sender, EventArgs eventArgs) { if (sender != ProblemDefinitionParameter.Value) return; Name = ProblemDefinitionParameter.Value.Name; } protected override void OnNameChanged() { base.OnNameChanged(); ProblemDefinitionParameter.Value.Name = Name; } protected override void OnEvaluatorChanged() { base.OnEvaluatorChanged(); Parameterize(); } protected virtual void ProblemDefinitionHostOnInstanceChanged(object sender, EventArgs eventArgs) { Parameterize(); } protected virtual void Parameterize() { var instance = ProblemDefinitionParameter.Value.Instance; if (instance == null) return; Configuration configuration; try { configuration = instance.GetConfiguration(); } catch { return; } ConfigurationParameter.Value = configuration; Maximization.Value = instance.IsMaximizationProblem; Evaluator.ConfigurationParameter.ActualName = ConfigurationParameter.Name; Evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name; foreach (var evalOp in Operators.OfType()) { evalOp.ConfigurationParameter.ActualName = ConfigurationParameter.Name; evalOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name; } foreach (var analyzeOp in Operators.OfType()) { analyzeOp.ConfigurationParameter.ActualName = ConfigurationParameter.Name; analyzeOp.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name; analyzeOp.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName; } var solutionCreators = UpdateDynamicConfigurationParameters(configuration); if (solutionCreators.Count == 1) { Operators.RemoveAll(x => x is ParameterVectorCrossover || x is ParameterVectorManipulator); UpdateSingleVectorEncodingOperators(solutionCreators, configuration); } else { UpdateMultiVectorEncodingOperators(solutionCreators, configuration); } UpdateMoveOperators(); } protected virtual List UpdateDynamicConfigurationParameters(Configuration configuration) { foreach (var param in DynamicConfigurationParameters) if (Parameters.Contains(param)) Parameters.Remove(param); DynamicConfigurationParameters.Clear(); var solutionCreators = new List(); foreach (var param in configuration.Parameters) { #region Configure BinaryVector Creator var binConfig = param.Value as BinaryParameterConfiguration; if (binConfig != null) { var p = new ValueParameter(param.Key + "Length", binConfig.Length); DynamicConfigurationParameters.Add(p); var creator = new RandomBinaryVectorCreator(); creator.BinaryVectorParameter.ActualName = param.Key; creator.LengthParameter.ActualName = p.Name; solutionCreators.Add(creator); } #endregion #region Configure IntegerVector Creator var intConfig = param.Value as IntegerParameterConfiguration; if (intConfig != null) { var l = new ValueParameter(param.Key + "Length", intConfig.Length); var b = new ValueParameter(param.Key + "Bounds", intConfig.Bounds); DynamicConfigurationParameters.Add(l); DynamicConfigurationParameters.Add(b); var creator = new UniformRandomIntegerVectorCreator(); creator.IntegerVectorParameter.ActualName = param.Key; creator.LengthParameter.ActualName = l.Name; creator.BoundsParameter.ActualName = b.Name; solutionCreators.Add(creator); } #endregion #region Configure RealVector Creator var realConfig = param.Value as RealParameterConfiguration; if (realConfig != null) { var l = new ValueParameter(param.Key + "Length", realConfig.Length); var b = new ValueParameter(param.Key + "Bounds", realConfig.Bounds); DynamicConfigurationParameters.Add(l); DynamicConfigurationParameters.Add(b); var creator = new UniformRandomRealVectorCreator(); creator.RealVectorParameter.ActualName = param.Key; creator.LengthParameter.ActualName = l.Name; creator.BoundsParameter.ActualName = b.Name; solutionCreators.Add(creator); } #endregion #region Configure Permutation Creator var permConfig = param.Value as PermutationParameterConfiguration; if (permConfig != null) { var l = new ValueParameter(param.Key + "Length", permConfig.Length); DynamicConfigurationParameters.Add(l); var creator = new RandomPermutationCreator(); creator.PermutationParameter.ActualName = param.Key; creator.LengthParameter.ActualName = l.Name; creator.PermutationTypeParameter.Value = permConfig.Type; solutionCreators.Add(creator); } #endregion } foreach (var param in DynamicConfigurationParameters) { param.Hidden = true; Parameters.Add(param); } return solutionCreators; } protected virtual void UpdateSingleVectorEncodingOperators(List solutionCreators, Configuration configuration) { var newCreator = solutionCreators.Single(); #region Configure Operators for BinaryVectorEncoding var binCreator = newCreator as IBinaryVectorCreator; if (binCreator != null) { var paramName = binCreator.BinaryVectorParameter.ActualName; // do not replace a binary vector creator that was manually set if (!(SolutionCreator is IBinaryVectorCreator) || ((IBinaryVectorCreator)SolutionCreator).BinaryVectorParameter.ActualName != paramName) { Operators.Remove(SolutionCreator); SolutionCreator = newCreator; Operators.Add(SolutionCreator); } #region Wire BinaryVector Crossovers Operators.RemoveAll(x => x is IBinaryVectorCrossover && ((IBinaryVectorCrossover)x).ChildParameter.ActualName != paramName); var crossovers = ApplicationManager.Manager.GetInstances().ToList(); foreach (var xo in crossovers) { xo.ChildParameter.ActualName = binCreator.BinaryVectorParameter.ActualName; xo.ChildParameter.Hidden = true; xo.ParentsParameter.ActualName = binCreator.BinaryVectorParameter.ActualName; xo.ParentsParameter.Hidden = true; } Operators.AddRange(crossovers.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #region Wire BinaryVector Manipulators Operators.RemoveAll(x => x is IBinaryVectorManipulator && ((IBinaryVectorManipulator)x).BinaryVectorParameter.ActualName != paramName); var manipulators = ApplicationManager.Manager.GetInstances().ToList(); foreach (var m in manipulators) { m.BinaryVectorParameter.ActualName = binCreator.BinaryVectorParameter.ActualName; m.BinaryVectorParameter.Hidden = true; } Operators.AddRange(manipulators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #region Wire BinaryVector ShakingOperators Operators.RemoveAll(x => x is IBinaryVectorMultiNeighborhoodShakingOperator && ((IBinaryVectorManipulator)x).BinaryVectorParameter.ActualName != paramName); var shakingOperators = ApplicationManager.Manager.GetInstances().ToList(); foreach (var so in shakingOperators) { so.BinaryVectorParameter.ActualName = paramName; so.BinaryVectorParameter.Hidden = true; } Operators.AddRange(shakingOperators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion } else { Operators.RemoveAll(x => x is IBinaryVectorCrossover || x is IBinaryVectorManipulator || x is IBinaryVectorMultiNeighborhoodShakingOperator); } #endregion #region Configure Operators for IntegerVectorEncoding var intCreator = newCreator as IIntegerVectorCreator; if (intCreator != null) { var paramName = intCreator.IntegerVectorParameter.ActualName; // do not replace an integer vector creator that was manually set if (!(SolutionCreator is IIntegerVectorCreator) || ((IIntegerVectorCreator)SolutionCreator).IntegerVectorParameter.ActualName != intCreator.IntegerVectorParameter.ActualName) { Operators.Remove(SolutionCreator); SolutionCreator = newCreator; Operators.Add(SolutionCreator); } #region Wire IntegerVector Crossovers Operators.RemoveAll(x => x is IIntegerVectorCrossover && ((IIntegerVectorCrossover)x).ChildParameter.ActualName != paramName); var crossovers = ApplicationManager.Manager.GetInstances().ToList(); foreach (var xo in crossovers) { xo.ChildParameter.ActualName = intCreator.IntegerVectorParameter.ActualName; xo.ChildParameter.Hidden = true; xo.ParentsParameter.ActualName = intCreator.IntegerVectorParameter.ActualName; xo.ParentsParameter.Hidden = true; var bx = xo as IBoundedIntegerVectorOperator; if (bx != null) { bx.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName; bx.BoundsParameter.Hidden = true; } } Operators.AddRange(crossovers.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #region Wire IntegerVector Manipulators Operators.RemoveAll(x => x is IIntegerVectorManipulator && ((IIntegerVectorManipulator)x).IntegerVectorParameter.ActualName != paramName); var manipulators = ApplicationManager.Manager.GetInstances().ToList(); foreach (var m in manipulators) { m.IntegerVectorParameter.ActualName = intCreator.IntegerVectorParameter.ActualName; m.IntegerVectorParameter.Hidden = true; var sm = m as ISelfAdaptiveManipulator; if (sm != null) { var p = sm.StrategyParameterParameter as ILookupParameter; if (p != null) { p.ActualName = paramName + "Strategy"; p.Hidden = true; } } var bm = m as IBoundedIntegerVectorOperator; if (bm != null) { bm.BoundsParameter.ActualName = intCreator.BoundsParameter.ActualName; bm.BoundsParameter.Hidden = true; } } Operators.AddRange(manipulators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #region Wire IntegerVector StrategyParameters for SelfAdaptiveManipulators Operators.RemoveAll(x => x is IStrategyParameterCreator && !(x is IIntegerVectorStdDevStrategyParameterCreator) || x is IIntegerVectorStdDevStrategyParameterCreator && ((IIntegerVectorStdDevStrategyParameterCreator)x).StrategyParameterParameter.ActualName != paramName + "Strategy"); Operators.RemoveAll(x => x is IStrategyParameterManipulator && !(x is IIntegerVectorStdDevStrategyParameterManipulator) || x is IIntegerVectorStdDevStrategyParameterManipulator && ((IIntegerVectorStdDevStrategyParameterManipulator)x).StrategyParameterParameter.ActualName != paramName + "Strategy"); Operators.RemoveAll(x => x is IStrategyParameterCrossover && !(x is IIntegerVectorStdDevStrategyParameterCrossover) || x is IIntegerVectorStdDevStrategyParameterCrossover && ((IIntegerVectorStdDevStrategyParameterCrossover)x).StrategyParameterParameter.ActualName != paramName + "Strategy"); var strategyOperators = ApplicationManager.Manager.GetInstances().ToList(); if (!(configuration.Parameters.First().Value is IntegerParameterConfiguration)) throw new InvalidOperationException("Single-encoded problem with integervector creator that is not an integer-coded problem."); var problemSize = ((IntegerParameterConfiguration)configuration.Parameters.First().Value).Length.Value; var b = ((IntegerParameterConfiguration)configuration.Parameters.First().Value).Bounds; var bounds = new DoubleMatrix(b.Rows, b.Columns); for (var i = 0; i < bounds.Rows; i++) { bounds[i, 1] = (int)Math.Ceiling(0.33 * (b[i, 1] - b[i, 0])); bounds[i, 0] = 0; if (bounds.Columns > 2) bounds[i, 2] = b[i, 2]; } foreach (var s in strategyOperators) { var c = s as IIntegerVectorStdDevStrategyParameterCreator; if (c != null) { c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone(); c.LengthParameter.ActualName = intCreator.LengthParameter.ActualName; c.StrategyParameterParameter.ActualName = paramName + "Strategy"; } var m = s as IIntegerVectorStdDevStrategyParameterManipulator; if (m != null) { m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone(); m.StrategyParameterParameter.ActualName = paramName + "Strategy"; } var mm = s as Encodings.IntegerVectorEncoding.StdDevStrategyVectorManipulator; if (mm != null) { mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * problemSize)); mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(problemSize))); } var x = s as IIntegerVectorStdDevStrategyParameterCrossover; if (x != null) { x.ParentsParameter.ActualName = paramName + "Strategy"; x.StrategyParameterParameter.ActualName = paramName + "Strategy"; } } Operators.AddRange(strategyOperators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #endregion #region Wire IntegerVector ShakingOperators Operators.RemoveAll(x => x is IIntegerVectorMultiNeighborhoodShakingOperator && ((IIntegerVectorMultiNeighborhoodShakingOperator)x).IntegerVectorParameter.ActualName != paramName); var shakingOperators = ApplicationManager.Manager.GetInstances().ToList(); foreach (var so in shakingOperators) { so.IntegerVectorParameter.ActualName = paramName; so.IntegerVectorParameter.Hidden = true; } Operators.AddRange(shakingOperators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion } else { Operators.RemoveAll(x => x is IIntegerVectorCrossover || x is IIntegerVectorManipulator || x is IIntegerVectorStdDevStrategyParameterOperator || x is IIntegerVectorMultiNeighborhoodShakingOperator); } #endregion #region Configure Operators for RealVectorEncoding var realCreator = newCreator as IRealVectorCreator; if (realCreator != null) { var paramName = realCreator.RealVectorParameter.ActualName; // do not replace a real vector creator that was manually set if (!(SolutionCreator is IRealVectorCreator) || ((IRealVectorCreator)SolutionCreator).RealVectorParameter.ActualName != realCreator.RealVectorParameter.ActualName) { Operators.Remove(SolutionCreator); SolutionCreator = newCreator; Operators.Add(SolutionCreator); } #region Wire RealVector Crossovers Operators.RemoveAll(x => x is IRealVectorCrossover && ((IRealVectorCrossover)x).ChildParameter.ActualName != paramName); var crossovers = ApplicationManager.Manager.GetInstances().ToList(); foreach (var xo in crossovers) { xo.ChildParameter.ActualName = paramName; xo.ChildParameter.Hidden = true; xo.ParentsParameter.ActualName = paramName; xo.ParentsParameter.Hidden = true; xo.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName; xo.BoundsParameter.Hidden = true; } Operators.AddRange(crossovers.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #region Wire RealVector Manipulators Operators.RemoveAll(x => x is IRealVectorManipulator && ((IRealVectorManipulator)x).RealVectorParameter.ActualName != paramName); var manipulators = ApplicationManager.Manager.GetInstances().ToList(); foreach (var m in manipulators) { m.RealVectorParameter.ActualName = paramName; m.RealVectorParameter.Hidden = true; m.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName; m.BoundsParameter.Hidden = true; var sm = m as ISelfAdaptiveManipulator; if (sm != null) { var p = sm.StrategyParameterParameter as ILookupParameter; if (p != null) { p.ActualName = paramName + "Strategy"; p.Hidden = true; } } } Operators.AddRange(manipulators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #region Wire RealVector Strategy Parameters for SelfAdaptiveManipulators Operators.RemoveAll(x => x is IStrategyParameterCreator && !(x is IRealVectorStdDevStrategyParameterCreator) || x is IRealVectorStdDevStrategyParameterCreator && ((IRealVectorStdDevStrategyParameterCreator)x).StrategyParameterParameter.ActualName != paramName + "Strategy"); Operators.RemoveAll(x => x is IStrategyParameterManipulator && !(x is IRealVectorStdDevStrategyParameterManipulator) || x is IRealVectorStdDevStrategyParameterManipulator && ((IRealVectorStdDevStrategyParameterManipulator)x).StrategyParameterParameter.ActualName != paramName + "Strategy"); Operators.RemoveAll(x => x is IStrategyParameterCrossover && !(x is IRealVectorStdDevStrategyParameterCrossover) || x is IRealVectorStdDevStrategyParameterCrossover && ((IRealVectorStdDevStrategyParameterCrossover)x).StrategyParameterParameter.ActualName != paramName + "Strategy"); var strategyOperators = ApplicationManager.Manager.GetInstances().ToList(); if (!(configuration.Parameters.First().Value is RealParameterConfiguration)) throw new InvalidOperationException("Single-encoded problem with realvector creator that is not a real-coded problem."); var problemSize = ((RealParameterConfiguration)configuration.Parameters.First().Value).Length.Value; var bounds = (DoubleMatrix)((RealParameterConfiguration)configuration.Parameters.First().Value).Bounds.Clone(); for (var i = 0; i < bounds.Rows; i++) { bounds[i, 1] = 0.1 * (bounds[i, 1] - bounds[i, 0]); bounds[i, 0] = 0; } foreach (var s in strategyOperators) { var c = s as IRealVectorStdDevStrategyParameterCreator; if (c != null) { c.BoundsParameter.Value = (DoubleMatrix)bounds.Clone(); c.LengthParameter.ActualName = realCreator.LengthParameter.ActualName; c.StrategyParameterParameter.ActualName = paramName + "Strategy"; } var m = s as IRealVectorStdDevStrategyParameterManipulator; if (m != null) { m.BoundsParameter.Value = (DoubleMatrix)bounds.Clone(); m.StrategyParameterParameter.ActualName = paramName + "Strategy"; } var mm = s as Encodings.RealVectorEncoding.StdDevStrategyVectorManipulator; if (mm != null) { mm.GeneralLearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * problemSize)); mm.LearningRateParameter.Value = new DoubleValue(1.0 / Math.Sqrt(2 * Math.Sqrt(problemSize))); } var x = s as IRealVectorStdDevStrategyParameterCrossover; if (x != null) { x.ParentsParameter.ActualName = paramName + "Strategy"; x.StrategyParameterParameter.ActualName = paramName + "Strategy"; } } Operators.AddRange(strategyOperators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #endregion #region Wire RealVector ParticleCreators Operators.RemoveAll(x => x is IRealVectorParticleCreator && ((IRealVectorParticleCreator)x).RealVectorParameter.ActualName != paramName); var particleCreators = ApplicationManager.Manager.GetInstances().ToList(); foreach (var pc in particleCreators) { pc.RealVectorParameter.ActualName = paramName; pc.RealVectorParameter.Hidden = true; pc.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName; pc.BoundsParameter.Hidden = true; pc.ProblemSizeParameter.ActualName = realCreator.LengthParameter.ActualName; pc.ProblemSizeParameter.Hidden = true; } Operators.AddRange(particleCreators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #region Wire RealVector ParticleUpdaters Operators.RemoveAll(x => x is IRealVectorParticleUpdater && ((IRealVectorParticleUpdater)x).RealVectorParameter.ActualName != paramName); var particleUpdaters = ApplicationManager.Manager.GetInstances().ToList(); foreach (var pu in particleUpdaters) { pu.RealVectorParameter.ActualName = paramName; pu.RealVectorParameter.Hidden = true; pu.BoundsParameter.ActualName = realCreator.BoundsParameter.ActualName; pu.BoundsParameter.Hidden = true; } Operators.AddRange(particleUpdaters.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #region Wire RealVector SwarmUpdaters Operators.RemoveAll(x => x is IRealVectorSwarmUpdater && ((IRealVectorSwarmUpdater)x).RealVectorParameter.ActualName != paramName); var swarmUpdaters = ApplicationManager.Manager.GetInstances().ToList(); foreach (var su in swarmUpdaters) { su.RealVectorParameter.ActualName = paramName; su.RealVectorParameter.Hidden = true; su.MaximizationParameter.ActualName = MaximizationParameter.Name; su.MaximizationParameter.Hidden = true; } Operators.AddRange(swarmUpdaters.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #region Wire RealVector ShakingOperators Operators.RemoveAll(x => x is IRealVectorMultiNeighborhoodShakingOperator && ((IRealVectorMultiNeighborhoodShakingOperator)x).RealVectorParameter.ActualName != paramName); var shakingOperators = ApplicationManager.Manager.GetInstances().ToList(); foreach (var so in shakingOperators) { so.RealVectorParameter.ActualName = paramName; so.RealVectorParameter.Hidden = true; } Operators.AddRange(shakingOperators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion } else { Operators.RemoveAll(x => x is IRealVectorCrossover || x is IRealVectorManipulator || x is IRealVectorStdDevStrategyParameterOperator || x is IRealVectorParticleCreator || x is IRealVectorParticleUpdater || x is IRealVectorSwarmUpdater || x is IRealVectorMultiNeighborhoodShakingOperator); } #endregion #region Configure Operators for PermutationEncoding var permCreator = newCreator as IPermutationCreator; if (permCreator != null) { var paramName = permCreator.PermutationParameter.ActualName; // do not replace a permutation creator that was manually set if (!(SolutionCreator is IPermutationCreator) || ((IPermutationCreator)SolutionCreator).PermutationParameter.ActualName != permCreator.PermutationParameter.ActualName) { Operators.Remove(SolutionCreator); SolutionCreator = newCreator; Operators.Add(SolutionCreator); } #region Wire Permutation Crossovers Operators.RemoveAll(x => x is IPermutationCrossover && ((IPermutationCrossover)x).ChildParameter.ActualName != paramName); var crossovers = ApplicationManager.Manager.GetInstances().ToList(); foreach (var xo in crossovers) { xo.ChildParameter.ActualName = permCreator.PermutationParameter.ActualName; xo.ChildParameter.Hidden = true; xo.ParentsParameter.ActualName = permCreator.PermutationParameter.ActualName; xo.ParentsParameter.Hidden = true; } Operators.AddRange(crossovers.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #region Wire Permutation Manipulators Operators.RemoveAll(x => x is IPermutationManipulator && ((IPermutationManipulator)x).PermutationParameter.ActualName != paramName); var manipulators = ApplicationManager.Manager.GetInstances().ToList(); foreach (var m in manipulators) { m.PermutationParameter.ActualName = permCreator.PermutationParameter.ActualName; m.PermutationParameter.Hidden = true; } Operators.AddRange(manipulators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion #region Wire ShakingOperators Operators.RemoveAll(x => x is IPermutationMultiNeighborhoodShakingOperator && ((IPermutationMultiNeighborhoodShakingOperator)x).PermutationParameter.ActualName != paramName); var shakingOperators = ApplicationManager.Manager.GetInstances().ToList(); foreach (var op in shakingOperators) { op.PermutationParameter.ActualName = paramName; op.PermutationParameter.Hidden = true; } Operators.AddRange(shakingOperators.Where(x => Operators.All(y => x.GetType() != y.GetType()))); #endregion } else { Operators.RemoveAll(x => x is IPermutationCrossover || x is IPermutationManipulator || x is IPermutationMultiNeighborhoodShakingOperator); } #endregion } protected virtual void UpdateMultiVectorEncodingOperators(List solutionCreators, Configuration configuration) { var oldCreator = SolutionCreator as ParameterVectorCreater; var newCreator = new ParameterVectorCreater(); #region Configure BinaryVector Creator var newBinParams = new HashSet(solutionCreators.OfType().Select(x => x.BinaryVectorParameter.ActualName)); if (oldCreator != null) { // we want to reuse the old creator var oldParams = new HashSet(oldCreator.Operators.OfType() .Select(x => x.BinaryVectorParameter.ActualName)); foreach (var toAdd in newBinParams.Except(oldParams)) { var paramName = toAdd; oldCreator.Operators.Add( solutionCreators.OfType().Single(x => x.BinaryVectorParameter.ActualName == paramName)); } foreach (var toRemove in oldParams.Except(newBinParams)) { var paramName = toRemove; var op = oldCreator.Operators.OfType() .SingleOrDefault(x => x.BinaryVectorParameter.ActualName == paramName); if (op != null) oldCreator.Operators.Remove(op); } } else { // we will use the new creator foreach (var binCreator in solutionCreators.OfType()) { newCreator.Operators.Add(binCreator); } } #endregion #region Configure IntegerVector Creator var newIntParams = new HashSet(solutionCreators.OfType().Select(x => x.IntegerVectorParameter.ActualName)); if (oldCreator != null) { // we want to reuse the old creator var oldParams = new HashSet(oldCreator .Operators.OfType() .Select(x => x.IntegerVectorParameter.ActualName)); foreach (var toAdd in newIntParams.Except(oldParams)) { var paramName = toAdd; oldCreator.Operators.Add( solutionCreators.OfType().Single(x => x.IntegerVectorParameter.ActualName == paramName)); } foreach (var toRemove in oldParams.Except(newIntParams)) { var paramName = toRemove; var op = oldCreator.Operators.OfType() .SingleOrDefault(x => x.IntegerVectorParameter.ActualName == paramName); if (op != null) oldCreator.Operators.Remove(op); } } else { // we will use the new creator foreach (var intCreator in solutionCreators.OfType()) { newCreator.Operators.Add(intCreator); } } #endregion #region Configure RealVector Creator var newRealParams = new HashSet(solutionCreators.OfType().Select(x => x.RealVectorParameter.ActualName)); if (oldCreator != null) { // we want to reuse the old creator var oldParams = new HashSet(oldCreator .Operators.OfType() .Select(x => x.RealVectorParameter.ActualName)); foreach (var toAdd in newRealParams.Except(oldParams)) { var paramName = toAdd; oldCreator.Operators.Add( solutionCreators.OfType().Single(x => x.RealVectorParameter.ActualName == paramName)); } foreach (var toRemove in oldParams.Except(newRealParams)) { var paramName = toRemove; var op = oldCreator.Operators.OfType() .SingleOrDefault(x => x.RealVectorParameter.ActualName == paramName); if (op != null) oldCreator.Operators.Remove(op); } } else { // we will use the new creator foreach (var realCreator in solutionCreators.OfType()) { newCreator.Operators.Add(realCreator); } } #endregion #region Configure Permutation Creator var newPermParams = new HashSet(solutionCreators.OfType().Select(x => x.PermutationParameter.ActualName)); if (oldCreator != null) { // we want to reuse the old creator var oldParams = new HashSet(oldCreator .Operators.OfType() .Select(x => x.PermutationParameter.ActualName)); foreach (var toAdd in newPermParams.Except(oldParams)) { var paramName = toAdd; oldCreator.Operators.Add( solutionCreators.OfType().Single(x => x.PermutationParameter.ActualName == paramName)); } foreach (var toRemove in oldParams.Except(newPermParams)) { var paramName = toRemove; var op = oldCreator.Operators.OfType() .SingleOrDefault(x => x.PermutationParameter.ActualName == paramName); if (op != null) oldCreator.Operators.Remove(op); } // we also have to sync the permutation type (in case this changes, as it is a value parameter) foreach (var intersect in newPermParams.Intersect(oldParams)) { var paramName = intersect; var oldPermCreator = oldCreator.Operators.OfType() .Single(x => x.PermutationParameter.ActualName == paramName); var newPermCreator = solutionCreators.OfType() .Single(x => x.PermutationParameter.ActualName == paramName); oldPermCreator.PermutationTypeParameter.Value = newPermCreator.PermutationTypeParameter.Value; } } else { // we will use the new creator foreach (var permCreator in solutionCreators.OfType()) { newCreator.Operators.Add(permCreator); } } #endregion if (oldCreator == null) SolutionCreator = newCreator; // crossover and manipulator for multi-vector encoding // the condition checks if a multi-vector encoding is to be updated (there already exists ParameterVectorCrossover and ParameterVectorManipulator) if (Operators.OfType().Any() && Operators.OfType().Any()) { #region Update existing multi-vector encoding #region Update ParameterVector Crossover ... foreach (var oldXo in Operators.OfType()) { #region ... for binary parameters var oldBinParams = new HashSet(oldXo.Operators.OfType() .Select(x => x.ChildParameter.ActualName)); foreach (var toAdd in newBinParams.Except(oldBinParams)) oldXo.Operators.Add(GetDefaultBinaryCrossover(toAdd, configuration)); foreach (var toRemove in oldBinParams.Except(newBinParams)) { var op = oldXo.Operators.OfType().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove); if (op != null) oldXo.Operators.Remove(op); } #endregion #region ... for integer parameters var oldIntParams = new HashSet(oldXo.Operators.OfType() .Select(x => x.ChildParameter.ActualName)); foreach (var toAdd in newIntParams.Except(oldIntParams)) oldXo.Operators.Add(GetDefaultIntegerCrossover(toAdd, configuration)); foreach (var toRemove in oldIntParams.Except(newIntParams)) { var op = oldXo.Operators.OfType() .SingleOrDefault(x => x.ChildParameter.ActualName == toRemove); if (op != null) oldXo.Operators.Remove(op); } #endregion #region ... for real parameters var oldRealParams = new HashSet(oldXo.Operators.OfType() .Select(x => x.ChildParameter.ActualName)); foreach (var toAdd in newRealParams.Except(oldRealParams)) oldXo.Operators.Add(GetDefaultRealCrossover(toAdd, configuration)); foreach (var toRemove in oldRealParams.Except(newRealParams)) { var op = oldXo.Operators.OfType().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove); if (op != null) oldXo.Operators.Remove(op); } #endregion #region ... for permutation parameters var oldPermParams = new HashSet(oldXo.Operators.OfType() .Select(x => x.ChildParameter.ActualName)); foreach (var toAdd in newPermParams.Except(oldPermParams)) oldXo.Operators.Add(GetDefaultPermutationCrossover(toAdd, configuration)); foreach (var toRemove in oldPermParams.Except(newPermParams)) { var op = oldXo.Operators.OfType().SingleOrDefault(x => x.ChildParameter.ActualName == toRemove); if (op != null) oldXo.Operators.Remove(op); } #endregion } #endregion #region Update ParameterVector Manipulator ... foreach (var oldM in Operators.OfType()) { #region ... for binary parameters var oldBinParams = new HashSet(oldM.Operators.OfType() .Select(x => x.BinaryVectorParameter.ActualName)); foreach (var toAdd in newBinParams.Except(oldBinParams)) oldM.Operators.Add(GetDefaultBinaryManipulator(toAdd, configuration)); foreach (var toRemove in oldBinParams.Except(newBinParams)) { var op = oldM.Operators.OfType() .SingleOrDefault(x => x.BinaryVectorParameter.ActualName == toRemove); if (op != null) oldM.Operators.Remove(op); } #endregion #region ... for integer parameters var oldIntParams = new HashSet(oldM.Operators.OfType() .Select(x => x.IntegerVectorParameter.ActualName)); foreach (var toAdd in newIntParams.Except(oldIntParams)) oldM.Operators.Add(GetDefaultIntegerManipulator(toAdd, configuration)); foreach (var toRemove in oldIntParams.Except(newIntParams)) { var op = oldM.Operators.OfType() .SingleOrDefault(x => x.IntegerVectorParameter.ActualName == toRemove); if (op != null) oldM.Operators.Remove(op); } #endregion #region ... for real parameters var oldRealParams = new HashSet(oldM.Operators.OfType() .Select(x => x.RealVectorParameter.ActualName)); foreach (var toAdd in newRealParams.Except(oldRealParams)) oldM.Operators.Add(GetDefaultRealManipulator(toAdd, configuration)); foreach (var toRemove in oldRealParams.Except(newRealParams)) { var op = oldM.Operators.OfType() .SingleOrDefault(x => x.RealVectorParameter.ActualName == toRemove); if (op != null) oldM.Operators.Remove(op); } #endregion #region ... for permutation parameters var oldPermParams = new HashSet(oldM.Operators.OfType() .Select(x => x.PermutationParameter.ActualName)); foreach (var toAdd in newPermParams.Except(oldPermParams)) oldM.Operators.Add(GetDefaultPermutationManipulator(toAdd, configuration)); foreach (var toRemove in oldPermParams.Except(newPermParams)) { var op = oldM.Operators.OfType() .SingleOrDefault(x => x.PermutationParameter.ActualName == toRemove); if (op != null) oldM.Operators.Remove(op); } #endregion } #endregion #endregion } else { #region Handle transition from single-vector to multi-vector encoding Operators.RemoveAll(x => x is ICrossover); Operators.RemoveAll(x => x is IManipulator); Operators.RemoveAll(x => x is IStrategyParameterCreator || x is IStrategyParameterManipulator || x is IStrategyParameterCrossover); Operators.RemoveAll(x => x is IParticleCreator); Operators.RemoveAll(x => x is IParticleUpdater); Operators.RemoveAll(x => x is ISwarmUpdater); Operators.RemoveAll(x => x is IMultiNeighborhoodShakingOperator); var crossover = new ParameterVectorCrossover(); var manipulator = new ParameterVectorManipulator(); foreach (var param in configuration.Parameters) { if (param.Value is BinaryParameterConfiguration) { crossover.Operators.Add(GetDefaultBinaryCrossover(param.Key, configuration)); manipulator.Operators.Add(GetDefaultBinaryManipulator(param.Key, configuration)); continue; } var intConfig = param.Value as IntegerParameterConfiguration; if (intConfig != null) { crossover.Operators.Add(GetDefaultIntegerCrossover(param.Key, configuration)); manipulator.Operators.Add(GetDefaultIntegerManipulator(param.Key, configuration)); continue; } var realConfig = param.Value as RealParameterConfiguration; if (realConfig != null) { crossover.Operators.Add(GetDefaultRealCrossover(param.Key, configuration)); manipulator.Operators.Add(GetDefaultRealManipulator(param.Key, configuration)); continue; } var permConfig = param.Value as PermutationParameterConfiguration; if (permConfig != null) { crossover.Operators.Add(GetDefaultPermutationCrossover(param.Key, configuration)); manipulator.Operators.Add(GetDefaultPermutationManipulator(param.Key, configuration)); continue; } throw new InvalidOperationException("Unknown type for parameter " + param.Key); } Operators.Add(crossover); Operators.Add(manipulator); #endregion } } protected virtual void UpdateMoveOperators() { Operators.RemoveAll(x => x is IParameterVectorMoveOperator); var generator = new ParameterVectorMoveGenerator(); generator.ConfigurationParameter.ActualName = ConfigurationParameter.Name; generator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name; var evaluator = new ParameterVectorMoveEvaluator(); evaluator.ConfigurationParameter.ActualName = ConfigurationParameter.Name; evaluator.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName; evaluator.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name; var maker = new ParameterVectorMoveMaker(); maker.ConfigurationParameter.ActualName = ConfigurationParameter.Name; maker.MoveQualityParameter.ActualName = evaluator.MoveQualityParameter.ActualName; maker.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName; Operators.AddRange(new IItem[] { generator, evaluator, maker }); } #region GetDefaultOperators for Crossovers and Manipulators // ReSharper disable RedundantNameQualifier protected virtual IBinaryVectorCrossover GetDefaultBinaryCrossover(string paramName, Configuration config) { var binConfig = (BinaryParameterConfiguration)config.Parameters[paramName]; IBinaryVectorCrossover binXo; if (binConfig.Length.Value > 3) binXo = new Encodings.BinaryVectorEncoding.SinglePointCrossover(); else binXo = new Encodings.BinaryVectorEncoding.UniformCrossover(); binXo.ChildParameter.ActualName = paramName; binXo.ParentsParameter.ActualName = paramName; return binXo; } protected virtual IBinaryVectorManipulator GetDefaultBinaryManipulator(string paramName, Configuration config) { var binM = new Encodings.BinaryVectorEncoding.SomePositionsBitflipManipulator(); binM.BinaryVectorParameter.ActualName = paramName; binM.MutationProbabilityParameter.Value = new DoubleValue(0.1); return binM; } protected virtual IIntegerVectorCrossover GetDefaultIntegerCrossover(string paramName, Configuration config) { var intXo = new Encodings.IntegerVectorEncoding.RoundedBlendAlphaBetaCrossover(); intXo.ChildParameter.ActualName = paramName; intXo.ParentsParameter.ActualName = paramName; intXo.BoundsParameter.ActualName = paramName + "Bounds"; intXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName; intXo.MaximizationParameter.ActualName = MaximizationParameter.Name; return intXo; } protected virtual IIntegerVectorManipulator GetDefaultIntegerManipulator(string paramName, Configuration configuration) { var intM = new Encodings.IntegerVectorEncoding.UniformSomePositionsManipulator(); intM.IntegerVectorParameter.ActualName = paramName; intM.BoundsParameter.ActualName = paramName + "Bounds"; intM.ProbabilityParameter.Value = new DoubleValue(0.1); return intM; } protected virtual IRealVectorCrossover GetDefaultRealCrossover(string paramName, Configuration configuration) { var realXo = new Encodings.RealVectorEncoding.BlendAlphaBetaCrossover(); realXo.ChildParameter.ActualName = paramName; realXo.ParentsParameter.ActualName = paramName; realXo.BoundsParameter.ActualName = paramName + "Bounds"; realXo.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName; realXo.MaximizationParameter.ActualName = MaximizationParameter.Name; return realXo; } protected virtual IRealVectorManipulator GetDefaultRealManipulator(string paramName, Configuration configuration) { var realM = new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator(); realM.RealVectorParameter.ActualName = paramName; realM.BoundsParameter.ActualName = paramName + "Bounds"; return realM; } protected virtual IPermutationCrossover GetDefaultPermutationCrossover(string paramName, Configuration configuration) { var permXo = new Encodings.PermutationEncoding.PartiallyMatchedCrossover(); permXo.ChildParameter.ActualName = paramName; permXo.ParentsParameter.ActualName = paramName; return permXo; } protected virtual IPermutationManipulator GetDefaultPermutationManipulator(string paramName, Configuration configuration) { var permM = new Encodings.PermutationEncoding.Swap2Manipulator(); permM.PermutationParameter.ActualName = paramName; return permM; } // ReSharper restore RedundantNameQualifier #endregion } }