Index: /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainer.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainer.cs	(revision 14776)
@@ -26,4 +26,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel;
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
@@ -31,4 +32,6 @@
 
 namespace HeuristicLab.Algorithms.MemPR.Binary.SolutionModel.Univariate {
+  public enum ModelBiasOptions { Rank, Fitness }
+
   [Item("Biased Univariate Model Trainer (binary)", "", ExcludeGenericTypeInfo = true)]
   [StorableClass]
@@ -60,5 +63,17 @@
 
     public void TrainModel(TContext context) {
-      context.Model = Trainer.TrainBiased(ModelBias, context.Random, context.Maximization, context.Population.Select(x => x.Solution), context.Population.Select(x => x.Fitness));
+      var biasType = modelBiasParameter.Value.Value;
+      switch (biasType) {
+        case ModelBiasOptions.Fitness:
+          context.Model = UnivariateModelTrainer.TrainWithFitnessBias(context.Random, context.Maximization,
+            context.Population.Select(x => x.Solution),
+            context.Population.Select(x => x.Fitness));
+          break;
+        case ModelBiasOptions.Rank:
+          context.Model = UnivariateModelTrainer.TrainWithRankBias(context.Random, context.Maximization,
+            context.Population.Select(x => x.Solution),
+            context.Population.Select(x => x.Fitness));
+          break;
+      }
     }
   }
Index: /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainer.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainer.cs	(revision 14776)
@@ -25,4 +25,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel;
 using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -49,5 +50,5 @@
 
     public void TrainModel(TContext context) {
-      context.Model = Trainer.TrainUnbiased(context.Random, context.Population.Select(x => x.Solution));
+      context.Model = UnivariateModelTrainer.TrainUnbiased(context.Random, context.Population.Select(x => x.Solution));
     }
   }
Index: anches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnivariateSolutionModel.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnivariateSolutionModel.cs	(revision 14775)
+++ 	(revision )
@@ -1,125 +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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Algorithms.MemPR.Interfaces;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.BinaryVectorEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Random;
-
-namespace HeuristicLab.Algorithms.MemPR.Binary.SolutionModel.Univariate {
-  [Item("Univariate solution model (binary)", "")]
-  [StorableClass]
-  public sealed class UnivariateModel : Item, ISolutionModel<BinaryVector> {
-    [Storable]
-    public DoubleArray Probabilities { get; set; }
-    [Storable]
-    public IRandom Random { get; set; }
-
-    [StorableConstructor]
-    private UnivariateModel(bool deserializing) : base(deserializing) { }
-    private UnivariateModel(UnivariateModel original, Cloner cloner)
-      : base(original, cloner) {
-      Probabilities = cloner.Clone(original.Probabilities);
-      Random = cloner.Clone(original.Random);
-    }
-    public UnivariateModel(IRandom random, int N) : this(random, Enumerable.Range(0, N).Select(x => 0.5).ToArray()) { }
-    public UnivariateModel(IRandom random, double[] probabilities) {
-      Probabilities = new DoubleArray(probabilities);
-      Random = random;
-    }
-    public UnivariateModel(IRandom random, DoubleArray probabilties) {
-      Probabilities = probabilties;
-      Random = random;
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new UnivariateModel(this, cloner);
-    }
-
-    public BinaryVector Sample() {
-      var vec = new BinaryVector(Probabilities.Length);
-      for (var i = 0; i < Probabilities.Length; i++)
-        vec[i] = Random.NextDouble() < Probabilities[i];
-      return vec;
-    }
-
-    public static ISolutionModel<BinaryVector> CreateWithoutBias(IRandom random, IEnumerable<BinaryVector> population) {
-      double[] model = null;
-      var popSize = 0;
-      foreach (var p in population) {
-        popSize++;
-        if (model == null) model = new double[p.Length];
-        for (var x = 0; x < model.Length; x++) {
-          if (p[x]) model[x]++;
-        }
-      }
-      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
-      // normalize to [0;1]
-      var factor = 1.0 / popSize;
-      for (var x = 0; x < model.Length; x++) {
-        model[x] *= factor;
-      }
-      return new UnivariateModel(random, model);
-    }
-
-    public static ISolutionModel<BinaryVector> CreateWithRankBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
-      var popSize = 0;
-
-      double[] model = null;
-      var pop = population.Zip(qualities, (b, q) => new { Solution = b, Fitness = q });
-      foreach (var ind in maximization ? pop.OrderBy(x => x.Fitness) : pop.OrderByDescending(x => x.Fitness)) {
-        // from worst to best, worst solution has 1 vote, best solution N votes
-        popSize++;
-        if (model == null) model = new double[ind.Solution.Length];
-        for (var x = 0; x < model.Length; x++) {
-          if (ind.Solution[x]) model[x] += popSize;
-        }
-      }
-      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
-      // normalize to [0;1]
-      var factor = 2.0 / (popSize + 1);
-      for (var i = 0; i < model.Length; i++) {
-        model[i] *= factor / popSize;
-      }
-      return new UnivariateModel(random, model);
-    }
-
-    public static ISolutionModel<BinaryVector> CreateWithFitnessBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
-      var proportions = Util.Auxiliary.PrepareProportional(qualities, true, !maximization);
-      var factor = 1.0 / proportions.Sum();
-      double[] model = null;
-      foreach (var ind in population.Zip(proportions, (p, q) => new { Solution = p, Proportion = q })) {
-        if (model == null) model = new double[ind.Solution.Length];
-        for (var x = 0; x < model.Length; x++) {
-          if (ind.Solution[x]) model[x] += ind.Proportion * factor;
-        }
-      }
-      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
-      return new UnivariateModel(random, model);
-    }
-  }
-}
Index: /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/HeuristicLab.Algorithms.MemPR-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/HeuristicLab.Algorithms.MemPR-3.3.csproj	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/HeuristicLab.Algorithms.MemPR-3.3.csproj	(revision 14776)
@@ -102,12 +102,4 @@
       <Private>False</Private>
     </Reference>
-    <Reference Include="HeuristicLab.Encodings.BinaryVectorEncoding-3.3">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.BinaryVectorEncoding-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Encodings.LinearLinkageEncoding-3.4">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.LinearLinkageEncoding-3.4.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
     <Reference Include="HeuristicLab.Operators-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
@@ -165,6 +157,4 @@
     <Compile Include="Binary\LocalSearch\ExhaustiveBitflip.cs" />
     <Compile Include="Binary\LocalSearch\StaticAPI\ExhaustiveBitflip.cs" />
-    <Compile Include="Binary\SolutionModel\Univariate\StaticAPI\Trainer.cs" />
-    <Compile Include="Binary\SolutionModel\Univariate\UnivariateSolutionModel.cs" />
     <Compile Include="Binary\SolutionModel\Univariate\BiasedModelTrainer.cs" />
     <Compile Include="Binary\SolutionModel\Univariate\UnbiasedModelTrainer.cs" />
@@ -179,4 +169,6 @@
     <Compile Include="LinearLinkage\SolutionModel\Univariate\UnivariateSolutionModel.cs" />
     <Compile Include="MemPRAlgorithm.cs" />
+    <Compile Include="Permutation\InversionPathRelinker.cs" />
+    <Compile Include="Permutation\LocalSearch\ExhaustiveInversionImprover.cs" />
     <Compile Include="Permutation\PermutationMemPR.cs" />
     <Compile Include="Permutation\PermutationMemPRContext.cs" />
@@ -212,4 +204,14 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.BinaryVectorEncoding\3.3\HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj">
+      <Project>{66d249c3-a01d-42a8-82a2-919bc8ec3d83}</Project>
+      <Name>HeuristicLab.Encodings.BinaryVectorEncoding-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.LinearLinkageEncoding\3.4\HeuristicLab.Encodings.LinearLinkageEncoding-3.4.csproj">
+      <Project>{be698769-975a-429e-828c-72bb2b6182c8}</Project>
+      <Name>HeuristicLab.Encodings.LinearLinkageEncoding-3.4</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Encodings.PermutationEncoding\3.3\HeuristicLab.Encodings.PermutationEncoding-3.3.csproj">
       <Project>{dbecb8b0-b166-4133-baf1-ed67c3fd7fca}</Project>
Index: /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Interfaces/Interfaces.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Interfaces/Interfaces.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Interfaces/Interfaces.cs	(revision 14776)
@@ -37,8 +37,4 @@
    * ********************************************* *
    *************************************************/
-
-  public interface ISolutionModel<TSolution> : IItem {
-    TSolution Sample();
-  }
 
   public interface ISolutionSubspace<TSolution> : IItem { }
@@ -89,4 +85,5 @@
       where TProblem : class, ISingleObjectiveHeuristicOptimizationProblem {
     IEnumerable<ISingleObjectiveSolutionScope<TSolution>> Population { get; }
+    int PopulationCount { get; }
   }
 
Index: /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/LinearLinkage/SolutionModel/Univariate/StaticAPI/Trainer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/LinearLinkage/SolutionModel/Univariate/StaticAPI/Trainer.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/LinearLinkage/SolutionModel/Univariate/StaticAPI/Trainer.cs	(revision 14776)
@@ -21,7 +21,7 @@
 
 using System.Collections.Generic;
