[13672]  1  #region License Information


 2  /* HeuristicLab


[17226]  3  * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)


[13672]  4  *


 5  * This file is part of HeuristicLab.


 6  *


 7  * HeuristicLab is free software: you can redistribute it and/or modify


 8  * it under the terms of the GNU General Public License as published by


 9  * the Free Software Foundation, either version 3 of the License, or


 10  * (at your option) any later version.


 11  *


 12  * HeuristicLab is distributed in the hope that it will be useful,


 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


 15  * GNU General Public License for more details.


 16  *


 17  * You should have received a copy of the GNU General Public License


 18  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.


 19  */


 20  #endregion


 21  using System;


 22  using System.Linq;


[16807]  23  using HEAL.Attic;


[17225]  24  using HeuristicLab.Analysis;


[13421]  25  using HeuristicLab.Common;


 26  using HeuristicLab.Core;


 27  using HeuristicLab.Data;


 28  using HeuristicLab.Encodings.RealVectorEncoding;


 29  using HeuristicLab.Optimization;


 30  using HeuristicLab.Parameters;


[13620]  31  using HeuristicLab.Problems.Instances;


[13421]  32 


[14111]  33  namespace HeuristicLab.Problems.TestFunctions.MultiObjective {


[16723]  34  [StorableType("AB0C6A73C43246FDAE3B9841EAB2478C")]


[14073]  35  [Creatable(CreatableAttribute.Categories.Problems, Priority = 95)]


 36  [Item("Test Function (multiobjective)", "Test functions with real valued inputs and multiple objectives.")]


[17225]  37  public class MultiObjectiveTestFunctionProblem : RealVectorMultiObjectiveProblem, IProblemInstanceConsumer<MOTFData>, IMultiObjectiveProblemDefinition<RealVectorEncoding, RealVector> {


[13672]  38  #region Parameter Properties


[14073]  39  public IFixedValueParameter<IntValue> ProblemSizeParameter {


[13421]  40  get { return (IFixedValueParameter<IntValue>)Parameters["ProblemSize"]; }


 41  }


[14073]  42  public IFixedValueParameter<IntValue> ObjectivesParameter {


[13672]  43  get { return (IFixedValueParameter<IntValue>)Parameters["Objectives"]; }


[13421]  44  }


[14073]  45  public IValueParameter<DoubleMatrix> BoundsParameter {


[13421]  46  get { return (IValueParameter<DoubleMatrix>)Parameters["Bounds"]; }


 47  }


 48  public IValueParameter<IMultiObjectiveTestFunction> TestFunctionParameter {


 49  get { return (IValueParameter<IMultiObjectiveTestFunction>)Parameters["TestFunction"]; }


 50  }


 51  #endregion


 52 


 53  #region Properties


[14073]  54  public override bool[] Maximization {


 55  get {


[16807]  56  //necessary because of virtual member call in base ctor


 57  if (!Parameters.ContainsKey("TestFunction")) return new bool[0];


 58  return TestFunction.Maximization(Objectives).ToArray();


[14073]  59  }


[13672]  60  }


 61 


 62  public int ProblemSize {


[13421]  63  get { return ProblemSizeParameter.Value.Value; }


 64  set { ProblemSizeParameter.Value.Value = value; }


 65  }


[16950]  66  public new int Objectives {


[13672]  67  get { return ObjectivesParameter.Value.Value; }


 68  set { ObjectivesParameter.Value.Value = value; }


[13421]  69  }


 70  public DoubleMatrix Bounds {


 71  get { return BoundsParameter.Value; }


 72  set { BoundsParameter.Value = value; }


 73  }


 74  public IMultiObjectiveTestFunction TestFunction {


 75  get { return TestFunctionParameter.Value; }


 76  set { TestFunctionParameter.Value = value; }


 77  }


 78  #endregion


 79 


 80  [StorableConstructor]


[16723]  81  protected MultiObjectiveTestFunctionProblem(StorableConstructorFlag _) : base(_) { }


[14073]  82  [StorableHook(HookType.AfterDeserialization)]


 83  private void AfterDeserialization() {


 84  RegisterEventHandlers();


 85  }


 86 


[17225]  87  protected MultiObjectiveTestFunctionProblem(MultiObjectiveTestFunctionProblem original, Cloner cloner) : base(original, cloner) {


[13421]  88  RegisterEventHandlers();


 89  }


[14073]  90  public override IDeepCloneable Clone(Cloner cloner) {


 91  return new MultiObjectiveTestFunctionProblem(this, cloner);


 92  }


 93 


[17225]  94  public MultiObjectiveTestFunctionProblem() : base() {


[13421]  95  Parameters.Add(new FixedValueParameter<IntValue>("ProblemSize", "The dimensionality of the problem instance (number of variables in the function).", new IntValue(2)));


[13672]  96  Parameters.Add(new FixedValueParameter<IntValue>("Objectives", "The dimensionality of the solution vector (number of objectives).", new IntValue(2)));


[13448]  97  Parameters.Add(new ValueParameter<DoubleMatrix>("Bounds", "The bounds of the solution given as either one line for all variables or a line for each variable. The first column specifies lower bound, the second upper bound.", new DoubleMatrix(new double[,] { { 4, 4 } })));


[13421]  98  Parameters.Add(new ValueParameter<IMultiObjectiveTestFunction>("TestFunction", "The function that is to be optimized.", new Fonseca()));


 99 


 100  Encoding.LengthParameter = ProblemSizeParameter;


 101  Encoding.BoundsParameter = BoundsParameter;


[13725]  102  BestKnownFrontParameter.Hidden = true;


[13421]  103 


[14073]  104  UpdateParameterValues();


[13421]  105  InitializeOperators();


 106  RegisterEventHandlers();


 107  }


[14073]  108 


 109  private void RegisterEventHandlers() {


 110  TestFunctionParameter.ValueChanged += TestFunctionParameterOnValueChanged;


 111  ProblemSizeParameter.Value.ValueChanged += ProblemSizeOnValueChanged;


 112  ObjectivesParameter.Value.ValueChanged += ObjectivesOnValueChanged;


[13421]  113  }


 114 


[14073]  115 


[16807]  116  public override void Analyze(RealVector[] solutions, double[][] qualities, ResultCollection results, IRandom random) {


 117  base.Analyze(solutions, qualities, results, random);


[17225]  118  if (results.ContainsKey("Pareto Front"))


[13725]  119  ((DoubleMatrix)results["Pareto Front"].Value).SortableView = true;


[13421]  120  }


 121 


[13776]  122  /// <summary>


 123  /// Checks whether a given solution violates the contraints of this function.


 124  /// </summary>


 125  /// <param name="individual"></param>


 126  /// <returns>a double array that holds the distances that describe how much every contraint is violated (0 is not violated). If the current TestFunction does not have constraints an array of length 0 is returned</returns>


[14068]  127  public double[] CheckContraints(RealVector individual) {


 128  var constrainedTestFunction = (IConstrainedTestFunction)TestFunction;


[17225]  129  return constrainedTestFunction != null ? constrainedTestFunction.CheckConstraints(individual, Objectives) : new double[0];


[13776]  130  }


 131 


[16807]  132  public override double[] Evaluate(RealVector solution, IRandom random) {


 133  return TestFunction.Evaluate(solution, Objectives);


[13421]  134  }


[13448]  135 


[13421]  136 


[13620]  137  public void Load(MOTFData data) {


[14065]  138  TestFunction = data.TestFunction;


[13620]  139  }


[13448]  140 


[14073]  141  #region Events


 142  private void UpdateParameterValues() {


[17225]  143  Parameters.Remove(MaximizationParameterName);


 144  Parameters.Add(new FixedValueParameter<BoolArray>(MaximizationParameterName, "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(TestFunction.Maximization(Objectives)).AsReadOnly()));


[14073]  145 


[17225]  146  Parameters.Remove(BestKnownFrontParameterName);


[14085]  147  var front = TestFunction.OptimalParetoFront(Objectives);


[17225]  148  var bkf = front != null ? (DoubleMatrix)Utilities.ToMatrix(front).AsReadOnly() : null;


[17261]  149  Parameters.Add(new FixedValueParameter<DoubleMatrix>(BestKnownFrontParameterName, "A double matrix representing the best known qualities for this problem (aka points on the Pareto front). Points are to be given in a rowwise fashion.", bkf));


[14085]  150 


[17225]  151  Parameters.Remove(ReferencePointParameterName);


[17261]  152  Parameters.Add(new FixedValueParameter<DoubleArray>(ReferencePointParameterName, "The reference point for hypervolume calculations on this problem", new DoubleArray(TestFunction.ReferencePoint(Objectives))));


[14085]  153 


 154  BoundsParameter.Value = new DoubleMatrix(TestFunction.Bounds(Objectives));


[13672]  155  }


 156 


[13421]  157  protected override void OnEncodingChanged() {


 158  base.OnEncodingChanged();


[14073]  159  UpdateParameterValues();


[13421]  160  }


[17225]  161 


[13421]  162  protected override void OnEvaluatorChanged() {


 163  base.OnEvaluatorChanged();


[14073]  164  UpdateParameterValues();


[13421]  165  }


[13448]  166 


[13421]  167  private void TestFunctionParameterOnValueChanged(object sender, EventArgs eventArgs) {


[14073]  168  ProblemSize = Math.Max(TestFunction.MinimumSolutionLength, Math.Min(ProblemSize, TestFunction.MaximumSolutionLength));


 169  Objectives = Math.Max(TestFunction.MinimumObjectives, Math.Min(Objectives, TestFunction.MaximumObjectives));


[17225]  170  Parameters.Remove(ReferencePointParameterName);


[17261]  171  Parameters.Add(new FixedValueParameter<DoubleArray>(ReferencePointParameterName, "The reference point for hypervolume calculations on this problem", new DoubleArray(TestFunction.ReferencePoint(Objectives))));


[14073]  172  UpdateParameterValues();


[13421]  173  OnReset();


 174  }


 175 


 176  private void ProblemSizeOnValueChanged(object sender, EventArgs eventArgs) {


[14073]  177  ProblemSize = Math.Min(TestFunction.MaximumSolutionLength, Math.Max(TestFunction.MinimumSolutionLength, ProblemSize));


 178  UpdateParameterValues();


[13421]  179  }


 180 


[13672]  181  private void ObjectivesOnValueChanged(object sender, EventArgs eventArgs) {


[14073]  182  Objectives = Math.Min(TestFunction.MaximumObjectives, Math.Max(TestFunction.MinimumObjectives, Objectives));


 183  UpdateParameterValues();


[13421]  184  }


 185  #endregion


 186 


 187  #region Helpers


 188  private void InitializeOperators() {


[13672]  189  Operators.Add(new CrowdingAnalyzer());


 190  Operators.Add(new GenerationalDistanceAnalyzer());


 191  Operators.Add(new InvertedGenerationalDistanceAnalyzer());


 192  Operators.Add(new HypervolumeAnalyzer());


 193  Operators.Add(new SpacingAnalyzer());


[17225]  194  Operators.Add(new TimelineAnalyzer());


[13421]  195  }


 196  #endregion


 197  }


[17225]  198  } 
