Index: /stable/HeuristicLab 3.3.sln
===================================================================
--- /stable/HeuristicLab 3.3.sln (revision 15243)
+++ /stable/HeuristicLab 3.3.sln (revision 15244)
@@ -2,5 +2,5 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26430.6
+VisualStudioVersion = 15.0.26430.15
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96396439-A764-4022-A8D2-BE021449B8D1}"
@@ -455,4 +455,6 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.GraphColoring-3.3", "HeuristicLab.Problems.GraphColoring\3.3\HeuristicLab.Problems.GraphColoring-3.3.csproj", "{4B76E2CB-A990-4959-B080-1D81D418D325}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3", "HeuristicLab.Algorithms.MOCMAEvolutionStrategy\3.3\HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj", "{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}"
EndProject
Global
@@ -2218,4 +2220,16 @@
{4B76E2CB-A990-4959-B080-1D81D418D325}.Release|x86.ActiveCfg = Release|x86
{4B76E2CB-A990-4959-B080-1D81D418D325}.Release|x86.Build.0 = Release|x86
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|x64.ActiveCfg = Debug|x64
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|x64.Build.0 = Debug|x64
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|x86.ActiveCfg = Debug|x86
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|x86.Build.0 = Debug|x86
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x64.ActiveCfg = Release|x64
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x64.Build.0 = Release|x64
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x86.ActiveCfg = Release|x86
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/DoubleMatrixHelper.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/DoubleMatrixHelper.cs (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/DoubleMatrixHelper.cs (revision 15244)
@@ -0,0 +1,50 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+ internal static class DoubleMatrixHelper {
+ internal static double[][] ToJaggedArray(this DoubleMatrix m) {
+ if (m == null) return null;
+ var i = m.Rows - 1;
+ var a = new double[i][];
+ for (i--; i >= 0; i--) {
+ var j = m.Columns;
+ a[i] = new double[j];
+ for (j--; j >= 0; j--) a[i][j] = m[i, j];
+ }
+ return a;
+ }
+
+ internal static DoubleMatrix ToMatrix(this IEnumerable> data) {
+ var d2 = data.ToArray();
+ var mat = new DoubleMatrix(d2.Length, d2[0].Count);
+ for (var i = 0; i < mat.Rows; i++)
+ for (var j = 0; j < mat.Columns; j++)
+ mat[i, j] = d2[i][j];
+ return mat;
+ }
+ }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj (revision 15244)
@@ -0,0 +1,193 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {0E2E224F-E9B2-41F3-B510-09183EEBA2AF}
+ Library
+ Properties
+ HeuristicLab.Algorithms.MOCMAEvolutionStrategy
+ HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3
+ v4.5
+ 512
+
+
+ true
+ full
+ false
+ $(SolutionDir)\bin\
+ DEBUG;TRACE
+ prompt
+ 4
+ 5
+
+
+ pdbonly
+ true
+ $(SolutionDir)\bin\
+ TRACE
+ prompt
+ 4
+ 5
+
+
+ true
+ $(SolutionDir)\bin\
+ DEBUG;TRACE
+ full
+ x64
+ 5
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ $(SolutionDir)\bin\
+ TRACE
+ true
+ pdbonly
+ x64
+ 5
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ true
+ $(SolutionDir)\bin\
+ DEBUG;TRACE
+ full
+ x86
+ 5
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ $(SolutionDir)\bin\
+ TRACE
+ true
+ pdbonly
+ x86
+ 5
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+
+ ..\..\bin\ALGLIB-3.7.0.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {887425B4-4348-49ED-A457-B7D2C26DDBF9}
+ HeuristicLab.Analysis-3.3
+ False
+
+
+ {958B43BC-CC5C-4FA2-8628-2B3B01D890B6}
+ HeuristicLab.Collections-3.3
+ False
+
+
+ {A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}
+ HeuristicLab.Common-3.3
+ False
+
+
+ {C36BD924-A541-4A00-AFA8-41701378DDC5}
+ HeuristicLab.Core-3.3
+ False
+
+
+ {BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}
+ HeuristicLab.Data-3.3
+ False
+
+
+ {BB6D334A-4BB6-4674-9883-31A6EBB32CAB}
+ HeuristicLab.Encodings.RealVectorEncoding-3.3
+ False
+
+
+ {23da7ff4-d5b8-41b6-aa96-f0561d24f3ee}
+ HeuristicLab.Operators-3.3
+ False
+
+
+ {14AB8D24-25BC-400C-A846-4627AA945192}
+ HeuristicLab.Optimization-3.3
+ False
+
+
+ {56F9106A-079F-4C61-92F6-86A84C2D84B7}
+ HeuristicLab.Parameters-3.3
+ False
+
+
+ {102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}
+ HeuristicLab.Persistence-3.3
+ False
+
+
+ {94186a6a-5176-4402-ae83-886557b53cca}
+ HeuristicLab.PluginInfrastructure-3.3
+ False
+
+
+ {3540e29e-4793-49e7-8ee2-fea7f61c3994}
+ HeuristicLab.Problems.Instances-3.3
+ False
+
+
+ {D53E8E48-CFAA-4F57-AC35-63BEF4476159}
+ HeuristicLab.Problems.TestFunctions.MultiObjective-3.3
+ False
+
+
+ {F4539FB6-4708-40C9-BE64-0A1390AEA197}
+ HeuristicLab.Random-3.3
+ False
+
+
+
+
+ set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+
+
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+
+
+
+
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs (revision 15244)
@@ -0,0 +1,38 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+ public interface IIndicator : IItem {
+ ///
+ /// Selects the least contributing Point of a front. Please keep in mind, that the contribution of a point depends on its value as well as on the other points of a front.
+ /// A particularly good point may not be as benefical in another front.
+ ///
+ ///
+ /// a front which will be evaluated
+ /// The problem on which the front is evaluated (!! The function itself will NOT be evluated only bounds referencePoints & other metadata will be used
+ /// the index of the least contributing point according to any type of quality criteria
+ int LeastContributer(IReadOnlyList front, MultiObjectiveBasicProblem problem);
+ }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs (revision 15244)
@@ -0,0 +1,65 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see .
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+ [Item("CrowdingIndicator", "Selection of Offspring based on CrowdingDistance")]
+ [StorableClass]
+ internal class CrowdingIndicator : Item, IIndicator {
+ #region Constructors and Cloning
+ [StorableConstructor]
+ protected CrowdingIndicator(bool deserializing) : base(deserializing) { }
+ protected CrowdingIndicator(CrowdingIndicator original, Cloner cloner) : base(original, cloner) { }
+ public override IDeepCloneable Clone(Cloner cloner) { return new CrowdingIndicator(this, cloner); }
+ public CrowdingIndicator() { }
+ #endregion
+
+ public int LeastContributer(IReadOnlyList front, MultiObjectiveBasicProblem problem) {
+ var bounds = problem.Encoding.Bounds;
+ var extracted = front.Select(x => x.PenalizedFitness).ToArray();
+ if (extracted.Length <= 2) return 0;
+ var pointsums = new double[extracted.Length];
+
+ for (var dim = 0; dim < problem.Maximization.Length; dim++) {
+ var arr = extracted.Select(x => x[dim]).ToArray();
+ Array.Sort(arr);
+ var fmax = problem.Encoding.Bounds[dim % bounds.Rows, 1];
+ var fmin = bounds[dim % bounds.Rows, 0];
+ var pointIdx = 0;
+ foreach (var point in extracted) {
+ var pos = Array.BinarySearch(arr, point[dim]);
+ var d = pos != 0 && pos != arr.Length - 1 ? (arr[pos + 1] - arr[pos - 1]) / (fmax - fmin) : double.PositiveInfinity;
+ pointsums[pointIdx] += d;
+ pointIdx++;
+ }
+ }
+ return pointsums.Select((value, index) => new { value, index }).OrderBy(x => x.value).First().index;
+ }
+ }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs (revision 15244)
@@ -0,0 +1,69 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see .
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.TestFunctions.MultiObjective;
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+ [Item("HypervolumeIndicator", "Selection of Offspring based on contributing Hypervolume")]
+ [StorableClass]
+ internal class HypervolumeIndicator : Item, IIndicator {
+ #region Constructors and Cloning
+ [StorableConstructor]
+ protected HypervolumeIndicator(bool deserializing) : base(deserializing) { }
+ protected HypervolumeIndicator(HypervolumeIndicator original, Cloner cloner) : base(original, cloner) { }
+ public override IDeepCloneable Clone(Cloner cloner) { return new HypervolumeIndicator(this, cloner); }
+ public HypervolumeIndicator() { }
+ #endregion
+
+ public int LeastContributer(IReadOnlyList front, MultiObjectiveBasicProblem problem) {
+ var frontCopy = front.Select(x => x.PenalizedFitness).ToList();
+ if (frontCopy.Count <= 1) return 0;
+ var p = problem as MultiObjectiveTestFunctionProblem;
+ var refPoint = BuildReferencePoint(p != null ? frontCopy.Concat(new[] { p.ReferencePoint.CloneAsArray() }) : frontCopy, problem.Maximization);
+ var contributions = Enumerable.Range(0, frontCopy.Count).Select(i => Contribution(frontCopy, i, problem.Maximization, refPoint));
+ return contributions.Select((value, index) => new { value, index }).OrderBy(x => x.value).First().index;
+ }
+
+ #region Helpers
+ private static double Contribution(IList front, int idx, bool[] maximization, double[] refPoint) {
+ var point = front[idx];
+ front.RemoveAt(idx);
+ var contribution = -Hypervolume.Calculate(front.ToArray(), refPoint, maximization);
+ front.Insert(idx, point);
+ return contribution;
+ }
+ private static double[] BuildReferencePoint(IEnumerable front, IReadOnlyList maximization) {
+ var refPoint = new double[maximization.Count];
+ foreach (var point in front)
+ for (var i = 0; i < maximization.Count; i++)
+ refPoint[i] = maximization[i] ? Math.Min(refPoint[i], point[i]) : Math.Max(refPoint[i], point[i]);
+ return refPoint;
+ }
+ #endregion
+ }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs (revision 15244)
@@ -0,0 +1,100 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see .
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+ [Item("MinimalDistanceIndicator", "Selection of Offspring based on distance to nearest neighbour")]
+ [StorableClass]
+ internal class MinimalDistanceIndicator : Item, IIndicator {
+
+ #region Constructor and Cloning
+ [StorableConstructor]
+ protected MinimalDistanceIndicator(bool deserializing) : base(deserializing) { }
+ protected MinimalDistanceIndicator(MinimalDistanceIndicator original, Cloner cloner) : base(original, cloner) { }
+ public override IDeepCloneable Clone(Cloner cloner) { return new MinimalDistanceIndicator(this, cloner); }
+ public MinimalDistanceIndicator() { }
+ #endregion
+
+ public int LeastContributer(IReadOnlyList front, MultiObjectiveBasicProblem problem) {
+ var extracted = front.Select(x => x.PenalizedFitness).ToArray();
+ if (extracted.Length <= 2) return 0;
+ var distances = CalcDistances(extracted);
+ var mindexI = 0;
+ var mindexJ = 0;
+ var min = double.MaxValue;
+ for (var i = 0; i < extracted.Length; i++) {
+ var d = double.MaxValue;
+ var minj = 0;
+ for (var j = 0; j < extracted.Length; j++) {
+ if (i == j) continue;
+ var d1 = distances[i, j];
+ if (!(d1 < d)) continue;
+ minj = j;
+ d = d1;
+ }
+ if (!(d < min)) continue;
+ min = d;
+ mindexI = i;
+ mindexJ = minj;
+ }
+
+ //break tie with distance to second nearest
+ var minI = double.MaxValue;
+ var minJ = double.MaxValue;
+
+ for (var i = 0; i < extracted.Length; i++) {
+ double d;
+ if (mindexI != i) {
+ d = distances[mindexI, i];
+ if (!d.IsAlmost(min)) minI = Math.Min(minI, d);
+ }
+ if (mindexJ == i) continue;
+ d = distances[mindexJ, i];
+ if (!d.IsAlmost(min)) minJ = Math.Min(minJ, d);
+ }
+
+ //find min
+ return minI < minJ ? mindexI : mindexJ;
+ }
+
+ #region Helpers
+ private static double[,] CalcDistances(IReadOnlyList extracted) {
+ var res = new double[extracted.Count, extracted.Count];
+ for (var i = 0; i < extracted.Count; i++)
+ for (var j = 0; j < i; j++)
+ res[i, j] = res[j, i] = Dist(extracted[i], extracted[j]);
+ return res;
+ }
+
+ private static double Dist(IEnumerable a, IEnumerable b) {
+ return Math.Sqrt(a.Zip(b, (x, y) => (x - y) * (x - y)).Sum());
+ }
+ #endregion
+ }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Individual.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Individual.cs (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Individual.cs (revision 15244)
@@ -0,0 +1,197 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+ [StorableClass]
+ public class Individual : IDeepCloneable {
+
+ #region Properties
+ [Storable]
+ private MOCMAEvolutionStrategy strategy;
+
+ //Chromosome
+ [Storable]
+ public RealVector Mean { get; private set; }
+ [Storable]
+ private double sigma;//stepsize
+ [Storable]
+ private RealVector evolutionPath; // pc
+ [Storable]
+ private RealVector lastStep;
+ [Storable]
+ private RealVector lastZ;
+ [Storable]
+ private double[,] lowerCholesky;
+
+ //Phenotype
+ [Storable]
+ public double[] Fitness { get; set; }
+ [Storable]
+ public double[] PenalizedFitness { get; set; }
+ [Storable]
+ public bool Selected { get; set; }
+ [Storable]
+ public double SuccessProbability { get; set; }
+ #endregion
+
+ #region Constructors and Cloning
+ [StorableConstructor]
+ protected Individual(bool deserializing) { }
+
+ public Individual(RealVector mean, double pSucc, double sigma, RealVector pc, double[,] c, MOCMAEvolutionStrategy strategy) {
+ Mean = mean;
+ lastStep = new RealVector(mean.Length);
+ SuccessProbability = pSucc;
+ this.sigma = sigma;
+ evolutionPath = pc;
+ CholeskyDecomposition(c);
+ Selected = true;
+ this.strategy = strategy;
+ }
+
+ public Individual(Individual other) {
+ SuccessProbability = other.SuccessProbability;
+ sigma = other.sigma;
+ evolutionPath = (RealVector)other.evolutionPath.Clone();
+ Mean = (RealVector)other.Mean.Clone();
+ lowerCholesky = (double[,])other.lowerCholesky.Clone();
+ Selected = true;
+ strategy = other.strategy;
+ }
+
+ public Individual(Individual other, Cloner cloner) {
+ strategy = cloner.Clone(other.strategy);
+ Mean = cloner.Clone(other.Mean);
+ sigma = other.sigma;
+ evolutionPath = cloner.Clone(other.evolutionPath);
+ lastStep = cloner.Clone(other.evolutionPath);
+ lastZ = cloner.Clone(other.lastZ);
+ lowerCholesky = other.lowerCholesky != null ? other.lowerCholesky.Clone() as double[,] : null;
+ Fitness = other.Fitness != null ? other.Fitness.Select(x => x).ToArray() : null;
+ PenalizedFitness = other.PenalizedFitness != null ? other.PenalizedFitness.Select(x => x).ToArray() : null;
+ Selected = other.Selected;
+ SuccessProbability = other.SuccessProbability;
+ }
+
+ public object Clone() {
+ return new Cloner().Clone(this);
+ }
+
+ public IDeepCloneable Clone(Cloner cloner) {
+ return new Individual(this, cloner);
+ }
+ #endregion
+
+ public void Mutate(NormalDistributedRandom gauss) {
+ //sampling a random z from N(0,I) where I is the Identity matrix;
+ lastZ = new RealVector(Mean.Length);
+ var n = lastZ.Length;
+ for (var i = 0; i < n; i++) lastZ[i] = gauss.NextDouble();
+ //Matrixmultiplication: lastStep = lowerCholesky * lastZ;
+ lastStep = new RealVector(Mean.Length);
+ for (var i = 0; i < n; i++) {
+ double sum = 0;
+ for (var j = 0; j <= i; j++) sum += lowerCholesky[i, j] * lastZ[j];
+ lastStep[i] = sum;
+ }
+ //add the step to x weighted by stepsize;
+ for (var i = 0; i < Mean.Length; i++) Mean[i] += sigma * lastStep[i];
+ }
+
+ public void UpdateAsParent(bool offspringSuccessful) {
+ SuccessProbability = (1 - strategy.StepSizeLearningRate) * SuccessProbability + strategy.StepSizeLearningRate * (offspringSuccessful ? 1 : 0);
+ sigma *= Math.Exp(1 / strategy.StepSizeDampeningFactor * (SuccessProbability - strategy.TargetSuccessProbability) / (1 - strategy.TargetSuccessProbability));
+ if (!offspringSuccessful) return;
+ if (SuccessProbability < strategy.SuccessThreshold && lastZ != null) {
+ var stepNormSqr = lastZ.Sum(d => d * d);
+ var rate = strategy.CovarianceMatrixUnlearningRate;
+ if (stepNormSqr > 1 && 1 < strategy.CovarianceMatrixUnlearningRate * (2 * stepNormSqr - 1)) rate = 1 / (2 * stepNormSqr - 1);
+ CholeskyUpdate(lastStep, 1 + rate, -rate);
+ } else RoundUpdate();
+ }
+
+ public void UpdateAsOffspring() {
+ SuccessProbability = (1 - strategy.StepSizeLearningRate) * SuccessProbability + strategy.StepSizeLearningRate;
+ sigma *= Math.Exp(1 / strategy.StepSizeDampeningFactor * (SuccessProbability - strategy.TargetSuccessProbability) / (1 - strategy.TargetSuccessProbability));
+ var evolutionpathUpdateWeight = strategy.EvolutionPathLearningRate * (2.0 - strategy.EvolutionPathLearningRate);
+ if (SuccessProbability < strategy.SuccessThreshold) {
+ UpdateEvolutionPath(1 - strategy.EvolutionPathLearningRate, evolutionpathUpdateWeight);
+ CholeskyUpdate(evolutionPath, 1 - strategy.CovarianceMatrixLearningRate, strategy.CovarianceMatrixLearningRate);
+ } else RoundUpdate();
+ }
+
+ public void UpdateEvolutionPath(double learningRate, double updateWeight) {
+ updateWeight = Math.Sqrt(updateWeight);
+ for (var i = 0; i < evolutionPath.Length; i++) {
+ evolutionPath[i] *= learningRate;
+ evolutionPath[i] += updateWeight * lastStep[i];
+ }
+ }
+
+ #region Helpers
+ private void CholeskyDecomposition(double[,] c) {
+ if (!alglib.spdmatrixcholesky(ref c, c.GetLength(0), false))
+ throw new ArgumentException("Covariancematrix is not symmetric positiv definit");
+ lowerCholesky = (double[,])c.Clone();
+ }
+
+ private void CholeskyUpdate(RealVector v, double alpha, double beta) {
+ var n = v.Length;
+ var temp = new double[n];
+ for (var i = 0; i < n; i++) temp[i] = v[i];
+ double betaPrime = 1;
+ var a = Math.Sqrt(alpha);
+ for (var j = 0; j < n; j++) {
+ var ljj = a * lowerCholesky[j, j];
+ var dj = ljj * ljj;
+ var wj = temp[j];
+ var swj2 = beta * wj * wj;
+ var gamma = dj * betaPrime + swj2;
+ var x1 = dj + swj2 / betaPrime;
+ if (x1 < 0.0) return;
+ var nLjj = Math.Sqrt(x1);
+ lowerCholesky[j, j] = nLjj;
+ betaPrime += swj2 / dj;
+ if (j + 1 >= n) continue;
+ for (var i = j + 1; i < n; i++) lowerCholesky[i, j] *= a;
+ for (var i = j + 1; i < n; i++) temp[i] = wj / ljj * lowerCholesky[i, j];
+ if (gamma.IsAlmost(0)) continue;
+ for (var i = j + 1; i < n; i++) lowerCholesky[i, j] *= nLjj / ljj;
+ for (var i = j + 1; i < n; i++) lowerCholesky[i, j] += nLjj * beta * wj / gamma * temp[i];
+ }
+ }
+
+ private void RoundUpdate() {
+ var evolutionPathUpdateWeight = strategy.EvolutionPathLearningRate * (2.0 - strategy.EvolutionPathLearningRate);
+ UpdateEvolutionPath(1 - strategy.EvolutionPathLearningRate, 0);
+ CholeskyUpdate(evolutionPath, 1 - strategy.CovarianceMatrixLearningRate + evolutionPathUpdateWeight, strategy.CovarianceMatrixLearningRate);
+ }
+ #endregion
+ }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs (revision 15244)
@@ -0,0 +1,504 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see .
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.TestFunctions.MultiObjective;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+ [Item("Multi-Objective CMA Evolution Strategy (MOCMAES)", "A multi objective evolution strategy based on covariance matrix adaptation. Code is based on 'Covariance Matrix Adaptation for Multi - objective Optimization' by Igel, Hansen and Roth")]
+ [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 210)]
+ [StorableClass]
+ public class MOCMAEvolutionStrategy : BasicAlgorithm {
+ public override Type ProblemType {
+ get { return typeof(MultiObjectiveBasicProblem); }
+ }
+ public new MultiObjectiveBasicProblem Problem {
+ get { return (MultiObjectiveBasicProblem)base.Problem; }
+ set { base.Problem = value; }
+ }
+ public override bool SupportsPause {
+ get { return true; }
+ }
+
+ #region Storable fields
+ [Storable]
+ private IRandom random = new MersenneTwister();
+ [Storable]
+ private NormalDistributedRandom gauss;
+ [Storable]
+ private Individual[] solutions;
+ [Storable]
+ private double stepSizeLearningRate; //=cp learning rate in [0,1]
+ [Storable]
+ private double stepSizeDampeningFactor; //d
+ [Storable]
+ private double targetSuccessProbability;// p^target_succ
+ [Storable]
+ private double evolutionPathLearningRate;//cc
+ [Storable]
+ private double covarianceMatrixLearningRate;//ccov
+ [Storable]
+ private double covarianceMatrixUnlearningRate;
+ [Storable]
+ private double successThreshold; //ptresh
+
+ #endregion
+
+ #region ParameterNames
+ private const string MaximumRuntimeName = "Maximum Runtime";
+ private const string SeedName = "Seed";
+ private const string SetSeedRandomlyName = "SetSeedRandomly";
+ private const string PopulationSizeName = "PopulationSize";
+ private const string MaximumGenerationsName = "MaximumGenerations";
+ private const string MaximumEvaluatedSolutionsName = "MaximumEvaluatedSolutions";
+ private const string InitialSigmaName = "InitialSigma";
+ private const string IndicatorName = "Indicator";
+
+ private const string EvaluationsResultName = "Evaluations";
+ private const string IterationsResultName = "Generations";
+ private const string TimetableResultName = "Timetable";
+ private const string HypervolumeResultName = "Hypervolume";
+ private const string GenerationalDistanceResultName = "Generational Distance";
+ private const string InvertedGenerationalDistanceResultName = "Inverted Generational Distance";
+ private const string CrowdingResultName = "Crowding";
+ private const string SpacingResultName = "Spacing";
+ private const string CurrentFrontResultName = "Pareto Front";
+ private const string BestHypervolumeResultName = "Best Hypervolume";
+ private const string BestKnownHypervolumeResultName = "Best known hypervolume";
+ private const string DifferenceToBestKnownHypervolumeResultName = "Absolute Distance to BestKnownHypervolume";
+ private const string ScatterPlotResultName = "ScatterPlot";
+ #endregion
+
+ #region ParameterProperties
+ public IFixedValueParameter MaximumRuntimeParameter {
+ get { return (IFixedValueParameter)Parameters[MaximumRuntimeName]; }
+ }
+ public IFixedValueParameter SeedParameter {
+ get { return (IFixedValueParameter)Parameters[SeedName]; }
+ }
+ public FixedValueParameter SetSeedRandomlyParameter {
+ get { return (FixedValueParameter)Parameters[SetSeedRandomlyName]; }
+ }
+ public IFixedValueParameter PopulationSizeParameter {
+ get { return (IFixedValueParameter)Parameters[PopulationSizeName]; }
+ }
+ public IFixedValueParameter MaximumGenerationsParameter {
+ get { return (IFixedValueParameter)Parameters[MaximumGenerationsName]; }
+ }
+ public IFixedValueParameter MaximumEvaluatedSolutionsParameter {
+ get { return (IFixedValueParameter)Parameters[MaximumEvaluatedSolutionsName]; }
+ }
+ public IValueParameter InitialSigmaParameter {
+ get { return (IValueParameter)Parameters[InitialSigmaName]; }
+ }
+ public IConstrainedValueParameter IndicatorParameter {
+ get { return (IConstrainedValueParameter)Parameters[IndicatorName]; }
+ }
+ #endregion
+
+ #region Properties
+ public int MaximumRuntime {
+ get { return MaximumRuntimeParameter.Value.Value; }
+ set { MaximumRuntimeParameter.Value.Value = value; }
+ }
+ public int Seed {
+ get { return SeedParameter.Value.Value; }
+ set { SeedParameter.Value.Value = value; }
+ }
+ public bool SetSeedRandomly {
+ get { return SetSeedRandomlyParameter.Value.Value; }
+ set { SetSeedRandomlyParameter.Value.Value = value; }
+ }
+ public int PopulationSize {
+ get { return PopulationSizeParameter.Value.Value; }
+ set { PopulationSizeParameter.Value.Value = value; }
+ }
+ public int MaximumGenerations {
+ get { return MaximumGenerationsParameter.Value.Value; }
+ set { MaximumGenerationsParameter.Value.Value = value; }
+ }
+ public int MaximumEvaluatedSolutions {
+ get { return MaximumEvaluatedSolutionsParameter.Value.Value; }
+ set { MaximumEvaluatedSolutionsParameter.Value.Value = value; }
+ }
+ public DoubleArray InitialSigma {
+ get { return InitialSigmaParameter.Value; }
+ set { InitialSigmaParameter.Value = value; }
+ }
+ public IIndicator Indicator {
+ get { return IndicatorParameter.Value; }
+ set { IndicatorParameter.Value = value; }
+ }
+
+ public double StepSizeLearningRate { get { return stepSizeLearningRate; } }
+ public double StepSizeDampeningFactor { get { return stepSizeDampeningFactor; } }
+ public double TargetSuccessProbability { get { return targetSuccessProbability; } }
+ public double EvolutionPathLearningRate { get { return evolutionPathLearningRate; } }
+ public double CovarianceMatrixLearningRate { get { return covarianceMatrixLearningRate; } }
+ public double CovarianceMatrixUnlearningRate { get { return covarianceMatrixUnlearningRate; } }
+ public double SuccessThreshold { get { return successThreshold; } }
+ #endregion
+
+ #region ResultsProperties
+ private int ResultsEvaluations {
+ get { return ((IntValue)Results[EvaluationsResultName].Value).Value; }
+ set { ((IntValue)Results[EvaluationsResultName].Value).Value = value; }
+ }
+ private int ResultsIterations {
+ get { return ((IntValue)Results[IterationsResultName].Value).Value; }
+ set { ((IntValue)Results[IterationsResultName].Value).Value = value; }
+ }
+ #region Datatable
+ private DataTable ResultsQualities {
+ get { return (DataTable)Results[TimetableResultName].Value; }
+ }
+ private DataRow ResultsBestHypervolumeDataLine {
+ get { return ResultsQualities.Rows[BestHypervolumeResultName]; }
+ }
+ private DataRow ResultsHypervolumeDataLine {
+ get { return ResultsQualities.Rows[HypervolumeResultName]; }
+ }
+ private DataRow ResultsGenerationalDistanceDataLine {
+ get { return ResultsQualities.Rows[GenerationalDistanceResultName]; }
+ }
+ private DataRow ResultsInvertedGenerationalDistanceDataLine {
+ get { return ResultsQualities.Rows[InvertedGenerationalDistanceResultName]; }
+ }
+ private DataRow ResultsCrowdingDataLine {
+ get { return ResultsQualities.Rows[CrowdingResultName]; }
+ }
+ private DataRow ResultsSpacingDataLine {
+ get { return ResultsQualities.Rows[SpacingResultName]; }
+ }
+ private DataRow ResultsHypervolumeDifferenceDataLine {
+ get { return ResultsQualities.Rows[DifferenceToBestKnownHypervolumeResultName]; }
+ }
+ #endregion
+ //QualityIndicators
+ private double ResultsHypervolume {
+ get { return ((DoubleValue)Results[HypervolumeResultName].Value).Value; }
+ set { ((DoubleValue)Results[HypervolumeResultName].Value).Value = value; }
+ }
+ private double ResultsGenerationalDistance {
+ get { return ((DoubleValue)Results[GenerationalDistanceResultName].Value).Value; }
+ set { ((DoubleValue)Results[GenerationalDistanceResultName].Value).Value = value; }
+ }
+ private double ResultsInvertedGenerationalDistance {
+ get { return ((DoubleValue)Results[InvertedGenerationalDistanceResultName].Value).Value; }
+ set { ((DoubleValue)Results[InvertedGenerationalDistanceResultName].Value).Value = value; }
+ }
+ private double ResultsCrowding {
+ get { return ((DoubleValue)Results[CrowdingResultName].Value).Value; }
+ set { ((DoubleValue)Results[CrowdingResultName].Value).Value = value; }
+ }
+ private double ResultsSpacing {
+ get { return ((DoubleValue)Results[SpacingResultName].Value).Value; }
+ set { ((DoubleValue)Results[SpacingResultName].Value).Value = value; }
+ }
+ private double ResultsBestHypervolume {
+ get { return ((DoubleValue)Results[BestHypervolumeResultName].Value).Value; }
+ set { ((DoubleValue)Results[BestHypervolumeResultName].Value).Value = value; }
+ }
+ private double ResultsBestKnownHypervolume {
+ get { return ((DoubleValue)Results[BestKnownHypervolumeResultName].Value).Value; }
+ set { ((DoubleValue)Results[BestKnownHypervolumeResultName].Value).Value = value; }
+ }
+ private double ResultsDifferenceBestKnownHypervolume {
+ get { return ((DoubleValue)Results[DifferenceToBestKnownHypervolumeResultName].Value).Value; }
+ set { ((DoubleValue)Results[DifferenceToBestKnownHypervolumeResultName].Value).Value = value; }
+
+ }
+ //Solutions
+ private DoubleMatrix ResultsSolutions {
+ get { return (DoubleMatrix)Results[CurrentFrontResultName].Value; }
+ set { Results[CurrentFrontResultName].Value = value; }
+ }
+ private ParetoFrontScatterPlot ResultsScatterPlot {
+ get { return (ParetoFrontScatterPlot)Results[ScatterPlotResultName].Value; }
+ set { Results[ScatterPlotResultName].Value = value; }
+ }
+ #endregion
+
+ #region Constructors
+ public MOCMAEvolutionStrategy() {
+ Parameters.Add(new FixedValueParameter(MaximumRuntimeName, "The maximum runtime in seconds after which the algorithm stops. Use -1 to specify no limit for the runtime", new IntValue(3600)));
+ Parameters.Add(new FixedValueParameter(SeedName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+ Parameters.Add(new FixedValueParameter(SetSeedRandomlyName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+ Parameters.Add(new FixedValueParameter(PopulationSizeName, "λ (lambda) - the size of the offspring population.", new IntValue(20)));
+ Parameters.Add(new ValueParameter(InitialSigmaName, "The initial sigma can be a single value or a value for each dimension. All values need to be > 0.", new DoubleArray(new[] { 0.5 })));
+ Parameters.Add(new FixedValueParameter(MaximumGenerationsName, "The maximum number of generations which should be processed.", new IntValue(1000)));
+ Parameters.Add(new FixedValueParameter(MaximumEvaluatedSolutionsName, "The maximum number of evaluated solutions that should be computed.", new IntValue(int.MaxValue)));
+ var set = new ItemSet { new HypervolumeIndicator(), new CrowdingIndicator(), new MinimalDistanceIndicator() };
+ Parameters.Add(new ConstrainedValueParameter(IndicatorName, "The selection mechanism on non-dominated solutions", set, set.First()));
+ }
+
+ [StorableConstructor]
+ protected MOCMAEvolutionStrategy(bool deserializing) : base(deserializing) { }
+
+ protected MOCMAEvolutionStrategy(MOCMAEvolutionStrategy original, Cloner cloner) : base(original, cloner) {
+ random = cloner.Clone(original.random);
+ gauss = cloner.Clone(original.gauss);
+ solutions = original.solutions != null ? original.solutions.Select(cloner.Clone).ToArray() : null;
+ stepSizeLearningRate = original.stepSizeLearningRate;
+ stepSizeDampeningFactor = original.stepSizeDampeningFactor;
+ targetSuccessProbability = original.targetSuccessProbability;
+ evolutionPathLearningRate = original.evolutionPathLearningRate;
+ covarianceMatrixLearningRate = original.covarianceMatrixLearningRate;
+ covarianceMatrixUnlearningRate = original.covarianceMatrixUnlearningRate;
+ successThreshold = original.successThreshold;
+ }
+
+ public override IDeepCloneable Clone(Cloner cloner) { return new MOCMAEvolutionStrategy(this, cloner); }
+ #endregion
+
+ #region Initialization
+ protected override void Initialize(CancellationToken cancellationToken) {
+ if (SetSeedRandomly) Seed = new System.Random().Next();
+ random.Reset(Seed);
+ gauss = new NormalDistributedRandom(random, 0, 1);
+
+ InitResults();
+ InitStrategy();
+ InitSolutions();
+ Analyze();
+
+ ResultsIterations = 1;
+ }
+ private Individual InitializeIndividual(RealVector x) {
+ var zeros = new RealVector(x.Length);
+ var c = new double[x.Length, x.Length];
+ var sigma = InitialSigma.Max();
+ for (var i = 0; i < x.Length; i++) {
+ var d = InitialSigma[i % InitialSigma.Length] / sigma;
+ c[i, i] = d * d;
+ }
+ return new Individual(x, targetSuccessProbability, sigma, zeros, c, this);
+ }
+ private void InitSolutions() {
+ solutions = new Individual[PopulationSize];
+ for (var i = 0; i < PopulationSize; i++) {
+ var x = new RealVector(Problem.Encoding.Length); // Uniform distibution in all dimensions assumed.
+ var bounds = Problem.Encoding.Bounds;
+ for (var j = 0; j < Problem.Encoding.Length; j++) {
+ var dim = j % bounds.Rows;
+ x[j] = random.NextDouble() * (bounds[dim, 1] - bounds[dim, 0]) + bounds[dim, 0];
+ }
+ solutions[i] = InitializeIndividual(x);
+ PenalizeEvaluate(solutions[i]);
+ }
+ ResultsEvaluations += solutions.Length;
+ }
+ private void InitStrategy() {
+ const int lambda = 1;
+ double n = Problem.Encoding.Length;
+ targetSuccessProbability = 1.0 / (5.0 + Math.Sqrt(lambda) / 2.0);
+ stepSizeDampeningFactor = 1.0 + n / (2.0 * lambda);
+ stepSizeLearningRate = targetSuccessProbability * lambda / (2.0 + targetSuccessProbability * lambda);
+ evolutionPathLearningRate = 2.0 / (n + 2.0);
+ covarianceMatrixLearningRate = 2.0 / (n * n + 6.0);
+ covarianceMatrixUnlearningRate = 0.4 / (Math.Pow(n, 1.6) + 1);
+ successThreshold = 0.44;
+ }
+ private void InitResults() {
+ Results.Add(new Result(IterationsResultName, "The number of gererations evaluated", new IntValue(0)));
+ Results.Add(new Result(EvaluationsResultName, "The number of function evaltions performed", new IntValue(0)));
+ Results.Add(new Result(HypervolumeResultName, "The hypervolume of the current front considering the Referencepoint defined in the Problem", new DoubleValue(0.0)));
+ Results.Add(new Result(BestHypervolumeResultName, "The best hypervolume of the current run considering the Referencepoint defined in the Problem", new DoubleValue(0.0)));
+ Results.Add(new Result(BestKnownHypervolumeResultName, "The best knwon hypervolume considering the Referencepoint defined in the Problem", new DoubleValue(double.NaN)));
+ Results.Add(new Result(DifferenceToBestKnownHypervolumeResultName, "The difference between the current and the best known hypervolume", new DoubleValue(double.NaN)));
+ Results.Add(new Result(GenerationalDistanceResultName, "The generational distance to an optimal pareto front defined in the Problem", new DoubleValue(double.NaN)));
+ Results.Add(new Result(InvertedGenerationalDistanceResultName, "The inverted generational distance to an optimal pareto front defined in the Problem", new DoubleValue(double.NaN)));
+ Results.Add(new Result(CrowdingResultName, "The average crowding value for the current front (excluding infinities)", new DoubleValue(0.0)));
+ Results.Add(new Result(SpacingResultName, "The spacing for the current front (excluding infinities)", new DoubleValue(0.0)));
+
+ var table = new DataTable("QualityIndicators");
+ table.Rows.Add(new DataRow(BestHypervolumeResultName));
+ table.Rows.Add(new DataRow(HypervolumeResultName));
+ table.Rows.Add(new DataRow(CrowdingResultName));
+ table.Rows.Add(new DataRow(GenerationalDistanceResultName));
+ table.Rows.Add(new DataRow(InvertedGenerationalDistanceResultName));
+ table.Rows.Add(new DataRow(DifferenceToBestKnownHypervolumeResultName));
+ table.Rows.Add(new DataRow(SpacingResultName));
+ Results.Add(new Result(TimetableResultName, "Different quality meassures in a timeseries", table));
+ Results.Add(new Result(CurrentFrontResultName, "The current front", new DoubleMatrix()));
+ Results.Add(new Result(ScatterPlotResultName, "A scatterplot displaying the evaluated solutions and (if available) the analytically optimal front", new ParetoFrontScatterPlot()));
+
+ var problem = Problem as MultiObjectiveTestFunctionProblem;
+ if (problem == null) return;
+ if (problem.BestKnownFront != null) {
+ ResultsBestKnownHypervolume = Hypervolume.Calculate(problem.BestKnownFront.ToJaggedArray(), problem.TestFunction.ReferencePoint(problem.Objectives), Problem.Maximization);
+ ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume;
+ }
+ ResultsScatterPlot = new ParetoFrontScatterPlot(new double[0][], new double[0][], problem.BestKnownFront.ToJaggedArray(), problem.Objectives, problem.ProblemSize);
+ }
+ #endregion
+
+ #region Mainloop
+ protected override void Run(CancellationToken cancellationToken) {
+ while (ResultsIterations < MaximumGenerations) {
+ try {
+ Iterate();
+ ResultsIterations++;
+ cancellationToken.ThrowIfCancellationRequested();
+ } finally {
+ Analyze();
+ }
+ }
+ }
+ private void Iterate() {
+ var offspring = solutions.Select(i => {
+ var o = new Individual(i);
+ o.Mutate(gauss);
+ PenalizeEvaluate(o);
+ return o;
+ });
+ ResultsEvaluations += solutions.Length;
+ var parents = solutions.Concat(offspring).ToArray();
+ SelectParents(parents, solutions.Length);
+ UpdatePopulation(parents);
+ }
+ protected override void OnExecutionTimeChanged() {
+ base.OnExecutionTimeChanged();
+ if (CancellationTokenSource == null) return;
+ if (MaximumRuntime == -1) return;
+ if (ExecutionTime.TotalSeconds > MaximumRuntime) CancellationTokenSource.Cancel();
+ }
+ #endregion
+
+ #region Evaluation
+ private void PenalizeEvaluate(Individual individual) {
+ if (IsFeasable(individual.Mean)) {
+ individual.Fitness = Evaluate(individual.Mean);
+ individual.PenalizedFitness = individual.Fitness;
+ } else {
+ var t = ClosestFeasible(individual.Mean);
+ individual.Fitness = Evaluate(t);
+ individual.PenalizedFitness = Penalize(individual.Mean, t, individual.Fitness);
+ }
+ }
+ private double[] Evaluate(RealVector x) {
+ var res = Problem.Evaluate(new SingleEncodingIndividual(Problem.Encoding, new Scope { Variables = { new Variable(Problem.Encoding.Name, x) } }), random);
+ return res;
+ }
+ private double[] Penalize(RealVector x, RealVector t, IEnumerable fitness) {
+ var penalty = x.Zip(t, (a, b) => (a - b) * (a - b)).Sum() * 1E-6;
+ return fitness.Select((v, i) => Problem.Maximization[i] ? v - penalty : v + penalty).ToArray();
+ }
+ private RealVector ClosestFeasible(RealVector x) {
+ var bounds = Problem.Encoding.Bounds;
+ var r = new RealVector(x.Length);
+ for (var i = 0; i < x.Length; i++) {
+ var dim = i % bounds.Rows;
+ r[i] = Math.Min(Math.Max(bounds[dim, 0], x[i]), bounds[dim, 1]);
+ }
+ return r;
+ }
+ private bool IsFeasable(RealVector offspring) {
+ var bounds = Problem.Encoding.Bounds;
+ for (var i = 0; i < offspring.Length; i++) {
+ var dim = i % bounds.Rows;
+ if (bounds[dim, 0] > offspring[i] || offspring[i] > bounds[dim, 1]) return false;
+ }
+ return true;
+ }
+ #endregion
+
+ private void SelectParents(IReadOnlyList parents, int length) {
+ //perform a nondominated sort to assign the rank to every element
+ int[] ranks;
+ var fronts = DominationCalculator.CalculateAllParetoFronts(parents.ToArray(), parents.Select(i => i.PenalizedFitness).ToArray(), Problem.Maximization, out ranks);
+
+ //deselect the highest rank fronts until we would end up with less or equal mu elements
+ var rank = fronts.Count - 1;
+ var popSize = parents.Count;
+ while (popSize - fronts[rank].Count >= length) {
+ var front = fronts[rank];
+ foreach (var i in front) i.Item1.Selected = false;
+ popSize -= front.Count;
+ rank--;
+ }
+
+ //now use the indicator to deselect the approximatingly worst elements of the last selected front
+ var front1 = fronts[rank].OrderBy(x => x.Item1.PenalizedFitness[0]).ToList();
+ for (; popSize > length; popSize--) {
+ var lc = Indicator.LeastContributer(front1.Select(i => i.Item1).ToArray(), Problem);
+ front1[lc].Item1.Selected = false;
+ front1.Swap(lc, front1.Count - 1);
+ front1.RemoveAt(front1.Count - 1);
+ }
+ }
+
+ private void UpdatePopulation(IReadOnlyList parents) {
+ foreach (var p in parents.Skip(solutions.Length).Where(i => i.Selected))
+ p.UpdateAsOffspring();
+ for (var i = 0; i < solutions.Length; i++)
+ if (parents[i].Selected)
+ parents[i].UpdateAsParent(parents[i + solutions.Length].Selected);
+ solutions = parents.Where(p => p.Selected).ToArray();
+ }
+
+ private void Analyze() {
+ ResultsScatterPlot = new ParetoFrontScatterPlot(solutions.Select(x => x.Fitness).ToArray(), solutions.Select(x => x.Mean.ToArray()).ToArray(), ResultsScatterPlot.ParetoFront, ResultsScatterPlot.Objectives, ResultsScatterPlot.ProblemSize);
+ ResultsSolutions = solutions.Select(x => x.Mean.ToArray()).ToMatrix();
+
+ var problem = Problem as MultiObjectiveTestFunctionProblem;
+ if (problem == null) return;
+
+ var front = NonDominatedSelect.GetDominatingVectors(solutions.Select(x => x.Fitness), problem.ReferencePoint.CloneAsArray(), Problem.Maximization, true).ToArray();
+ if (front.Length == 0) return;
+ var bounds = problem.Bounds.CloneAsMatrix();
+ ResultsCrowding = Crowding.Calculate(front, bounds);
+ ResultsSpacing = Spacing.Calculate(front);
+ ResultsGenerationalDistance = problem.BestKnownFront != null ? GenerationalDistance.Calculate(front, problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN;
+ ResultsInvertedGenerationalDistance = problem.BestKnownFront != null ? InvertedGenerationalDistance.Calculate(front, problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN;
+ ResultsHypervolume = Hypervolume.Calculate(front, problem.ReferencePoint.CloneAsArray(), Problem.Maximization);
+ ResultsBestHypervolume = Math.Max(ResultsHypervolume, ResultsBestHypervolume);
+ ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume - ResultsBestHypervolume;
+
+ ResultsBestHypervolumeDataLine.Values.Add(ResultsBestHypervolume);
+ ResultsHypervolumeDataLine.Values.Add(ResultsHypervolume);
+ ResultsCrowdingDataLine.Values.Add(ResultsCrowding);
+ ResultsGenerationalDistanceDataLine.Values.Add(ResultsGenerationalDistance);
+ ResultsInvertedGenerationalDistanceDataLine.Values.Add(ResultsInvertedGenerationalDistance);
+ ResultsSpacingDataLine.Values.Add(ResultsSpacing);
+ ResultsHypervolumeDifferenceDataLine.Values.Add(ResultsDifferenceBestKnownHypervolume);
+
+ Problem.Analyze(
+ solutions.Select(x => (Optimization.Individual)new SingleEncodingIndividual(Problem.Encoding, new Scope { Variables = { new Variable(Problem.Encoding.Name, x.Mean) } })).ToArray(),
+ solutions.Select(x => x.Fitness).ToArray(),
+ Results,
+ random);
+ }
+ }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Plugin.cs.frame (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Plugin.cs.frame (revision 15244)
@@ -0,0 +1,44 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+ ///
+ /// Plugin class for HeuristicLab.Algorithms.EvolutionStrategy plugin.
+ ///
+ [Plugin("HeuristicLab.Algorithms.MOCMAEvolutionStrategy", "3.3.14.$WCREV$")]
+ [PluginFile("HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.dll", PluginFileType.Assembly)]
+ [PluginDependency("HeuristicLab.ALGLIB", "3.7")]
+ [PluginDependency("HeuristicLab.Analysis", "3.3")]
+ [PluginDependency("HeuristicLab.Collections", "3.3")]
+ [PluginDependency("HeuristicLab.Common", "3.3")]
+ [PluginDependency("HeuristicLab.Core", "3.3")]
+ [PluginDependency("HeuristicLab.Data", "3.3")]
+ [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
+ [PluginDependency("HeuristicLab.Optimization", "3.3")]
+ [PluginDependency("HeuristicLab.Parameters", "3.3")]
+ [PluginDependency("HeuristicLab.Persistence", "3.3")]
+ [PluginDependency("HeuristicLab.Problems.TestFunctions.MultiObjective", "3.3")]
+ [PluginDependency("HeuristicLab.Random", "3.3")]
+ public class HeuristicLabAlgorithmsMOCMAEvolutionStrategyPlugin : PluginBase {
+ }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Properties/AssemblyInfo.cs.frame (revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Properties/AssemblyInfo.cs.frame (revision 15244)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Algorithms.MOCMAEvolutionStrategy")]
+[assembly: AssemblyDescription("HeuristicLab implementation of Multi-Objective CMA Evolution Strategy (MO-CMA-ES)")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("c27ab3d3-44d4-44e8-a3cd-3cea09d19a8f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.14.$WCREV$")]
Index: /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs (revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs (revision 15244)
@@ -37,6 +37,6 @@
}
- public IResultParameter ScatterPlotResultParameter {
- get { return (IResultParameter)Parameters["Scatterplot"]; }
+ public IResultParameter ScatterPlotResultParameter {
+ get { return (IResultParameter)Parameters["Scatterplot"]; }
}
@@ -51,5 +51,5 @@
public ScatterPlotAnalyzer() {
Parameters.Add(new ScopeTreeLookupParameter("Individuals", "The individual solutions to the problem"));
- Parameters.Add(new ResultParameter("Scatterplot", "The scatterplot for the current and optimal (if known front)"));
+ Parameters.Add(new ResultParameter("Scatterplot", "The scatterplot for the current and optimal (if known front)"));
}
@@ -57,7 +57,8 @@
public override IOperation Apply() {
var qualities = QualitiesParameter.ActualValue;
+ var individuals = IndividualsParameter.ActualValue;
var testFunction = TestFunctionParameter.ActualValue;
int objectives = qualities[0].Length;
- var individuals = IndividualsParameter.ActualValue;
+ int problemSize = individuals[0].Length;
double[][] optimalFront = new double[0][];
@@ -68,5 +69,5 @@
var solutionClones = individuals.Select(s => s.ToArray()).ToArray();
- ScatterPlotResultParameter.ActualValue = new ScatterPlotContent(qualityClones, solutionClones, optimalFront, objectives);
+ ScatterPlotResultParameter.ActualValue = new ParetoFrontScatterPlot(qualityClones, solutionClones, optimalFront, objectives, problemSize);
return base.Apply();
Index: /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj (revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj (revision 15244)
@@ -111,5 +111,5 @@
-
+
@@ -179,4 +179,9 @@
False
+
+ {0e27a536-1c4a-4624-a65e-dc4f4f23e3e1}
+ HeuristicLab.Common.Resources-3.3
+ False
+
{a9ad58b9-3ef9-4cc1-97e5-8d909039ff5c}
Index: /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ParetoFrontScatterPlot.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ParetoFrontScatterPlot.cs (revision 15244)
+++ /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ParetoFrontScatterPlot.cs (revision 15244)
@@ -0,0 +1,93 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Drawing;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
+ [StorableClass]
+ [Item("Pareto Front Scatter Plot", "The optimal front, current front and its associated Points in the searchspace")]
+ public class ParetoFrontScatterPlot : Item {
+ public static new Image StaticItemImage {
+ get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
+ }
+
+ [Storable]
+ private int objectives;
+ public int Objectives {
+ get { return objectives; }
+ }
+
+ [Storable]
+ private int problemSize;
+ public int ProblemSize {
+ get { return problemSize; }
+ }
+
+ [Storable]
+ private double[][] qualities;
+ public double[][] Qualities {
+ get { return qualities; }
+ }
+
+ [Storable]
+ private double[][] solutions;
+ public double[][] Solutions {
+ get { return solutions; }
+ }
+
+ [Storable]
+ private double[][] paretoFront;
+ public double[][] ParetoFront {
+ get { return paretoFront; }
+ }
+
+ #region Constructor, Cloning & Persistance
+ public ParetoFrontScatterPlot(double[][] qualities, double[][] solutions, double[][] paretoFront, int objectives, int problemSize) {
+ this.qualities = qualities;
+ this.solutions = solutions;
+ this.paretoFront = paretoFront;
+ this.objectives = objectives;
+ this.problemSize = problemSize;
+ }
+ public ParetoFrontScatterPlot() { }
+
+ protected ParetoFrontScatterPlot(ParetoFrontScatterPlot original, Cloner cloner)
+ : base(original, cloner) {
+ if (original.qualities != null) qualities = original.qualities.Select(s => s.ToArray()).ToArray();
+ if (original.solutions != null) solutions = original.solutions.Select(s => s.ToArray()).ToArray();
+ if (original.paretoFront != null) paretoFront = original.paretoFront.Select(s => s.ToArray()).ToArray();
+ objectives = original.objectives;
+ problemSize = original.problemSize;
+ }
+ public override IDeepCloneable Clone(Cloner cloner) {
+ return new ParetoFrontScatterPlot(this, cloner);
+ }
+
+ [StorableConstructor]
+ protected ParetoFrontScatterPlot(bool deserializing)
+ : base(deserializing) { }
+ #endregion
+ }
+}
Index: /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Plugin.cs.frame (revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Plugin.cs.frame (revision 15244)
@@ -25,5 +25,6 @@
[Plugin("HeuristicLab.Problems.TestFunctions.MultiObjective", "3.3.14.$WCREV$")]
[PluginFile("HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.dll", PluginFileType.Assembly)]
- [PluginDependency("HeuristicLab.Collections", "3.3")]
+ [PluginDependency("HeuristicLab.Collections", "3.3")]
+ [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
[PluginDependency("HeuristicLab.Common", "3.3")]
[PluginDependency("HeuristicLab.Core", "3.3")]
Index: able/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ScatterPlotContent.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ScatterPlotContent.cs (revision 15243)
+++ (revision )
@@ -1,101 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 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.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
- [StorableClass]
- [Item("ScatterPlot", "The optimal front, current front and its associated Points in the searchspace")]
- public class ScatterPlotContent : Item {
-
- [Storable]
- private double[][] qualities;
- public double[][] Qualities {
- get {
- return qualities;
- }
-
- private set {
- qualities = value;
- }
- }
-
- [Storable]
- private int objectives;
- public int Objectives {
- get {
- return objectives;
- }
-
- private set {
- objectives = value;
- }
- }
-
- [Storable]
- private double[][] solutions;
- public double[][] Solutions {
- get {
- return solutions;
- }
-
- private set {
- solutions = value;
- }
- }
-
- [Storable]
- private double[][] paretoFront;
- public double[][] ParetoFront {
- get {
- return paretoFront;
- }
-
- private set {
- paretoFront = value;
- }
- }
-
- [StorableConstructor]
- protected ScatterPlotContent(bool deserializing) : base() { }
-
- protected ScatterPlotContent(ScatterPlotContent original, Cloner cloner)
- : this() {
- this.qualities = original.qualities.Select(s => s.ToArray()).ToArray();
- this.solutions = original.solutions.Select(s => s.ToArray()).ToArray();
- this.paretoFront = original.paretoFront.Select(s => s.ToArray()).ToArray();
- this.objectives = original.objectives;
- }
- protected ScatterPlotContent() : base() { }
- public ScatterPlotContent(double[][] qualities, double[][] solutions, double[][] paretoFront, int objectives) {
- this.qualities = qualities;
- this.solutions = solutions;
- this.paretoFront = paretoFront;
- this.objectives = objectives;
- }
-
- public override IDeepCloneable Clone(Cloner cloner) {
- return new ScatterPlotContent(this, cloner);
- }
- }
-}
Index: /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/HeuristicLab.Problems.TestFunctions.Views-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/HeuristicLab.Problems.TestFunctions.Views-3.3.csproj (revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/HeuristicLab.Problems.TestFunctions.Views-3.3.csproj (revision 15244)
@@ -105,20 +105,11 @@
-
-
- 3.5
-
-
- 3.5
-
-
-
-
-
-
+
+
+
UserControl
-
- MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs
+
+ ParetoFrontScatterPlotView.cs
@@ -143,4 +134,14 @@
+
+ {76945d76-ca61-4147-9dc2-0acdcddf87f9}
+ HeuristicLab.Analysis.Views-3.3
+ False
+
+
+ {887425B4-4348-49ED-A457-B7D2C26DDBF9}
+ HeuristicLab.Analysis-3.3
+ False
+
{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}
@@ -211,9 +212,4 @@
{88B9B0E3-344E-4196-82A3-0F9732506FE8}
HeuristicLab.Problems.TestFunctions-3.3
- False
-
-
- {315bda09-3f4f-49b3-9790-b37cfc1c5750}
- HeuristicLab.Visualization.ChartControlsExtensions-3.3
False
Index: able/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.Designer.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.Designer.cs (revision 15243)
+++ (revision )
@@ -1,137 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 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
-
-namespace HeuristicLab.Problems.TestFunctions.Views {
- partial class MultiObjectiveTestFunctionParetoFrontScatterPlotView {
- ///
- /// Required designer variable.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing) {
- if (disposing && (components != null)) {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Component Designer generated code
-
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent() {
- this.components = new System.ComponentModel.Container();
- System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
- System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend();
- this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
- this.menuStrip1 = new System.Windows.Forms.MenuStrip();
- this.chooseDimensionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.chooseYDimensionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.testToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
- this.menuStrip1.SuspendLayout();
- this.SuspendLayout();
- //
- // chart
- //
- chartArea2.Name = "ChartArea";
- this.chart.ChartAreas.Add(chartArea2);
- this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
- legend2.Alignment = System.Drawing.StringAlignment.Center;
- legend2.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
- legend2.Name = "Default";
- this.chart.Legends.Add(legend2);
- this.chart.Location = new System.Drawing.Point(0, 42);
- this.chart.Margin = new System.Windows.Forms.Padding(6);
- this.chart.Name = "chart";
- this.chart.Size = new System.Drawing.Size(1054, 712);
- this.chart.TabIndex = 1;
- this.chart.CustomizeLegend += new System.EventHandler(this.chart_CustomizeLegend);
- this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
- this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
- //
- // menuStrip1
- //
- this.menuStrip1.ImageScalingSize = new System.Drawing.Size(32, 32);
- this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.chooseDimensionToolStripMenuItem,
- this.chooseYDimensionToolStripMenuItem});
- this.menuStrip1.Location = new System.Drawing.Point(0, 0);
- this.menuStrip1.Name = "menuStrip1";
- this.menuStrip1.Size = new System.Drawing.Size(1054, 42);
- this.menuStrip1.TabIndex = 2;
- this.menuStrip1.Text = "menuStrip1";
- this.menuStrip1.ShowItemToolTips = true;
- //
- // chooseDimensionToolStripMenuItem
- //
- this.chooseDimensionToolStripMenuItem.Name = "chooseDimensionToolStripMenuItem";
- this.chooseDimensionToolStripMenuItem.Size = new System.Drawing.Size(253, 38);
- this.chooseDimensionToolStripMenuItem.Text = "Objective 0";
- this.chooseDimensionToolStripMenuItem.ToolTipText = "Choose X-Dimension";
- //
- // chooseYDimensionToolStripMenuItem
- //
- this.chooseYDimensionToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.testToolStripMenuItem});
- this.chooseYDimensionToolStripMenuItem.Name = "chooseYDimensionToolStripMenuItem";
- this.chooseYDimensionToolStripMenuItem.Size = new System.Drawing.Size(252, 38);
- this.chooseYDimensionToolStripMenuItem.Text = "Objective 1";
- this.chooseYDimensionToolStripMenuItem.ToolTipText = "Choose Y-Dimension";
- //
- // testToolStripMenuItem
- //
- this.testToolStripMenuItem.Name = "testToolStripMenuItem";
- this.testToolStripMenuItem.Size = new System.Drawing.Size(269, 38);
- this.testToolStripMenuItem.Text = "Test";
- //
- // MOQualitiesScatterPlotView
- //
- this.AllowDrop = true;
- this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
- this.Controls.Add(this.chart);
- this.Controls.Add(this.menuStrip1);
- this.Margin = new System.Windows.Forms.Padding(6);
- this.Name = "MOQualitiesScatterPlotView";
- this.Size = new System.Drawing.Size(1054, 754);
- ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
- this.menuStrip1.ResumeLayout(false);
- this.menuStrip1.PerformLayout();
- this.ResumeLayout(false);
- this.PerformLayout();
-
- }
-
- #endregion
-
- private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
- private System.Windows.Forms.MenuStrip menuStrip1;
- private System.Windows.Forms.ToolStripMenuItem chooseDimensionToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem chooseYDimensionToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem testToolStripMenuItem;
- }
-}
Index: able/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs (revision 15243)
+++ (revision )
@@ -1,359 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 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 System.Text;
-using System.Windows.Forms;
-using System.Windows.Forms.DataVisualization.Charting;
-using HeuristicLab.Core.Views;
-using HeuristicLab.MainForm;
-using HeuristicLab.Problems.TestFunctions.MultiObjective;
-
-namespace HeuristicLab.Problems.TestFunctions.Views {
- [View("Scatter Plot")]
- [Content(typeof(ScatterPlotContent))]
- public partial class MultiObjectiveTestFunctionParetoFrontScatterPlotView : ItemView {
- private const string QUALITIES = "Qualities";
- private const string PARETO_FRONT = "Best Known Pareto Front";
- private Series qualitySeries;
- private Series paretoSeries;
- private int xDim = 0;
- private int yDim = 1;
- int objectives = -1;
-
- public new ScatterPlotContent Content {
- get { return (ScatterPlotContent)base.Content; }
- set { base.Content = value; }
- }
-
- public MultiObjectiveTestFunctionParetoFrontScatterPlotView()
- : base() {
- InitializeComponent();
-
- BuildEmptySeries();
-
- //start with qualities toggled ON
- qualitySeries.Points.AddXY(0, 0);
-
- this.chart.TextAntiAliasingQuality = TextAntiAliasingQuality.High;
- this.chart.AxisViewChanged += new EventHandler(chart_AxisViewChanged);
- this.chart.GetToolTipText += new System.EventHandler(this.Chart_GetToolTipText);
-
- //configure axis
- this.chart.CustomizeAllChartAreas();
- this.chart.ChartAreas[0].AxisX.Title = "Objective " + xDim;
- this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
- this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
- this.chart.ChartAreas[0].CursorX.Interval = 1;
- this.chart.ChartAreas[0].CursorY.Interval = 1;
-
- this.chart.ChartAreas[0].AxisY.Title = "Objective " + yDim;
- this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
- this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
- this.chart.ChartAreas[0].AxisY.IsStartedFromZero = true;
- }
-
-
- private void Chart_GetToolTipText(object sender, ToolTipEventArgs e) {
- if (e.HitTestResult.ChartElementType == ChartElementType.LegendItem) {
- if (e.HitTestResult.Series == paretoSeries && (Content.ParetoFront == null || Content.ParetoFront.Length == 0)) {
- e.Text = "No optimal pareto front is available for this problem with this number of objectives";
- }
- if (e.HitTestResult.Series == paretoSeries && (xDim >= Content.Objectives || yDim >= Content.Objectives)) {
- e.Text = "The optimal pareto front can only be displayed in Objective Space";
- }
- }
-
- // Check selected chart element and set tooltip text
- if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint) {
- int i = e.HitTestResult.PointIndex;
- StringBuilder toolTippText = new StringBuilder();
- DataPoint qp = e.HitTestResult.Series.Points[i];
- toolTippText.Append("Objective " + xDim + " = " + qp.XValue + "\n");
- toolTippText.Append("Objective " + yDim + " = " + qp.YValues[0]);
-
- Series s = e.HitTestResult.Series;
- if (s.Equals(this.chart.Series[QUALITIES])) {
- double[] dp = Content.Solutions[i];
- toolTippText.Append("\nSolution: {");
- for (int j = 0; j < dp.Length; j++) {
- toolTippText.Append(dp[j]);
- toolTippText.Append(";");
- }
- toolTippText.Remove(toolTippText.Length - 1, 1);
- toolTippText.Append("}");
- e.Text = toolTippText.ToString();
- }
-
-
- }
- }
-
- protected override void OnContentChanged() {
- base.OnContentChanged();
- if (Content == null) return;
- if (objectives != Content.Objectives) {
- AddMenuItems();
- objectives = Content.Objectives;
- }
- if (Content.ParetoFront == null && chart.Series.Contains(paretoSeries)) {
- Series s = this.chart.Series[PARETO_FRONT];
- paretoSeries = null;
- this.chart.Series.Remove(s);
-
- } else if (Content.ParetoFront != null && !chart.Series.Contains(paretoSeries)) {
- this.chart.Series.Add(PARETO_FRONT);
- paretoSeries = this.chart.Series[PARETO_FRONT];
- this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT;
- this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint;
- }
- UpdateChart();
- }
-
- private void UpdateChart() {
- if (InvokeRequired) Invoke((Action)UpdateChart);
- else {
- if (Content != null) {
- this.UpdateSeries();
- if (!this.chart.Series.Any(s => s.Points.Count > 0))
- this.ClearChart();
- }
- }
- }
-
- private void UpdateCursorInterval() {
- var estimatedValues = this.chart.Series[QUALITIES].Points.Select(x => x.XValue).DefaultIfEmpty(1.0);
- var targetValues = this.chart.Series[QUALITIES].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
- double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();
- double targetValuesRange = targetValues.Max() - targetValues.Min();
- double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));
- double digits = (int)Math.Log10(interestingValuesRange) - 3;
- double zoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
- this.chart.ChartAreas[0].CursorX.Interval = zoomInterval;
- this.chart.ChartAreas[0].CursorY.Interval = zoomInterval;
-
- this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = zoomInterval;
- this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = zoomInterval;
-
- this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;
- this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = zoomInterval;
- this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;
- this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSize = zoomInterval;
-
- if (digits < 0) {
- this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F" + (int)Math.Abs(digits);
- this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F" + (int)Math.Abs(digits);
- } else {
- this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F0";
- this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F0";
- }
- }
-
- private void UpdateSeries() {
- if (InvokeRequired) Invoke((Action)UpdateSeries);
- else {
-
- if (this.chart.Series.Contains(qualitySeries) && qualitySeries.Points.Count() != 0) {
- FillSeries(Content.Qualities, Content.Solutions, qualitySeries);
- }
- if (this.chart.Series.Contains(paretoSeries) && paretoSeries.Points.Count() != 0) {
- FillSeries(Content.ParetoFront, null, paretoSeries);
- }
-
-
- double minX = Double.MaxValue;
- double maxX = Double.MinValue;
- double minY = Double.MaxValue;
- double maxY = Double.MinValue;
- foreach (Series s in this.chart.Series) {
- if (s.Points.Count == 0) continue;
- minX = Math.Min(minX, s.Points.Select(p => p.XValue).Min());
- maxX = Math.Max(maxX, s.Points.Select(p => p.XValue).Max());
- minY = Math.Min(minY, s.Points.Select(p => p.YValues.Min()).Min());
- maxY = Math.Max(maxY, s.Points.Select(p => p.YValues.Max()).Max());
- }
-
- maxX = maxX + 0.2 * Math.Abs(maxX);
- minX = minX - 0.2 * Math.Abs(minX);
- maxY = maxY + 0.2 * Math.Abs(maxY);
- minY = minY - 0.2 * Math.Abs(minY);
-
- double interestingValuesRangeX = maxX - minX;
- double interestingValuesRangeY = maxY - minY;
-
- int digitsX = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeX));
- int digitsY = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeY));
-
-
- maxX = Math.Round(maxX, digitsX);
- minX = Math.Round(minX, digitsX);
- maxY = Math.Round(maxY, digitsY);
- minY = Math.Round(minY, digitsY);
- if (minX > maxX) {
- minX = 0;
- maxX = 1;
- }
- if (minY > maxY) {
- minY = 0;
- maxY = 1;
- }
-
-
- this.chart.ChartAreas[0].AxisX.Maximum = maxX;
- this.chart.ChartAreas[0].AxisX.Minimum = minX;
- this.chart.ChartAreas[0].AxisY.Maximum = maxY;
- this.chart.ChartAreas[0].AxisY.Minimum = minY;
- UpdateCursorInterval();
- }
- }
-
- private void ClearChart() {
- if (chart.Series.Contains(qualitySeries)) chart.Series.Remove(qualitySeries);
- if (chart.Series.Contains(paretoSeries)) chart.Series.Remove(paretoSeries);
- BuildEmptySeries();
- }
-
- private void ToggleSeriesData(Series series) {
- if (series.Points.Count > 0) { //checks if series is shown
- series.Points.Clear();
- } else if (Content != null) {
- switch (series.Name) {
- case PARETO_FRONT:
- FillSeries(Content.ParetoFront, null, this.chart.Series[PARETO_FRONT]);
- break;
- case QUALITIES:
- FillSeries(Content.Qualities, Content.Solutions, this.chart.Series[QUALITIES]);
- break;
- }
- }
- }
-
- private void chart_MouseDown(object sender, MouseEventArgs e) {
- HitTestResult result = chart.HitTest(e.X, e.Y);
- if (result.ChartElementType == ChartElementType.LegendItem) {
- this.ToggleSeriesData(result.Series);
- }
-
- }
-
- private void chart_MouseMove(object sender, MouseEventArgs e) {
- HitTestResult result = chart.HitTest(e.X, e.Y);
- if (result.ChartElementType == ChartElementType.LegendItem)
- this.Cursor = Cursors.Hand;
- else
- this.Cursor = Cursors.Default;
- }
-
- private void chart_AxisViewChanged(object sender, System.Windows.Forms.DataVisualization.Charting.ViewEventArgs e) {
- this.chart.ChartAreas[0].AxisX.ScaleView.Size = e.NewSize;
- this.chart.ChartAreas[0].AxisY.ScaleView.Size = e.NewSize;
- }
-
- private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
- if (this.chart.Series.Contains(qualitySeries)) e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[QUALITIES].Points.Count == 0 ? Color.Gray : Color.Black;
- if (this.chart.Series.Contains(paretoSeries)) e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[PARETO_FRONT].Points.Count == 0 ? Color.Gray : Color.Black;
- }
-
- private void AddMenuItems() {
- chooseDimensionToolStripMenuItem.DropDownItems.Clear();
- chooseYDimensionToolStripMenuItem.DropDownItems.Clear();
- if (Content == null) { return; }
- int i = 0;
- for (; i < Content.Objectives; i++) {
- //add Menu Points
- ToolStripMenuItem xItem = MakeMenuItem("X", "Objective " + i, i);
- ToolStripMenuItem yItem = MakeMenuItem("Y", "Objective " + i, i);
- xItem.Click += new System.EventHandler(this.XMenu_Click);
- yItem.Click += new System.EventHandler(this.YMenu_Click);
- chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem);
- chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem);
- }
-
- for (; i < Content.Solutions[0].Length + Content.Objectives; i++) {
- ToolStripMenuItem xItem = MakeMenuItem("X", "ProblemDimension " + (i - Content.Objectives), i);
- ToolStripMenuItem yItem = MakeMenuItem("Y", "ProblemDimension " + (i - Content.Objectives), i); ;
- xItem.Click += new System.EventHandler(this.XMenu_Click);
- yItem.Click += new System.EventHandler(this.YMenu_Click);
- chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem);
- chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem);
- }
- }
-
- private ToolStripMenuItem MakeMenuItem(String axis, String label, int i) {
- ToolStripMenuItem xItem = new ToolStripMenuItem();
- xItem.Name = "obj" + i;
- xItem.Size = new System.Drawing.Size(269, 38);
- xItem.Text = label;
- return xItem;
- }
-
- private void YMenu_Click(object sender, EventArgs e) {
- ToolStripMenuItem item = (ToolStripMenuItem)sender;
- yDim = Int32.Parse(item.Name.Remove(0, 3));
- String label = item.Text;
- this.chooseYDimensionToolStripMenuItem.Text = label;
- this.chart.ChartAreas[0].AxisY.Title = label;
- UpdateChart();
- }
-
- private void XMenu_Click(object sender, EventArgs e) {
- ToolStripMenuItem item = (ToolStripMenuItem)sender;
- xDim = Int32.Parse(item.Name.Remove(0, 3));
- String label = item.Text;
- this.chooseDimensionToolStripMenuItem.Text = label;
- this.chart.ChartAreas[0].AxisX.Title = label;
- UpdateChart();
- }
-
- private void FillSeries(double[][] qualities, double[][] solutions, Series series) {
- series.Points.Clear();
- if (qualities == null || qualities.Length == 0) return;
- int jx = xDim - qualities[0].Length;
- int jy = yDim - qualities[0].Length;
- if ((jx >= 0 || jy >= 0) && solutions == null) {
- return;
- }
- for (int i = 0; i < qualities.Length; i++) { //Assumtion: Columnwise
- double[] d = qualities[i];
- double[] q = null;
- if (jx >= 0 || jy >= 0) { q = solutions[i]; }
- series.Points.AddXY(jx < 0 ? d[xDim] : q[jx], jy < 0 ? d[yDim] : q[jy]);
- }
- }
-
- private void BuildEmptySeries() {
-
- this.chart.Series.Add(QUALITIES);
- qualitySeries = this.chart.Series[QUALITIES];
-
- this.chart.Series[QUALITIES].LegendText = QUALITIES;
- this.chart.Series[QUALITIES].ChartType = SeriesChartType.FastPoint;
-
- this.chart.Series.Add(PARETO_FRONT);
- paretoSeries = this.chart.Series[PARETO_FRONT];
- paretoSeries.Color = Color.FromArgb(100, Color.Orange);
- this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT;
- this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint;
- }
- }
-}
-
Index: /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.Designer.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.Designer.cs (revision 15244)
+++ /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.Designer.cs (revision 15244)
@@ -0,0 +1,129 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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
+
+namespace HeuristicLab.Problems.TestFunctions.Views {
+ partial class ParetoFrontScatterPlotView {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if (disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent() {
+ this.scatterPlotView = new HeuristicLab.Analysis.Views.ScatterPlotView();
+ this.xAxisComboBox = new System.Windows.Forms.ComboBox();
+ this.yAxisComboBox = new System.Windows.Forms.ComboBox();
+ this.xLabel = new System.Windows.Forms.Label();
+ this.yLabel = new System.Windows.Forms.Label();
+ this.SuspendLayout();
+ //
+ // scatterPlotView
+ //
+ this.scatterPlotView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.scatterPlotView.Caption = "ScatterPlot View";
+ this.scatterPlotView.Content = null;
+ this.scatterPlotView.Location = new System.Drawing.Point(3, 37);
+ this.scatterPlotView.Name = "scatterPlotView";
+ this.scatterPlotView.ReadOnly = false;
+ this.scatterPlotView.ShowName = false;
+ this.scatterPlotView.Size = new System.Drawing.Size(615, 342);
+ this.scatterPlotView.TabIndex = 3;
+ //
+ // xAxisComboBox
+ //
+ this.xAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.xAxisComboBox.FormattingEnabled = true;
+ this.xAxisComboBox.Location = new System.Drawing.Point(29, 3);
+ this.xAxisComboBox.Name = "xAxisComboBox";
+ this.xAxisComboBox.Size = new System.Drawing.Size(135, 28);
+ this.xAxisComboBox.TabIndex = 4;
+ this.xAxisComboBox.SelectedIndexChanged += new System.EventHandler(this.axisComboBox_SelectedIndexChanged);
+ //
+ // yAxisComboBox
+ //
+ this.yAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.yAxisComboBox.FormattingEnabled = true;
+ this.yAxisComboBox.Location = new System.Drawing.Point(240, 3);
+ this.yAxisComboBox.Name = "yAxisComboBox";
+ this.yAxisComboBox.Size = new System.Drawing.Size(135, 28);
+ this.yAxisComboBox.TabIndex = 5;
+ this.yAxisComboBox.SelectedIndexChanged += new System.EventHandler(this.axisComboBox_SelectedIndexChanged);
+ //
+ // xLabel
+ //
+ this.xLabel.AutoSize = true;
+ this.xLabel.Location = new System.Drawing.Point(3, 6);
+ this.xLabel.Name = "xLabel";
+ this.xLabel.Size = new System.Drawing.Size(20, 20);
+ this.xLabel.TabIndex = 6;
+ this.xLabel.Text = "x:";
+ //
+ // yLabel
+ //
+ this.yLabel.AutoSize = true;
+ this.yLabel.Location = new System.Drawing.Point(214, 6);
+ this.yLabel.Name = "yLabel";
+ this.yLabel.Size = new System.Drawing.Size(20, 20);
+ this.yLabel.TabIndex = 7;
+ this.yLabel.Text = "y:";
+ //
+ // ParetoFrontScatterPlotView
+ //
+ this.AllowDrop = true;
+ this.Controls.Add(this.yLabel);
+ this.Controls.Add(this.xLabel);
+ this.Controls.Add(this.yAxisComboBox);
+ this.Controls.Add(this.xAxisComboBox);
+ this.Controls.Add(this.scatterPlotView);
+ this.Margin = new System.Windows.Forms.Padding(6);
+ this.Name = "ParetoFrontScatterPlotView";
+ this.Size = new System.Drawing.Size(621, 382);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+ private HeuristicLab.Analysis.Views.ScatterPlotView scatterPlotView;
+ private System.Windows.Forms.ComboBox xAxisComboBox;
+ private System.Windows.Forms.ComboBox yAxisComboBox;
+ private System.Windows.Forms.Label xLabel;
+ private System.Windows.Forms.Label yLabel;
+ }
+}
Index: /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.cs (revision 15244)
+++ /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.cs (revision 15244)
@@ -0,0 +1,187 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.TestFunctions.MultiObjective;
+
+namespace HeuristicLab.Problems.TestFunctions.Views {
+ [View("Scatter Plot")]
+ [Content(typeof(ParetoFrontScatterPlot))]
+ public partial class ParetoFrontScatterPlotView : ItemView {
+
+ private readonly ScatterPlot scatterPlot;
+ private readonly ScatterPlotDataRow qualitiesRow;
+ private readonly ScatterPlotDataRow paretoFrontRow;
+
+ private int oldObjectives = -1;
+ private int oldProblemSize = -1;
+
+ private bool suppressEvents;
+
+ public new ParetoFrontScatterPlot Content {
+ get { return (ParetoFrontScatterPlot)base.Content; }
+ set { base.Content = value; }
+ }
+
+ public ParetoFrontScatterPlotView() {
+ InitializeComponent();
+
+ scatterPlot = new ScatterPlot();
+
+ qualitiesRow = new ScatterPlotDataRow("Qualities", string.Empty, Enumerable.Empty>()) {
+ VisualProperties = {
+ PointSize = 8 ,
+ PointStyle = ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Circle
+ }
+ };
+ scatterPlot.Rows.Add(qualitiesRow);
+
+ paretoFrontRow = new ScatterPlotDataRow("Best Known Pareto Front", string.Empty, Enumerable.Empty>()) {
+ VisualProperties = {
+ PointSize = 4,
+ PointStyle = ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Square
+ }
+ };
+ scatterPlot.Rows.Add(paretoFrontRow);
+ }
+
+ protected override void OnContentChanged() {
+ base.OnContentChanged();
+
+ if (Content == null) {
+ scatterPlotView.Content = null;
+ xAxisComboBox.Items.Clear();
+ xAxisComboBox.SelectedIndex = -1;
+ yAxisComboBox.Items.Clear();
+ yAxisComboBox.SelectedIndex = -1;
+ return;
+ }
+
+ scatterPlotView.Content = scatterPlot;
+
+ if (oldObjectives != Content.Objectives || oldProblemSize != Content.ProblemSize)
+ UpdateAxisComboBoxes();
+
+ UpdateChartData();
+
+ oldObjectives = Content.Objectives;
+ oldProblemSize = Content.ProblemSize;
+ }
+
+ private void UpdateChartData() {
+ if (InvokeRequired) {
+ Invoke((Action)UpdateChartData);
+ return;
+ }
+
+ int xDimGlobal = xAxisComboBox.SelectedIndex;
+ int yDimGlobal = yAxisComboBox.SelectedIndex;
+
+ qualitiesRow.Points.Replace(CreatePoints(Content.Qualities, Content.Solutions, xDimGlobal, yDimGlobal));
+
+ paretoFrontRow.Points.Replace(CreatePoints(Content.ParetoFront, null, xDimGlobal, yDimGlobal));
+ paretoFrontRow.VisualProperties.IsVisibleInLegend = paretoFrontRow.Points.Count > 0; // hide if empty
+ }
+
+ private void UpdateAxisComboBoxes() {
+ try {
+ suppressEvents = true;
+
+ string prevSelectedX = (string)xAxisComboBox.SelectedItem;
+ string prevSelectedY = (string)yAxisComboBox.SelectedItem;
+
+ xAxisComboBox.Items.Clear();
+ yAxisComboBox.Items.Clear();
+
+ // Add Objectives first
+ for (int i = 0; i < Content.Objectives; i++) {
+ xAxisComboBox.Items.Add("Objective " + i);
+ yAxisComboBox.Items.Add("Objective " + i);
+ }
+
+ // Add Problem Dimension
+ for (int i = 0; i < Content.ProblemSize; i++) {
+ xAxisComboBox.Items.Add("Problem Dimension " + i);
+ yAxisComboBox.Items.Add("Problem Dimension " + i);
+ }
+
+ // Selection
+ int count = xAxisComboBox.Items.Count;
+ if (count > 0) {
+ if (prevSelectedX != null && xAxisComboBox.Items.Contains(prevSelectedX))
+ xAxisComboBox.SelectedItem = prevSelectedX;
+ else xAxisComboBox.SelectedIndex = 0;
+
+ if (prevSelectedY != null && yAxisComboBox.Items.Contains(prevSelectedY))
+ yAxisComboBox.SelectedItem = prevSelectedY;
+ else yAxisComboBox.SelectedIndex = Math.Min(1, count - 1);
+ } else {
+ xAxisComboBox.SelectedIndex = -1;
+ yAxisComboBox.SelectedIndex = -1;
+ }
+
+ UpdateAxisDescription();
+ } finally {
+ suppressEvents = false;
+ }
+ }
+
+ private void UpdateAxisDescription() {
+ scatterPlot.VisualProperties.XAxisTitle = (string)xAxisComboBox.SelectedItem;
+ scatterPlot.VisualProperties.YAxisTitle = (string)yAxisComboBox.SelectedItem;
+ }
+
+ private static Point2D[] CreatePoints(double[][] qualities, double[][] solutions, int xDimGlobal, int yDimGlobal) {
+ if (qualities == null || qualities.Length == 0) return new Point2D[0];
+
+ int objectives = qualities[0].Length;
+
+ // "Global" dimension index describes the index as if the qualities and solutions would be in a single array
+ // If the global dimension index is too long for the qualities, use solutions
+ var xDimArray = xDimGlobal < objectives ? qualities : solutions;
+ var yDimArray = yDimGlobal < objectives ? qualities : solutions;
+ var xDimIndex = xDimGlobal < objectives ? xDimGlobal : xDimGlobal - objectives;
+ var yDimIndex = yDimGlobal < objectives ? yDimGlobal : yDimGlobal - objectives;
+
+ if (xDimArray == null || yDimArray == null)
+ return new Point2D[0];
+
+ var points = new Point2D[xDimArray.Length];
+ for (int i = 0; i < xDimArray.Length; i++) {
+ points[i] = new Point2D(xDimArray[i][xDimIndex], yDimArray[i][yDimIndex]);
+ }
+ return points;
+ }
+
+ #region Event Handler
+ private void axisComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+ if (suppressEvents) return;
+ UpdateAxisDescription();
+ UpdateChartData();
+ }
+ #endregion
+ }
+}
Index: /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/Plugin.cs.frame (revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/Plugin.cs.frame (revision 15244)
@@ -28,4 +28,6 @@
[Plugin("HeuristicLab.Problems.TestFunctions.Views", "3.3.14.$WCREV$")]
[PluginFile("HeuristicLab.Problems.TestFunctions.Views-3.3.dll", PluginFileType.Assembly)]
+ [PluginDependency("HeuristicLab.Analysis", "3.3")]
+ [PluginDependency("HeuristicLab.Analysis.Views", "3.3")]
[PluginDependency("HeuristicLab.Collections", "3.3")]
[PluginDependency("HeuristicLab.Common", "3.3")]
@@ -40,5 +42,4 @@
[PluginDependency("HeuristicLab.Problems.TestFunctions", "3.3")]
[PluginDependency("HeuristicLab.Problems.TestFunctions.MultiObjective", "3.3")]
- [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions", "3.3")]
public class HeuristicLabProblemsTestFunctionsViewsPlugin : PluginBase {
}