#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
}
}