-using HeuristicLab.Algorithms.MemPR.Interfaces;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.LinearLinkageEncoding;
+using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Algorithms.MemPR.Grouping.SolutionModel.Univariate {
Index: /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/LinearLinkage/SolutionModel/Univariate/UnivariateSolutionModel.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/LinearLinkage/SolutionModel/Univariate/UnivariateSolutionModel.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/LinearLinkage/SolutionModel/Univariate/UnivariateSolutionModel.cs	(revision 14776)
@@ -22,9 +22,9 @@
 using System;
 using System.Collections.Generic;
-using HeuristicLab.Algorithms.MemPR.Interfaces;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.LinearLinkageEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
Index: /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Permutation/InversionPathRelinker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Permutation/InversionPathRelinker.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Permutation/InversionPathRelinker.cs	(revision 14776)
@@ -0,0 +1,187 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Remoting.Contexts;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  [Item("InversionPathRelinker", "An operator that relinks solutions.")]
+  [StorableClass]
+  public sealed class InversionPathRelinker : SingleObjectivePathRelinker, IStochasticOperator {
+    public IValueLookupParameter<DoubleMatrix> DistanceMatrixParameter {
+      get { return (IValueLookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>) Parameters["Random"]; }
+    }
+    [StorableConstructor]
+    private InversionPathRelinker(bool deserializing) : base(deserializing) { }
+    private InversionPathRelinker(InversionPathRelinker original, Cloner cloner) : base(original, cloner) { }
+
+    public InversionPathRelinker() : base() {
+      Parameters.Add(new ValueLookupParameter<DoubleMatrix>("DistanceMatrix"));
+      Parameters.Add(new LookupParameter<IRandom>("Random"));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InversionPathRelinker(this, cloner);
+    }
+
+    protected override ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n) {
+      if (parents.Length != 2)
+        throw new ArgumentException("The number of parents is not equal to 2.");
+      var random = RandomParameter.ActualValue;
+      var distances = DistanceMatrixParameter.ActualValue;
+      Func<Permutation, double> eval = (p) => {
+        double length = 0;
+        for (int i = 0; i < p.Length - 1; i++)
+          length += distances[p[i], p[i + 1]];
+        length += distances[p[p.Length - 1], p[0]];
+        return length;
+      };
+      return new ItemArray<IItem>(RelinkOpt(random, (Permutation)parents[0],
+        (Permutation)parents[1], eval));
+    }
+
+    public IEnumerable<Permutation> RelinkOpt(IRandom random, Permutation p1, Permutation p2,
+                               Func<Permutation, double> eval) {
+
+      var evaluations = 0;
+      var child = (Permutation)p1.Clone();
+      
+      Permutation bestChild = null;
+
+      var invChild = new int[child.Length];
+      var invP2 = new int[child.Length];
+      for (var i = 0; i < child.Length; i++) {
+        invChild[child[i]] = i;
+        invP2[p2[i]] = i;
+      }
+
+      var bestChange = double.NaN;
+      var moveQueue = new Queue<Tuple<int, int>>();
+      var undoStack = new Stack<Tuple<int, int>>();
+      do {
+        Queue<Tuple<int, int>> bestQueue = null;
+        bestChange = double.NaN;
+        for (var j = 0; j < p2.Length; j++) {
+          if (IsUndirectedEdge(invChild, p2[j], p2.GetCircular(j + 1))) continue;
+
+          var a = invChild[p2[j]];
+          var b = invChild[p2.GetCircular(j + 1)];
+          if (a > b) { var h = a; a = b; b = h; }
+          var aprev = a - 1;
+          var bprev = b - 1;
+          while (IsUndirectedEdge(invP2, child.GetCircular(aprev), child.GetCircular(aprev + 1))) {
+            aprev--;
+          }
+          while (IsUndirectedEdge(invP2, child.GetCircular(bprev), child.GetCircular(bprev + 1))) {
+            bprev--;
+          }
+          var bnext = b + 1;
+          var anext = a + 1;
+          while (IsUndirectedEdge(invP2, child.GetCircular(bnext - 1), child.GetCircular(bnext))) {
+            bnext++;
+          }
+          while (IsUndirectedEdge(invP2, child.GetCircular(anext - 1), child.GetCircular(anext))) {
+            anext++;
+          }
+          aprev++; bprev++; anext--; bnext--;
+
+          if (aprev < a && bnext > b) {
+            if (aprev < 0) {
+              moveQueue.Enqueue(Tuple.Create(a + 1, bnext));
+              moveQueue.Enqueue(Tuple.Create(a + 1, a + 1 + (bnext - b)));
+            } else {
+              moveQueue.Enqueue(Tuple.Create(aprev, b - 1));
+              moveQueue.Enqueue(Tuple.Create(b - 1 - (a - aprev), b - 1));
+            }
+          } else if (aprev < a && bnext == b && bprev == b) {
+            moveQueue.Enqueue(Tuple.Create(a + 1, b));
+          } else if (aprev < a && bprev < b) {
+            moveQueue.Enqueue(Tuple.Create(a + 1, b));
+          } else if (aprev == a && anext == a && bnext > b) {
+            moveQueue.Enqueue(Tuple.Create(a, b - 1));
+          } else if (aprev == a && anext == a && bnext == b && bprev == b) {
+            moveQueue.Enqueue(Tuple.Create(a, b - 1));
+          } else if (aprev == a && anext == a && bprev < b) {
+            moveQueue.Enqueue(Tuple.Create(a + 1, b));
+          } else if (anext > a && bnext > b) {
+            moveQueue.Enqueue(Tuple.Create(a, b - 1));
+          } else if (anext > a && bnext == b && bprev == b) {
+            moveQueue.Enqueue(Tuple.Create(a, b - 1));
+          } else /*if (anext > a && bprev < b)*/ {
+            moveQueue.Enqueue(Tuple.Create(a, bprev - 1));
+            moveQueue.Enqueue(Tuple.Create(bprev, b));
+          }
+
+          while (moveQueue.Count > 0) {
+            var m = moveQueue.Dequeue();
+            Opt(child, m.Item1, m.Item2);
+            undoStack.Push(m);
+          }
+          var moveF = eval(child);
+
+          evaluations++;
+          if (double.IsNaN(bestChange) || moveF < bestChange) {
+            bestChange = moveF;
+            bestQueue = new Queue<Tuple<int, int>>(undoStack.Reverse());
+          }
+          // undo
+          while (undoStack.Count > 0) {
+            var m = undoStack.Pop();
+            Opt(child, m.Item1, m.Item2);
+          }
+        }
+        if (!double.IsNaN(bestChange)) {
+          while (bestQueue.Count > 0) {
+            var m = bestQueue.Dequeue();
+            Opt(child, m.Item1, m.Item2);
+            for (var i = m.Item1; i <= m.Item2; i++) invChild[child[i]] = i;
+          }
+          yield return (Permutation) child.Clone();
+        }
+      } while (!double.IsNaN(bestChange));
+    }
+
+    private static bool IsUndirectedEdge(int[] invP, int a, int b) {
+      var d = Math.Abs(invP[a] - invP[b]);
+      return d == 1 || d == invP.Length - 1;
+    }
+
+    private static void Opt(Permutation child, int from, int to) {
+      if (from > to) child.Reverse(to, from - to + 1);
+      else child.Reverse(from, to - from + 1);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Permutation/LocalSearch/ExhaustiveInversionImprover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Permutation/LocalSearch/ExhaustiveInversionImprover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Permutation/LocalSearch/ExhaustiveInversionImprover.cs	(revision 14776)
@@ -0,0 +1,74 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using HeuristicLab.Algorithms.MemPR.Permutation.LocalSearch;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.MemPR.Permutation {
+  [Item("Exhaustive Inversion Improver", "")]
+  [StorableClass]
+  public class ExhaustiveInversionImprover : SingleSuccessorOperator, IImprovementOperator {
+    #region Parameter properties
+    public ILookupParameter<DoubleMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<Encodings.PermutationEncoding.Permutation> PermutationParameter {
+      get { return (ILookupParameter<Encodings.PermutationEncoding.Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<IntValue> LocalEvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["LocalEvaluatedSolutions"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private ExhaustiveInversionImprover(bool deserializing) : base(deserializing) { }
+    private ExhaustiveInversionImprover(ExhaustiveInversionImprover original, Cloner cloner) : base(original, cloner) { }
+    public ExhaustiveInversionImprover()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new LookupParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "A pseudo random number generator."));
+      Parameters.Add(new ValueLookupParameter<Encodings.PermutationEncoding.Permutation>("Permutation", "The solution to be improved. This parameter is used for name translation only."));
+      Parameters.Add(new LookupParameter<IntValue>("LocalEvaluatedSolutions", "The amount of locally evaluated solutions."));
+      #endregion
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExhaustiveInversionImprover(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var random = RandomParameter.ActualValue;
+      var perm = PermutationParameter.ActualValue;
+
+      var distances = DistanceMatrixParameter.ActualValue;
+      Func<Encodings.PermutationEncoding.Permutation, CancellationToken, double> eval = (p, _) => {
+        double length = 0;
+        for (int i = 0; i < p.Length - 1; i++)
+          length += distances[p[i], p[i + 1]];
+        length += distances[p[p.Length - 1], p[0]];
+        return length;
+      };
+      var quality = eval(perm, CancellationToken.None);
+      var path = Exhaustive2Opt.HillClimb(random, perm, quality, false, eval, CancellationToken.None);
+      var final = path.Last();
+
+      LocalEvaluatedSolutionsParameter.ActualValue = new IntValue(final.Item3);
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Permutation/SolutionModel/Univariate/StaticAPI/Trainer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Permutation/SolutionModel/Univariate/StaticAPI/Trainer.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Permutation/SolutionModel/Univariate/StaticAPI/Trainer.cs	(revision 14776)
@@ -22,7 +22,7 @@
 using System;
 using System.Collections.Generic;
-using HeuristicLab.Algorithms.MemPR.Interfaces;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Algorithms.MemPR.Permutation.SolutionModel.Univariate {
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/AdaptiveWalkCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/AdaptiveWalkCalculator.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/AdaptiveWalkCalculator.cs	(revision 14776)
@@ -58,11 +58,12 @@
       characteristics = cloner.Clone(original.characteristics);
     }
-    public AdaptiveWalkCalculator() {
+    public AdaptiveWalkCalculator() : this(new AdaptiveWalk()) { }
+    public AdaptiveWalkCalculator(AdaptiveWalk walker) {
       Name = ItemName;
       Description = ItemDescription;
-      walker = new AdaptiveWalk();
+      this.walker = walker;
       characteristics = new CheckedItemList<StringValue>(
         new[] { "AutoCorrelation1", "CorrelationLength", "InformationContent",
-        "PartialInformationContent", "DensityBasinInformation", "InformationStability", 
+        "PartialInformationContent", "DensityBasinInformation", "InformationStability",
         "Diversity", "Regularity", "TotalEntropy", "PeakInformationContent",
         "PeakDensityBasinInformation" }.Select(x => new StringValue(x)));
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/GanttData.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/GanttData.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/GanttData.cs	(revision 14776)
@@ -0,0 +1,188 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [Item("Gantt Data", "Data of a Gantt visualization")]
+  [StorableClass]
+  public class GanttData : NamedItem {
+
+    [Storable]
+    private NamedItemCollection<GanttRow> rows;
+    public NamedItemCollection<GanttRow> Rows { get { return rows; } }
+
+    [Storable]
+    private ObservableDictionary<string, Color> categoryColors;
+    public ObservableDictionary<string, Color> CategoryColors { get { return categoryColors; } }
+
+    [StorableConstructor]
+    protected GanttData(bool deserializing) : base(deserializing) {}
+    protected GanttData(GanttData original, Cloner cloner)
+      : base(original, cloner) {
+      rows = cloner.Clone(original.rows);
+      categoryColors = new ObservableDictionary<string, Color>(original.categoryColors);
+    }
+    public GanttData() : this("Gantt Data", "Data of a Gantt visualization") { }
+    public GanttData(string name) : this(name, string.Empty) { }
+    public GanttData(string name, string description) : base(name, description) {
+      rows = new NamedItemCollection<GanttRow>();
+      categoryColors = new ObservableDictionary<string, Color>();
+    }
+    public GanttData(IEnumerable<GanttRow> rows) : this("Gantt Data", rows) { }
+    public GanttData(string name, IEnumerable<GanttRow> rows) : this(name, string.Empty, rows) { }
+    public GanttData(string name, string description, IEnumerable<GanttRow> rows) : base(name, description) {
+      this.rows = new NamedItemCollection<GanttRow>(rows);
+      categoryColors = new ObservableDictionary<string, Color>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GanttData(this, cloner);
+    }
+  }
+
+  [Item("Gantt Row", "Row of a Gantt chart")]
+  [StorableClass]
+  public class GanttRow : NamedItem {
+    [Storable]
+    private ItemList<GanttItem> items;
+    public ItemList<GanttItem> Items { get { return items; } }
+
+    [StorableConstructor]
+    protected GanttRow(bool deserializing) : base(deserializing) {}
+    protected GanttRow(GanttRow original, Cloner cloner)
+      : base(original, cloner) {
+      items = cloner.Clone(original.items);
+    }
+    public GanttRow() : this("Gantt Row", "Row of a Gantt chart") { }
+    public GanttRow(string name) : this(name, string.Empty) { }
+    public GanttRow(string name, string description) : base(name, description) {
+      items = new ItemList<GanttItem>();
+    }
+    public GanttRow(IEnumerable<GanttItem> items) : this("Gantt Row", items) { }
+    public GanttRow(string name, IEnumerable<GanttItem> items) : this(name, string.Empty, items) { }
+    public GanttRow(string name, string description, IEnumerable<GanttItem> items) : base(name, description) {
+      this.items = new ItemList<GanttItem>(items);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GanttRow(this, cloner);
+    }
+  }
+
+  [Item("Gantt Item", "Item of a Gantt chart row")]
+  [StorableClass]
+  public class GanttItem : Item, INotifyPropertyChanged {
+
+    [Storable]
+    private DateTime startDate;
+    public DateTime StartDate {
+      get { return startDate; }
+      set {
+        if (startDate == value) return;
+        startDate = value;
+        OnPropertyChanged("StartDate");
+      }
+    }
+
+    [Storable]
+    private DateTime endDate;
+    public DateTime EndDate {
+      get { return endDate; }
+      set {
+        if (endDate == value) return;
+        endDate = value;
+        OnPropertyChanged("EndDate");
+      }
+    }
+
+    [Storable]
+    private string toolTip;
+    public string ToolTip {
+      get { return toolTip; }
+      set {
+        if (toolTip == value) return;
+        toolTip = value;
+        OnPropertyChanged("ToolTip");
+      }
+    }
+
+    [Storable]
+    private string category;
+    public string Category {
+      get { return category; }
+      set {
+        if (category == value) return;
+        category = value;
+        OnPropertyChanged("Category");
+      }
+    }
+
+    [Storable]
+    private bool showLabel;
+    public bool ShowLabel {
+      get { return showLabel; }
+      set {
+        if (showLabel == value) return;
+        showLabel = value;
+        OnPropertyChanged("ShowLabel");
+      }
+    }
+
+    [StorableConstructor]
+    protected GanttItem(bool deserializing) : base(deserializing) { }
+    protected GanttItem(GanttItem original, Cloner cloner)
+      : base(original, cloner) {
+      startDate = original.startDate;
+      endDate = original.endDate;
+      toolTip = original.toolTip;
+      category = original.category;
+      showLabel = original.showLabel;
+    }
+    public GanttItem() : this(DateTime.Now, DateTime.Now) { }
+    public GanttItem(DateTime start, DateTime end) {
+      startDate = start;
+      endDate = end;
+      toolTip = string.Empty;
+      category = string.Empty;
+      showLabel = false;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GanttItem(this, cloner);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected virtual void OnPropertyChanged(string propertyName) {
+      var handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 14776)
@@ -187,4 +187,5 @@
     <Compile Include="BestNScopesSolutionAnalyzer.cs" />
     <Compile Include="BestScopeSolutionAnalyzer.cs" />
+    <Compile Include="DataVisualization\GanttData.cs" />
     <Compile Include="Clustering\CkMeans1D.cs">
       <SubType>Code</SubType>
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/ExpectedRuntimeHelper.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/ExpectedRuntimeHelper.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/ExpectedRuntimeHelper.cs	(revision 14776)
@@ -30,5 +30,5 @@
       if (successful.Count > 0) {
         var succAvg = successful.Average();
-        var succDev = successful.StandardDeviation();
+        var succDev = successful.StandardDeviation() + 1e-7;
         successful.RemoveAll(x => x < succAvg - 2 * succDev);
         unsuccessful.RemoveAll(x => x < succAvg - 2 * succDev);
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVector.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVector.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVector.cs	(revision 14776)
@@ -0,0 +1,62 @@
+#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [StorableClass]
+  [Item("BinaryVector", "Represents a vector of binary values.")]
+  public class BinaryVector : BoolArray {
+    [StorableConstructor]
+    protected BinaryVector(bool deserializing) : base(deserializing) { }
+    protected BinaryVector(BinaryVector original, Cloner cloner) : base(original, cloner) { }
+    public BinaryVector() : base() { }
+    public BinaryVector(int length) : base(length) { }
+    public BinaryVector(int length, IRandom random)
+      : this(length) {
+      Randomize(random);
+    }
+    public BinaryVector(bool[] elements) : base(elements) { }
+    public BinaryVector(BoolArray elements)
+      : this(elements.Length) {
+      for (int i = 0; i < array.Length; i++)
+        array[i] = elements[i];
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BinaryVector(this, cloner);
+    }
+
+    public virtual void Randomize(IRandom random, int startIndex, int length) {
+      if (length > 0) {
+        for (int i = 0; i < length; i++)
+          array[startIndex + i] = random.Next(2) == 0;
+        OnReset();
+      }
+    }
+    public void Randomize(IRandom random) {
+      Randomize(random, 0, Length);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorCreator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorCreator.cs	(revision 14776)
@@ -0,0 +1,67 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// A base class for operators creating bool-valued vectors.
+  /// </summary>
+  [Item("BinaryVectorCreator", "A base class for operators creating bool-valued vectors.")]
+  [StorableClass]
+  public abstract class BinaryVectorCreator : InstrumentedOperator, IBinaryVectorCreator, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+    public IValueLookupParameter<IntValue> LengthParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["Length"]; }
+    }
+
+    [StorableConstructor]
+    protected BinaryVectorCreator(bool deserializing) : base(deserializing) { }
+    protected BinaryVectorCreator(BinaryVectorCreator original, Cloner cloner) : base(original, cloner) { }
+    protected BinaryVectorCreator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The vector which should be manipulated."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("Length", "The length of the vector."));
+    }
+
+    public sealed override IOperation InstrumentedApply() {
+      BinaryVectorParameter.ActualValue = Create(RandomParameter.ActualValue, LengthParameter.ActualValue);
+      return base.InstrumentedApply();
+    }
+
+    protected abstract BinaryVector Create(IRandom random, IntValue length);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorCrossover.cs	(revision 14776)
@@ -0,0 +1,68 @@
+#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// A base class for operators that perform a crossover of bool-valued vectors.
+  /// </summary>
+  [Item("BinaryVectorCrossover", "A base class for operators that perform a crossover of bool-valued vectors.")]
+  [StorableClass]
+  public abstract class BinaryVectorCrossover : InstrumentedOperator, IBinaryVectorCrossover, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<ItemArray<BinaryVector>> ParentsParameter {
+      get { return (ScopeTreeLookupParameter<BinaryVector>)Parameters["Parents"]; }
+    }
+    public ILookupParameter<BinaryVector> ChildParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["Child"]; }
+    }
+
+    [StorableConstructor]
+    protected BinaryVectorCrossover(bool deserializing) : base(deserializing) { }
+    protected BinaryVectorCrossover(BinaryVectorCrossover original, Cloner cloner) : base(original, cloner) { }
+    protected BinaryVectorCrossover()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic crossover operators."));
+      Parameters.Add(new ScopeTreeLookupParameter<BinaryVector>("Parents", "The parent vectors which should be crossed."));
+      ParentsParameter.ActualName = "BinaryVector";
+      Parameters.Add(new LookupParameter<BinaryVector>("Child", "The child vector resulting from the crossover."));
+      ChildParameter.ActualName = "BinaryVector";
+    }
+
+    public sealed override IOperation InstrumentedApply() {
+      ChildParameter.ActualValue = Cross(RandomParameter.ActualValue, ParentsParameter.ActualValue);
+      return base.InstrumentedApply();
+    }
+
+    protected abstract BinaryVector Cross(IRandom random, ItemArray<BinaryVector> parents);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorEncoding.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorEncoding.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorEncoding.cs	(revision 14776)
@@ -0,0 +1,179 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("BinaryVectorEncoding", "Describes a binary vector encoding.")]
+  [StorableClass]
+  public sealed class BinaryVectorEncoding : Encoding<IBinaryVectorCreator> {
+    #region Encoding Parameters
+    [Storable]
+    private IFixedValueParameter<IntValue> lengthParameter;
+    public IFixedValueParameter<IntValue> LengthParameter {
+      get { return lengthParameter; }
+      set {
+        if (value == null) throw new ArgumentNullException("Length parameter must not be null.");
+        if (value.Value == null) throw new ArgumentNullException("Length parameter value must not be null.");
+        if (lengthParameter == value) return;
+
+        if (lengthParameter != null) Parameters.Remove(lengthParameter);
+        lengthParameter = value;
+        Parameters.Add(lengthParameter);
+        OnLengthParameterChanged();
+      }
+    }
+    #endregion
+
+
+    public int Length {
+      get { return LengthParameter.Value.Value; }
+      set { LengthParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    private BinaryVectorEncoding(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+      DiscoverOperators();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new BinaryVectorEncoding(this, cloner); }
+    private BinaryVectorEncoding(BinaryVectorEncoding original, Cloner cloner)
+      : base(original, cloner) {
+      lengthParameter = cloner.Clone(original.lengthParameter);
+      RegisterParameterEvents();
+    }
+
+    public BinaryVectorEncoding() : this("BinaryVector", 10) { }
+    public BinaryVectorEncoding(string name) : this(name, 10) { }
+    public BinaryVectorEncoding(int length) : this("BinaryVector", length) { }
+    public BinaryVectorEncoding(string name, int length)
+      : base(name) {
+      lengthParameter = new FixedValueParameter<IntValue>(Name + ".Length", new IntValue(length));
+      Parameters.Add(lengthParameter);
+
+      SolutionCreator = new RandomBinaryVectorCreator();
+      RegisterParameterEvents();
+      DiscoverOperators();
+    }
+
+    private void OnLengthParameterChanged() {
+      RegisterLengthParameterEvents();
+      ConfigureOperators(Operators);
+    }
+    private void RegisterParameterEvents() {
+      RegisterLengthParameterEvents();
+    }
+    private void RegisterLengthParameterEvents() {
+      LengthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators);
+      LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
+    }
+
+    #region Operator Discovery
+    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
+    static BinaryVectorEncoding() {
+      encodingSpecificOperatorTypes = new List<Type>() {
+        typeof (IBinaryVectorOperator),
+        typeof (IBinaryVectorCreator),
+        typeof (IBinaryVectorCrossover),
+        typeof (IBinaryVectorManipulator),
+        typeof (IBinaryVectorMoveOperator),
+        typeof (IBinaryVectorMultiNeighborhoodShakingOperator),
+      };
+    }
+    private void DiscoverOperators() {
+      var assembly = typeof(IBinaryVectorOperator).Assembly;
+      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, assembly, true, false, false);
+      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
+      var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
+
+      ConfigureOperators(newOperators);
+      foreach (var @operator in newOperators)
+        AddOperator(@operator);
+    }
+    #endregion
+
+    public override void ConfigureOperators(IEnumerable<IOperator> operators) {
+      ConfigureCreators(operators.OfType<IBinaryVectorCreator>());
+      ConfigureCrossovers(operators.OfType<IBinaryVectorCrossover>());
+      ConfigureManipulators(operators.OfType<IBinaryVectorManipulator>());
+      ConfigureMoveOperators(operators.OfType<IBinaryVectorMoveOperator>());
+      ConfigureBitFlipMoveOperators(operators.OfType<IOneBitflipMoveOperator>());
+      ConfigureShakingOperators(operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>());
+    }
+
+    #region Specific Operator Wiring
+    private void ConfigureCreators(IEnumerable<IBinaryVectorCreator> creators) {
+      foreach (var creator in creators) {
+        creator.BinaryVectorParameter.ActualName = Name;
+        creator.LengthParameter.ActualName = LengthParameter.Name;
+      }
+    }
+    private void ConfigureCrossovers(IEnumerable<IBinaryVectorCrossover> crossovers) {
+      foreach (var crossover in crossovers) {
+        crossover.ParentsParameter.ActualName = Name;
+        crossover.ChildParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureManipulators(IEnumerable<IBinaryVectorManipulator> manipulators) {
+      foreach (var manipulator in manipulators) {
+        manipulator.BinaryVectorParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureMoveOperators(IEnumerable<IBinaryVectorMoveOperator> moveOperators) {
+      foreach (var moveOperator in moveOperators) {
+        moveOperator.BinaryVectorParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureBitFlipMoveOperators(IEnumerable<IOneBitflipMoveOperator> oneBitflipMoveOperators) {
+      foreach (var oneBitFlipMoveOperator in oneBitflipMoveOperators) {
+        oneBitFlipMoveOperator.OneBitflipMoveParameter.ActualName = Name + "_OneBitFlipMove";
+      }
+    }
+    private void ConfigureShakingOperators(IEnumerable<IBinaryVectorMultiNeighborhoodShakingOperator> shakingOperators) {
+      foreach (var shakingOperator in shakingOperators) {
+        shakingOperator.BinaryVectorParameter.ActualName = Name;
+      }
+    }
+    #endregion
+  }
+
+  public static class IndividualExtensionMethods {
+    public static BinaryVector BinaryVector(this Individual individual) {
+      var encoding = individual.GetEncoding<BinaryVectorEncoding>();
+      return individual.BinaryVector(encoding.Name);
+    }
+
+    public static BinaryVector BinaryVector(this Individual individual, string name) {
+      return (BinaryVector)individual[name];
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorEqualityComparer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorEqualityComparer.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorEqualityComparer.cs	(revision 14776)
@@ -0,0 +1,40 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+ 
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  public class BinaryVectorEqualityComparer : EqualityComparer<BinaryVector> {
+    public override bool Equals(BinaryVector first, BinaryVector second) {
+      return first.SequenceEqual(second);
+    }
+    public override int GetHashCode(BinaryVector obj) {
+      unchecked {
+        int hash = 17;
+        foreach (var bit in obj) {
+          hash = hash * 29 + (bit ? 1231 : 1237);
+        }
+        return hash;
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorManipulator.cs	(revision 14776)
@@ -0,0 +1,62 @@
+#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// A base class for operators that manipulate bool-valued vectors.
+  /// </summary>
+  [Item("BinaryVectorManipulator", "A base class for operators that manipulate bool-valued vectors.")]
+  [StorableClass]
+  public abstract class BinaryVectorManipulator : InstrumentedOperator, IBinaryVectorManipulator, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+
+    [StorableConstructor]
+    protected BinaryVectorManipulator(bool deserializing) : base(deserializing) { }
+    protected BinaryVectorManipulator(BinaryVectorManipulator original, Cloner cloner) : base(original, cloner) { }
+    protected BinaryVectorManipulator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The vector which should be manipulated."));
+    }
+
+    public sealed override IOperation InstrumentedApply() {
+      Manipulate(RandomParameter.ActualValue, BinaryVectorParameter.ActualValue);
+      return base.InstrumentedApply();
+    }
+
+    protected abstract void Manipulate(IRandom random, BinaryVector binaryVector);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Creators/RandomBinaryVectorCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Creators/RandomBinaryVectorCreator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Creators/RandomBinaryVectorCreator.cs	(revision 14776)
@@ -0,0 +1,99 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// Generates a new random binary vector with each element randomly initialized.
+  /// </summary>
+  [Item("RandomBinaryVectorCreator", "An operator which creates a new random binary vector with each element randomly initialized.")]
+  [StorableClass]
+  public sealed class RandomBinaryVectorCreator : BinaryVectorCreator {
+    private const string TrueProbabilityParameterName = "TrueProbability";
+
+    private IValueLookupParameter<DoubleValue> TrueProbabilityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[TrueProbabilityParameterName]; }
+    }
+
+    public DoubleValue TrueProbability {
+      get { return TrueProbabilityParameter.Value; }
+      set { TrueProbabilityParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    private RandomBinaryVectorCreator(bool deserializing) : base(deserializing) { }
+    private RandomBinaryVectorCreator(RandomBinaryVectorCreator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new RandomBinaryVectorCreator(this, cloner); }
+    public RandomBinaryVectorCreator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(TrueProbabilityParameterName, "Probability of true value", new DoubleValue(0.5)));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      var defaultValue = 0.5;
+      const string parameterNameWithTypo = "TruePropability";
+      if (Parameters.ContainsKey(parameterNameWithTypo) && Parameters[parameterNameWithTypo] is IValueParameter<DoubleValue>) {
+        defaultValue = ((IValueParameter<DoubleValue>)Parameters[parameterNameWithTypo]).Value.Value;
+        Parameters.Remove(parameterNameWithTypo);
+      }
+      if (!Parameters.ContainsKey(TrueProbabilityParameterName))
+        Parameters.Add(new ValueLookupParameter<DoubleValue>(TrueProbabilityParameterName, "Probability of true value", new DoubleValue(defaultValue)));
+      #endregion
+    }
+
+    /// <summary>
+    /// Generates a new random binary vector with the given <paramref name="length"/>.
+    /// </summary>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="length">The length of the binary vector.</param>
+    /// <param name="trueProbability">The propability for true to occur at a certain position in the binary vector</param>
+    /// <returns>The newly created binary vector.</returns>
+    public static BinaryVector Apply(IRandom random, int length, double trueProbability = 0.5) {
+      BinaryVector result;
+
+      //Backwards compatiblity code to ensure the same behavior for existing algorithm runs
+      //remove with HL 3.4
+      if (trueProbability.IsAlmost(0.5))
+        result = new BinaryVector(length, random);
+      else {
+        var values = new bool[length];
+        for (int i = 0; i < length; i++)
+          values[i] = random.NextDouble() < trueProbability;
+        result = new BinaryVector(values);
+      }
+      return result;
+    }
+
+    protected override BinaryVector Create(IRandom random, IntValue length) {
+      if (TrueProbabilityParameter.ActualValue == null) throw new InvalidOperationException("RandomBinaryVectorCreator: Parameter " + TrueProbabilityParameter.ActualName + " could not be found.");
+      return Apply(random, length.Value, TrueProbabilityParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/MultiBinaryVectorCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/MultiBinaryVectorCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/MultiBinaryVectorCrossover.cs	(revision 14776)
@@ -0,0 +1,99 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("MultiBinaryVectorCrossover", "Randomly selects and applies one of its crossovers every time it is called.")]
+  [StorableClass]
+  public class MultiBinaryVectorCrossover : StochasticMultiBranch<IBinaryVectorCrossover>, IBinaryVectorCrossover, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+
+    public ILookupParameter<ItemArray<BinaryVector>> ParentsParameter {
+      get { return (ILookupParameter<ItemArray<BinaryVector>>)Parameters["Parents"]; }
+    }
+
+    public ILookupParameter<BinaryVector> ChildParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["Child"]; }
+    }
+
+    [StorableConstructor]
+    protected MultiBinaryVectorCrossover(bool deserializing) : base(deserializing) { }
+    protected MultiBinaryVectorCrossover(MultiBinaryVectorCrossover original, Cloner cloner) : base(original, cloner) { }
+    public MultiBinaryVectorCrossover()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<BinaryVector>("Parents", "The parent binary vector which should be crossed."));
+      ParentsParameter.ActualName = "BinaryVector";
+      Parameters.Add(new LookupParameter<BinaryVector>("Child", "The child binary vector resulting from the crossover."));
+      ChildParameter.ActualName = "BinaryVector";
+
+      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IBinaryVectorCrossover))) {
+        if (!typeof(MultiOperator<IBinaryVectorCrossover>).IsAssignableFrom(type))
+          Operators.Add((IBinaryVectorCrossover)Activator.CreateInstance(type), true);
+      }
+
+      SelectedOperatorParameter.ActualName = "SelectedCrossoverOperator";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiBinaryVectorCrossover(this, cloner);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IBinaryVectorCrossover>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeCrossovers();
+    }
+
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IBinaryVectorCrossover>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeCrossovers();
+    }
+
+    private void ParameterizeCrossovers() {
+      foreach (IBinaryVectorCrossover crossover in Operators.OfType<IBinaryVectorCrossover>()) {
+        crossover.ChildParameter.ActualName = ChildParameter.Name;
+        crossover.ParentsParameter.ActualName = ParentsParameter.Name;
+      }
+      foreach (IStochasticOperator crossover in Operators.OfType<IStochasticOperator>()) {
+        crossover.RandomParameter.ActualName = RandomParameter.Name;
+      }
+    }
+
+    public override IOperation InstrumentedApply() {
+      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one binary vector crossover to choose from.");
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/NPointCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/NPointCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/NPointCrossover.cs	(revision 14776)
@@ -0,0 +1,142 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// N point crossover for binary vectors.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Eiben, A.E. and Smith, J.E. 2003. Introduction to Evolutionary Computation. Natural Computing Series, Springer-Verlag Berlin Heidelberg..
+  /// </remarks>
+  [Item("NPointCrossover", "N point crossover for binary vectors. It is implemented as described in Eiben, A.E. and Smith, J.E. 2003. Introduction to Evolutionary Computation. Natural Computing Series, Springer-Verlag Berlin Heidelberg.")]
+  [StorableClass]
+  public sealed class NPointCrossover : BinaryVectorCrossover {
+    /// <summary>
+    /// Number of crossover points.
+    /// </summary>
+    public IValueLookupParameter<IntValue> NParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["N"]; }
+    }
+
+    [StorableConstructor]
+    private NPointCrossover(bool deserializing) : base(deserializing) { }
+    private NPointCrossover(NPointCrossover original, Cloner cloner) : base(original, cloner) { }
+    /// <summary>
+    /// Initializes a new instance of <see cref="NPointCrossover"/>
+    /// </summary>
+    public NPointCrossover()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("N", "Number of crossover points", new IntValue(2)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NPointCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs a N point crossover at randomly chosen positions of the two 
+    /// given parent binary vectors.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when the value for N is invalid or when the parent vectors are of different length.</exception>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parent1">The first parent for crossover.</param>
+    /// <param name="parent2">The second parent for crossover.</param>
+    /// <param name="n">Number of crossover points.</param>
+    /// <returns>The newly created binary vector, resulting from the N point crossover.</returns>
+    public static BinaryVector Apply(IRandom random, BinaryVector parent1, BinaryVector parent2, IntValue n) {
+      if (parent1.Length != parent2.Length)
+        throw new ArgumentException("NPointCrossover: The parents are of different length.");
+
+      if (n.Value > parent1.Length)
+        throw new ArgumentException("NPointCrossover: There cannot be more breakpoints than the size of the parents.");
+
+      if (n.Value < 1)
+        throw new ArgumentException("NPointCrossover: N cannot be < 1.");
+
+      int length = parent1.Length;
+      bool[] result = new bool[length];
+      int[] breakpoints = new int[n.Value];
+
+      //choose break points
+      List<int> breakpointPool = new List<int>();
+
+      for (int i = 0; i < length; i++)
+        breakpointPool.Add(i);
+
+      for (int i = 0; i < n.Value; i++) {
+        int index = random.Next(breakpointPool.Count);
+        breakpoints[i] = breakpointPool[index];
+        breakpointPool.RemoveAt(index);
+      }
+
+      Array.Sort(breakpoints);
+
+      //perform crossover
+      int arrayIndex = 0;
+      int breakPointIndex = 0;
+      bool firstParent = true;
+
+      while (arrayIndex < length) {
+        if (breakPointIndex < breakpoints.Length &&
+          arrayIndex == breakpoints[breakPointIndex]) {
+          breakPointIndex++;
+          firstParent = !firstParent;
+        }
+
+        if (firstParent)
+          result[arrayIndex] = parent1[arrayIndex];
+        else
+          result[arrayIndex] = parent2[arrayIndex];
+
+        arrayIndex++;
+      }
+
+      return new BinaryVector(result);
+    }
+
+    /// <summary>
+    /// Performs a N point crossover at a randomly chosen position of two 
+    /// given parent binary vectors.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown if there are not exactly two parents.</exception>
+    /// <exception cref="InvalidOperationException">
+    /// Thrown when the N parameter could not be found.</description></item>
+    /// </exception>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parents">An array containing the two binary vectors that should be crossed.</param>
+    /// <returns>The newly created binary vector, resulting from the N point crossover.</returns>
+    protected override BinaryVector Cross(IRandom random, ItemArray<BinaryVector> parents) {
+      if (parents.Length != 2) throw new ArgumentException("ERROR in NPointCrossover: The number of parents is not equal to 2");
+
+      if (NParameter.ActualValue == null) throw new InvalidOperationException("NPointCrossover: Parameter " + NParameter.ActualName + " could not be found.");
+
+      return Apply(random, parents[0], parents[1], NParameter.ActualValue);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/SinglePointCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/SinglePointCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/SinglePointCrossover.cs	(revision 14776)
@@ -0,0 +1,62 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// Single point crossover for binary vectors.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented based on the NPointCrossover
+  /// </remarks>
+  [Item("SinglePointCrossover", "Single point crossover for binary vectors. It is implemented based on the NPointCrossover.")]
+  [StorableClass]
+  public sealed class SinglePointCrossover : BinaryVectorCrossover {
+
+    [StorableConstructor]
+    private SinglePointCrossover(bool deserializing) : base(deserializing) { }
+    private SinglePointCrossover(SinglePointCrossover original, Cloner cloner) : base(original, cloner) { }
+    public SinglePointCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SinglePointCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs a single point crossover at a randomly chosen position of two 
+    /// given parent binary vectors.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown if there are not exactly two parents.</exception>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parents">An array containing the two binary vectors that should be crossed.</param>
+    /// <returns>The newly created binary vector, resulting from the single point crossover.</returns>
+    protected override BinaryVector Cross(IRandom random, ItemArray<BinaryVector> parents) {
+      if (parents.Length != 2) throw new ArgumentException("ERROR in SinglePointCrossover: The number of parents is not equal to 2");
+
+      return NPointCrossover.Apply(random, parents[0], parents[1], new IntValue(1));
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/UniformCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/UniformCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Crossovers/UniformCrossover.cs	(revision 14776)
@@ -0,0 +1,85 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// Uniform crossover for binary vectors.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Eiben, A.E. and Smith, J.E. 2003. Introduction to Evolutionary Computation. Natural Computing Series, Springer-Verlag Berlin Heidelberg.
+  /// </remarks>
+  [Item("UniformCrossover", "Uniform crossover for binary vectors. It is implemented as described in Eiben, A.E. and Smith, J.E. 2003. Introduction to Evolutionary Computation. Natural Computing Series, Springer-Verlag Berlin Heidelberg.")]
+  [StorableClass]
+  public sealed class UniformCrossover : BinaryVectorCrossover {
+
+    [StorableConstructor]
+    private UniformCrossover(bool deserializing) : base(deserializing) { }
+    private UniformCrossover(UniformCrossover original, Cloner cloner) : base(original, cloner) { }
+    public UniformCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UniformCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs a uniform crossover between two binary vectors.
+    /// </summary>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parent1">The first parent for crossover.</param>
+    /// <param name="parent2">The second parent for crossover.</param>
+    /// <returns>The newly created binary vector, resulting from the uniform crossover.</returns>
+    public static BinaryVector Apply(IRandom random, BinaryVector parent1, BinaryVector parent2) {
+      if (parent1.Length != parent2.Length)
+        throw new ArgumentException("UniformCrossover: The parents are of different length.");
+
+      int length = parent1.Length;
+      bool[] result = new bool[length];
+
+      for (int i = 0; i < length; i++) {
+        if (random.NextDouble() < 0.5)
+          result[i] = parent1[i];
+        else
+          result[i] = parent2[i];
+      }
+
+      return new BinaryVector(result);
+    }
+
+    /// <summary>
+    /// Performs a uniform crossover at a randomly chosen position of two 
+    /// given parent binary vectors.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown if there are not exactly two parents.</exception>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parents">An array containing the two binary vectors that should be crossed.</param>
+    /// <returns>The newly created binary vector, resulting from the uniform crossover.</returns>
+    protected override BinaryVector Cross(IRandom random, ItemArray<BinaryVector> parents) {
+      if (parents.Length != 2) throw new ArgumentException("ERROR in UniformCrossover: The number of parents is not equal to 2");
+
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj	(revision 14776)
@@ -0,0 +1,244 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{66D249C3-A01D-42A8-82A2-919BC8EC3D83}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Encodings.BinaryVectorEncoding</RootNamespace>
+    <AssemblyName>HeuristicLab.Encodings.BinaryVectorEncoding-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Operators-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BinaryVectorEncoding.cs" />
+    <Compile Include="BinaryVectorEqualityComparer.cs" />
+    <Compile Include="Creators\RandomBinaryVectorCreator.cs" />
+    <Compile Include="Crossovers\MultiBinaryVectorCrossover.cs" />
+    <Compile Include="Crossovers\UniformCrossover.cs" />
+    <Compile Include="Crossovers\SinglePointCrossover.cs" />
+    <Compile Include="Crossovers\NPointCrossover.cs" />
+    <Compile Include="BinaryVector.cs" />
+    <Compile Include="SimilarityCalculators\HammingSimilarityCalculator.cs" />
+    <Compile Include="Interfaces\IBinaryVectorMultiNeighborhoodShakingOperator.cs" />
+    <Compile Include="Interfaces\IOneBitflipMoveOperator.cs" />
+    <Compile Include="Interfaces\IBinaryVectorCreator.cs" />
+    <Compile Include="Interfaces\IBinaryVectorCrossover.cs" />
+    <Compile Include="Interfaces\IBinaryVectorManipulator.cs" />
+    <Compile Include="Interfaces\IBinaryVectorOperator.cs" />
+    <Compile Include="BinaryVectorCreator.cs" />
+    <Compile Include="BinaryVectorCrossover.cs" />
+    <Compile Include="BinaryVectorManipulator.cs" />
+    <Compile Include="Interfaces\IBinaryVectorMoveOperator.cs" />
+    <Compile Include="Manipulators\SomePositionsBitflipManipulator.cs" />
+    <Compile Include="Manipulators\SinglePositionBitflipManipulator.cs" />
+    <Compile Include="Moves\OneBitflipMove\ExhaustiveOneBitflipMoveGenerator.cs" />
+    <Compile Include="Moves\OneBitflipMove\OneBitflipMove.cs" />
+    <Compile Include="Moves\OneBitflipMove\OneBitflipMoveGenerator.cs" />
+    <Compile Include="Moves\OneBitflipMove\OneBitflipMoveMaker.cs" />
+    <Compile Include="Moves\OneBitflipMove\OneBitflipMoveTabuChecker.cs" />
+    <Compile Include="Moves\OneBitflipMove\OneBitflipMoveTabuMaker.cs" />
+    <Compile Include="Moves\OneBitflipMove\OneBitflipMoveAttribute.cs" />
+    <Compile Include="Moves\OneBitflipMove\StochasticOneBitflipMultiMoveGenerator.cs" />
+    <Compile Include="Moves\OneBitflipMove\StochasticOneBitflipSingleMoveGenerator.cs" />
+    <Compile Include="Moves\OneIndexMove.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShakingOperators\BinaryVectorShakingOperator.cs" />
+    <Compile Include="SolutionModel\Univariate\UnivariateModelTrainer.cs" />
+    <Compile Include="SolutionModel\Univariate\UnivariateModel.cs" />
+    <Compile Include="SolutionModel\SolutionSamplingOperator.cs" />
+    <Compile Include="SolutionModel\Univariate\UnivariateModelTrainingOperator.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorCreator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorCreator.cs	(revision 14776)
@@ -0,0 +1,34 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// An interface which represents an operator for creating vectors of bool-valued data.
+  /// </summary>
+  public interface IBinaryVectorCreator : IBinaryVectorOperator, ISolutionCreator {
+    IValueLookupParameter<IntValue> LengthParameter { get; }
+    ILookupParameter<BinaryVector> BinaryVectorParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorCrossover.cs	(revision 14776)
@@ -0,0 +1,33 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// An interface which represents an operator for crossing vectors of bool-valued data.
+  /// </summary>
+  public interface IBinaryVectorCrossover : IBinaryVectorOperator, ICrossover {
+    ILookupParameter<ItemArray<BinaryVector>> ParentsParameter { get; }
+    ILookupParameter<BinaryVector> ChildParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorManipulator.cs	(revision 14776)
@@ -0,0 +1,32 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// An interface which represents an operator for manipulating vectors of bool-valued data.
+  /// </summary>
+  public interface IBinaryVectorManipulator : IBinaryVectorOperator, IManipulator {
+    ILookupParameter<BinaryVector> BinaryVectorParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorMoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorMoveOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorMoveOperator.cs	(revision 14776)
@@ -0,0 +1,29 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  public interface IBinaryVectorMoveOperator : IBinaryVectorOperator, IMoveOperator {
+    ILookupParameter<BinaryVector> BinaryVectorParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorMultiNeighborhoodShakingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorMultiNeighborhoodShakingOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorMultiNeighborhoodShakingOperator.cs	(revision 14776)
@@ -0,0 +1,28 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  public interface IBinaryVectorMultiNeighborhoodShakingOperator : IBinaryVectorOperator {
+    ILookupParameter<BinaryVector> BinaryVectorParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorOperator.cs	(revision 14776)
@@ -0,0 +1,29 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// An interface which represents an operator dealing with vectors of bool-valued data.
+  /// </summary>
+  public interface IBinaryVectorOperator : IOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IOneBitflipMoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IOneBitflipMoveOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IOneBitflipMoveOperator.cs	(revision 14776)
@@ -0,0 +1,28 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  public interface IOneBitflipMoveOperator : IBinaryVectorMoveOperator {
+    ILookupParameter<OneBitflipMove> OneBitflipMoveParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Manipulators/SinglePositionBitflipManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Manipulators/SinglePositionBitflipManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Manipulators/SinglePositionBitflipManipulator.cs	(revision 14776)
@@ -0,0 +1,66 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// Flips exactly one bit of a binary vector.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Michalewicz, Z. 1999. Genetic Algorithms + Data Structures = Evolution Programs. Third, Revised and Extended Edition, Spring-Verlag Berlin Heidelberg.
+  /// </remarks>
+  [Item("SinglePositionBitflipManipulator", "Flips exactly one bit of a binary vector. It is implemented as described in Michalewicz, Z. 1999. Genetic Algorithms + Data Structures = Evolution Programs. Third, Revised and Extended Edition, Spring-Verlag Berlin Heidelberg.")]
+  [StorableClass]
+  public sealed class SinglePositionBitflipManipulator : BinaryVectorManipulator {
+
+    [StorableConstructor]
+    private SinglePositionBitflipManipulator(bool deserializing) : base(deserializing) { }
+    private SinglePositionBitflipManipulator(SinglePositionBitflipManipulator original, Cloner cloner) : base(original, cloner) { }
+    public SinglePositionBitflipManipulator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SinglePositionBitflipManipulator(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs the single position bitflip mutation on a binary vector.
+    /// </summary>
+    /// <param name="random">The random number generator to use.</param>
+    /// <param name="vector">The vector that should be manipulated.</param>
+    public static void Apply(IRandom random, BinaryVector vector) {
+      int position = random.Next(vector.Length);
+
+      vector[position] = !vector[position];
+    }
+
+    /// <summary>
+    /// Forwards the call to <see cref="Apply(IRandom, BinaryVector)"/>.
+    /// </summary>
+    /// <param name="random">The random number generator to use.</param>
+    /// <param name="realVector">The vector of binary values to manipulate.</param>
+    protected override void Manipulate(IRandom random, BinaryVector binaryVector) {
+      Apply(random, binaryVector);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Manipulators/SomePositionsBitflipManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Manipulators/SomePositionsBitflipManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Manipulators/SomePositionsBitflipManipulator.cs	(revision 14776)
@@ -0,0 +1,85 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// Flips some bits of a binary vector.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Eiben, A.E. and Smith, J.E. 2003. Introduction to Evolutionary Computation. Natural Computing Series, Springer-Verlag Berlin Heidelberg, p. 43.
+  /// </remarks>
+  [Item("SomePositionsBitflipManipulator", "Flips some bits of a binary vector, each position is flipped with a probability of pm. It is implemented as described in Eiben, A.E. and Smith, J.E. 2003. Introduction to Evolutionary Computation. Natural Computing Series, Springer-Verlag Berlin Heidelberg, p. 43.")]
+  [StorableClass]
+  public sealed class SomePositionsBitflipManipulator : BinaryVectorManipulator {
+    /// <summary>
+    /// Mmutation probability for each position.
+    /// </summary>
+    public IValueLookupParameter<DoubleValue> MutationProbabilityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["MutationProbability"]; }
+    }
+
+    [StorableConstructor]
+    private SomePositionsBitflipManipulator(bool deserializing) : base(deserializing) { }
+    private SomePositionsBitflipManipulator(SomePositionsBitflipManipulator original, Cloner cloner) : base(original, cloner) { }
+    /// <summary>
+    /// Initializes a new instance of <see cref="NPointCrossover"/>
+    /// </summary>
+    public SomePositionsBitflipManipulator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MutationProbability", "The mutation probability for each position", new DoubleValue(0.2)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SomePositionsBitflipManipulator(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs the some positions bitflip mutation on a binary vector.
+    /// </summary>
+    /// <param name="random">The random number generator to use.</param>
+    /// <param name="vector">The vector that should be manipulated.</param>
+    /// <param name="pm">The probability a bit is flipped.</param>
+    public static void Apply(IRandom random, BinaryVector vector, DoubleValue pm) {
+      for (int i = 0; i < vector.Length; i++) {
+        if (random.NextDouble() < pm.Value) {
+          vector[i] = !vector[i];
+        }
+      }
+    }
+
+    /// <summary>
+    /// Forwards the call to <see cref="Apply(IRandom, BinaryVector)"/>.
+    /// </summary>
+    /// <param name="random">The random number generator to use.</param>
+    /// <param name="realVector">The vector of binary values to manipulate.</param>
+    protected override void Manipulate(IRandom random, BinaryVector binaryVector) {
+      if (MutationProbabilityParameter.ActualValue == null) throw new InvalidOperationException("SomePositionsBitflipManipulator: Parameter " + MutationProbabilityParameter.ActualName + " could not be found.");
+      Apply(random, binaryVector, MutationProbabilityParameter.ActualValue);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/ExhaustiveOneBitflipMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/ExhaustiveOneBitflipMoveGenerator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/ExhaustiveOneBitflipMoveGenerator.cs	(revision 14776)
@@ -0,0 +1,54 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("ExhaustiveBitflipMoveGenerator", "Generates all possible one bitflip moves from a given binaryVector.")]
+  [StorableClass]
+  public sealed class ExhaustiveOneBitflipMoveGenerator : OneBitflipMoveGenerator, IExhaustiveMoveGenerator {
+    [StorableConstructor]
+    private ExhaustiveOneBitflipMoveGenerator(bool deserializing) : base(deserializing) { }
+    private ExhaustiveOneBitflipMoveGenerator(ExhaustiveOneBitflipMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public ExhaustiveOneBitflipMoveGenerator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExhaustiveOneBitflipMoveGenerator(this, cloner);
+    }
+
+    public static OneBitflipMove[] Apply(BinaryVector binaryVector) {
+      int length = binaryVector.Length;
+      int totalMoves = length;
+      OneBitflipMove[] moves = new OneBitflipMove[totalMoves];
+      for (int i = 0; i < length; i++)
+        moves[i] = new OneBitflipMove(i);
+
+      return moves;
+    }
+
+    protected override OneBitflipMove[] GenerateMoves(BinaryVector binaryVector) {
+      return Apply(binaryVector);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMove.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMove.cs	(revision 14776)
@@ -0,0 +1,41 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("OneBitflipMove", "Item that describes a one bitflip move.")]
+  [StorableClass]
+  public class OneBitflipMove : OneIndexMove {
+    [StorableConstructor]
+    protected OneBitflipMove(bool deserializing) : base(deserializing) { }
+    protected OneBitflipMove(OneBitflipMove original, Cloner cloner) : base(original, cloner) { }
+    public OneBitflipMove() : base() { }
+    public OneBitflipMove(int index) : this(index, null) { }
+    public OneBitflipMove(int index, BinaryVector binaryVector) : base(index, binaryVector) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OneBitflipMove(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveAttribute.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveAttribute.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveAttribute.cs	(revision 14776)
@@ -0,0 +1,53 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("OneBitflipMoveAttribute", "Describes the attributes (move quality and index) of a single bitflip move.")]
+  [StorableClass]
+  public class OneBitflipMoveAttribute : Item {
+    [Storable]
+    public double MoveQuality { get; protected set; }
+    [Storable]
+    public int Index { get; protected set; }
+
+    [StorableConstructor]
+    protected OneBitflipMoveAttribute(bool deserializing) : base(deserializing) { }
+    protected OneBitflipMoveAttribute(OneBitflipMoveAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.MoveQuality = original.MoveQuality;
+      this.Index = original.Index;
+    }
+    public OneBitflipMoveAttribute() : this(-1, 0) { }
+    public OneBitflipMoveAttribute(int index, double moveQuality)
+      : base() {
+      Index = index;
+      MoveQuality = moveQuality;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OneBitflipMoveAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveGenerator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveGenerator.cs	(revision 14776)
@@ -0,0 +1,70 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("OneBitflipMoveGenerator", "Base class for all one bitflip move generators.")]
+  [StorableClass]
+  public abstract class OneBitflipMoveGenerator : SingleSuccessorOperator, IOneBitflipMoveOperator, IMoveGenerator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+    public ILookupParameter<OneBitflipMove> OneBitflipMoveParameter {
+      get { return (LookupParameter<OneBitflipMove>)Parameters["OneBitflipMove"]; }
+    }
+    protected ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+
+    [StorableConstructor]
+    protected OneBitflipMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected OneBitflipMoveGenerator(OneBitflipMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public OneBitflipMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The BinaryVector for which moves should be generated."));
+      Parameters.Add(new LookupParameter<OneBitflipMove>("OneBitflipMove", "The moves that should be generated in subscopes."));
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope where the moves should be added as subscopes."));
+    }
+
+    public override IOperation Apply() {
+      BinaryVector v = BinaryVectorParameter.ActualValue;
+      OneBitflipMove[] moves = GenerateMoves(v);
+      Scope[] moveScopes = new Scope[moves.Length];
+      for (int i = 0; i < moveScopes.Length; i++) {
+        moveScopes[i] = new Scope(i.ToString());
+        moveScopes[i].Variables.Add(new Variable(OneBitflipMoveParameter.ActualName, moves[i]));
+      }
+      CurrentScopeParameter.ActualValue.SubScopes.AddRange(moveScopes);
+      return base.Apply();
+    }
+
+    protected abstract OneBitflipMove[] GenerateMoves(BinaryVector binaryVector);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveMaker.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveMaker.cs	(revision 14776)
@@ -0,0 +1,78 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("OneBitflipMoveMaker", "Peforms a one bitflip move on a given BitVector and updates the quality.")]
+  [StorableClass]
+  public class OneBitflipMoveMaker : SingleSuccessorOperator, IOneBitflipMoveOperator, IMoveMaker, ISingleObjectiveOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ILookupParameter<OneBitflipMove> OneBitflipMoveParameter {
+      get { return (ILookupParameter<OneBitflipMove>)Parameters["OneBitflipMove"]; }
+    }
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+
+    [StorableConstructor]
+    protected OneBitflipMoveMaker(bool deserializing) : base(deserializing) { }
+    protected OneBitflipMoveMaker(OneBitflipMoveMaker original, Cloner cloner) : base(original, cloner) { }
+    public OneBitflipMoveMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
+      Parameters.Add(new LookupParameter<OneBitflipMove>("OneBitflipMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The solution as BinaryVector."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OneBitflipMoveMaker(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      OneBitflipMove move = OneBitflipMoveParameter.ActualValue;
+      BinaryVector binaryVector = BinaryVectorParameter.ActualValue;
+      DoubleValue moveQuality = MoveQualityParameter.ActualValue;
+      DoubleValue quality = QualityParameter.ActualValue;
+
+      binaryVector[move.Index] = !binaryVector[move.Index];
+
+      quality.Value = moveQuality.Value;
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveTabuChecker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveTabuChecker.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveTabuChecker.cs	(revision 14776)
@@ -0,0 +1,106 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("OneBitflipMoveTabuChecker", "Prevents peforming a one bitflip move again.")]
+  [StorableClass]
+  public class OneBitflipMoveTabuChecker : SingleSuccessorOperator, IOneBitflipMoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<OneBitflipMove> OneBitflipMoveParameter {
+      get { return (LookupParameter<OneBitflipMove>)Parameters["OneBitflipMove"]; }
+    }
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (LookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+    public ILookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (ILookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public ILookupParameter<BoolValue> MoveTabuParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["MoveTabu"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ValueParameter<BoolValue> UseAspirationCriterionParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["UseAspirationCriterion"]; }
+    }
+
+    public BoolValue UseAspirationCriterion {
+      get { return UseAspirationCriterionParameter.Value; }
+      set { UseAspirationCriterionParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected OneBitflipMoveTabuChecker(bool deserializing) : base(deserializing) { }
+    protected OneBitflipMoveTabuChecker(OneBitflipMoveTabuChecker original, Cloner cloner) : base(original, cloner) { }
+    public OneBitflipMoveTabuChecker()
+      : base() {
+      Parameters.Add(new LookupParameter<OneBitflipMove>("OneBitflipMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
+      Parameters.Add(new ValueParameter<BoolValue>("UseAspirationCriterion", "Whether to use the aspiration criterion or not.", new BoolValue(true)));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the current move."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OneBitflipMoveTabuChecker(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      OneBitflipMove move = OneBitflipMoveParameter.ActualValue;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool isTabu = false;
+      foreach (IItem tabuMove in tabuList) {
+        OneBitflipMoveAttribute attribute = (tabuMove as OneBitflipMoveAttribute);
+        if (attribute != null) {
+          if (!useAspiration
+            || maximization && moveQuality <= attribute.MoveQuality
+            || !maximization && moveQuality >= attribute.MoveQuality) {
+            if (attribute.Index == move.Index) {
+              isTabu = true;
+              break;
+            }
+          }
+        }
+      }
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveTabuMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveTabuMaker.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveTabuMaker.cs	(revision 14776)
@@ -0,0 +1,58 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("OneBitflipMoveTabuMaker", "Declares a given one bitflip move as tabu, by adding its attributes to the tabu list. It also removes the oldest entry in the tabu list when its size is greater than tenure.")]
+  [StorableClass]
+  public class OneBitflipMoveTabuMaker : TabuMaker, IOneBitflipMoveOperator {
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+    public ILookupParameter<OneBitflipMove> OneBitflipMoveParameter {
+      get { return (LookupParameter<OneBitflipMove>)Parameters["OneBitflipMove"]; }
+    }
+
+    [StorableConstructor]
+    protected OneBitflipMoveTabuMaker(bool deserializing) : base(deserializing) { }
+    protected OneBitflipMoveTabuMaker(OneBitflipMoveTabuMaker original, Cloner cloner) : base(original, cloner) { }
+    public OneBitflipMoveTabuMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The solution as BinaryVector."));
+      Parameters.Add(new LookupParameter<OneBitflipMove>("OneBitflipMove", "The move that was made."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OneBitflipMoveTabuMaker(this, cloner);
+    }
+
+    protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality) {
+      double baseQuality = moveQuality;
+      if (maximization && quality > moveQuality || !maximization && quality < moveQuality) baseQuality = quality;
+      return new OneBitflipMoveAttribute(OneBitflipMoveParameter.ActualValue.Index, baseQuality);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/StochasticOneBitflipMultiMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/StochasticOneBitflipMultiMoveGenerator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/StochasticOneBitflipMultiMoveGenerator.cs	(revision 14776)
@@ -0,0 +1,73 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("StochasticOneBitflipMultiMoveGenerator", "Randomly samples n from all possible one bitflip moves from a given BinaryVector.")]
+  [StorableClass]
+  public class StochasticOneBitflipMultiMoveGenerator : OneBitflipMoveGenerator, IStochasticOperator, IMultiMoveGenerator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    public IntValue SampleSize {
+      get { return SampleSizeParameter.Value; }
+      set { SampleSizeParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected StochasticOneBitflipMultiMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticOneBitflipMultiMoveGenerator(StochasticOneBitflipMultiMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticOneBitflipMultiMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticOneBitflipMultiMoveGenerator(this, cloner);
+    }
+
+    public static OneBitflipMove[] Apply(BinaryVector binaryVector, IRandom random, int sampleSize) {
+      OneBitflipMove[] moves = new OneBitflipMove[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        moves[i] = StochasticOneBitflipSingleMoveGenerator.Apply(binaryVector, random);
+      }
+      return moves;
+    }
+
+    protected override OneBitflipMove[] GenerateMoves(BinaryVector binaryVector) {
+      IRandom random = RandomParameter.ActualValue;
+      if (SampleSizeParameter.ActualValue == null) throw new InvalidOperationException("StochasticOneBitflipMultiMoveGenerator: Parameter " + SampleSizeParameter.ActualName + " could not be found.");
+      return Apply(binaryVector, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/StochasticOneBitflipSingleMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/StochasticOneBitflipSingleMoveGenerator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/StochasticOneBitflipSingleMoveGenerator.cs	(revision 14776)
@@ -0,0 +1,59 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("StochasticOneBitflipSingleMoveGenerator", "Randomly samples a single from all possible one bitflip moves from a given BinaryVector.")]
+  [StorableClass]
+  public class StochasticOneBitflipSingleMoveGenerator : OneBitflipMoveGenerator, IStochasticOperator, ISingleMoveGenerator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected StochasticOneBitflipSingleMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticOneBitflipSingleMoveGenerator(StochasticOneBitflipSingleMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticOneBitflipSingleMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticOneBitflipSingleMoveGenerator(this, cloner);
+    }
+
+    public static OneBitflipMove Apply(BinaryVector binaryVector, IRandom random) {
+      int length = binaryVector.Length;
+      int index = random.Next(length);
+      return new OneBitflipMove(index);
+    }
+
+    protected override OneBitflipMove[] GenerateMoves(BinaryVector binaryVector) {
+      IRandom random = RandomParameter.ActualValue;
+      return new OneBitflipMove[] { Apply(binaryVector, random) };
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneIndexMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneIndexMove.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneIndexMove.cs	(revision 14776)
@@ -0,0 +1,54 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("OneIndexMove", "A move on a binary vector that is specified by 1 index")]
+  [StorableClass]
+  public class OneIndexMove : Item {
+    [Storable]
+    public int Index { get; protected set; }
+    [Storable]
+    public BinaryVector BinaryVector { get; protected set; }
+
+    [StorableConstructor]
+    protected OneIndexMove(bool deserializing) : base(deserializing) { }
+    protected OneIndexMove(OneIndexMove original, Cloner cloner)
+      : base(original, cloner) {
+      this.Index = original.Index;
+      if (original.BinaryVector != null)
+        this.BinaryVector = cloner.Clone(original.BinaryVector);
+    }
+    public OneIndexMove() : this(-1, null) { }
+    public OneIndexMove(int index, BinaryVector binaryVector)
+      : base() {
+      Index = index;
+      BinaryVector = binaryVector;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OneIndexMove(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Plugin.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Plugin.cs.frame	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Plugin.cs.frame	(revision 14776)
@@ -0,0 +1,41 @@
+#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Encodings.BinaryVectorEncoding plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Encodings.BinaryVectorEncoding", "3.3.14.$WCREV$")]
+  [PluginFile("HeuristicLab.Encodings.BinaryVectorEncoding-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  public class HeuristicLabEncodingsBinaryVectorEncodingPlugin : PluginBase {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Properties/AssemblyInfo.cs.frame	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Properties/AssemblyInfo.cs.frame	(revision 14776)
@@ -0,0 +1,56 @@
+#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+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.Encodings.BinaryVectorEncoding")]
+[assembly: AssemblyDescription("HeuristicLab binary vector encoding and related operators")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2016 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("FA3481EF-21E0-4474-9AAE-B74F27D95AEA")]
+
+// 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: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/ShakingOperators/BinaryVectorShakingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/ShakingOperators/BinaryVectorShakingOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/ShakingOperators/BinaryVectorShakingOperator.cs	(revision 14776)
@@ -0,0 +1,84 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// A shaking operator for VNS.
+  /// </summary>
+  [Item("BinaryVectorShakingOperator", "A shaking operator for VNS which uses available manipulation operators to perform the shaking.")]
+  [StorableClass]
+  public class BinaryVectorShakingOperator : ShakingOperator<IBinaryVectorManipulator>, IBinaryVectorMultiNeighborhoodShakingOperator, IStochasticOperator {
+
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected BinaryVectorShakingOperator(bool deserializing) : base(deserializing) { }
+    protected BinaryVectorShakingOperator(BinaryVectorShakingOperator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BinaryVectorShakingOperator(this, cloner);
+    }
+    public BinaryVectorShakingOperator()
+      : base() {
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The binary vector to shake."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that will be used for stochastic shaking operators."));
+      foreach (IBinaryVectorManipulator shaker in ApplicationManager.Manager.GetInstances<IBinaryVectorManipulator>().OrderBy(x => x.Name))
+        Operators.Add(shaker);
+    }
+
+    #region Wiring of some parameters
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IBinaryVectorManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IBinaryVectorManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    private void ParameterizeOperators(IEnumerable<IndexedItem<IBinaryVectorManipulator>> items) {
+      if (items.Any()) {
+        foreach (IStochasticOperator op in items.Select(x => x.Value).OfType<IStochasticOperator>())
+          op.RandomParameter.ActualName = RandomParameter.Name;
+        foreach (IBinaryVectorManipulator op in items.Select(x => x.Value).OfType<IBinaryVectorManipulator>())
+          op.BinaryVectorParameter.ActualName = BinaryVectorParameter.Name;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SimilarityCalculators/HammingSimilarityCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SimilarityCalculators/HammingSimilarityCalculator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SimilarityCalculators/HammingSimilarityCalculator.cs	(revision 14776)
@@ -0,0 +1,66 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  [Item("Hamming Similarity Calculator for BinaryVector", "Calculates the solution similarity based on the Hamming distance between two binary vectors.")]
+  [StorableClass]
+  public sealed class HammingSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator {
+    protected override bool IsCommutative {
+      get { return true; }
+    }
+
+    [StorableConstructor]
+    private HammingSimilarityCalculator(bool deserializing) : base(deserializing) { }
+    private HammingSimilarityCalculator(HammingSimilarityCalculator original, Cloner cloner) : base(original, cloner) { }
+    public HammingSimilarityCalculator() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HammingSimilarityCalculator(this, cloner);
+    }
+
+    public static double CalculateSimilarity(BinaryVector left, BinaryVector right) {
+      if (left == null || right == null)
+        throw new ArgumentException("Cannot calculate similarity because one or both of the provided scopes is null.");
+      if (left.Length != right.Length)
+        throw new ArgumentException("Cannot calculate similarity because the provided solutions have different lengths.");
+      if (left == right) return 1.0;
+
+      double similarity = 0.0;
+      for (int i = 0; i < left.Length; i++)
+        if (left[i] == right[i]) similarity++;
+      return similarity / left.Length;
+
+    }
+
+    public override double CalculateSolutionSimilarity(IScope leftSolution, IScope rightSolution) {
+      var left = leftSolution.Variables[SolutionVariableName].Value as BinaryVector;
+      var right = rightSolution.Variables[SolutionVariableName].Value as BinaryVector;
+
+      return CalculateSimilarity(left, right);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/SolutionSamplingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/SolutionSamplingOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/SolutionSamplingOperator.cs	(revision 14776)
@@ -0,0 +1,75 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel {
+  [Item("Solution Sampling Operator", "Creates new solutions by sampling from a given model.")]
+  [StorableClass]
+  public class SolutionSamplingOperator : InstrumentedOperator {
+    
+    public ILookupParameter<UnivariateModel> ModelParameter {
+      get { return (ILookupParameter<UnivariateModel>)Parameters["Model"]; }
+    }
+
+    public IValueLookupParameter<IntValue> NumberOfSampledSolutionsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["NumberOfSampledSolutions"]; }
+    }
+
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+
+    [StorableConstructor]
+    protected SolutionSamplingOperator(bool deserializing) : base() { }
+    protected SolutionSamplingOperator(SolutionSamplingOperator original, Cloner cloner)
+      : base(original, cloner) { }
+    public SolutionSamplingOperator() {
+      Parameters.Add(new LookupParameter<UnivariateModel>("Model", "The model that is being trained by this operator."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("NumberOfSampledSolutions", "The amount of solutions that should be created through sampling."));
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The vector which should be manipulated."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SolutionSamplingOperator(this, cloner);
+    }
+
+    public override IOperation InstrumentedApply() {
+      var model = ModelParameter.ActualValue;
+      var samples = NumberOfSampledSolutionsParameter.ActualValue.Value;
+      var solutionName = BinaryVectorParameter.TranslatedName;
+      var scope = ExecutionContext.Scope;
+      for (var i = 0; i < samples; i++) {
+        var solution = model.Sample();
+        var solutionScope = new Scope(scope.SubScopes.Count.ToString());
+        solutionScope.Variables.Add(new Variable(solutionName, solution));
+        scope.SubScopes.Add(solutionScope);
+      }
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModel.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModel.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModel.cs	(revision 14776)
@@ -0,0 +1,66 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel {
+  [Item("Univariate solution model (binary)", "")]
+  [StorableClass]
+  public sealed class UnivariateModel : Item, ISolutionModel<BinaryVector> {
+    [Storable]
+    public DoubleArray Probabilities { get; set; }
+    [Storable]
+    public IRandom Random { get; set; }
+
+    [StorableConstructor]
+    private UnivariateModel(bool deserializing) : base(deserializing) { }
+    private UnivariateModel(UnivariateModel original, Cloner cloner)
+      : base(original, cloner) {
+      Probabilities = cloner.Clone(original.Probabilities);
+      Random = cloner.Clone(original.Random);
+    }
+    public UnivariateModel(IRandom random, int N) : this(random, Enumerable.Range(0, N).Select(x => 0.5).ToArray()) { }
+    public UnivariateModel(IRandom random, double[] probabilities) {
+      Probabilities = new DoubleArray(probabilities);
+      Random = random;
+    }
+    public UnivariateModel(IRandom random, DoubleArray probabilties) {
+      Probabilities = probabilties;
+      Random = random;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UnivariateModel(this, cloner);
+    }
+
+    public BinaryVector Sample() {
+      var vec = new BinaryVector(Probabilities.Length);
+      for (var i = 0; i < Probabilities.Length; i++)
+        vec[i] = Random.NextDouble() < Probabilities[i];
+      return vec;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainer.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainer.cs	(revision 14776)
@@ -0,0 +1,146 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel {
+  public static class UnivariateModelTrainer {
+    /// <summary>
+    /// Creates a univariate sampling model out of a ranked population.
+    /// The first solution in <paramref name="rankedPopulation"/> is the 
+    /// highest influential one, the last solution has the least influence.
+    /// </summary>
+    /// <param name="random">The model is stochastic and will use this RNG for sampling.</param>
+    /// <param name="maximization">Whether higher or lower qualities are better</param>
+    /// <param name="population">The population that is ranked from highest influential to least influential, e.g. best to worst.</param>
+    /// <param name="qualities">The solution quality of the respective solution.</param>
+    /// <returns>The sampling model which is created with the given population.</returns>
+    public static UnivariateModel TrainWithRankBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
+      var popSize = 0;
+      double[] model = null;
+      var pop = population.Zip(qualities, (b, q) => new { Solution = b, Fitness = q });
+      foreach (var ind in maximization ? pop.OrderBy(x => x.Fitness) : pop.OrderByDescending(x => x.Fitness)) {
+        // from worst to best, worst solution has 1 vote, best solution N votes
+        popSize++;
+        if (model == null) model = new double[ind.Solution.Length];
+        for (var x = 0; x < model.Length; x++) {
+          if (ind.Solution[x]) model[x] += popSize;
+        }
+      }
+      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
+      // normalize to [0;1]
+      var factor = 2.0 / (popSize + 1);
+      for (var i = 0; i < model.Length; i++) {
+        model[i] *= factor / popSize;
+      }
+      return new UnivariateModel(random, model);
+    }
+
+    /// <summary>
+    /// Creates a univariate sampling model out of solutions and their given fitness.
+    /// The best solution's influence is proportional to its fitness, while the worst
+    /// solution does not have an influence at all (except if the fitness of worst and
+    /// best are equal).
+    /// </summary>
+    /// <param name="random">The model is stochastic and makes use of this RNG instance for sampling.</param>
+    /// <param name="maximization">Whether higher fitness values are better or lower ones.</param>
+    /// <param name="population">The solutions that will be used to create the model.</param>
+    /// <param name="qualities">The solutions' associated qualities.</param>
+    /// <returns>The sampling model which is created with the given population.</returns>
+    public static UnivariateModel TrainWithFitnessBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
+      var proportions = PrepareProportional(qualities, true, !maximization);
+      var factor = 1.0 / proportions.Sum();
+      double[] model = null;
+      foreach (var ind in population.Zip(proportions, (p, q) => new { Solution = p, Proportion = q })) {
+        if (model == null) model = new double[ind.Solution.Length];
+        for (var x = 0; x < model.Length; x++) {
+          if (ind.Solution[x]) model[x] += ind.Proportion * factor;
+        }
+      }
+      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
+      return new UnivariateModel(random, model);
+    }
+
+    /// <summary>
+    /// Creates a univariate sampling model out of solutions. Each of the solutions
+    /// has the same influence on the model.
+    /// </summary>
+    /// <param name="random">The model is stochastic and will make use of this RNG instance.</param>
+    /// <param name="population">The solutions that are used to create the model.</param>
+    /// <returns>The model created from the population.</returns>
+    public static UnivariateModel TrainUnbiased(IRandom random, IEnumerable<BinaryVector> population) {
+      double[] model = null;
+      var popSize = 0;
+      foreach (var p in population) {
+        popSize++;
+        if (model == null) model = new double[p.Length];
+        for (var x = 0; x < model.Length; x++) {
+          if (p[x]) model[x]++;
+        }
+      }
+      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
+      // normalize to [0;1]
+      var factor = 1.0 / popSize;
+      for (var x = 0; x < model.Length; x++) {
+        model[x] *= factor;
+      }
+      return new UnivariateModel(random, model);
+    }
+
+    // TODO: make PrepareProportional public in EnumerableExtensions
+    private static double[] PrepareProportional(IEnumerable<double> weights, bool windowing, bool inverseProportional) {
+      double maxValue = double.MinValue, minValue = double.MaxValue;
+      double[] valueArray = weights.ToArray();
+
+      for (int i = 0; i < valueArray.Length; i++) {
+        if (valueArray[i] > maxValue) maxValue = valueArray[i];
+        if (valueArray[i] < minValue) minValue = valueArray[i];
+      }
+      if (minValue == maxValue) {  // all values are equal
+        for (int i = 0; i < valueArray.Length; i++) {
+          valueArray[i] = 1.0;
+        }
+      } else {
+        if (windowing) {
+          if (inverseProportional) InverseProportionalScale(valueArray, maxValue);
+          else ProportionalScale(valueArray, minValue);
+        } else {
+          if (minValue < 0.0) throw new InvalidOperationException("Proportional selection without windowing does not work with values < 0.");
+          if (inverseProportional) InverseProportionalScale(valueArray, 2 * maxValue);
+        }
+      }
+      return valueArray;
+    }
+    private static void ProportionalScale(double[] values, double minValue) {
+      for (int i = 0; i < values.Length; i++) {
+        values[i] = values[i] - minValue;
+      }
+    }
+    private static void InverseProportionalScale(double[] values, double maxValue) {
+      for (int i = 0; i < values.Length; i++) {
+        values[i] = maxValue - values[i];
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainingOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainingOperator.cs	(revision 14776)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel {
+  public enum ModelBiasOptions {
+    Unbiased,
+    RankBiased,
+    FitnessBiased
+  };
+
+  [Item("Univariate Model Training Operator", "Adds a univariate solution sampling model to the scope.")]
+  [StorableClass]
+  public class UnivariateModelTrainingOperator : InstrumentedOperator, IStochasticOperator, ISingleObjectiveOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public IScopeTreeLookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (IScopeTreeLookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+
+    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<UnivariateModel> ModelParameter {
+      get { return (ILookupParameter<UnivariateModel>)Parameters["Model"]; }
+    }
+
+    public IValueParameter<EnumValue<ModelBiasOptions>> ModelBiasParameter {
+      get { return (IValueParameter<EnumValue<ModelBiasOptions>>)Parameters["ModelBias"]; }
+    }
+
+    public ModelBiasOptions ModelBias {
+      get { return ModelBiasParameter.Value.Value; }
+      set { ModelBiasParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected UnivariateModelTrainingOperator(bool deserializing) : base() { }
+    protected UnivariateModelTrainingOperator(UnivariateModelTrainingOperator original, Cloner cloner)
+      : base(original, cloner) { }
+    public UnivariateModelTrainingOperator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use for sampling from the model."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Whether or not solution qualities are to be maximized."));
+      Parameters.Add(new ScopeTreeLookupParameter<BinaryVector>("BinaryVector", "The population of solutions to create the model."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The fitness values of the solutions."));
+      Parameters.Add(new LookupParameter<UnivariateModel>("Model", "The model that is being trained by this operator."));
+      Parameters.Add(new ValueParameter<EnumValue<ModelBiasOptions>>("ModelBias", "The type of bias that is used to created the model.", new EnumValue<ModelBiasOptions>(ModelBiasOptions.Unbiased)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UnivariateModelTrainingOperator(this, cloner);
+    }
+
+    public override IOperation InstrumentedApply() {
+      var random = RandomParameter.ActualValue;
+      var population = BinaryVectorParameter.ActualValue;
+      var biasType = ModelBiasParameter.Value.Value;
+      UnivariateModel model = null;
+      switch (biasType) {
+        case ModelBiasOptions.Unbiased:
+          model = UnivariateModelTrainer.TrainUnbiased(random, population);
+          break;
+        case ModelBiasOptions.RankBiased: {
+            var qualities = QualityParameter.ActualValue;
+            var maximization = MaximizationParameter.ActualValue.Value;
+            model = UnivariateModelTrainer.TrainWithRankBias(random, maximization, population,
+              qualities.Select(x => x.Value));
+          }
+          break;
+        case ModelBiasOptions.FitnessBiased: {
+            var qualities = QualityParameter.ActualValue;
+            var maximization = MaximizationParameter.ActualValue.Value;
+            model = UnivariateModelTrainer.TrainWithFitnessBias(random, maximization, population,
+              qualities.Select(x => x.Value));
+          }
+          break;
+        default: throw new InvalidOperationException(string.Format("Unknown bias type {0}", biasType));
+      }
+      ModelParameter.ActualValue = model;
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/ExactGroupsLinearLinkageCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/ExactGroupsLinearLinkageCreator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/ExactGroupsLinearLinkageCreator.cs	(revision 14776)
@@ -0,0 +1,72 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Exactgroups Linear Linkage Creator", "Creates a random linear linkage LLE encoded solution with a given number of equal-sized groups.")]
+  [StorableClass]
+  public sealed class ExactGroupsLinearLinkageCreator : LinearLinkageCreator {
+
+    public IValueLookupParameter<IntValue> ExactGroupsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["ExactGroups"]; }
+    }
+
+    public IntValue ExactGroups {
+      get { return ExactGroupsParameter.Value; }
+      set { ExactGroupsParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    private ExactGroupsLinearLinkageCreator(bool deserializing) : base(deserializing) { }
+    private ExactGroupsLinearLinkageCreator(ExactGroupsLinearLinkageCreator original, Cloner cloner) : base(original, cloner) { }
+
+    public ExactGroupsLinearLinkageCreator() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("ExactGroups", "The exact number of equal-sized groups to create.", new IntValue(3)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExactGroupsLinearLinkageCreator(this, cloner);
+    }
+
+    public static LinearLinkage Apply(IRandom random, int length, int groups) {
+      var groupNumbers = Enumerable.Range(0, length).Select(x => x % groups).Shuffle(random);
+      var grouping = Enumerable.Range(0, groups).Select(x => new List<int>()).ToList();
+      var idx = 0;
+      foreach (var g in groupNumbers)
+        grouping[g].Add(idx++);
+
+      return LinearLinkage.FromGroups(length, grouping);
+    }
+
+    protected override LinearLinkage Create(IRandom random, int length) {
+      var groups = ExactGroupsParameter.ActualValue.Value;
+      return Apply(random, length, groups);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/MaxGroupSizeLinearLinkageCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/MaxGroupSizeLinearLinkageCreator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/MaxGroupSizeLinearLinkageCreator.cs	(revision 14776)
@@ -0,0 +1,52 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding.Creators {
+  [Item("Max Group-size Linear Linkage Creator", "Creates a random linear linkage LLE encoded solution with a given maximum number of items per group.")]
+  [StorableClass]
+  public class MaxGroupSizeLinearLinkageCreator: LinearLinkageCreator {
+
+    public IValueLookupParameter<IntValue> MaxGroupSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaxGroupSize"]; }
+    }
+
+    public IntValue MaxGroupSize {
+      get { return MaxGroupSizeParameter.Value; }
+      set { MaxGroupSizeParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected MaxGroupSizeLinearLinkageCreator(bool deserializing) : base(deserializing) { }
+    protected MaxGroupSizeLinearLinkageCreator(MaxGroupSizeLinearLinkageCreator original, Cloner cloner) : base(original, cloner) { }
+
+    public MaxGroupSizeLinearLinkageCreator() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaxGroupSize", "The maximum number items in every group.", new IntValue(4)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MaxGroupSizeLinearLinkageCreator(this, cloner);
+    }
+
+    public static LinearLinkage Apply(IRandom random, int length, int maxGroupSize) {
+      var groups = Enumerable.Range(0, length).Select(x => new { Item = x, Group = random.Next(length)})
+        .GroupBy(x => x.Group)
+        .SelectMany(x => 
+           x.Select((y, i) => new {SubGroup = i%maxGroupSize, y.Item})
+            .GroupBy(y=>y.SubGroup)
+            .Select(y=>
+              y.Select(z=>z.Item).ToList()));
+      return LinearLinkage.FromGroups(length, groups);
+    }
+
+    protected override LinearLinkage Create(IRandom random, int length) {
+      var maxGroupSize = MaxGroupSizeParameter.ActualValue.Value;
+      return Apply(random, length, maxGroupSize);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/MaxGroupsLinearLinkageCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/MaxGroupsLinearLinkageCreator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/MaxGroupsLinearLinkageCreator.cs	(revision 14776)
@@ -0,0 +1,68 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Maxgroups Linear Linkage Creator", "Creates a random linear linkage LLE encoded solution with a given maximum number of groups.")]
+  [StorableClass]
+  public sealed class MaxGroupsLinearLinkageCreator : LinearLinkageCreator {
+
+    public IValueLookupParameter<IntValue> MaxGroupsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaxGroups"]; }
+    }
+
+    public IntValue MaxGroups {
+      get { return MaxGroupsParameter.Value; }
+      set { MaxGroupsParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    private MaxGroupsLinearLinkageCreator(bool deserializing) : base(deserializing) { }
+    private MaxGroupsLinearLinkageCreator(MaxGroupsLinearLinkageCreator original, Cloner cloner) : base(original, cloner) { }
+
+    public MaxGroupsLinearLinkageCreator() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaxGroups", "The maximum number of groups to create.", new IntValue(3)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MaxGroupsLinearLinkageCreator(this, cloner);
+    }
+
+    public static LinearLinkage Apply(IRandom random, int length, int maxGroups) {
+      var groups = Enumerable.Range(0, length).Select(x => Tuple.Create(x, random.Next(maxGroups)))
+                                              .GroupBy(x => x.Item2)
+                                              .Select(x => x.Select(y => y.Item1).ToList());
+      return LinearLinkage.FromGroups(length, groups);
+    }
+
+    protected override LinearLinkage Create(IRandom random, int length) {
+      var maxGroups = MaxGroupsParameter.ActualValue.Value;
+      return Apply(random, length, maxGroups);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/RandomLinearLinkageCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/RandomLinearLinkageCreator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Creators/RandomLinearLinkageCreator.cs	(revision 14776)
@@ -0,0 +1,53 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Random Linear Linkage Creator", "Creates a random linear linkage LLE encoded solution (similar to MaxGroups set to N).")]
+  [StorableClass]
+  public sealed class RandomLinearLinkageCreator : LinearLinkageCreator {
+
+    [StorableConstructor]
+    private RandomLinearLinkageCreator(bool deserializing) : base(deserializing) { }
+    private RandomLinearLinkageCreator(RandomLinearLinkageCreator original, Cloner cloner) : base(original, cloner) { }
+    public RandomLinearLinkageCreator() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RandomLinearLinkageCreator(this, cloner);
+    }
+
+    public static LinearLinkage Apply(IRandom random, int length) {
+      var groups = Enumerable.Range(0, length).Select(x => Tuple.Create(x, random.Next(length)))
+                                              .GroupBy(x => x.Item2)
+                                              .Select(x => x.Select(y => y.Item1).ToList());
+      return LinearLinkage.FromGroups(length, groups);
+    }
+
+    protected override LinearLinkage Create(IRandom random, int length) {
+      return Apply(random, length);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/GreedyPartitionCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/GreedyPartitionCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/GreedyPartitionCrossover.cs	(revision 14776)
@@ -0,0 +1,76 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Greedy Partition Crossover", "The Greedy Partition Crossover (GPX) is implemented as described in Ülker, Ö., Özcan, E., Korkmaz, E. E. 2007. Linear linkage encoding in grouping problems: applications on graph coloring and timetabling. In Practice and Theory of Automated Timetabling VI, pp. 347-363. Springer Berlin Heidelberg.")]
+  [StorableClass]
+  public sealed class GreedyPartitionCrossover : LinearLinkageCrossover {
+
+    [StorableConstructor]
+    private GreedyPartitionCrossover(bool deserializing) : base(deserializing) { }
+    private GreedyPartitionCrossover(GreedyPartitionCrossover original, Cloner cloner) : base(original, cloner) { }
+    public GreedyPartitionCrossover() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GreedyPartitionCrossover(this, cloner);
+    }
+
+    public static LinearLinkage Apply(IRandom random, ItemArray<LinearLinkage> parents) {
+      var len = parents[0].Length;
+      var childGroup = new List<HashSet<int>>();
+      var currentParent = random.Next(parents.Length);
+      var groups = parents.Select(x => x.GetGroups().Select(y => new HashSet<int>(y)).ToList()).ToList();
+      bool remaining;
+      do {
+        var maxGroup = groups[currentParent].Select((v, i) => Tuple.Create(i, v))
+          .MaxItems(x => x.Item2.Count)
+          .SampleRandom(random).Item1;
+        var group = groups[currentParent][maxGroup];
+        groups[currentParent].RemoveAt(maxGroup);
+        childGroup.Add(group);
+
+        remaining = false;
+        for (var p = 0; p < groups.Count; p++) {
+          for (var j = 0; j < groups[p].Count; j++) {
+            foreach (var elem in group) groups[p][j].Remove(elem);
+            if (!remaining && groups[p][j].Count > 0) remaining = true;
+          }
+        }
+
+        currentParent = (currentParent + 1) % parents.Length;
+      } while (remaining);
+
+      return LinearLinkage.FromGroups(len, childGroup);
+    }
+
+    protected override LinearLinkage Cross(IRandom random, ItemArray<LinearLinkage> parents) {
+      return Apply(random, parents);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/GroupCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/GroupCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/GroupCrossover.cs	(revision 14776)
@@ -0,0 +1,85 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Group Crossover", "The Group Crossover is implemented as described in Korkmaz, E.E. 2010. Multi-objective Genetic Algorithms for grouping problems. Applied Intelligence 33(2), pp. 179-192.")]
+  [StorableClass]
+  public sealed class GroupCrossover : LinearLinkageCrossover {
+
+    [StorableConstructor]
+    private GroupCrossover(bool deserializing) : base(deserializing) { }
+    private GroupCrossover(GroupCrossover original, Cloner cloner) : base(original, cloner) { }
+    public GroupCrossover() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GroupCrossover(this, cloner);
+    }
+    
+    public static LinearLinkage Apply(IRandom random, LinearLinkage p1, LinearLinkage p2) {
+      var length = p1.Length;
+      var lleeP1 = p1.ToEndLinks();
+      var lleeP2 = p2.ToEndLinks();
+      var lleeChild = new int[length];
+      var isTransfered = new bool[length];
+
+      for (var i = p1.Length - 1; i >= 0; i--) {
+        lleeChild[i] = i;
+
+        // Step 1
+        var isEndP1 = p1[i] == i;
+        var isEndP2 = p2[i] == i;
+        if (isEndP1 & isEndP2 || (isEndP1 | isEndP2 && random.NextDouble() < 0.5)) {
+          isTransfered[i] = true;
+          continue;
+        }
+
+        // Step 2
+        var end1 = lleeP1[i];
+        var end2 = lleeP2[i];
+
+        if (isTransfered[end1] & isTransfered[end2]) {
+          var end = random.NextDouble() < 0.5 ? end1 : end2;
+          lleeChild[i] = end;
+        } else if (isTransfered[end1]) {
+          lleeChild[i] = end1;
+        } else if (isTransfered[end2]) {
+          lleeChild[i] = end2;
+        } else {
+          var next = random.NextDouble() < 0.5 ? p1[i] : p2[i];
+          var end = lleeChild[next];
+          lleeChild[i] = end;
+        }
+      }
+      return LinearLinkage.FromEndLinks(lleeChild);
+    }
+
+    protected override LinearLinkage Cross(IRandom random, ItemArray<LinearLinkage> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException(Name + ": Can only cross exactly two parents.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/LowestIndexFirstCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/LowestIndexFirstCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/LowestIndexFirstCrossover.cs	(revision 14776)
@@ -0,0 +1,68 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Lowest Index First Crossover", "The Lowest Index First Crossover (LIFX) is implemented as described in Ülker, Ö., Özcan, E., Korkmaz, E. E. 2007. Linear linkage encoding in grouping problems: applications on graph coloring and timetabling. In Practice and Theory of Automated Timetabling VI, pp. 347-363. Springer Berlin Heidelberg.")]
+  [StorableClass]
+  public sealed class LowestIndexFirstCrossover : LinearLinkageCrossover {
+
+    [StorableConstructor]
+    private LowestIndexFirstCrossover(bool deserializing) : base(deserializing) { }
+    private LowestIndexFirstCrossover(LowestIndexFirstCrossover original, Cloner cloner) : base(original, cloner) { }
+    public LowestIndexFirstCrossover() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LowestIndexFirstCrossover(this, cloner);
+    }
+
+    public static LinearLinkage Apply(IRandom random, ItemArray<LinearLinkage> parents) {
+      var len = parents[0].Length;
+      var p = random.Next(parents.Length);
+      var child = LinearLinkage.SingleElementGroups(len);
+      var remaining = new SortedSet<int>(Enumerable.Range(0, len));
+      do {
+        var i = remaining.Min;
+        foreach (var g in parents[p].GetGroupForward(i)) {
+          if (!remaining.Contains(g)) continue;
+          child[i] = g;
+          i = g;
+          remaining.Remove(g);
+        }
+        child[i] = i;
+        remaining.Remove(i);
+
+        p = (p + 1) % parents.Length;
+      } while (remaining.Count > 0);
+
+      return child;
+    }
+
+    protected override LinearLinkage Cross(IRandom random, ItemArray<LinearLinkage> parents) {
+      return Apply(random, parents);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/LowestIndexMaxCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/LowestIndexMaxCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/LowestIndexMaxCrossover.cs	(revision 14776)
@@ -0,0 +1,68 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Lowest Index Max Crossover", "The Lowest Index Max Crossover (LIMX) is implemented as described in Ülker, Ö., Özcan, E., Korkmaz, E. E. 2007. Linear linkage encoding in grouping problems: applications on graph coloring and timetabling. In Practice and Theory of Automated Timetabling VI, pp. 347-363. Springer Berlin Heidelberg.")]
+  [StorableClass]
+  public sealed class LowestIndexMaxCrossover : LinearLinkageCrossover {
+
+    [StorableConstructor]
+    private LowestIndexMaxCrossover(bool deserializing) : base(deserializing) { }
+    private LowestIndexMaxCrossover(LowestIndexMaxCrossover original, Cloner cloner) : base(original, cloner) { }
+    public LowestIndexMaxCrossover() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LowestIndexMaxCrossover(this, cloner);
+    }
+
+    public static LinearLinkage Apply(IRandom random, ItemArray<LinearLinkage> parents) {
+      var len = parents[0].Length;
+      var child = LinearLinkage.SingleElementGroups(len);
+      var remaining = new SortedSet<int>(Enumerable.Range(0, len));
+      do {
+        var groups = parents.Select(x => x.GetGroupForward(remaining.Min).Where(y => remaining.Contains(y)).ToList()).ToList();
+        var max = groups.Select((v, idx) => Tuple.Create(idx, v.Count)).MaxItems(x => x.Item2).SampleRandom(random).Item1;
+        var i = groups[max][0];
+        for (var k = 1; k < groups[max].Count; k++) {
+          child[i] = groups[max][k];
+          remaining.Remove(i);
+          i = child[i];
+        }
+        child[i] = i;
+        remaining.Remove(i);
+      } while (remaining.Count > 0);
+
+      return child;
+    }
+
+    protected override LinearLinkage Cross(IRandom random, ItemArray<LinearLinkage> parents) {
+      return Apply(random, parents);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/MultiLLECrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/MultiLLECrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/MultiLLECrossover.cs	(revision 14776)
@@ -0,0 +1,100 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Multi LLE Crossover", "Randomly selects and applies one of its crossovers every time it is called.")]
+  [StorableClass]
+  public class MultiLinearLinkageCrossover : StochasticMultiBranch<ILinearLinkageCrossover>, ILinearLinkageCrossover, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+
+    public IScopeTreeLookupParameter<LinearLinkage> ParentsParameter {
+      get { return (IScopeTreeLookupParameter<LinearLinkage>)Parameters["Parents"]; }
+    }
+
+    public ILookupParameter<LinearLinkage> ChildParameter {
+      get { return (ILookupParameter<LinearLinkage>)Parameters["Child"]; }
+    }
+
+    [StorableConstructor]
+    protected MultiLinearLinkageCrossover(bool deserializing) : base(deserializing) { }
+    protected MultiLinearLinkageCrossover(MultiLinearLinkageCrossover original, Cloner cloner) : base(original, cloner) { }
+    public MultiLinearLinkageCrossover()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<LinearLinkage>("Parents", "The parent LLE which should be crossed."));
+      ParentsParameter.ActualName = "LLE";
+      Parameters.Add(new LookupParameter<LinearLinkage>("Child", "The child LLE resulting from the crossover."));
+      ChildParameter.ActualName = "LLE";
+
+      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(ILinearLinkageCrossover), typeof(LinearLinkageEncoding).Assembly)) {
+        if (!typeof(MultiOperator<ILinearLinkageCrossover>).IsAssignableFrom(type))
+          Operators.Add((ILinearLinkageCrossover)Activator.CreateInstance(type), true);
+      }
+
+      SelectedOperatorParameter.ActualName = "SelectedCrossoverOperator";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiLinearLinkageCrossover(this, cloner);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<ILinearLinkageCrossover>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeCrossovers(e.Items);
+    }
+
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<ILinearLinkageCrossover>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeCrossovers(e.Items);
+    }
+
+    private void ParameterizeCrossovers(IEnumerable<IndexedItem<ILinearLinkageCrossover>> crossovers) {
+      foreach (var c in crossovers.Select(x => x.Value)) {
+        c.ChildParameter.ActualName = ChildParameter.Name;
+        c.ParentsParameter.ActualName = ParentsParameter.Name;
+        var stOp = c as IStochasticOperator;
+        if (stOp != null) stOp.RandomParameter.ActualName = RandomParameter.Name;
+      }
+    }
+
+    public override IOperation InstrumentedApply() {
+      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one LLE crossover to choose from.");
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/SinglePointCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/SinglePointCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Crossovers/SinglePointCrossover.cs	(revision 14776)
@@ -0,0 +1,56 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Single Point Crossover", "The single point crossover concatenates two linkage strings at a randomly chosen point.")]
+  [StorableClass]
+  public sealed class SinglePointCrossover : LinearLinkageCrossover {
+
+    [StorableConstructor]
+    private SinglePointCrossover(bool deserializing) : base(deserializing) { }
+    private SinglePointCrossover(SinglePointCrossover original, Cloner cloner) : base(original, cloner) { }
+    public SinglePointCrossover() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SinglePointCrossover(this, cloner);
+    }
+
+    public static LinearLinkage Apply(IRandom random, LinearLinkage p1, LinearLinkage p2) {
+      var length = p1.Length;
+      var child = LinearLinkage.SingleElementGroups(length);
+      var bp = random.Next(length - 1);
+      for (var i = 0; i <= bp; i++) child[i] = p1[i];
+      for (var i = bp + 1; i < length; i++) child[i] = p2[i];
+      child.LinearizeTreeStructures();
+      return child;
+    }
+
+    protected override LinearLinkage Cross(IRandom random, ItemArray<LinearLinkage> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException(Name + ": Can only cross exactly two parents.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/HeuristicLab.Encodings.LinearLinkageEncoding-3.4.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/HeuristicLab.Encodings.LinearLinkageEncoding-3.4.csproj	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/HeuristicLab.Encodings.LinearLinkageEncoding-3.4.csproj	(revision 14776)
@@ -0,0 +1,219 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{BE698769-975A-429E-828C-72BB2B6182C8}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Encodings.LinearLinkageEncoding</RootNamespace>
+    <AssemblyName>HeuristicLab.Encodings.LinearLinkageEncoding-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Operators-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Creators\ExactGroupsLinearLinkageCreator.cs" />
+    <Compile Include="Creators\MaxGroupSizeLinearLinkageCreator.cs" />
+    <Compile Include="Creators\MaxGroupsLinearLinkageCreator.cs" />
+    <Compile Include="Creators\RandomLinearLinkageCreator.cs" />
+    <Compile Include="Crossovers\GreedyPartitionCrossover.cs" />
+    <Compile Include="Crossovers\GroupCrossover.cs" />
+    <Compile Include="Crossovers\LowestIndexMaxCrossover.cs" />
+    <Compile Include="Crossovers\MultiLLECrossover.cs" />
+    <Compile Include="Crossovers\SinglePointCrossover.cs" />
+    <Compile Include="Interfaces\ILinearLinkageMoveOperator.cs" />
+    <Compile Include="Interfaces\ILinearLinkageSwap2MoveOperator.cs" />
+    <Compile Include="Interfaces\ILinearLinkageCreator.cs" />
+    <Compile Include="LinearLinkage.cs" />
+    <Compile Include="LinearLinkageCreator.cs" />
+    <Compile Include="LinearLinkageEncoding.cs" />
+    <Compile Include="LinearLinkageEqualityComparer.cs" />
+    <Compile Include="LinearLinkageManipulator.cs" />
+    <Compile Include="LinearLinkageCrossover.cs" />
+    <Compile Include="Manipulators\GraftManipulator.cs" />
+    <Compile Include="Manipulators\MoveItemManipulator.cs" />
+    <Compile Include="Manipulators\MergeGroupManipulator.cs" />
+    <Compile Include="Manipulators\MultiLLEManipulator.cs" />
+    <Compile Include="Moves\ExtractMove.cs" />
+    <Compile Include="Moves\MergeMove.cs" />
+    <Compile Include="Moves\Move.cs" />
+    <Compile Include="Moves\ShiftMove.cs" />
+    <Compile Include="Moves\SplitMove.cs" />
+    <Compile Include="Moves\StaticAPI\MoveGenerator.cs" />
+    <Compile Include="Moves\Swap\ExhaustiveSwap2MoveGenerator.cs" />
+    <Compile Include="Moves\Swap\StochasticSwap2MultiMoveGenerator.cs" />
+    <Compile Include="Moves\Swap\StochasticSwap2SingleMoveGenerator.cs" />
+    <Compile Include="Moves\Swap\Swap2Move.cs" />
+    <Compile Include="Moves\Swap\Swap2MoveGenerator.cs" />
+    <Compile Include="Moves\Swap\Swap2MoveMaker.cs" />
+    <Compile Include="ShakingOperators\LLEShakingOperator.cs" />
+    <Compile Include="SimilarityCalculators\HammingSimilarityCalculator.cs" />
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Crossovers\LowestIndexFirstCrossover.cs" />
+    <Compile Include="Interfaces\ILinearLinkageCrossover.cs" />
+    <Compile Include="Interfaces\ILinearLinkageManipulator.cs" />
+    <Compile Include="Interfaces\ILinearLinkageOperator.cs" />
+    <Compile Include="Interfaces\ILinearLinkageShakingOperator.cs" />
+    <Compile Include="Manipulators\SplitGroupManipulator.cs" />
+    <Compile Include="Manipulators\SwapItemManipulator.cs" />
+    <Compile Include="Plugin.cs" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+    </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+    </PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageCreator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageCreator.cs	(revision 14776)
@@ -0,0 +1,31 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public interface ILinearLinkageCreator : ISolutionCreator, ILinearLinkageOperator {
+    IValueLookupParameter<IntValue> LengthParameter { get; }
+    ILookupParameter<LinearLinkage> LLEParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageCrossover.cs	(revision 14776)
@@ -0,0 +1,30 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public interface ILinearLinkageCrossover : ICrossover, ILinearLinkageOperator {
+    ILookupParameter<LinearLinkage> ChildParameter { get; }
+    IScopeTreeLookupParameter<LinearLinkage> ParentsParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageManipulator.cs	(revision 14776)
@@ -0,0 +1,29 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public interface ILinearLinkageManipulator : IManipulator, ILinearLinkageOperator {
+    ILookupParameter<LinearLinkage> LLEParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageMoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageMoveOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageMoveOperator.cs	(revision 14776)
@@ -0,0 +1,36 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  /// <summary>
+  /// Move operators can be extended by deriving a new interface from this interface
+  /// and implementing that derived interface in all move operators that belong to
+  /// the same group of move operators.
+  /// 
+  /// See <see cref="ILinearLinkageSwap2MoveOperator"/> for a reference implementation.
+  /// </summary>
+  public interface ILinearLinkageMoveOperator : IMoveOperator, ILinearLinkageOperator {
+    ILookupParameter<LinearLinkage> LLEParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageOperator.cs	(revision 14776)
@@ -0,0 +1,27 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public interface ILinearLinkageOperator : IOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageShakingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageShakingOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageShakingOperator.cs	(revision 14776)
@@ -0,0 +1,29 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public interface ILinearLinkageShakingOperator : ILinearLinkageOperator {
+    ILookupParameter<LinearLinkage> LLEParameter { get; }
+    ICheckedItemList<ILinearLinkageManipulator> Shakers { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageSwap2MoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageSwap2MoveOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Interfaces/ILinearLinkageSwap2MoveOperator.cs	(revision 14776)
@@ -0,0 +1,28 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public interface ILinearLinkageSwap2MoveOperator : ILinearLinkageMoveOperator {
+    ILookupParameter<Swap2Move> Swap2MoveParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkage.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkage.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkage.cs	(revision 14776)
@@ -0,0 +1,409 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("LinearLinkage", "Represents an LLE grouping of items.")]
+  [StorableClass]
+  public sealed class LinearLinkage : IntArray {
+
+    [StorableConstructor]
+    private LinearLinkage(bool deserializing) : base(deserializing) { }
+    private LinearLinkage(LinearLinkage original, Cloner cloner) : base(original, cloner) { }
+    public LinearLinkage() { }
+
+    private LinearLinkage(int length) : base(length) { }
+    private LinearLinkage(int[] elements) : base(elements) { }
+
+    /// <summary>
+    /// Create a new LinearLinkage object where every element is in a seperate group.
+    /// </summary>
+    public static LinearLinkage SingleElementGroups(int length) {
+      var elements = new int[length];
+      for (var i = 0; i < length; i++) {
+        elements[i] = i;
+      }
+      return new LinearLinkage(elements);
+    }
+
+    /// <summary>
+    /// Create a new LinearLinkage object from an int[] in LLE
+    /// </summary>
+    /// <remarks>
+    /// This operation checks if the argument is a well formed LLE
+    /// and throws an ArgumentException otherwise.
+    /// </remarks>
+    /// <exception cref="ArgumentException">If <paramref name="lle"/> does not represent a valid LLE array.</exception>
+    /// <param name="lle">The LLE representation</param>
+    /// <returns>The linear linkage encoding in LLE format (with forward-links).</returns>
+    public static LinearLinkage FromForwardLinks(int[] lle) {
+      if (!Validate(lle))
+        throw new ArgumentException("Array is malformed and does not represent a valid LLE forward encoding.", "elements");
+      return new LinearLinkage(lle);
+    }
+
+    /// <summary>
+    /// Create a new LinearLinkage object by parsing a LLE-b representation
+    /// and modifing the underlying array so that it is in LLE representation.
+    /// </summary>
+    /// <remarks>
+    /// This operation runs in O(n) time, the parameter <paramref name="lleb"/> is not modified.
+    /// </remarks>
+    /// <exception cref="ArgumentException">If <paramref name="lleb"/> does not represent a valid LLE-b array.</exception>
+    /// <param name="lleb">The LLE-b representation (LLE with back-links)</param>
+    /// <returns>The linear linkage encoding in LLE format (with forward-links).</returns>
+    public static LinearLinkage FromBackLinks(int[] lleb) {
+      var result = new LinearLinkage(lleb.Length);
+      for (var i = lleb.Length - 1; i > 0; i--) {
+        if (lleb[i] == i) {
+          if (result[i] == 0) result[i] = i;
+          continue;
+        }
+        result[lleb[i]] = i;
+        if (result[i] == 0) result[i] = i;
+      }
+      if (!Validate(result.array))
+        throw new ArgumentException("Array is malformed and does not represent a valid LLE-b encoding (with back-links).", "lleb");
+      return result;
+    }
+
+    /// <summary>
+    /// Create a new LinearLinkage object by parsing an LLE-e representation
+    /// and modifing the underlying array so that it is in LLE representation.
+    /// </summary>
+    /// <remarks>
+    /// This operation runs in O(n) time, but requires additional memory
+    /// in form of a int[].
+    /// </remarks>
+    /// <param name="llee">The LLE-e representation</param>
+    /// <returns>The linear linkage encoding in LLE format (with forward-links).</returns>
+    public static LinearLinkage FromEndLinks(int[] llee) {
+      var result = new LinearLinkage(llee.Length);
+      result.SetEndLinks(llee);
+      return result;
+    }
+
+    /// <summary>
+    /// Create a new LinearLinkage object by translating
+    /// an enumeration of groups into the underlying array representation.
+    /// </summary>
+    /// <remarks>
+    /// Throws an ArgumentException when there is an element assigned to
+    /// multiple groups or elements that are not assigned to any group.
+    /// </remarks>
+    /// <param name="grouping">The grouping of the elements, each element must
+    /// be part of exactly one group.</param>
+    public static LinearLinkage FromGroups(int length, IEnumerable<IEnumerable<int>> grouping) {
+      var result = new LinearLinkage(length);
+      result.SetGroups(grouping);
+      return result;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LinearLinkage(this, cloner);
+    }
+
+    /// <summary>
+    /// This method parses the encoded array and calculates the membership of
+    /// each element to the groups. It starts at the lowest element.
+    /// </summary>
+    /// <remarks>
+    /// Runtime complexity of this method is O(n) where n is the length of the
+    /// array.
+    /// </remarks>
+    /// <exception cref="InvalidOperationException">If this object is not vaild LLE.</exception>
+    /// <returns>An enumeration of all groups.</returns>
+    public IEnumerable<List<int>> GetGroups() {
+      var len = array.Length;
+      var used = new bool[len];
+      for (var i = 0; i < len; i++) {
+        if (used[i]) continue;
+        var curr = i;
+        var next = array[curr];
+        var group = new List<int> { curr };
+        while (next > curr && next < len && !used[next]) {
+          used[curr] = true;
+          curr = next;
+          next = array[next];
+          group.Add(curr);
+        }
+        if (curr != next) throw new InvalidOperationException("Array is malformed and does not represent a valid LLE forward encoding.");
+        used[curr] = true;
+        yield return group;
+      }
+    }
+
+    /// <summary>
+    /// This method parses the encoded array and gathers all elements
+    /// that belong to the same group as element <paramref name="index"/>.
+    /// </summary>
+    /// <param name="index">The element whose group should be returned.
+    /// </param>
+    /// <returns>The element at <paramref name="index"/> and all other
+    /// elements in the same group.</returns>
+    public IEnumerable<int> GetGroup(int index) {
+      foreach (var n in GetGroupForward(index))
+        yield return n;
+      // the element index has already been yielded
+      foreach (var n in GetGroupBackward(index).Skip(1))
+        yield return n;
+    }
+
+    /// <summary>
+    /// This method parses the encoded array and gathers the element
+    /// <paramref name="index"/> as well as subsequent elements that
+    /// belong to the same group.
+    /// </summary>
+    /// <param name="index">The element from which subsequent (having a
+    /// larger number) elements in the group should be returned.
+    /// </param>
+    /// <returns>The element <paramref name="index"/> and all subsequent
+    /// elements in the same group.</returns>
+    public IEnumerable<int> GetGroupForward(int index) {
+      yield return index;
+      var next = array[index];
+      if (next == index) yield break;
+      int prev;
+      do {
+        yield return next;
+        prev = next;
+        next = array[next];
+      } while (next != prev);
+    }
+
+    /// <summary>
+    /// This method parses the encoded array and gathers the element
+    /// given <paramref name="index"/> as well as preceeding elements that
+    /// belong to the same group.
+    /// </summary>
+    /// <remarks>
+    /// Warning, this code has performance O(index) as the array has to
+    /// be fully traversed backwards from the given index.
+    /// </remarks>
+    /// <param name="index">The element from which preceeding (having a
+    /// smaller number) elements in the group should be returned.
+    /// </param>
+    /// <returns>The element <paramref name="index"/> and all preceeding
+    /// elements in the same group.</returns>
+    public IEnumerable<int> GetGroupBackward(int index) {
+      yield return index;
+      var next = array[index];
+      // return preceding elements in group
+      for (var prev = index - 1; prev >= 0; prev--) {
+        if (array[prev] != next) continue;
+        next = prev;
+        yield return next;
+      }
+    }
+
+    /// <summary>
+    /// This method translates an enumeration of groups into the underlying
+    /// array representation.
+    /// </summary>
+    /// <remarks>
+    /// Throws an ArgumentException when there is an element assigned to
+    /// multiple groups or elements that are not assigned to any group.
+    /// </remarks>
+    /// <param name="grouping">The grouping of the elements, each element must
+    /// be part of exactly one group.</param>
+    /// <exception cref="ArgumentException">If <paramref name="grouping"/> cannot be converted
+    /// to a valid LLE representation. For instance, because elements are too big or too small,
+    /// or they're contained in multiple groups, or there are elements not assigned to any group.
+    /// </exception>
+    public void SetGroups(IEnumerable<IEnumerable<int>> grouping) {
+      var len = array.Length;
+      var used = new bool[len];
+      foreach (var group in grouping) {
+        var prev = -1;
+        foreach (var g in group.OrderBy(x => x)) {
+          if (g < prev || g >= len) throw new ArgumentException(string.Format("Element {0} is bigger than {1} or smaller than 0.", g, len - 1), "grouping");
+          if (prev >= 0) array[prev] = g;
+          prev = g;
+          if (used[prev]) {
+            throw new ArgumentException(string.Format("Element {0} is contained at least twice.", prev), "grouping");
+          }
+          used[prev] = true;
+        }
+        array[prev] = prev;
+      }
+      if (!used.All(x => x))
+        throw new ArgumentException(string.Format("Elements are not assigned a group: {0}", string.Join(", ", used.Select((x, i) => new { x, i }).Where(x => !x.x).Select(x => x.i))));
+    }
+
+    /// <summary>
+    /// Performs a check whether the array represents a valid LLE encoding.
+    /// </summary>
+    /// <remarks>
+    /// The runtime complexity of this method is O(n) where n is the length of
+    /// the array.
+    /// </remarks>
+    /// <returns>True if the encoding is valid.</returns>
+    public bool Validate() {
+      return Validate(array);
+    }
+
+    private static bool Validate(int[] array) {
+      var len = array.Length;
+      var used = new bool[len];
+      for (var i = 0; i < len; i++) {
+        if (used[i]) continue;
+        var curr = i;
+        var next = array[curr];
+        while (next > curr && next < len && !used[next]) {
+          used[curr] = true;
+          curr = next;
+          next = array[next];
+        }
+        if (curr != next) return false;
+        used[curr] = true;
+      }
+      return true;
+    }
+
+    /// <summary>
+    /// This method flattens tree structures that may be present in groups.
+    /// These tree structures may be created by e.g. merging two groups by
+    /// linking one end node to the end node of another.
+    /// Consider following array: 5, 5, 6, 4, 4, 7, 7, 7, 8.
+    /// This results in the following tree structure for group 7:
+    ///      7
+    ///    /   \
+    ///   5     6
+    ///  / \    |
+    /// 0   1   2
+    /// After this operation the array will be 1, 2, 5, 4, 4, 6, 7, 7, 8.
+    /// Representing a tree with one branch: 0 -> 1 -> 2 -> 5 -> 6 -> 7.
+    /// </summary>
+    /// <remarks>
+    /// The method first converts the array to LLE-e format and then
+    /// linearizes the links. This requires two passes of the whole array
+    /// as well as another copy of the underlying array.
+    /// The runtime complexity is O(n).
+    /// 
+    /// The method assumes that there are no back links present.
+    /// </remarks>
+    public void LinearizeTreeStructures() {
+      // Step 1: Convert the array into LLE-e
+      ToEndLinksInplace(array);
+      // Step 2: For all groups linearize the links
+      SetEndLinks(array);
+    }
+
+    /// <summary>
+    /// Creates a copy of the underlying array and turns it into LLE-e.
+    /// </summary>
+    /// <remarks>
+    /// LLE-e is a special format where each element points to the
+    /// ending item of a group.
+    /// The LLE representation 1, 2, 4, 5, 4, 6, 7, 7 would become 
+    /// 4, 4, 4, 7, 4, 7, 7, 7 in LLE-e.
+    /// 
+    /// This operation runs in O(n) time.
+    /// </remarks>
+    /// <exception cref="ArgumentException">In case, this object does not
+    /// represent a valid LLE encoding.
+    /// </exception>
+    /// <returns>An integer array in LLE-e representation</returns>
+    public int[] ToEndLinks() {
+      var result = (int[])array.Clone();
+      ToEndLinksInplace(result);
+      return result;
+    }
+
+    private static void ToEndLinksInplace(int[] array) {
+      var length = array.Length;
+      for (var i = length - 1; i >= 0; i--) {
+        var next = array[i];
+        if (next > i) {
+          array[i] = array[next];
+        } else if (next < i) {
+          throw new ArgumentException("Array is malformed and does not represent a valid LLE encoding.", "array");
+        }
+      }
+    }
+
+    /// <summary>
+    /// Parses an LLE-e representation and modifies the underlying array
+    /// so that it is in LLE representation.
+    /// </summary>
+    /// <remarks>
+    /// This operation runs in O(n) time, but requires additional memory
+    /// in form of a int[].
+    /// </remarks>
+    /// <param name="llee">The LLE-e representation</param>
+    /// <exception cref="ArgumentException">
+    /// If <paramref name="llee"/> does not contain a valid LLE-e representation or
+    /// has a different length to the given instance.
+    /// </exception>
+    public void SetEndLinks(int[] llee) {
+      var length = array.Length;
+      if (length != llee.Length) {
+        throw new ArgumentException(string.Format("Expected length {0} but length was {1}", length, llee.Length), "llee");
+      }
+      // If we are ok with mutating llee we can avoid this clone
+      var lookup = (int[])llee.Clone();
+      for (var i = length - 1; i >= 0; i--) {
+        var end = llee[i];
+        if (end == i) {
+          array[i] = end;
+        } else if (end > i && end < length) {
+          array[i] = lookup[end];
+          lookup[end] = i;
+        } else {
+          throw new ArgumentException("Array is malformed and does not represent a valid LLE-e end encoding.", "llee");
+        }
+      }
+    }
+
+    /// <summary>
+    /// Creates a copy of the underlying array and turns it into LLE-b.
+    /// </summary>
+    /// <remarks>
+    /// LLE-b is a special format where each element points to the
+    /// predecessor instead of the successor.
+    /// The LLE representation 1, 2, 4, 5, 4, 6, 7, 7
+    /// would become           0, 0, 1, 3, 2, 3, 5, 6 in LLE-b.
+    /// 
+    /// This operation runs in O(n) time.
+    /// </remarks>
+    /// <returns>An integer array in LLE-b representation</returns>
+    public int[] ToBackLinks() {
+      var result = new int[array.Length];
+      var zeroLink = array[0];
+      for (var i = 0; i < array.Length; i++) {
+        if (array[i] == i) {
+          if (result[i] == 0 && i != zeroLink) result[i] = i;
+          continue;
+        }
+        result[array[i]] = i;
+        if (result[i] == 0 && i != zeroLink) result[i] = i;
+      }
+      return result;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageCreator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageCreator.cs	(revision 14776)
@@ -0,0 +1,64 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Linear Linkage Creator", "Base class for linear linkage creators.")]
+  [StorableClass]
+  public abstract class LinearLinkageCreator : InstrumentedOperator, ILinearLinkageCreator, IStochasticOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<LinearLinkage> LLEParameter {
+      get { return (ILookupParameter<LinearLinkage>)Parameters["LLE"]; }
+    }
+
+    public IValueLookupParameter<IntValue> LengthParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["Length"]; }
+    }
+
+    [StorableConstructor]
+    protected LinearLinkageCreator(bool deserializing) : base(deserializing) { }
+    protected LinearLinkageCreator(LinearLinkageCreator original, Cloner cloner) : base(original, cloner) { }
+    protected LinearLinkageCreator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<LinearLinkage>("LLE", "The encoding vector that is to be created.") { Hidden = false });
+      Parameters.Add(new ValueLookupParameter<IntValue>("Length", "The length of the vector that is to be created."));
+    }
+
+    public override IOperation InstrumentedApply() {
+      var random = RandomParameter.ActualValue;
+      LLEParameter.ActualValue = Create(random, LengthParameter.ActualValue.Value);
+      return base.InstrumentedApply();
+    }
+
+    protected abstract LinearLinkage Create(IRandom random, int length);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageCrossover.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageCrossover.cs	(revision 14776)
@@ -0,0 +1,67 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Linear Linkage Crossover", "Base class for linear linkage crossovers.")]
+  [StorableClass]
+  public abstract class LinearLinkageCrossover : InstrumentedOperator, ILinearLinkageCrossover, IStochasticOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<LinearLinkage> ChildParameter {
+      get { return (ILookupParameter<LinearLinkage>)Parameters["Child"]; }
+    }
+
+    public IScopeTreeLookupParameter<LinearLinkage> ParentsParameter {
+      get { return (IScopeTreeLookupParameter<LinearLinkage>)Parameters["Parents"]; }
+    }
+
+    [StorableConstructor]
+    protected LinearLinkageCrossover(bool deserializing) : base(deserializing) { }
+    protected LinearLinkageCrossover(LinearLinkageCrossover original, Cloner cloner) : base(original, cloner) { }
+    protected LinearLinkageCrossover() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<LinearLinkage>("Child", "The child that is to be created."));
+      Parameters.Add(new ScopeTreeLookupParameter<LinearLinkage>("Parents", "The parents that are to be crossed."));
+    }
+
+    public override IOperation InstrumentedApply() {
+      var random = RandomParameter.ActualValue;
+      var parents = ParentsParameter.ActualValue;
+      if (parents == null) throw new InvalidOperationException(Name + ": Parents could not be found.");
+      var child = Cross(random, parents);
+      ChildParameter.ActualValue = child;
+      return base.InstrumentedApply();
+    }
+
+    protected abstract LinearLinkage Cross(IRandom random, ItemArray<LinearLinkage> parents);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageEncoding.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageEncoding.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageEncoding.cs	(revision 14776)
@@ -0,0 +1,179 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Linear Linkage Encoding", "Describes a linear linkage (LLE) encoding.")]
+  [StorableClass]
+  public sealed class LinearLinkageEncoding : Encoding<ILinearLinkageCreator> {
+    #region encoding parameters
+    [Storable]
+    private IFixedValueParameter<IntValue> lengthParameter;
+    public IFixedValueParameter<IntValue> LengthParameter {
+      get { return lengthParameter; }
+      set {
+        if (value == null) throw new ArgumentNullException("Length parameter must not be null.");
+        if (value.Value == null) throw new ArgumentNullException("Length parameter value must not be null.");
+        if (lengthParameter == value) return;
+
+        if (lengthParameter != null) Parameters.Remove(lengthParameter);
+        lengthParameter = value;
+        Parameters.Add(lengthParameter);
+        OnLengthParameterChanged();
+      }
+    }
+    #endregion
+
+    public int Length {
+      get { return LengthParameter.Value.Value; }
+      set { LengthParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    private LinearLinkageEncoding(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+      DiscoverOperators();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) { return new LinearLinkageEncoding(this, cloner); }
+    private LinearLinkageEncoding(LinearLinkageEncoding original, Cloner cloner)
+      : base(original, cloner) {
+      lengthParameter = cloner.Clone(original.lengthParameter);
+      RegisterParameterEvents();
+    }
+
+
+    public LinearLinkageEncoding() : this("LLE", 10) { }
+    public LinearLinkageEncoding(string name) : this(name, 10) { }
+    public LinearLinkageEncoding(int length) : this("LLE", length) { }
+    public LinearLinkageEncoding(string name, int length)
+      : base(name) {
+      lengthParameter = new FixedValueParameter<IntValue>(Name + ".Length", new IntValue(length));
+      Parameters.Add(lengthParameter);
+
+      SolutionCreator = new RandomLinearLinkageCreator();
+      RegisterParameterEvents();
+      DiscoverOperators();
+    }
+
+    private void OnLengthParameterChanged() {
+      RegisterLengthParameterEvents();
+      ConfigureOperators(Operators);
+    }
+
+    private void RegisterParameterEvents() {
+      RegisterLengthParameterEvents();
+    }
+    private void RegisterLengthParameterEvents() {
+      LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
+    }
+
+    #region Operator Discovery
+    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
+    static LinearLinkageEncoding() {
+      encodingSpecificOperatorTypes = new List<Type>() {
+          typeof (ILinearLinkageOperator),
+          typeof (ILinearLinkageCreator),
+          typeof (ILinearLinkageCrossover),
+          typeof (ILinearLinkageManipulator),
+          typeof (ILinearLinkageShakingOperator),
+          typeof (ILinearLinkageMoveOperator)
+      };
+    }
+    private void DiscoverOperators() {
+      var assembly = typeof(ILinearLinkageOperator).Assembly;
+      var discoveredTypes = ApplicationManager.Manager.GetTypes(encodingSpecificOperatorTypes, assembly, true, false, false);
+      var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t));
+      var newOperators = operators.Except(Operators, new TypeEqualityComparer<IOperator>()).ToList();
+
+      ConfigureOperators(newOperators);
+      foreach (var @operator in newOperators)
+        AddOperator(@operator);
+    }
+    #endregion
+
+    public override void ConfigureOperators(IEnumerable<IOperator> operators) {
+      ConfigureCreators(operators.OfType<ILinearLinkageCreator>());
+      ConfigureCrossovers(operators.OfType<ILinearLinkageCrossover>());
+      ConfigureManipulators(operators.OfType<ILinearLinkageManipulator>());
+      ConfigureShakingOperators(operators.OfType<ILinearLinkageShakingOperator>());
+      ConfigureMoveOperators(operators.OfType<ILinearLinkageMoveOperator>());
+      ConfigureSwap2MoveOperators(operators.OfType<ILinearLinkageSwap2MoveOperator>());
+    }
+
+    #region specific operator wiring
+    private void ConfigureCreators(IEnumerable<ILinearLinkageCreator> creators) {
+      foreach (var creator in creators) {
+        creator.LengthParameter.ActualName = LengthParameter.Name;
+        creator.LLEParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureCrossovers(IEnumerable<ILinearLinkageCrossover> crossovers) {
+      foreach (var crossover in crossovers) {
+        crossover.ChildParameter.ActualName = Name;
+        crossover.ParentsParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureManipulators(IEnumerable<ILinearLinkageManipulator> manipulators) {
+      foreach (var manipulator in manipulators) {
+        manipulator.LLEParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureShakingOperators(IEnumerable<ILinearLinkageShakingOperator> shakingOperators) {
+      foreach (var shakingOperator in shakingOperators) {
+        shakingOperator.LLEParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureMoveOperators(IEnumerable<ILinearLinkageMoveOperator> moveOperators) {
+      foreach (var moveOperator in moveOperators) {
+        moveOperator.LLEParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureSwap2MoveOperators(IEnumerable<ILinearLinkageSwap2MoveOperator> swap2MoveOperators) {
+      foreach (var swap2MoveOperator in swap2MoveOperators) {
+        swap2MoveOperator.Swap2MoveParameter.ActualName = Name + ".Swap2Move";
+      }
+    }
+    #endregion
+  }
+
+  public static class IndividualExtensionMethods {
+    public static LinearLinkage LinearLinkage(this Individual individual) {
+      var encoding = individual.GetEncoding<LinearLinkageEncoding>();
+      return individual.LinearLinkage(encoding.Name);
+    }
+    public static LinearLinkage LinearLinkage(this Individual individual, string name) {
+      return (LinearLinkage)individual[name];
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageEqualityComparer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageEqualityComparer.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageEqualityComparer.cs	(revision 14776)
@@ -0,0 +1,44 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public class LinearLinkageEqualityComparer : EqualityComparer<LinearLinkage> {
+    public override bool Equals(LinearLinkage x, LinearLinkage y) {
+      if (x == null && y == null) return true;
+      if (x == null || y == null) return false;
+      if (x.Length != y.Length) return false;
+      for (var i = 0; i < x.Length; i++)
+        if (x[i] != y[i]) return false;
+      return true;
+    }
+
+    public override int GetHashCode(LinearLinkage obj) {
+      unchecked {
+        int hash = 17;
+        foreach (var o in obj)
+          hash = hash * 31 + o.GetHashCode();
+        return hash;
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageManipulator.cs	(revision 14776)
@@ -0,0 +1,58 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Linear Linkage Manipulator", "Base class for linear linkage manipulators.")]
+  [StorableClass]
+  public abstract class LinearLinkageManipulator : InstrumentedOperator, ILinearLinkageManipulator, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<LinearLinkage> LLEParameter {
+      get { return (ILookupParameter<LinearLinkage>)Parameters["LLE"]; }
+    }
+
+    [StorableConstructor]
+    protected LinearLinkageManipulator(bool deserializing) : base(deserializing) { }
+    protected LinearLinkageManipulator(LinearLinkageManipulator original, Cloner cloner) : base(original, cloner) { }
+    protected LinearLinkageManipulator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<LinearLinkage>("LLE", "The encoding vector that is to be manipulated."));
+    }
+
+    public override IOperation InstrumentedApply() {
+      var random = RandomParameter.ActualValue;
+      var lle = LLEParameter.ActualValue;
+      Manipulate(random, lle);
+      return base.InstrumentedApply();
+    }
+
+    protected abstract void Manipulate(IRandom random, LinearLinkage lle);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/GraftManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/GraftManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/GraftManipulator.cs	(revision 14776)
@@ -0,0 +1,77 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Graft Manipulator", "Performs graft mutation as described in Du, J., Korkmaz, E.E., Alhajj, R., and Barker, K. 2004. Novel Clustering Approach that employs Genetic Algorithm with New Representation Scheme and Multiple Objectives. Data Warehousing and Knowledge Discovery, pp. 219-228. Springer Berlin Heidelberg.")]
+  [StorableClass]
+  public sealed class GraftManipulator : LinearLinkageManipulator {
+
+    [StorableConstructor]
+    private GraftManipulator(bool deserializing) : base(deserializing) { }
+    private GraftManipulator(GraftManipulator original, Cloner cloner) : base(original, cloner) { }
+    public GraftManipulator() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GraftManipulator(this, cloner);
+    }
+
+    public static void Apply(IRandom random, LinearLinkage lle) {
+      int tries = lle.Length;
+      var index = random.Next(lle.Length);
+      while (tries > 0 && lle[index] == index) {
+        index = random.Next(lle.Length);
+        tries--;
+      }
+      if (lle[index] != index) Apply(random, lle, index);
+    }
+
+    public static void Apply(IRandom random, LinearLinkage lle, int index) {
+      var groups = lle.Select((val, idx) => Tuple.Create(idx, val))
+                      .Where(x => x.Item1 == x.Item2)
+                      .Select(x => x.Item2).ToList();
+      var z = groups.Count;
+
+      if (random.NextDouble() < 0.5)
+        lle[index] = index; // divide the cluster into two
+      else {
+        var c = random.Next(z);
+        if (groups[c] > index)
+          lle[index] = groups[c]; // combine the portion with another class
+        else {
+          // combine the other class here
+          lle[groups[c]] = lle[index];
+          lle[index] = index;
+        }
+        lle.LinearizeTreeStructures();
+      }
+    }
+
+    protected override void Manipulate(IRandom random, LinearLinkage lle) {
+      Apply(random, lle);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/MergeGroupManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/MergeGroupManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/MergeGroupManipulator.cs	(revision 14776)
@@ -0,0 +1,74 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Merge Group Manipulator", "Performs a maximum of N merge operations on the groups. An already merged group may be merged again.")]
+  [StorableClass]
+  public sealed class MergeGroupManipulator : LinearLinkageManipulator {
+
+    public IValueLookupParameter<IntValue> NParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["N"]; }
+    }
+
+    [StorableConstructor]
+    private MergeGroupManipulator(bool deserializing) : base(deserializing) { }
+    private MergeGroupManipulator(MergeGroupManipulator original, Cloner cloner) : base(original, cloner) { }
+    public MergeGroupManipulator() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("N", "The number of groups to merge.", new IntValue(1)));
+    }
+    public MergeGroupManipulator(int n)
+      : this() {
+      NParameter.Value = new IntValue(n);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MergeGroupManipulator(this, cloner);
+    }
+
+    public static void Apply(IRandom random, LinearLinkage lle, int n) {
+      var grouping = lle.GetGroups().ToList();
+      if (grouping.Count == 1) return; // nothing to merge
+
+      for (var i = 0; i < n; i++) {
+        var g1 = random.Next(grouping.Count);
+        var g2 = random.Next(grouping.Count);
+        while (g1 == g2) g2 = random.Next(grouping.Count);
+        grouping[g1].AddRange(grouping[g2]);
+        grouping.RemoveAt(g2);
+        if (grouping.Count == 1) break;
+      }
+
+      lle.SetGroups(grouping);
+    }
+
+    protected override void Manipulate(IRandom random, LinearLinkage lle) {
+      var N = NParameter.ActualValue.Value;
+      Apply(random, lle, N);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/MoveItemManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/MoveItemManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/MoveItemManipulator.cs	(revision 14776)
@@ -0,0 +1,82 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Move Item Manipulator", "Performs a maximum of N move operations between groups or to new groups. An already moved item may be moved again.")]
+  [StorableClass]
+  public sealed class MoveItemManipulator : LinearLinkageManipulator {
+
+    public IValueLookupParameter<IntValue> NParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["N"]; }
+    }
+
+    [StorableConstructor]
+    private MoveItemManipulator(bool deserializing) : base(deserializing) { }
+    private MoveItemManipulator(MoveItemManipulator original, Cloner cloner) : base(original, cloner) { }
+    public MoveItemManipulator() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("N", "The number of items to move.", new IntValue(1)));
+    }
+    public MoveItemManipulator(int n)
+      : this() {
+      NParameter.Value = new IntValue(n);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MoveItemManipulator(this, cloner);
+    }
+
+    public static void Apply(IRandom random, LinearLinkage lle, int n) {
+      var grouping = lle.GetGroups().ToList();
+      grouping.Add(new List<int>()); // add an empty group
+
+      for (var i = 0; i < n; i++) {
+        var src = random.Next(grouping.Count - 1); // only select from non-empty groups
+        var dest = random.Next(grouping.Count);
+        while (src == dest || grouping[src].Count == 1 && dest == grouping.Count - 1) {
+          src = random.Next(grouping.Count - 1);
+          dest = random.Next(grouping.Count);
+        }
+        if (dest == grouping.Count - 1) grouping.Add(new List<int>());
+
+        var e = random.Next(grouping[src].Count);
+        grouping[dest].Add(grouping[src][e]);
+        grouping[src].RemoveAt(e);
+        if (grouping[src].Count == 0)
+          grouping.RemoveAt(src);
+      }
+
+      lle.SetGroups(grouping.Where(x => x.Count > 0));
+    }
+
+    protected override void Manipulate(IRandom random, LinearLinkage lle) {
+      var N = NParameter.ActualValue.Value;
+      Apply(random, lle, N);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/MultiLLEManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/MultiLLEManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/MultiLLEManipulator.cs	(revision 14776)
@@ -0,0 +1,90 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Multi LLE Manipulator", "Randomly selects and applies one of its manipulators every time it is called.")]
+  [StorableClass]
+  public class MultiLinearLinkageManipulator : StochasticMultiBranch<ILinearLinkageManipulator>, ILinearLinkageManipulator, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+
+    public ILookupParameter<LinearLinkage> LLEParameter {
+      get { return (ILookupParameter<LinearLinkage>)Parameters["LLE"]; }
+    }
+
+    [StorableConstructor]
+    protected MultiLinearLinkageManipulator(bool deserializing) : base(deserializing) { }
+    protected MultiLinearLinkageManipulator(MultiLinearLinkageManipulator original, Cloner cloner) : base(original, cloner) { }
+    public MultiLinearLinkageManipulator()
+      : base() {
+      Parameters.Add(new LookupParameter<LinearLinkage>("LLE", "The encoding vector that is to be manipulated."));
+      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(ILinearLinkageManipulator), typeof(LinearLinkageEncoding).Assembly)) {
+        if (!typeof(MultiOperator<ILinearLinkageManipulator>).IsAssignableFrom(type))
+          Operators.Add((ILinearLinkageManipulator)Activator.CreateInstance(type), true);
+      }
+      SelectedOperatorParameter.ActualName = "SelectedManipulationOperator";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiLinearLinkageManipulator(this, cloner);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<ILinearLinkageManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeManipulators(e.Items);
+    }
+
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<ILinearLinkageManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeManipulators(e.Items);
+    }
+
+    private void ParameterizeManipulators(IEnumerable<IndexedItem<ILinearLinkageManipulator>> manipulators) {
+      foreach (var m in manipulators.Select(x => x.Value)) {
+        m.LLEParameter.ActualName = LLEParameter.Name;
+        var stOp = m as IStochasticOperator;
+        if (stOp != null) stOp.RandomParameter.ActualName = RandomParameter.Name;
+      }
+    }
+
+    public override IOperation InstrumentedApply() {
+      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one LLE manipulator to choose from.");
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/SplitGroupManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/SplitGroupManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/SplitGroupManipulator.cs	(revision 14776)
@@ -0,0 +1,95 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Split Group Manipulator", "Performs a maximum of N split operations on the groups. An already split group may be split again.")]
+  [StorableClass]
+  public sealed class SplitGroupManipulator : LinearLinkageManipulator {
+
+    public IValueLookupParameter<IntValue> NParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["N"]; }
+    }
+
+    [StorableConstructor]
+    private SplitGroupManipulator(bool deserializing) : base(deserializing) { }
+    private SplitGroupManipulator(SplitGroupManipulator original, Cloner cloner) : base(original, cloner) { }
+    public SplitGroupManipulator() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("N", "The number of groups to split.", new IntValue(1)));
+    }
+    public SplitGroupManipulator(int n)
+      : this() {
+      NParameter.Value = new IntValue(n);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SplitGroupManipulator(this, cloner);
+    }
+
+    public static void Apply(IRandom random, LinearLinkage lle, int n) {
+      var grouping = lle.GetGroups().ToList();
+      var groupsLargerOne = grouping.Select((v, i) => Tuple.Create(i, v))
+                                    .Where(x => x.Item2.Count > 1)
+                                    .ToDictionary(x => x.Item1, x => x.Item2);
+      if (groupsLargerOne.Count == 0) return;
+      var toRemove = new List<int>();
+
+      for (var i = 0; i < n; i++) {
+        var g = groupsLargerOne.Keys.SampleRandom(random);
+        var idx = random.Next(1, groupsLargerOne[g].Count);
+        // shuffle here to avoid a potential bias of grouping smaller and larger numbers together
+        var tmp = groupsLargerOne[g].Shuffle(random);
+        var before = new List<int>();
+        var after = new List<int>();
+        foreach (var t in tmp) {
+          if (idx > 0) before.Add(t);
+          else after.Add(t);
+          idx--;
+        }
+        if (before.Count > 1) groupsLargerOne[grouping.Count] = before;
+        grouping.Add(before);
+        if (after.Count > 1) groupsLargerOne[grouping.Count] = after;
+        grouping.Add(after);
+        toRemove.Add(g);
+        groupsLargerOne.Remove(g);
+        if (groupsLargerOne.Count == 0) break;
+      }
+      foreach (var r in toRemove.OrderByDescending(x => x))
+        grouping.RemoveAt(r);
+
+      lle.SetGroups(grouping);
+    }
+
+    protected override void Manipulate(IRandom random, LinearLinkage lle) {
+      var N = NParameter.ActualValue.Value;
+      Apply(random, lle, N);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/SwapItemManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/SwapItemManipulator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Manipulators/SwapItemManipulator.cs	(revision 14776)
@@ -0,0 +1,80 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Swap Item Manipulator", "Performs N swaps operations of two items each. The same items may be swapped multiple times, at least two groups need to be present.")]
+  [StorableClass]
+  public sealed class SwapItemManipulator : LinearLinkageManipulator {
+
+    public IValueLookupParameter<IntValue> NParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["N"]; }
+    }
+
+    [StorableConstructor]
+    private SwapItemManipulator(bool deserializing) : base(deserializing) { }
+    private SwapItemManipulator(SwapItemManipulator original, Cloner cloner) : base(original, cloner) { }
+    public SwapItemManipulator() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("N", "The number of swaps to perform.", new IntValue(1)));
+    }
+    public SwapItemManipulator(int n)
+      : this() {
+      NParameter.Value = new IntValue(n);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SwapItemManipulator(this, cloner);
+    }
+
+    public static void Apply(IRandom random, LinearLinkage lle, int n) {
+      var grouping = lle.GetGroups().Select(x => x.ToList()).ToList();
+      if (grouping.Count == 1) return; // nothing can be changed
+
+      var prevGroup = random.Next(grouping.Count);
+      var prevItem = random.Next(grouping[prevGroup].Count);
+      for (var i = 0; i < n; i++) {
+        int nextGroup, nextItem;
+        do {
+          nextGroup = random.Next(grouping.Count);
+          nextItem = random.Next(grouping[nextGroup].Count);
+        } while (nextGroup == prevGroup);
+        var h = grouping[nextGroup][nextItem];
+        grouping[nextGroup][nextItem] = grouping[prevGroup][prevItem];
+        grouping[prevGroup][prevItem] = h;
+        prevGroup = nextGroup;
+        prevItem = nextItem;
+      }
+
+      lle.SetGroups(grouping);
+    }
+
+    protected override void Manipulate(IRandom random, LinearLinkage lle) {
+      var N = NParameter.ActualValue.Value;
+      Apply(random, lle, N);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/ExtractMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/ExtractMove.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/ExtractMove.cs	(revision 14776)
@@ -0,0 +1,60 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public class ExtractMove : Move {
+    public int PreviousItem { get; private set; }
+    public int NextItem { get; private set; }
+
+    private bool IsFirst { get { return PreviousItem == Item; } }
+    private bool IsLast { get { return NextItem == Item; } }
+
+    public ExtractMove(int item, int prev, int next) {
+      Item = item;
+      PreviousItem = prev;
+      NextItem = next;
+    }
+
+    public override void Apply(LinearLinkage lle) {
+      if ((!IsFirst && lle[PreviousItem] != Item)
+        || lle[Item] != NextItem)
+        throw new ArgumentException("Move conditions have changed!");
+      if (!IsFirst) lle[PreviousItem] = IsLast ? PreviousItem : NextItem;
+      lle[Item] = Item;
+    }
+
+    public override void Undo(LinearLinkage lle) {
+      if (!IsFirst && lle[PreviousItem] != (IsLast ? PreviousItem : NextItem)
+        || lle[Item] != Item)
+        throw new ArgumentException("Move conditions have changed, cannot undo move.");
+
+      if (!IsFirst) lle[PreviousItem] = Item;
+      lle[Item] = NextItem;
+    }
+
+    public override void ApplyToLLEb(int[] lleb) {
+      if (!IsLast) lleb[NextItem] = IsFirst ? NextItem : PreviousItem;
+      lleb[Item] = Item;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/MergeMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/MergeMove.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/MergeMove.cs	(revision 14776)
@@ -0,0 +1,48 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public class MergeMove : Move {
+
+    public int LastItemOfOtherGroup { get; private set; }
+
+    public MergeMove(int item, int lastOfOther) {
+      Item = item;
+      LastItemOfOtherGroup = lastOfOther;
+    }
+
+    public override void Apply(LinearLinkage lle) {
+      if (lle[LastItemOfOtherGroup] != LastItemOfOtherGroup) throw new ArgumentException("Move conditions have changed, group does not terminate at " + LastItemOfOtherGroup);
+      lle[LastItemOfOtherGroup] = Item;
+    }
+
+    public override void Undo(LinearLinkage lle) {
+      if (lle[LastItemOfOtherGroup] != Item) throw new ArgumentException("Move conditions have changed, groups are no longer linked between " + LastItemOfOtherGroup + " and " + Item);
+      lle[LastItemOfOtherGroup] = LastItemOfOtherGroup;
+    }
+
+    public override void ApplyToLLEb(int[] lleb) {
+      lleb[Item] = LastItemOfOtherGroup;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Move.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Move.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Move.cs	(revision 14776)
@@ -0,0 +1,31 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public abstract class Move {
+    public int Item { get; protected set; }
+
+    public abstract void Apply(LinearLinkage lle);
+    public abstract void Undo(LinearLinkage lle);
+
+    public abstract void ApplyToLLEb(int[] lleb);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/ShiftMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/ShiftMove.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/ShiftMove.cs	(revision 14776)
@@ -0,0 +1,74 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public class ShiftMove : Move {
+    public int PreviousItemOfOldGroup { get; private set; }
+    public int PreviousItemOfNewGroup { get; private set; }
+    public int NextItemOfOldGroup { get; private set; }
+    public int NextItemOfNewGroup { get; private set; }
+
+    private bool IsFirst { get { return PreviousItemOfOldGroup == Item; } }
+    private bool IsLast { get { return NextItemOfOldGroup == Item; } }
+    private bool NewGroupClosed { get { return PreviousItemOfNewGroup == NextItemOfNewGroup; } }
+
+    public ShiftMove(int item, int prevOld, int prevNew, int nextOld, int nextNew) {
+      Item = item;
+      PreviousItemOfOldGroup = prevOld;
+      PreviousItemOfNewGroup = prevNew;
+      NextItemOfOldGroup = nextOld;
+      NextItemOfNewGroup = nextNew;
+    }
+
+    public override void Apply(LinearLinkage lle) {
+      if ((!IsFirst && lle[PreviousItemOfOldGroup] != Item)
+        || lle[Item] != NextItemOfOldGroup
+        || lle[PreviousItemOfNewGroup] != NextItemOfNewGroup)
+        throw new ArgumentException("Move conditions have changed!");
+      if (!IsFirst)
+        lle[PreviousItemOfOldGroup] = IsLast ? PreviousItemOfOldGroup : NextItemOfOldGroup;
+      lle[PreviousItemOfNewGroup] = Item;
+      lle[Item] = NewGroupClosed ? Item : NextItemOfNewGroup;
+    }
+
+    public override void Undo(LinearLinkage lle) {
+      if (!IsFirst && lle[PreviousItemOfOldGroup] != (IsLast ? PreviousItemOfOldGroup : NextItemOfOldGroup)
+        || lle[PreviousItemOfNewGroup] != Item
+        || lle[Item] != (NewGroupClosed ? Item : NextItemOfNewGroup))
+        throw new ArgumentException("Move conditions have changed, cannot undo move.");
+
+      if (!IsFirst)
+        lle[PreviousItemOfOldGroup] = Item;
+      lle[PreviousItemOfNewGroup] = NextItemOfNewGroup;
+      lle[Item] = NextItemOfOldGroup;
+    }
+
+    public override void ApplyToLLEb(int[] lleb) {
+      if (!IsLast)
+        lleb[NextItemOfOldGroup] = IsFirst ? NextItemOfOldGroup : PreviousItemOfOldGroup;
+      lleb[Item] = PreviousItemOfNewGroup;
+      if (!NewGroupClosed)
+        lleb[NextItemOfNewGroup] = Item;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/SplitMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/SplitMove.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/SplitMove.cs	(revision 14776)
@@ -0,0 +1,51 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public class SplitMove : Move {
+
+    private int nextItem;
+
+    public SplitMove(int item) {
+      Item = item;
+      nextItem = -1;
+    }
+
+    public override void Apply(LinearLinkage lle) {
+      if (lle[Item] == Item) throw new ArgumentException("Move conditions have changed, group is already split at " + Item);
+      nextItem = lle[Item];
+      lle[Item] = Item;
+    }
+
+    public override void Undo(LinearLinkage lle) {
+      if (lle[Item] != Item) throw new ArgumentException("Move conditions have changed, group no longer terminates at " + Item);
+      if (nextItem < 0) throw new InvalidOperationException("Cannot undo move that has not been applied first.");
+      lle[Item] = nextItem;
+    }
+
+    public override void ApplyToLLEb(int[] lleb) {
+      if (nextItem < 0) throw new InvalidOperationException("Cannot undo move that has not been applied first to LLE.");
+      lleb[nextItem] = nextItem;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/StaticAPI/MoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/StaticAPI/MoveGenerator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/StaticAPI/MoveGenerator.cs	(revision 14776)
@@ -0,0 +1,68 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  public static class MoveGenerator {
+    public static IEnumerable<Move> GenerateForItem(int i, List<int> groupItems, LinearLinkage lle, int[] lleb) {
+      var pred = lleb[i];
+      var next = lle[i];
+      var isFirst = pred == i;
+      var isLast = next == i;
+
+      // First: shift i into each previous group
+      foreach (var m in groupItems.Where(x => lle[x] != i)) {
+        yield return new ShiftMove(i, pred, m, next, lle[m]);
+      }
+
+      if (!isLast) {
+        // Second: split group at i
+        yield return new SplitMove(i);
+
+        if (isFirst) {
+          // Third: merge with closed groups
+          foreach (var m in groupItems.Where(x => lle[x] == x)) {
+            yield return new MergeMove(i, m);
+          }
+        } else {
+          // Fourth: extract i into group of its own (exclude first and last, because of SplitMove)
+          yield return new ExtractMove(i, pred, next);
+        }
+      }
+        
+
+    }
+
+    public static IEnumerable<Move> Generate(LinearLinkage lle) {
+      var groupItems = new List<int>();
+      var lleb = lle.ToBackLinks();
+      for (var i = 0; i < lle.Length; i++) {
+        foreach (var move in GenerateForItem(i, groupItems, lle, lleb))
+          yield return move;
+        if (lleb[i] != i)
+          groupItems.Remove(lleb[i]);
+        groupItems.Add(i);
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/ExhaustiveSwap2MoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/ExhaustiveSwap2MoveGenerator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/ExhaustiveSwap2MoveGenerator.cs	(revision 14776)
@@ -0,0 +1,62 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("ExhaustiveSwap2MoveGenerator", "Generates all possible swap-2 moves from a given permutation.")]
+  [StorableClass]
+  public class ExhaustiveSwap2MoveGenerator : Swap2MoveGenerator, IExhaustiveMoveGenerator {
+    [StorableConstructor]
+    protected ExhaustiveSwap2MoveGenerator(bool deserializing) : base(deserializing) { }
+    protected ExhaustiveSwap2MoveGenerator(ExhaustiveSwap2MoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public ExhaustiveSwap2MoveGenerator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExhaustiveSwap2MoveGenerator(this, cloner);
+    }
+
+    public static IEnumerable<Swap2Move> Generate(LinearLinkage lle) {
+      int length = lle.Length;
+      if (length == 1) throw new ArgumentException("ExhaustiveSwap2MoveGenerator: There cannot be an Swap move given only one item.", "lle");
+
+      var groups = lle.GetGroups().ToList();
+      if (groups.Count == 1) throw new InvalidOperationException("ExhaustiveSwap2MoveGenerator: Swap moves cannot be applied when there is only one group.");
+
+      for (int i = 0; i < groups.Count; i++)
+        for (int j = i + 1; j < groups.Count; j++)
+          for (var k = 0; k < groups[i].Count; k++)
+            for (var m = 0; m < groups[j].Count; m++) {
+              yield return new Swap2Move(groups[i][k], groups[j][m]);
+            }
+    }
+
+    protected override Swap2Move[] GenerateMoves(LinearLinkage lle) {
+      return Generate(lle).ToArray();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/StochasticSwap2MultiMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/StochasticSwap2MultiMoveGenerator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/StochasticSwap2MultiMoveGenerator.cs	(revision 14776)
@@ -0,0 +1,72 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("StochasticSwap2MultiMoveGenerator", "Randomly samples n from all possible swap-2 moves from a given lle grouping.")]
+  [StorableClass]
+  public class StochasticSwap2MultiMoveGenerator : Swap2MoveGenerator, IMultiMoveGenerator, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    public IntValue SampleSize {
+      get { return SampleSizeParameter.Value; }
+      set { SampleSizeParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected StochasticSwap2MultiMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticSwap2MultiMoveGenerator(StochasticSwap2MultiMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticSwap2MultiMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticSwap2MultiMoveGenerator(this, cloner);
+    }
+
+    public static Swap2Move[] Apply(LinearLinkage lle, IRandom random, int sampleSize) {
+      int length = lle.Length;
+      Swap2Move[] moves = new Swap2Move[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        moves[i] = StochasticSwap2SingleMoveGenerator.Apply(lle, random);
+      }
+      return moves;
+    }
+
+    protected override Swap2Move[] GenerateMoves(LinearLinkage lle) {
+      IRandom random = RandomParameter.ActualValue;
+      return Apply(lle, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/StochasticSwap2SingleMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/StochasticSwap2SingleMoveGenerator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/StochasticSwap2SingleMoveGenerator.cs	(revision 14776)
@@ -0,0 +1,73 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("StochasticSwap2SingleMoveGenerator", "Randomly samples a single from all possible swap-2 moves from a given grouping.")]
+  [StorableClass]
+  public class StochasticSwap2SingleMoveGenerator : Swap2MoveGenerator, IStochasticOperator, ISingleMoveGenerator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected StochasticSwap2SingleMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticSwap2SingleMoveGenerator(StochasticSwap2SingleMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticSwap2SingleMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticSwap2SingleMoveGenerator(this, cloner);
+    }
+
+    public static Swap2Move Apply(LinearLinkage lle, IRandom random) {
+      int length = lle.Length;
+      if (length < 2) throw new ArgumentException("StochasticSwap2SingleMoveGenerator: There cannot be a swap-2 move given only one item.", "lle");
+
+      var groups = lle.GetGroups().ToList();
+      if (groups.Count == 1) throw new InvalidOperationException("StochasticSwap2SingleMoveGenerator: Swap moves cannot be applied when there is only one group.");
+
+      int index1 = random.Next(groups.Count), index2 = 0;
+      do {
+        index2 = random.Next(length);
+      } while (index1 == index2);
+
+      var item1 = random.Next(groups[index1].Count);
+      var item2 = random.Next(groups[index2].Count);
+
+      return new Swap2Move(groups[index1][item1], groups[index2][item2]);
+    }
+
+    protected override Swap2Move[] GenerateMoves(LinearLinkage lle) {
+      IRandom random = RandomParameter.ActualValue;
+      return new[] { Apply(lle, random) };
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/Swap2Move.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/Swap2Move.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/Swap2Move.cs	(revision 14776)
@@ -0,0 +1,53 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Swap2Move", "Item that describes a swap-2 move.")]
+  [StorableClass]
+  public class Swap2Move : Item {
+    [Storable]
+    public int Item1 { get; protected set; }
+    [Storable]
+    public int Item2 { get; protected set; }
+    [Storable]
+    public LinearLinkage LLE { get; protected set; }
+
+    [StorableConstructor]
+    protected Swap2Move(bool deserializing) : base(deserializing) { }
+    protected Swap2Move(Swap2Move original, Cloner cloner) : base(original, cloner) { }
+    public Swap2Move() : this(-1, -1, null) { }
+    public Swap2Move(int item1, int item2) : this(item1, item2, null) { }
+    public Swap2Move(int item1, int item2, LinearLinkage lle)
+      : base() {
+      Item1 = item1;
+      Item2 = item2;
+      LLE = lle;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2Move(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/Swap2MoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/Swap2MoveGenerator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/Swap2MoveGenerator.cs	(revision 14776)
@@ -0,0 +1,66 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Swap2MoveGenerator", "Base class for all swap-2 move generators.")]
+  [StorableClass]
+  public abstract class Swap2MoveGenerator : SingleSuccessorOperator, ILinearLinkageSwap2MoveOperator, IMoveGenerator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<LinearLinkage> LLEParameter {
+      get { return (ILookupParameter<LinearLinkage>)Parameters["LLE"]; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (LookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+
+    [StorableConstructor]
+    protected Swap2MoveGenerator(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveGenerator(Swap2MoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<LinearLinkage>("LLE", "The LLE solution for which moves should be generated."));
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The moves that should be generated in subscopes."));
+    }
+
+    public override IOperation Apply() {
+      var lle = LLEParameter.ActualValue;
+      var moves = GenerateMoves(lle);
+      var moveScopes = new Scope[moves.Length];
+      for (var i = 0; i < moveScopes.Length; i++) {
+        moveScopes[i] = new Scope(i.ToString());
+        moveScopes[i].Variables.Add(new Variable(Swap2MoveParameter.ActualName, moves[i]));
+      }
+      ExecutionContext.Scope.SubScopes.AddRange(moveScopes);
+      return base.Apply();
+    }
+
+    protected abstract Swap2Move[] GenerateMoves(LinearLinkage lle);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/Swap2MoveMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/Swap2MoveMaker.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Moves/Swap/Swap2MoveMaker.cs	(revision 14776)
@@ -0,0 +1,106 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Swap2MoveMaker", "Peforms a swap-2 move on a given grouping and updates the quality.")]
+  [StorableClass]
+  public class Swap2MoveMaker : SingleSuccessorOperator, ILinearLinkageSwap2MoveOperator, IMoveMaker, ISingleObjectiveOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (ILookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+    public ILookupParameter<LinearLinkage> LLEParameter {
+      get { return (ILookupParameter<LinearLinkage>)Parameters["LLE"]; }
+    }
+
+    [StorableConstructor]
+    protected Swap2MoveMaker(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveMaker(Swap2MoveMaker original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The move to apply."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
+      Parameters.Add(new LookupParameter<LinearLinkage>("LLE", "The linear linkage encoded solution to which the move should be applied."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveMaker(this, cloner);
+    }
+
+    public static void Apply(LinearLinkage lle, Swap2Move move) {
+      var groups = lle.GetGroups().ToList();
+      int g1 = -1, g2 = -1, g1Idx = -1, g2Idx = -1;
+      for (var i = 0; i < groups.Count; i++) {
+        if (g1 < 0) {
+          g1Idx = groups[i].IndexOf(move.Item1);
+          if (g1Idx >= 0) {
+            g1 = i;
+            continue;
+          }
+        }
+        if (g2 < 0) {
+          g2Idx = groups[i].IndexOf(move.Item2);
+          if (g2Idx >= 0) g2 = i;
+        }
+      }
+
+      // can happen if (for some reason) the items belong to the same group
+      if (g1 < 0 || g2 < 0) throw new InvalidOperationException("Swap2MoveMaker: Cannot apply swap move, items are not found in different groups.");
+
+      var h = groups[g1][g1Idx];
+      groups[g1][g1Idx] = groups[g2][g2Idx];
+      groups[g2][g2Idx] = h;
+      lle.SetGroups(groups);
+    }
+
+    public override IOperation Apply() {
+      var move = Swap2MoveParameter.ActualValue;
+      var lle = LLEParameter.ActualValue;
+      var moveQuality = MoveQualityParameter.ActualValue;
+      var quality = QualityParameter.ActualValue;
+
+      Apply(lle, move);
+
+      quality.Value = moveQuality.Value;
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Plugin.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Plugin.cs.frame	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Plugin.cs.frame	(revision 14776)
@@ -0,0 +1,38 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Plugin("HeuristicLab.Encodings.LinearLinkageEncoding", "Provides data structures and operators for the linear linkage encoding (LLE).", "3.4.14.$WCREV$")]
+  [PluginFile("HeuristicLab.Encodings.LinearLinkageEncoding-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class HeuristicLabEncodingsLinearLinkageEncodingPlugin : PluginBase { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Properties/AssemblyInfo.cs.frame	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/Properties/AssemblyInfo.cs.frame	(revision 14776)
@@ -0,0 +1,56 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#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.Encodings.LinearLinkage")]
+[assembly: AssemblyDescription("Linear linkage encoding (LLE) for HeuristicLab")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2016 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("1fb5c9e2-42ac-441a-ae79-bfdf261a7262")]
+
+// 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 Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.14.$WCREV$")]
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/ShakingOperators/LLEShakingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/ShakingOperators/LLEShakingOperator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/ShakingOperators/LLEShakingOperator.cs	(revision 14776)
@@ -0,0 +1,88 @@
+﻿#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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("LLE Shaking Operator", "A shaking operator for VNS which uses LLE manipulators to perform the shaking.")]
+  [StorableClass]
+  public class LLEShakingOperator : ShakingOperator<ILinearLinkageManipulator>, IStochasticOperator, ILinearLinkageShakingOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<LinearLinkage> LLEParameter {
+      get { return (ILookupParameter<LinearLinkage>)Parameters["LLE"]; }
+    }
+
+    public ICheckedItemList<ILinearLinkageManipulator> Shakers {
+      get { return Operators; }
+    }
+
+    [StorableConstructor]
+    protected LLEShakingOperator(bool deserializing) : base(deserializing) { }
+    protected LLEShakingOperator(LLEShakingOperator original, Cloner cloner) : base(original, cloner) { }
+    public LLEShakingOperator()
+      : base() {
+      Parameters.Add(new LookupParameter<LinearLinkage>("LLE", "The encoding to shake."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that will be used for stochastic shaking operators."));
+      for (var i = 1; i < 4; i++) {
+        Operators.Add(new MoveItemManipulator(i * 2));
+        Operators.Add(new SwapItemManipulator(i * 2));
+        Operators.Add(new SplitGroupManipulator(i * 2));
+        Operators.Add(new MergeGroupManipulator(i * 2));
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LLEShakingOperator(this, cloner);
+    }
+
+    #region Wiring of some parameters
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<ILinearLinkageManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<ILinearLinkageManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    private void ParameterizeOperators(IEnumerable<IndexedItem<ILinearLinkageManipulator>> items) {
+      if (!items.Any()) return;
+      foreach (var op in items.Select(x => x.Value).OfType<IStochasticOperator>())
+        op.RandomParameter.ActualName = RandomParameter.Name;
+      foreach (var op in items.Select(x => x.Value))
+        op.LLEParameter.ActualName = LLEParameter.Name;
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/SimilarityCalculators/HammingSimilarityCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/SimilarityCalculators/HammingSimilarityCalculator.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/SimilarityCalculators/HammingSimilarityCalculator.cs	(revision 14776)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.LinearLinkageEncoding {
+  [Item("Hamming Similarity Calculator for LinearLinkage", "Calculates the hamming similarity for two linear linkage encoded solutions.")]
+  [StorableClass]
+  public sealed class HammingSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator {
+
+    protected override bool IsCommutative {
+      get { return true; }
+    }
+
+    [StorableConstructor]
+    private HammingSimilarityCalculator(bool deserializing) : base(deserializing) { }
+    private HammingSimilarityCalculator(HammingSimilarityCalculator original, Cloner cloner) : base(original, cloner) { }
+    public HammingSimilarityCalculator() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HammingSimilarityCalculator(this, cloner);
+    }
+
+    public static double CalculateSimilarity(LinearLinkage left, LinearLinkage right) {
+      if (left.Length != right.Length) throw new ArgumentException("Comparing encodings of unequal length");
+      var similarity = 0;
+      for (var i = 0; i < left.Length; i++) {
+        if (left[i] == right[i]) similarity++;
+      }
+      return similarity / (double)left.Length;
+    }
+
+    public override double CalculateSolutionSimilarity(IScope leftSolution, IScope rightSolution) {
+      var left = leftSolution.Variables[SolutionVariableName].Value as LinearLinkage;
+      var right = rightSolution.Variables[SolutionVariableName].Value as LinearLinkage;
+
+      return CalculateSimilarity(left, right);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 14776)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -42,5 +42,5 @@
     private List<Series> invisibleTargetSeries;
 
-    private const string AllRuns = "All Runs";
+    private const string AllInstances = "All Instances";
 
     private static readonly Color[] colors = new[] {
@@ -223,5 +223,5 @@
       var groupings = Content.ParameterNames.OrderBy(x => x).ToArray();
       groupComboBox.Items.Clear();
-      groupComboBox.Items.Add(AllRuns);
+      groupComboBox.Items.Add(AllInstances);
       groupComboBox.Items.AddRange(groupings);
       if (selectedGroupItem != null && groupComboBox.Items.Contains(selectedGroupItem)) {
@@ -241,6 +241,10 @@
 
       var selectedProblemItem = (ProblemInstance)problemComboBox.SelectedItem;
+      problemComboBox.DataSource = null;
+      problemComboBox.Items.Clear();
       problems.Clear();
       problems.Add(ProblemInstance.MatchAll);
+      problemComboBox.DataSource = new BindingSource() { DataSource = problems };
+      problemComboBox.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
       if (problems[0].Equals(selectedProblemItem)) problemComboBox.SelectedItem = problems[0];
       foreach (var p in problemDict.ToList()) {
@@ -282,34 +286,24 @@
     }
 
-    private Dictionary<string, Dictionary<ProblemInstance, List<IRun>>> GroupRuns() {
-      var groupedRuns = new Dictionary<string, Dictionary<ProblemInstance, List<IRun>>>();
-
+    private IEnumerable<AlgorithmInstance> GroupRuns() {
       var table = (string)dataTableComboBox.SelectedItem;
-      if (string.IsNullOrEmpty(table)) return groupedRuns;
+      if (string.IsNullOrEmpty(table)) yield break;
 
       var selectedGroup = (string)groupComboBox.SelectedItem;
-      if (string.IsNullOrEmpty(selectedGroup)) return groupedRuns;
+      if (string.IsNullOrEmpty(selectedGroup)) yield break;
 
       var selectedProblem = (ProblemInstance)problemComboBox.SelectedItem;
-      if (selectedProblem == null) return groupedRuns;
+      if (selectedProblem == null) yield break;
       
       foreach (var x in (from r in Content
-                         where (selectedGroup == AllRuns || r.Parameters.ContainsKey(selectedGroup))
+                         where (selectedGroup == AllInstances || r.Parameters.ContainsKey(selectedGroup))
                            && selectedProblem.Match(r)
                            && r.Results.ContainsKey(table)
                            && r.Visible
-                         let key = selectedGroup == AllRuns ? AllRuns : r.Parameters[selectedGroup].ToString()
+                         let key = selectedGroup == AllInstances ? AllInstances : r.Parameters[selectedGroup].ToString()
                          group r by key into g
-                         select Tuple.Create(g.Key, g.ToList()))) {
-        var pDict = problems.ToDictionary(r => r, _ => new List<IRun>());
-        foreach (var y in x.Item2) {
-          var pd = new ProblemInstance(y);
-          List<IRun> l;
-          if (pDict.TryGetValue(pd, out l)) l.Add(y);
-        }
-        groupedRuns[x.Item1] = pDict.Where(a => a.Value.Count > 0).ToDictionary(a => a.Key, a => a.Value);
-      }
-
-      return groupedRuns;
+                         select new AlgorithmInstance(g.Key, g, problems))) {
+        yield return x;
+      }
     }
 
@@ -326,6 +320,6 @@
       if (targets == null) GenerateDefaultTargets();
 
-      var groupedRuns = GroupRuns();
-      if (groupedRuns.Count == 0) return;
+      var algInstances = GroupRuns().ToList();
+      if (algInstances.Count == 0) return;
 
       var xAxisTitles = new HashSet<string>();
@@ -337,18 +331,19 @@
       // how many targets have been left open at the point when the run ended
       var misses = new Dictionary<string, SortedList<double, int>>();
+      var totalRuns = new Dictionary<string, int>();
 
       var aggregate = aggregateTargetsCheckBox.Checked;
       double minEff = double.MaxValue, maxEff = double.MinValue;
-      var noRuns = 0;
-      foreach (var group in groupedRuns) {
+      foreach (var alg in algInstances) {
+        var noRuns = 0;
         SortedList<double, int> epdfHits = null, epdfMisses = null;
         if (aggregate) {
-          hits[group.Key] = epdfHits = new SortedList<double, int>();
-          misses[group.Key] = epdfMisses = new SortedList<double, int>();
-        }
-        foreach (var problem in group.Value) {
-          var max = problem.Key.IsMaximization();
-          var absTargets = GetAbsoluteTargets(problem.Key).ToArray();
-          foreach (var run in problem.Value) {
+          hits[alg.Name] = epdfHits = new SortedList<double, int>();
+          misses[alg.Name] = epdfMisses = new SortedList<double, int>();
+        }
+        foreach (var problem in alg.GetProblemInstances()) {
+          var max = problem.IsMaximization();
+          var absTargets = GetAbsoluteTargets(problem).ToArray();
+          foreach (var run in alg.GetRuns(problem)) {
             noRuns++;
             var resultsTable = (IndexedDataTable<double>)run.Results[table];
@@ -361,12 +356,13 @@
               var e = efforts[idx];
               if (!aggregate) {
-                var key = group.Key + "@" + (targetsAreRelative
-                  ? (targets[idx] * 100).ToString(CultureInfo.CurrentCulture.NumberFormat) + "%"
-                  : targets[idx].ToString(CultureInfo.CurrentCulture.NumberFormat));
+                var key = alg.Name + "@" + (targetsAreRelative
+                            ? (targets[idx] * 100).ToString(CultureInfo.CurrentCulture.NumberFormat) + "%"
+                            : targets[idx].ToString(CultureInfo.CurrentCulture.NumberFormat));
                 if (!hits.TryGetValue(key, out epdfHits))
                   hits[key] = epdfHits = new SortedList<double, int>();
                 if (!misses.TryGetValue(key, out epdfMisses))
                   misses[key] = epdfMisses = new SortedList<double, int>();
-              }
+                totalRuns[key] = noRuns;
+              };
               var list = e.Item1 ? epdfHits : epdfMisses;
               int v;
@@ -377,9 +373,10 @@
           }
         }
+        if (aggregate) totalRuns[alg.Name] = noRuns;
       }
 
       UpdateTargetChartAxisXBounds(minEff, maxEff);
 
-      DrawTargetsEcdf(hits, misses, noRuns);
+      DrawTargetsEcdf(hits, misses, totalRuns);
 
       if (targets.Length == 1) {
@@ -392,8 +389,8 @@
       targetChart.ChartAreas[0].CursorY.Interval = 0.05;
 
-      UpdateErtTables(groupedRuns);
-    }
-
-    private void DrawTargetsEcdf(Dictionary<string, SortedList<double, int>> hits, Dictionary<string, SortedList<double, int>> misses, int noRuns) {
+      UpdateErtTables(algInstances);
+    }
+
+    private void DrawTargetsEcdf(Dictionary<string, SortedList<double, int>> hits, Dictionary<string, SortedList<double, int>> misses, Dictionary<string, int> noRuns) {
       var colorCount = 0;
       var lineStyleCount = 0;
@@ -418,5 +415,5 @@
         var iter = misses[list.Key].GetEnumerator();
         var moreMisses = iter.MoveNext();
-        var totalTargets = noRuns;
+        var totalTargets = noRuns[list.Key];
         if (aggregateTargetsCheckBox.Checked) totalTargets *= targets.Length;
         var movingTargets = totalTargets;
@@ -594,8 +591,8 @@
     }
 
-    private void UpdateErtTables(Dictionary<string, Dictionary<ProblemInstance, List<IRun>>> groupedRuns) {
+    private void UpdateErtTables(List<AlgorithmInstance> algorithmInstances) {
       ertTableView.Content = null;
       var columns = 1 + targets.Length + 1;
-      var matrix = new string[groupedRuns.Count * groupedRuns.Max(x => x.Value.Count) + groupedRuns.Max(x => x.Value.Count), columns];
+      var matrix = new string[algorithmInstances.Count * algorithmInstances.Max(x => x.GetNumberOfProblemInstances()) + algorithmInstances.Max(x => x.GetNumberOfProblemInstances()), columns];
       var rowCount = 0;
 
@@ -603,5 +600,5 @@
       if (string.IsNullOrEmpty(tableName)) return;
       
-      var problems = groupedRuns.SelectMany(x => x.Value.Keys).Distinct().ToList();
+      var problems = algorithmInstances.SelectMany(x => x.GetProblemInstances()).Distinct().ToList();
 
       foreach (var problem in problems) {
@@ -615,12 +612,12 @@
         rowCount++;
 
-        foreach (var group in groupedRuns) {
-          matrix[rowCount, 0] = group.Key;
-          if (!group.Value.ContainsKey(problem)) {
+        foreach (var alg in algorithmInstances) {
+          matrix[rowCount, 0] = alg.Name;
+          var runs = alg.GetRuns(problem).ToList();
+          if (runs.Count == 0) {
             matrix[rowCount, columns - 1] = "N/A";
             rowCount++;
             continue;
           }
-          var runs = group.Value[problem];
           var result = default(ErtCalculationResult);
           for (var i = 0; i < absTargets.Length; i++) {
@@ -648,21 +645,21 @@
       if (budgets == null) GenerateDefaultBudgets(table);
 
-      var groupedRuns = GroupRuns();
-      if (groupedRuns.Count == 0) return;
+      var algInstances = GroupRuns().ToList();
+      if (algInstances.Count == 0) return;
 
       var colorCount = 0;
       var lineStyleCount = 0;
       
-      foreach (var group in groupedRuns) {
+      foreach (var alg in algInstances) {
         var hits = new Dictionary<string, SortedList<double, double>>();
 
-        foreach (var problem in group.Value) {
-          foreach (var run in problem.Value) {
+        foreach (var problem in alg.GetProblemInstances()) {
+          foreach (var run in alg.GetRuns(problem)) {
             var resultsTable = (IndexedDataTable<double>)run.Results[table];
 
             if (aggregateBudgetsCheckBox.Checked) {
-              CalculateHitsForAllBudgets(hits, resultsTable.Rows.First(), group.Value.Count, problem.Key, group.Key, problem.Value.Count);
+              CalculateHitsForAllBudgets(hits, resultsTable.Rows.First(), alg.GetNumberOfProblemInstances(), problem, alg.Name, alg.GetNumberOfRuns(problem));
             } else {
-              CalculateHitsForEachBudget(hits, resultsTable.Rows.First(), group.Value.Count, problem.Key, group.Key, problem.Value.Count);
+              CalculateHitsForEachBudget(hits, resultsTable.Rows.First(), alg.GetNumberOfProblemInstances(), problem, alg.Name, alg.GetNumberOfRuns(problem));
             }
           }
@@ -697,5 +694,5 @@
 
     private void GenerateDefaultBudgets(string table) {
-      var runs = GroupRuns().SelectMany(x => x.Value.Values).SelectMany(x => x).ToList();
+      var runs = Content;
       var min = runs.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Min()).Min();
       var max = runs.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Max()).Max();
@@ -1172,4 +1169,72 @@
     }
 
+    private class AlgorithmInstance : INotifyPropertyChanged {
+      private string name;
+      public string Name {
+        get { return name; }
+        set {
+          if (name == value) return;
+          name = value;
+          OnPropertyChanged("Name");
+        }
+      }
+
+      private Dictionary<ProblemInstance, List<IRun>> performanceData;
+
+      public int GetNumberOfProblemInstances() {
+        return performanceData.Count;
+      }
+
+      public IEnumerable<ProblemInstance> GetProblemInstances() {
+        return performanceData.Keys;
+      }
+
+      public int GetNumberOfRuns(ProblemInstance p) {
+        if (p == ProblemInstance.MatchAll) return performanceData.Select(x => x.Value.Count).Sum();
+        List<IRun> runs;
+        if (performanceData.TryGetValue(p, out runs))
+          return runs.Count;
+
+        return 0;
+      }
+
+      public IEnumerable<IRun> GetRuns(ProblemInstance p) {
+        if (p == ProblemInstance.MatchAll) return performanceData.SelectMany(x => x.Value);
+        List<IRun> runs;
+        if (performanceData.TryGetValue(p, out runs))
+          return runs;
+
+        return Enumerable.Empty<IRun>();
+      }
+
+      public AlgorithmInstance(string name, IEnumerable<IRun> runs, IEnumerable<ProblemInstance> problems) {
+        this.name = name;
+
+        var pDict = problems.ToDictionary(r => r, _ => new List<IRun>());
+        foreach (var y in runs) {
+          var pd = new ProblemInstance(y);
+          List<IRun> l;
+          if (pDict.TryGetValue(pd, out l)) l.Add(y);
+        }
+        performanceData = pDict.Where(x => x.Value.Count > 0).ToDictionary(x => x.Key, x => x.Value);
+      }
+
+      public override bool Equals(object obj) {
+        var other = obj as AlgorithmInstance;
+        if (other == null) return false;
+        return name == other.name;
+      }
+
+      public override int GetHashCode() {
+        return name.GetHashCode();
+      }
+
+      public event PropertyChangedEventHandler PropertyChanged;
+      protected virtual void OnPropertyChanged(string propertyName = null) {
+        var handler = PropertyChanged;
+        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+      }
+    }
+
     private class ProblemInstance : INotifyPropertyChanged {
       private readonly bool matchAll;
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 14776)
@@ -202,4 +202,5 @@
     <Compile Include="Interfaces\IMultiObjectiveOperator.cs" />
     <Compile Include="Interfaces\IPreexistingSolutionCreator.cs" />
+    <Compile Include="Interfaces\ISolutionModel.cs" />
     <Compile Include="Results\IResultParameter.cs" />
     <Compile Include="Interfaces\ISingleObjectiveOperator.cs" />
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISolutionModel.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISolutionModel.cs	(revision 14776)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISolutionModel.cs	(revision 14776)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface ISolutionModel<TSolution> : IItem {
+    TSolution Sample();
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/KnowledgeCenter.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/KnowledgeCenter.cs	(revision 14775)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/KnowledgeCenter.cs	(revision 14776)
@@ -202,6 +202,7 @@
         key2Idx.Add(kvp.Key, kvp.Index);
 
+      Func<double[], double[], double> euclid = (a, b) => Math.Sqrt(a.Zip(b, (x, y) => (x - y)).Sum(x => x * x));
+      Func<DoubleArray, DoubleArray, double> euclidDArray = (a, b) => Math.Sqrt(a.Zip(b, (x, y) => (x - y)).Sum(x => x * x));
       #region MDS
-      Func<double[], double[], double> euclid = (a, b) => Math.Sqrt(a.Zip(b, (x, y) => (x - y)).Sum(x => x * x));
       var num = instances.Count;
       var matrix = new DoubleMatrix(num, num);
@@ -243,5 +244,7 @@
         tsneFeatures[key2Idx.GetByFirst(instance.Key)] = new DoubleArray(instance.Value);
       }
-      var tsneCoords = TSNE<DoubleArray>.Run(tsneFeatures, 2, Math.Min((instances.Count - 1) / 3, 50), 0.1, (a, b) => Math.Sqrt(a.Zip(b, (c, d) => (c - d) * (c - d)).Sum()), new FastRandom(42));
+      var tsne = new TSNE<DoubleArray>(new EuclidianDistance(), new FastRandom(42), stopLyingIter: 0, momSwitchIter: 0, momentum: 0, finalMomentum: 0, eta: 10);
+      var tsneCoords = tsne.Run(tsneFeatures, 2, Math.Min((instances.Count - 1) / 4, 50), 0);
+      //var tsneCoords = TSNE<DoubleArray>.Run(tsneFeatures, 2, Math.Min((instances.Count - 1) / 4, 50), 0, euclidDArray, new FastRandom(42));
       #endregion
 
Index: /branches/PerformanceComparison/PerformanceComparison.sln
===================================================================
--- /branches/PerformanceComparison/PerformanceComparison.sln	(revision 14775)
+++ /branches/PerformanceComparison/PerformanceComparison.sln	(revision 14776)
@@ -27,4 +27,8 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.Instances.QAPLIB-3.3", "HeuristicLab.Problems.Instances.QAPLIB\3.3\HeuristicLab.Problems.Instances.QAPLIB-3.3.csproj", "{73F29D43-5714-4069-8FAB-0D18FEB5F175}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Encodings.BinaryVectorEncoding-3.3", "HeuristicLab.Encodings.BinaryVectorEncoding\3.3\HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj", "{66D249C3-A01D-42A8-82A2-919BC8EC3D83}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Encodings.LinearLinkageEncoding-3.4", "HeuristicLab.Encodings.LinearLinkageEncoding\3.4\HeuristicLab.Encodings.LinearLinkageEncoding-3.4.csproj", "{BE698769-975A-429E-828C-72BB2B6182C8}"
 EndProject
 Global
@@ -182,4 +186,28 @@
 		{73F29D43-5714-4069-8FAB-0D18FEB5F175}.Release|x86.ActiveCfg = Release|x86
 		{73F29D43-5714-4069-8FAB-0D18FEB5F175}.Release|x86.Build.0 = Release|x86
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Debug|x64.ActiveCfg = Debug|x64
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Debug|x64.Build.0 = Debug|x64
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Debug|x86.ActiveCfg = Debug|x86
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Debug|x86.Build.0 = Debug|x86
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Release|Any CPU.Build.0 = Release|Any CPU
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Release|x64.ActiveCfg = Release|x64
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Release|x64.Build.0 = Release|x64
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Release|x86.ActiveCfg = Release|x86
+		{66D249C3-A01D-42A8-82A2-919BC8EC3D83}.Release|x86.Build.0 = Release|x86
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Debug|x64.ActiveCfg = Debug|x64
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Debug|x64.Build.0 = Debug|x64
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Debug|x86.ActiveCfg = Debug|x86
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Debug|x86.Build.0 = Debug|x86
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Release|x64.ActiveCfg = Release|x64
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Release|x64.Build.0 = Release|x64
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Release|x86.ActiveCfg = Release|x86
+		{BE698769-975A-429E-828C-72BB2B6182C8}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /branches/PerformanceComparison/ProblemInstanceIdentifier/InstanceExplorer.cs
===================================================================
--- /branches/PerformanceComparison/ProblemInstanceIdentifier/InstanceExplorer.cs	(revision 14775)
+++ /branches/PerformanceComparison/ProblemInstanceIdentifier/InstanceExplorer.cs	(revision 14776)
@@ -74,4 +74,32 @@
   }
 
+  public class AdaptiveWalkExplorer : InstanceExplorer {
+    public int Iterations { get; set; }
+
+    public override string Name { get { return "Adaptive-Walk Explorer"; } }
+    public override int Effort { get { return Iterations; } }
+
+    public AdaptiveWalkExplorer() {
+
+    }
+
+    public override InstanceDescriptor Explore(QuadraticAssignmentProblem problem, int? seed = null) {
+      var walk = new AdaptiveWalk() {
+        SeedParameter = { Value = { Value = seed ?? 0 } },
+        SetSeedRandomlyParameter = { Value = { Value = seed.HasValue } },
+        MaximumIterationsParameter = { Value = { Value = Iterations } },
+        RepetitionsParameter = { Value = { Value = 1 } }
+      };
+      walk.Problem = problem;
+      walk.Engine = new SequentialEngine();
+      walk.MutatorParameter.Value = walk.MutatorParameter.ValidValues.First(x => x is Swap2Manipulator);
+      var calculator = new AdaptiveWalkCalculator(walk) { Problem = problem };
+      var features = calculator.Calculate().ToDictionary(x => x.Name, x => x.Value);
+
+      return new InstanceDescriptor(problem.Name, InstanceDescriptor.GetClass(problem.Name), problem.Weights.Rows,
+        features.Keys.ToArray(), features.Values.Select(x => ((DoubleValue)x).Value).ToArray());
+    }
+  }
+
   public class MemPRExplorer : InstanceExplorer {
     public int Seconds { get; set; }
Index: /branches/PerformanceComparison/ProblemInstanceIdentifier/Program.cs
===================================================================
--- /branches/PerformanceComparison/ProblemInstanceIdentifier/Program.cs	(revision 14775)
+++ /branches/PerformanceComparison/ProblemInstanceIdentifier/Program.cs	(revision 14776)
@@ -4,5 +4,4 @@
 using System.Linq;
 using System.Threading.Tasks;
-using HeuristicLab.Algorithms.MemPR.Permutation;
 using HeuristicLab.PluginInfrastructure;
 using HeuristicLab.Problems.Instances;
