#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.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.ParameterVectorEncoding; using HeuristicLab.Encodings.PermutationEncoding; using HeuristicLab.Encodings.RealVectorEncoding; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Problems.Programmable { [Item("Programmable Problem (single-objective)", "Represents a single-objective problem that can be programmed.")] [Creatable("Problems")] [StorableClass] public sealed class SingleObjectiveProgrammableProblem : SingleObjectiveHeuristicOptimizationProblem, IStorableContent { public string Filename { get; set; } public static new Image StaticItemImage { get { return HeuristicLab.Common.Resources.VSImageLibrary.Script; } } public IValueParameter ScriptParameter { get { return (IValueParameter)Parameters["Script"]; } } private IValueParameter BinaryVectorLengthParameter { get { return (IValueParameter)Parameters["BinaryVectorLength"]; } } private IValueParameter IntegerVectorLengthParameter { get { return (IValueParameter)Parameters["IntegerVectorLength"]; } } private IValueParameter IntegerVectorBoundsParameter { get { return (IValueParameter)Parameters["IntegerVectorBounds"]; } } private IValueParameter RealVectorLengthParameter { get { return (IValueParameter)Parameters["RealVectorLength"]; } } private IValueParameter RealVectorBoundsParameter { get { return (IValueParameter)Parameters["RealVectorBounds"]; } } private IValueParameter PermutationLengthParameter { get { return (IValueParameter)Parameters["PermutationLength"]; } } private IValueParameter PermutationTypeParameter { get { return (IValueParameter)Parameters["PermutationType"]; } } [Storable] private ParameterVectorCrossover Crossover { get; set; } [Storable] private ParameterVectorManipulator Manipulator { get; set; } [StorableConstructor] private SingleObjectiveProgrammableProblem(bool deserializing) : base(deserializing) { } private SingleObjectiveProgrammableProblem(SingleObjectiveProgrammableProblem original, Cloner cloner) : base(original, cloner) { Crossover = cloner.Clone(original.Crossover); Manipulator = cloner.Clone(original.Manipulator); RegisterEventHandlers(); } public SingleObjectiveProgrammableProblem() : base(new SingleObjectiveEvaluator(), new ParameterVectorCreater()) { Parameters.Add(new ValueParameter("Script", "Defines the problem.", new SingleObjectiveScript() { Name = ItemName })); Parameters.Add(new OptionalValueParameter("BinaryVectorLength", "The length of the binary vector.")); Parameters.Add(new OptionalValueParameter("IntegerVectorLength", "The length of the integer vector.")); Parameters.Add(new OptionalValueParameter("IntegerVectorBounds", "The bounds of the integer vector.")); Parameters.Add(new OptionalValueParameter("RealVectorLength", "The length of the real vector.")); Parameters.Add(new OptionalValueParameter("RealVectorBounds", "The bounds of the real vector.")); Parameters.Add(new OptionalValueParameter("PermutationLength", "The length of the permutation.")); Parameters.Add(new OptionalValueParameter("PermutationType", "The type of the permutation.")); Crossover = new ParameterVectorCrossover(); Manipulator = new ParameterVectorManipulator(); Operators.Add(new BestScopeSolutionAnalyzer()); Operators.Add(Evaluator); Operators.Add(SolutionCreator); Operators.Add(Crossover); Operators.Add(Manipulator); RegisterEventHandlers(); } public override IDeepCloneable Clone(Cloner cloner) { return new SingleObjectiveProgrammableProblem(this, cloner); } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { RegisterEventHandlers(); } private void RegisterEventHandlers() { ScriptParameter.ValueChanged += ScriptParameterOnValueChanged; Crossover.BeforeExecutionOperators.CollectionReset += CrossoverBeforeExecutionOperatorsOnChanged; Crossover.BeforeExecutionOperators.ItemsAdded += CrossoverBeforeExecutionOperatorsOnChanged; Crossover.BeforeExecutionOperators.ItemsReplaced += CrossoverBeforeExecutionOperatorsOnChanged; Manipulator.BeforeExecutionOperators.CollectionReset += ManipulatroBeforeExecutionOperatorsOnChanged; Manipulator.BeforeExecutionOperators.ItemsAdded += ManipulatroBeforeExecutionOperatorsOnChanged; Manipulator.BeforeExecutionOperators.ItemsReplaced += ManipulatroBeforeExecutionOperatorsOnChanged; RegisterScriptInstanceChanges(); } private void ScriptParameterOnValueChanged(object sender, EventArgs eventArgs) { RegisterScriptInstanceChanges(); } private void CrossoverBeforeExecutionOperatorsOnChanged(object sender, EventArgs e) { ParameterizeCrossover(); } private void ManipulatroBeforeExecutionOperatorsOnChanged(object sender, EventArgs e) { ParameterizeManipulator(); } private void RegisterScriptInstanceChanges() { ScriptParameter.Value.InstanceChanged += ScriptOnInstanceChanged; ScriptParameter.Value.NameChanged += ScriptOnNameChanged; } private void ScriptOnNameChanged(object sender, EventArgs eventArgs) { if (sender != ScriptParameter.Value) return; if (Name != ScriptParameter.Value.Name) Name = ScriptParameter.Value.Name; } protected override void OnNameChanged() { base.OnNameChanged(); if (ScriptParameter.Value.Name != Name) ScriptParameter.Value.Name = Name; } private void ScriptOnInstanceChanged(object sender, EventArgs eventArgs) { var instance = ScriptParameter.Value.Instance; if (instance == null) return; Maximization.Value = instance.IsMaximizationProblem; var vector = instance.GetParametersToOptimize(); BinaryVectorLengthParameter.Value = vector.BooleanParameters != null ? new IntValue(vector.BooleanParameters.Length) : null; IntegerVectorLengthParameter.Value = vector.IntegerParameters != null ? new IntValue(vector.IntegerParameters.Length) : null; IntegerVectorBoundsParameter.Value = vector.IntegerBounds; RealVectorLengthParameter.Value = vector.RealParameters != null ? new IntValue(vector.RealParameters.Length) : null; RealVectorBoundsParameter.Value = vector.RealBounds; PermutationLengthParameter.Value = vector.PermutationParameter != null ? new IntValue(vector.PermutationParameter.Length) : null; PermutationTypeParameter.Value = vector.PermutationParameter != null ? new PermutationType(vector.PermutationParameter.PermutationType) : null; ((IBinaryVectorCreator)SolutionCreator).LengthParameter.ActualName = BinaryVectorLengthParameter.Name; ((IIntegerVectorCreator)SolutionCreator).LengthParameter.ActualName = IntegerVectorLengthParameter.Name; ((IIntegerVectorCreator)SolutionCreator).BoundsParameter.ActualName = IntegerVectorBoundsParameter.Name; ((IRealVectorCreator)SolutionCreator).LengthParameter.ActualName = RealVectorLengthParameter.Name; ((IRealVectorCreator)SolutionCreator).BoundsParameter.ActualName = RealVectorBoundsParameter.Name; ((IPermutationCreator)SolutionCreator).LengthParameter.ActualName = PermutationLengthParameter.Name; ((IPermutationCreator)SolutionCreator).PermutationTypeParameter.Value = new PermutationType(vector.PermutationParameter != null ? vector.PermutationParameter.PermutationType : PermutationTypes.Absolute); if (vector.BooleanParameters != null) { if (!Crossover.BeforeExecutionOperators.Any(x => x is IBinaryVectorCrossover)) Crossover.BeforeExecutionOperators.Add(new Encodings.BinaryVectorEncoding.SinglePointCrossover()); if (!Manipulator.BeforeExecutionOperators.Any(x => x is IBinaryVectorManipulator)) Manipulator.BeforeExecutionOperators.Add(new Encodings.BinaryVectorEncoding.SinglePositionBitflipManipulator()); } else { Crossover.BeforeExecutionOperators.RemoveAll(x => x is IBinaryVectorCrossover); Manipulator.BeforeExecutionOperators.RemoveAll(x => x is IBinaryVectorManipulator); } if (vector.IntegerParameters != null) { if (!Crossover.BeforeExecutionOperators.Any(x => x is IIntegerVectorCrossover)) Crossover.BeforeExecutionOperators.Add(new Encodings.IntegerVectorEncoding.SinglePointCrossover()); if (!Manipulator.BeforeExecutionOperators.Any(x => x is IIntegerVectorManipulator)) Manipulator.BeforeExecutionOperators.Add(new Encodings.IntegerVectorEncoding.UniformOnePositionManipulator()); } else { Crossover.BeforeExecutionOperators.RemoveAll(x => x is IIntegerVectorCrossover); Manipulator.BeforeExecutionOperators.RemoveAll(x => x is IIntegerVectorManipulator); } if (vector.RealParameters != null) { if (!Crossover.BeforeExecutionOperators.Any(x => x is IRealVectorCrossover)) Crossover.BeforeExecutionOperators.Add(new Encodings.RealVectorEncoding.SinglePointCrossover()); if (!Manipulator.BeforeExecutionOperators.Any(x => x is IRealVectorManipulator)) Manipulator.BeforeExecutionOperators.Add(new Encodings.RealVectorEncoding.BreederGeneticAlgorithmManipulator()); } else { Crossover.BeforeExecutionOperators.RemoveAll(x => x is IRealVectorCrossover); Manipulator.BeforeExecutionOperators.RemoveAll(x => x is IRealVectorManipulator); } if (vector.PermutationParameter != null) { if (!Crossover.BeforeExecutionOperators.Any(x => x is IPermutationCrossover)) Crossover.BeforeExecutionOperators.Add(new Encodings.PermutationEncoding.OrderCrossover2()); if (!Manipulator.BeforeExecutionOperators.Any(x => x is IPermutationManipulator)) Manipulator.BeforeExecutionOperators.Add(new Encodings.PermutationEncoding.Swap2Manipulator()); } else { Crossover.BeforeExecutionOperators.RemoveAll(x => x is IPermutationCrossover); Manipulator.BeforeExecutionOperators.RemoveAll(x => x is IPermutationManipulator); } ParameterizeCrossover(); ParameterizeManipulator(); } private void ParameterizeCrossover() { Crossover.ChildParameter.ActualName = SolutionCreator.ParameterVectorParameter.ActualName; Crossover.ParentsParameter.ActualName = SolutionCreator.ParameterVectorParameter.ActualName; foreach (var xo in Crossover.BeforeExecutionOperators.OfType()) { xo.ChildParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName; xo.ParentsParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName; } foreach (var xo in Crossover.BeforeExecutionOperators.OfType()) { xo.ChildParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName; xo.ParentsParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName; var bxo = xo as IBoundedIntegerVectorOperator; if (bxo != null) bxo.BoundsParameter.ActualName = IntegerVectorBoundsParameter.Name; } foreach (var xo in Crossover.BeforeExecutionOperators.OfType()) { xo.ChildParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName; xo.ParentsParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName; xo.BoundsParameter.ActualName = RealVectorBoundsParameter.Name; } foreach (var xo in Crossover.BeforeExecutionOperators.OfType()) { xo.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; xo.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; } } private void ParameterizeManipulator() { foreach (var ma in Manipulator.BeforeExecutionOperators.OfType()) { ma.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName; } foreach (var ma in Manipulator.BeforeExecutionOperators.OfType()) { ma.IntegerVectorParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName; var bma = ma as IBoundedIntegerVectorOperator; if (bma != null) bma.BoundsParameter.ActualName = IntegerVectorBoundsParameter.Name; } foreach (var ma in Manipulator.BeforeExecutionOperators.OfType()) { ma.RealVectorParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName; ma.BoundsParameter.ActualName = RealVectorBoundsParameter.Name; } foreach (var ma in Manipulator.BeforeExecutionOperators.OfType()) { ma.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; } } } }