Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Creators/RandomPermutationCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Creators/RandomPermutationCreator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Creators/RandomPermutationCreator.cs	(revision 13694)
@@ -0,0 +1,79 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  /// <summary>
+  /// An operator which creates a new random permutation of integer values.
+  /// </summary>
+  [Item("RandomPermutationCreator", "An operator which creates a new random permutation of integer values.")]
+  [StorableClass]
+  public sealed class RandomPermutationCreator : InstrumentedOperator, IPermutationCreator, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<IntValue> LengthParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["Length"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public IValueParameter<PermutationType> PermutationTypeParameter {
+      get { return (IValueParameter<PermutationType>)Parameters["PermutationType"]; }
+    }
+
+    public PermutationTypes PermutationType {
+      get { return PermutationTypeParameter.Value.Value; }
+      set { PermutationTypeParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    private RandomPermutationCreator(bool deserializing) : base(deserializing) { }
+    private RandomPermutationCreator(RandomPermutationCreator original, Cloner cloner) : base(original, cloner) { }
+    public RandomPermutationCreator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used to initialize the new random permutation."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("Length", "The length of the new random permutation."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The new random permutation."));
+      Parameters.Add(new ValueParameter<PermutationType>("PermutationType", "The type of the permutation.", new PermutationType(PermutationTypes.RelativeUndirected)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RandomPermutationCreator(this, cloner);
+    }
+
+    public override IOperation InstrumentedApply() {
+      PermutationParameter.ActualValue = new Permutation(PermutationType, LengthParameter.ActualValue.Value, RandomParameter.ActualValue);
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/CosaCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/CosaCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/CosaCrossover.cs	(revision 13694)
@@ -0,0 +1,111 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Performs the crossover described in the COSA optimization method.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Wendt, O. 1994. COSA: COoperative Simulated Annealing - Integration von Genetischen Algorithmen und Simulated Annealing am Beispiel der Tourenplanung. Dissertation Thesis. IWI Frankfurt.<br />
+  /// The operator actually performs a 2-opt mutation on the first parent, but it uses the second parent to determine which new edge should be inserted.
+  /// Thus the mutation is not random as the second breakpoint depends on the information that is encoded in other members of the population.
+  /// The idea is that the child should not sit right inbetween the two parents, but rather go a little bit from one parent in direction to the other.
+  /// </remarks>
+  [Item("CosaCrossover", "An operator which performs the crossover described in the COSA optimization method. It is implemented as described in Wendt, O. 1994. COSA: COoperative Simulated Annealing - Integration von Genetischen Algorithmen und Simulated Annealing am Beispiel der Tourenplanung. Dissertation Thesis. IWI Frankfurt.")]
+  [StorableClass]
+  public class CosaCrossover : PermutationCrossover {
+    [StorableConstructor]
+    protected CosaCrossover(bool deserializing) : base(deserializing) { }
+    protected CosaCrossover(CosaCrossover original, Cloner cloner) : base(original, cloner) { }
+    public CosaCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CosaCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// The operator actually performs a 2-opt mutation on the first parent, but it uses the second parent to determine which new edge should be inserted.
+    /// Thus the mutation is not random as the second breakpoint depends on the information that is encoded in other members of the population.
+    /// The idea is that the child should not sit right inbetween the two parents, but rather go a little bit from one parent in direction to the other.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="parent1">The parent scope 1 to cross over.</param>
+    /// <param name="parent2">The parent scope 2 to cross over.</param>
+    /// <returns>The created cross over permutation as int array.</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("CosaCrossover: The parent permutations are of unequal length.");
+      int length = parent1.Length;
+      int[] result = new int[length];
+      int crossPoint, startIndex, endIndex;
+
+      crossPoint = random.Next(length);
+      startIndex = (crossPoint + 1) % length;
+
+      int i = 0;
+      while ((i < parent2.Length) && (parent2[i] != parent1[crossPoint])) {  // find index of cross point in second permutation
+        i++;
+      }
+      int newEdge = parent2[(i + 1) % length]; // the number that follows the cross point number in parent2 is the new edge that we want to insert
+      endIndex = 0;
+      while ((endIndex < parent1.Length) && (parent1[endIndex] != newEdge)) {  // find index of the new edge in the first permutation
+        endIndex++;
+      }
+
+      if (startIndex <= endIndex) {
+        // copy parent1 to child and reverse the order in between startIndex and endIndex
+        for (i = 0; i < parent1.Length; i++) {
+          if (i >= startIndex && i <= endIndex) {
+            result[i] = parent1[endIndex - i + startIndex];
+          } else {
+            result[i] = parent1[i];
+          }
+        }
+      } else { // startIndex > endIndex
+        for (i = 0; i < parent1.Length; i++) {
+          if (i >= startIndex || i <= endIndex) {
+            result[i] = parent1[(endIndex - i + startIndex + length) % length]; // add length to wrap around when dropping below index 0
+          } else {
+            result[i] = parent1[i];
+          }
+        }
+      }
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">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 permutations that should be crossed.</param>
+    /// <returns>The newly created permutation, resulting from the crossover operation.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("CosaCrossover: The number of parents is not equal to 2");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/CyclicCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/CyclicCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/CyclicCrossover.cs	(revision 13694)
@@ -0,0 +1,118 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An operator which performs the cyclic crossover on two permutations.
+  /// </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.<br />
+  /// The operator first determines all cycles in the permutation and then composes the offspring by alternating between the cycles of the two parents.
+  /// </remarks>
+  [Item("CyclicCrossover", "An operator which performs the cyclic crossover on two permutations. 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 class CyclicCrossover : PermutationCrossover {
+    [StorableConstructor]
+    protected CyclicCrossover(bool deserializing) : base(deserializing) { }
+    protected CyclicCrossover(CyclicCrossover original, Cloner cloner) : base(original, cloner) { }
+    public CyclicCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CyclicCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs the cyclic crossover on <paramref name="parent1"/> and <paramref name="parent2"/>.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
+    /// <exception cref="InvalidOperationException">Thrown if the numbers in the permutation elements are not in the range [0;N) with N = length of the permutation.</exception>
+    /// <remarks>
+    /// First this method randomly determines from which parent to start with equal probability.
+    /// Then it copies the first cycle from the chosen parent starting from index 0 in the permutation.
+    /// After the cycle is complete it copies the next cycle starting from the index closest to 0 which was not yet copied from the other parent.
+    /// It continues to switch between parents for each completed cycle until no new cycle is found anymore.<br /><br />
+    /// The stochasticity of this operator is rather low. There are only two possible outcomes for a given pair of parents.
+    /// </remarks>
+    /// <exception cref="ArgumentException">Thrown if the two parents are not of equal length.</exception>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="parent1">The parent scope 1 to cross over.</param>
+    /// <param name="parent2">The parent scope 2 to cross over.</param>
+    /// <returns>The created cross over permutation as int array.</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("CyclicCrossover: The parent permutations are of unequal length.");
+      int length = parent1.Length;
+      int[] result = new int[length];
+      bool[] indexCopied = new bool[length];
+      int[] invParent1 = new int[length];
+      int[] invParent2 = new int[length];
+
+      // calculate inverse mappings (number -> index) for parent1 and parent2
+      try {
+        for (int i = 0; i < length; i++) {
+          invParent1[parent1[i]] = i;
+          invParent2[parent2[i]] = i;
+        }
+      }
+      catch (IndexOutOfRangeException) {
+        throw new InvalidOperationException("CyclicCrossover: The permutation must consist of numbers in the interval [0;N) with N = length of the permutation.");
+      }
+
+      // randomly choose whether to start copying from parent1 or parent2
+      bool copyFromParent1 = ((random.NextDouble() < 0.5) ? (false) : (true));
+
+      int j = 0;
+      do {
+        do {
+          if (copyFromParent1) {
+            result[j] = parent1[j]; // copy number at position j from parent1
+            indexCopied[j] = true;
+            j = invParent2[result[j]]; // set position j to the position of the copied number in parent2
+          } else {
+            result[j] = parent2[j]; // copy number at position j from parent2
+            indexCopied[j] = true;
+            j = invParent1[result[j]]; // set position j to the position of the copied number in parent1
+          }
+        } while (!indexCopied[j]);
+        copyFromParent1 = !copyFromParent1;
+        j = 0;
+        while (j < length && indexCopied[j]) j++;
+      } while (j < length);
+
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">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 permutations that should be crossed.</param>
+    /// <returns>The newly created permutation, resulting from the crossover operation.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("CyclicCrossover: The number of parents is not equal to 2.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/CyclicCrossover2.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/CyclicCrossover2.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/CyclicCrossover2.cs	(revision 13694)
@@ -0,0 +1,104 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An operator which performs a variant of the cyclic crossover on two permutations.
+  /// </summary>
+  /// <remarks>It is implemented as described in Affenzeller, M. et al. 2009. Genetic Algorithms and Genetic Programming - Modern Concepts and Practical Applications. CRC Press. p. 136.<br />
+  /// The operator first selects a random position in the permutation and from that position copies the first cycle to the offspring.
+  /// Then all empty positions are filled from the second parent.
+  /// </remarks>
+  [Item("CyclicCrossover2", "An operator which performs the cyclic crossover on two permutations. It is implemented as described in Affenzeller, M. et al. 2009. Genetic Algorithms and Genetic Programming - Modern Concepts and Practical Applications. CRC Press. p. 136.")]
+  [StorableClass]
+  public class CyclicCrossover2 : PermutationCrossover {
+    [StorableConstructor]
+    protected CyclicCrossover2(bool deserializing) : base(deserializing) { }
+    protected CyclicCrossover2(CyclicCrossover2 original, Cloner cloner) : base(original, cloner) { }
+    public CyclicCrossover2() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CyclicCrossover2(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs a variant of the cyclic crossover on <paramref name="parent1"/> and <paramref name="parent2"/>.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
+    /// <exception cref="InvalidOperationException">Thrown if the numbers in the permutation elements are not in the range [0;N) with N = length of the permutation.</exception>
+    /// <remarks>
+    /// Start at a randomly chosen position x in parent1 and transfer it to the child at the same position.
+    /// Now this position x is no longer available for the node on position x in parent2, so
+    /// the value of the node at position x in parent2 is searched in parent1 and is then transferred
+    /// to the child preserving the position. Now this new position y is no longer available for the node in parent2 and so on.<br/>
+    /// This procedure is repeated until it is again at position x, then the cycle is over.<br/>
+    /// All further positions are copied from the second permutation.
+    /// </remarks>
+    /// <exception cref="ArgumentException">Thrown if the two parents are not of equal length.</exception>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="parent1">The parent scope 1 to cross over.</param>
+    /// <param name="parent2">The parent scope 2 to cross over.</param>
+    /// <returns>The created cross over permutation as int array.</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("CyclicCrossover2: The parent permutations are of unequal length.");
+      int length = parent1.Length;
+      int[] result = new int[length];
+      bool[] indexCopied = new bool[length];
+      int j, number;
+
+      j = random.Next(length);  // get number to start cycle
+      while (!indexCopied[j]) {  // copy whole cycle to new permutation
+        result[j] = parent1[j];
+        number = parent2[j];
+        indexCopied[j] = true;
+
+        j = 0;
+        while ((j < length) && (parent1[j] != number)) {  // search copied number in second permutation
+          j++;
+        }
+      }
+
+      for (int i = 0; i < length; i++) {  // copy rest of secound permutation to new permutation
+        if (!indexCopied[i]) {
+          result[i] = parent2[i];
+        }
+      }
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">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 permutations that should be crossed.</param>
+    /// <returns>The newly created permutation, resulting from the crossover operation.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("CyclicCrossover2: The number of parents is not equal to 2.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/EdgeRecombinationCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/EdgeRecombinationCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/EdgeRecombinationCrossover.cs	(revision 13694)
@@ -0,0 +1,163 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Performs a cross over permutation between two permutation arrays by calculating the edges (neighbours)
+  /// of each element. Starts at a randomly chosen position, the next element is a neighbour with the least 
+  /// number of neighbours, the next again a neighbour and so on.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Whitley et.al. 1991, The Traveling Salesman and Sequence Scheduling, in Davis, L. (Ed.), Handbook of Genetic Algorithms, New York, pp. 350-372.<br />
+  /// The operator first determines all cycles in the permutation and then composes the offspring by alternating between the cycles of the two parents.
+  /// </remarks>
+  [Item("EdgeRecombinationCrossover", "An operator which performs the edge recombination crossover on two permutations. It is implemented as described in Whitley et.al. 1991, The Traveling Salesman and Sequence Scheduling, in Davis, L. (Ed.), Handbook of Genetic Algorithms, New York, pp. 350-372.")]
+  [StorableClass]
+  public class EdgeRecombinationCrossover : PermutationCrossover {
+    [StorableConstructor]
+    protected EdgeRecombinationCrossover(bool deserializing) : base(deserializing) { }
+    protected EdgeRecombinationCrossover(EdgeRecombinationCrossover original, Cloner cloner) : base(original, cloner) { }
+    public EdgeRecombinationCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new EdgeRecombinationCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs a cross over permutation of <paramref name="parent1"/> and <paramref name="2"/>
+    /// by calculating the edges of each element. Starts at a randomly chosen position, 
+    /// the next element is a neighbour with the least 
+    /// number of neighbours, the next again a neighbour and so on.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
+    /// <exception cref="InvalidOperationException">Thrown when the permutation lacks a number.
+    /// </exception>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="parent1">The parent scope 1 to cross over.</param>
+    /// <param name="parent2">The parent scope 2 to cross over.</param>
+    /// <returns>The created cross over permutation as int array.</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("EdgeRecombinationCrossover: The parent permutations are of unequal length.");
+      int length = parent1.Length;
+      int[] result = new int[length];
+      int[,] edgeList = new int[length, 4];
+      bool[] remainingNumbers = new bool[length];
+      int index, currentEdge, currentNumber, nextNumber, currentEdgeCount, minEdgeCount;
+
+      for (int i = 0; i < length; i++) {  // generate edge list for every number
+        remainingNumbers[i] = true;
+
+        index = 0;
+        while ((index < length) && (parent1[index] != i)) {  // search edges in parent1
+          index++;
+        }
+        if (index == length) {
+          throw (new InvalidOperationException("Permutation doesn't contain number " + i + "."));
+        } else {
+          edgeList[i, 0] = parent1[(index - 1 + length) % length];
+          edgeList[i, 1] = parent1[(index + 1) % length];
+        }
+        index = 0;
+        while ((index < length) && (parent2[index] != i)) {  // search edges in parent2
+          index++;
+        }
+        if (index == length) {
+          throw (new InvalidOperationException("Permutation doesn't contain number " + i + "."));
+        } else {
+          currentEdge = parent2[(index - 1 + length) % length];
+          if ((edgeList[i, 0] != currentEdge) && (edgeList[i, 1] != currentEdge)) {  // new edge found ?
+            edgeList[i, 2] = currentEdge;
+          } else {
+            edgeList[i, 2] = -1;
+          }
+          currentEdge = parent2[(index + 1) % length];
+          if ((edgeList[i, 0] != currentEdge) && (edgeList[i, 1] != currentEdge)) {  // new edge found ?
+            edgeList[i, 3] = currentEdge;
+          } else {
+            edgeList[i, 3] = -1;
+          }
+        }
+      }
+
+      currentNumber = random.Next(length);  // get number to start
+      for (int i = 0; i < length; i++) {
+        result[i] = currentNumber;
+        remainingNumbers[currentNumber] = false;
+
+        for (int j = 0; j < 4; j++) {  // remove all edges to / from currentNumber
+          if (edgeList[currentNumber, j] != -1) {
+            for (int k = 0; k < 4; k++) {
+              if (edgeList[edgeList[currentNumber, j], k] == currentNumber) {
+                edgeList[edgeList[currentNumber, j], k] = -1;
+              }
+            }
+          }
+        }
+
+        minEdgeCount = 5;  // every number hasn't more than 4 edges
+        nextNumber = -1;
+        for (int j = 0; j < 4; j++) {  // find next number with least edges
+          if (edgeList[currentNumber, j] != -1) {  // next number found
+            currentEdgeCount = 0;
+            for (int k = 0; k < 4; k++) {  // count edges of next number
+              if (edgeList[edgeList[currentNumber, j], k] != -1) {
+                currentEdgeCount++;
+              }
+            }
+            if ((currentEdgeCount < minEdgeCount) ||
+              ((currentEdgeCount == minEdgeCount) && (random.NextDouble() < 0.5))) {
+              nextNumber = edgeList[currentNumber, j];
+              minEdgeCount = currentEdgeCount;
+            }
+          }
+        }
+        currentNumber = nextNumber;
+        if (currentNumber == -1) {  // current number has no more edge
+          index = 0;
+          while ((index < length) && (!remainingNumbers[index])) {  // choose next remaining number
+            index++;
+          }
+          if (index < length) {
+            currentNumber = index;
+          }
+        }
+      }
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">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 permutations that should be crossed.</param>
+    /// <returns>The newly created permutation, resulting from the crossover operation.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("ERROR in EdgeRecombinationCrossover: The number of parents is not equal to 2");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/MaximalPreservativeCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/MaximalPreservativeCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/MaximalPreservativeCrossover.cs	(revision 13694)
@@ -0,0 +1,151 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>An operator which performs the maximal preservative crossover on two permutations.</summary>
+  /// <remarks>
+  /// Performs a crossover between two permuation arrays by preserving a large number of edges in both parents.
+  /// The operator also maintains the position in the arrays to some extent.
+  /// It is implemented as described in Mühlenbein, H. 1991. Evolution in time and space - the parallel genetic algorithm. FOUNDATIONS OF GENETIC ALGORITHMS, pp. 316-337. Morgan Kaufmann.<br /><br />
+  /// The length of the segment copied from the first parent to the offspring is uniformly distributed in the interval [3;N/3) with N = length of the permutation.
+  /// This recommendation is mentioned in Pohlheim, H. 1999. Evolutionäre Algorithmen: Verfahren, Operatoren und Hinweise für die Praxis, p. 44, Springer.
+  /// If the length of the permutation is smaller than 15, the size of the segment is always equal to 3.
+  /// </remarks>
+  [Item("MaximalPreservativeCrossover", "An operator which performs the maximal preservative crossover on two permutations. It is implemented as described in Mühlenbein, H. 1991. Evolution in time and space - the parallel genetic algorithm. FOUNDATIONS OF GENETIC ALGORITHMS, pp. 316-337. Morgan Kaufmann.")]
+  [StorableClass]
+  public class MaximalPreservativeCrossover : PermutationCrossover {
+    [StorableConstructor]
+    protected MaximalPreservativeCrossover(bool deserializing) : base(deserializing) { }
+    protected MaximalPreservativeCrossover(MaximalPreservativeCrossover original, Cloner cloner) : base(original, cloner) { }
+    public MaximalPreservativeCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MaximalPreservativeCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs the maximal preservative crossover on <paramref name="parent1"/> and <paramref name="parent2"/>
+    /// by preserving a large number of edges in both parents.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length or when the permutations are shorter than 4 elements.</exception>
+    /// <exception cref="InvalidOperationException">Thrown if the numbers in the permutation elements are not in the range [0;N) with N = length of the permutation.</exception>
+    /// <remarks>
+    /// First one segment is copied from the first parent to the offspring in the same position.
+    /// Then the tour is completed by adding the next number from the second parent if such an edge exists,
+    /// or from the first parent, or from the next number of the second parent.
+    /// The last case results in an unwanted mutation.
+    /// </remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parent1">The first parent permutation to cross.</param>
+    /// <param name="parent2">The second parent permutation to cross.</param>
+    /// <returns>The new permutation resulting from the crossover.</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("MaximalPreservativeCrossover: The parent permutations are of unequal length.");
+      if (parent1.Length < 4) throw new ArgumentException("MaximalPreservativeCrossover: The parent permutation must be at least of size 4.");
+      int length = parent1.Length;
+      int[] result = new int[length];
+      bool[] numberCopied = new bool[length];
+      int breakPoint1, breakPoint2, subsegmentLength, index;
+
+      subsegmentLength = random.Next(3, Math.Max(length / 3, 4)); // as mentioned in Pohlheim, H. Evolutionäre Algorithmen: Verfahren, Operatoren und Hinweise für die Praxis, 1999, p.44, Springer.
+      breakPoint1 = random.Next(length);
+      breakPoint2 = breakPoint1 + subsegmentLength;
+      if (breakPoint2 >= length) breakPoint2 -= length;
+
+      // copy string between position [breakPoint1, breakPoint2) from parent1 to the offspring
+      index = breakPoint1;
+      do {
+        result[index] = parent1[index];
+        numberCopied[result[index]] = true;
+        index++;
+        if (index >= length) index -= length;
+      } while (index != breakPoint2);
+
+      // calculate inverse permutation (number -> index) to help finding the follower of a given number
+      int[] invParent1 = new int[length];
+      int[] invParent2 = new int[length];
+      try {
+        for (int i = 0; i < length; i++) {
+          invParent1[parent1[i]] = i;
+          invParent2[parent2[i]] = i;
+        }
+      }
+      catch (IndexOutOfRangeException) {
+        throw new InvalidOperationException("MaximalPreservativeCrossover: The permutation must consist of numbers in the interval [0;N) with N = length of the permutation.");
+      }
+
+      int prevIndex = ((index > 0) ? (index - 1) : (length - 1));
+      do {
+        // look for the follower of the last number in parent2
+        int p2Follower = GetFollower(parent2, invParent2[result[prevIndex]]);
+        if (!numberCopied[p2Follower]) {
+          result[index] = p2Follower;
+        } else {
+          // if that follower has already been added, look for the follower of the last number in parent1
+          int p1Follower = GetFollower(parent1, invParent1[result[prevIndex]]);
+          if (!numberCopied[p1Follower]) {
+            result[index] = p1Follower;
+          } else {
+            // if that has also been added, look for the next not already added number in parent2
+            int tempIndex = index;
+            for (int i = 0; i < parent2.Length; i++) {
+              if (!numberCopied[parent2[tempIndex]]) {
+                result[index] = parent2[tempIndex];
+                break;
+              }
+              tempIndex++;
+              if (tempIndex >= parent2.Length) tempIndex = 0;
+            }
+          }
+        }
+        numberCopied[result[index]] = true;
+        prevIndex = index;
+        index++;
+        if (index >= length) index -= length;
+      } while (index != breakPoint1);
+
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    private static int GetFollower(Permutation parent, int index) {
+      if (index + 1 == parent.Length)
+        return parent[0];
+      return parent[index + 1];
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">Thrown if there are not exactly two permutations in <paramref name="parents"/>.</exception>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parents">An array containing the two permutations that should be crossed.</param>
+    /// <returns>The newly created permutation, resulting from the crossover operation.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("MaximalPreservativeCrossover: Number of parents is not equal to 2.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/MultiPermutationCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/MultiPermutationCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/MultiPermutationCrossover.cs	(revision 13694)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("MultiPermutationCrossover", "Randomly selects and applies one of its crossovers every time it is called.")]
+  [StorableClass]
+  public class MultiPermutationCrossover : StochasticMultiBranch<IPermutationCrossover>, IPermutationCrossover, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+
+    public ILookupParameter<ItemArray<Permutation>> ParentsParameter {
+      get { return (ILookupParameter<ItemArray<Permutation>>)Parameters["Parents"]; }
+    }
+
+    public ILookupParameter<Permutation> ChildParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Child"]; }
+    }
+
+    [StorableConstructor]
+    protected MultiPermutationCrossover(bool deserializing) : base(deserializing) { }
+    protected MultiPermutationCrossover(MultiPermutationCrossover original, Cloner cloner) : base(original, cloner) { }
+    public MultiPermutationCrossover()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<Permutation>("Parents", "The parent permutations which should be crossed."));
+      ParentsParameter.ActualName = "Permutation";
+      Parameters.Add(new LookupParameter<Permutation>("Child", "The child permutation resulting from the crossover."));
+      ChildParameter.ActualName = "Permutation";
+
+      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IPermutationCrossover))) {
+        if (!typeof(MultiOperator<IPermutationCrossover>).IsAssignableFrom(type))
+          Operators.Add((IPermutationCrossover)Activator.CreateInstance(type), true);
+      }
+
+      SelectedOperatorParameter.ActualName = "SelectedCrossoverOperator";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiPermutationCrossover(this, cloner);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IPermutationCrossover>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeCrossovers();
+    }
+
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IPermutationCrossover>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeCrossovers();
+    }
+
+    private void ParameterizeCrossovers() {
+      foreach (IPermutationCrossover crossover in Operators.OfType<IPermutationCrossover>()) {
+        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 permutation crossover to choose from.");
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/OrderBasedCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/OrderBasedCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/OrderBasedCrossover.cs	(revision 13694)
@@ -0,0 +1,116 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Performs a cross over permutation of two permutation arrays by taking randomly a selection of values 
+  /// (not an interval!) from the first permutation keeping the correct order and filling 
+  /// the missing entries with the elements from the second permutation, also in the right order.
+  /// </summary>
+  /// <remarks>
+  /// This is in some papers also called Order Crossover #2.<br />
+  /// It is implemented as described in Syswerda, G. (1991). Schedule Optimization Using Genetic Algorithms. In Davis, L. (Ed.) Handbook of Genetic Algorithms, Van Nostrand Reinhold, New York, pp. 332-349.
+  /// </remarks>
+  [Item("OrderBasedCrossover", "An operator which performs an order based crossover of two permutations. It is implemented as described in Syswerda, G. (1991). Schedule Optimization Using Genetic Algorithms. In Davis, L. (Ed.) Handbook of Genetic Algorithms, Van Nostrand Reinhold, New York, pp. 332-349.")]
+  [StorableClass]
+  public class OrderBasedCrossover : PermutationCrossover {
+    [StorableConstructor]
+    protected OrderBasedCrossover(bool deserializing) : base(deserializing) { }
+    protected OrderBasedCrossover(OrderBasedCrossover original, Cloner cloner) : base(original, cloner) { }
+    public OrderBasedCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OrderBasedCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs a cross over permutation of <paramref name="parent1"/> and <paramref name="parent2"/> by
+    /// randomly selecting some values from the first permutation that will be inserted one after each 
+    /// other; the missing ones are picked in the correct order from the second permutation.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parent1">The first parent permutation to cross.</param>
+    /// <param name="parent2">The second parent permutation to cross.</param>
+    /// <returns>The new permutation resulting from the crossover.</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("OrderBasedCrossover: The parent permutations are of unequal length.");
+      int length = parent1.Length;
+      int[] result = new int[length];
+      int[] selectedNumbers = new int[random.Next(length + 1)];
+      bool[] numberSelected = new bool[length];
+      int index, selectedIndex, currentIndex;
+
+      for (int i = 0; i < selectedNumbers.Length; i++) {  // select numbers for array
+        index = 0;
+        while (numberSelected[parent1[index]]) {  // find first valid index
+          index++;
+        }
+
+        selectedIndex = random.Next(length - i);
+        currentIndex = 0;
+        while ((index < parent1.Length) && (currentIndex != selectedIndex)) {  // find selected number
+          index++;
+          if (!numberSelected[parent1[index]]) {
+            currentIndex++;
+          }
+        }
+        numberSelected[parent1[index]] = true;
+      }
+
+      index = 0;
+      for (int i = 0; i < parent1.Length; i++) {  // copy selected numbers in array
+        if (numberSelected[parent1[i]]) {
+          selectedNumbers[index] = parent1[i];
+          index++;
+        }
+      }
+
+      index = 0;
+      for (int i = 0; i < result.Length; i++) {  // copy rest of second permutation and selected numbers in order of first permutation
+        if (numberSelected[parent2[i]]) {
+          result[i] = selectedNumbers[index];
+          index++;
+        } else {
+          result[i] = parent2[i];
+        }
+      }
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">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 permutations that should be crossed.</param>
+    /// <returns>The new permutation resulting from the crossover.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("OrderCrossover: Number of parents is not equal to 2.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/OrderCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/OrderCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/OrderCrossover.cs	(revision 13694)
@@ -0,0 +1,108 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An operator which performs the order crossover on two permutations.
+  /// </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.<br />
+  /// Crosses two permutations by copying a randomly chosen interval from the first permutation, preserving
+  /// the positions. Then, starting from the end of the copied interval, copies the missing values from the second permutation
+  /// in the order they occur.
+  /// </remarks>
+  [Item("OrderCrossover", "An operator which performs an order crossover of two permutations. 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 class OrderCrossover : PermutationCrossover {
+    [StorableConstructor]
+    protected OrderCrossover(bool deserializing) : base(deserializing) { }
+    protected OrderCrossover(OrderCrossover original, Cloner cloner) : base(original, cloner) { }
+    public OrderCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OrderCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs the order crossover of two permutations.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
+    /// <exception cref="InvalidOperationException">Thrown if the numbers in the permutation elements are not in the range [0,N) with N = length of the permutation.</exception>
+    /// <remarks>
+    /// Crosses two permutations by copying a randomly chosen interval from the first permutation, preserving
+    /// the positions. Then, starting from the end of the copied interval, copies the missing values from the second permutation
+    /// in the order they occur.
+    /// </remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parent1">The first parent permutation to cross.</param>
+    /// <param name="parent2">The second parent permutation to cross.</param>
+    /// <returns>The new permutation resulting from the crossover.</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("OrderCrossover: The parent permutations are of unequal length.");
+      int length = parent1.Length;
+      int[] result = new int[length];
+      bool[] copied = new bool[length];
+
+      int breakPoint1 = random.Next(length - 1);
+      int breakPoint2 = random.Next(breakPoint1 + 1, length);
+
+      try {
+        for (int j = breakPoint1; j <= breakPoint2; j++) {  // copy part of first permutation
+          result[j] = parent1[j];
+          copied[parent1[j]] = true;
+        }
+
+        int index = ((breakPoint2 + 1 >= length) ? (0) : (breakPoint2 + 1));
+        int i = index; // for moving in parent2
+        while (index != breakPoint1) {
+          if (!copied[parent2[i]]) {
+            result[index] = parent2[i];
+            index++;
+            if (index >= length) index = 0;
+          }
+          i++;
+          if (i >= length) i = 0;
+        }
+      }
+      catch (IndexOutOfRangeException) {
+        throw new InvalidOperationException("OrderCrossover: The permutation must consist of numbers in the interval [0;N) with N = length of the permutation.");
+      }
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">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 permutations that should be crossed.</param>
+    /// <returns>The new permutation resulting from the crossover.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("OrderCrossover: Number of parents is not equal to 2.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/OrderCrossover2.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/OrderCrossover2.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/OrderCrossover2.cs	(revision 13694)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An operator which performs a slight variant of the order crossover on two permutations.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Affenzeller, M. et al. 2009. Genetic Algorithms and Genetic Programming - Modern Concepts and Practical Applications. CRC Press. p. 135.<br />
+  /// Crosses two permutations by copying a randomly chosen interval from the first permutation, preserving
+  /// the positions. But then, instead of starting from the end of the copied interval, the missing values are copied from the start of the permutation in the order they occur.
+  /// </remarks>
+  [Item("OrderCrossover2", "An operator which performs an order crossover of two permutations. It is implemented as described in Affenzeller, M. et al. 2009. Genetic Algorithms and Genetic Programming - Modern Concepts and Practical Applications. CRC Press. p. 135.")]
+  [StorableClass]
+  public class OrderCrossover2 : PermutationCrossover {
+    [StorableConstructor]
+    protected OrderCrossover2(bool deserializing) : base(deserializing) { }
+    protected OrderCrossover2(OrderCrossover2 original, Cloner cloner) : base(original, cloner) { }
+    public OrderCrossover2() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OrderCrossover2(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs a slight variation of the order crossover of two permutations.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
+    /// <remarks>
+    /// Crosses two permutations by copying a randomly chosen interval from the first permutation, preserving
+    /// the positions. Then, from the beginning of the permutation, copies the missing values from the second permutation
+    /// in the order they occur.
+    /// </remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parent1">The first parent permutation to cross.</param>
+    /// <param name="parent2">The second parent permutation to cross.</param>
+    /// <returns>The new permutation resulting from the crossover.</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("OrderCrossover2: The parent permutations are of unequal length.");
+      int[] result = new int[parent1.Length];
+      bool[] copied = new bool[result.Length];
+
+      int breakPoint1 = random.Next(result.Length - 1);
+      int breakPoint2 = random.Next(breakPoint1 + 1, result.Length);
+
+      for (int i = breakPoint1; i <= breakPoint2; i++) {  // copy part of first permutation
+        result[i] = parent1[i];
+        copied[parent1[i]] = true;
+      }
+
+      int index = 0;
+      for (int i = 0; i < parent2.Length; i++) {  // copy remaining part of second permutation
+        if (index == breakPoint1) {  // skip already copied part
+          index = breakPoint2 + 1;
+        }
+        if (!copied[parent2[i]]) {
+          result[index] = parent2[i];
+          index++;
+        }
+      }
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">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 permutations that should be crossed.</param>
+    /// <returns>The new permutation resulting from the crossover.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("OrderCrossover2: Number of parents is not equal to 2.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/PartiallyMatchedCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/PartiallyMatchedCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/PartiallyMatchedCrossover.cs	(revision 13694)
@@ -0,0 +1,112 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An operator which performs the partially matched crossover on two permutations.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Fogel, D.B. 1988. An Evolutionary Approach to the Traveling Salesman Problem. Biological Cybernetics, 60, pp. 139-144, Springer-Verlag.
+  /// which references Goldberg, D.E., and Lingle, R. 1985. Alleles, loci, and the traveling salesman problem. Proceedings of an International Conference on Genetic Algorithms and their Applications. Carnegie-Mellon University, pp. 154-159.
+  /// as the original source of the operator.
+  /// </remarks>
+  [Item("PartiallyMatchedCrossover", "An operator which performs the partially matched crossover on two permutations. It is implemented as described in Fogel, D.B. 1988. An Evolutionary Approach to the Traveling Salesman Problem. Biological Cybernetics, 60, pp. 139-144, Springer-Verlag.")]
+  [StorableClass]
+  public class PartiallyMatchedCrossover : PermutationCrossover {
+    [StorableConstructor]
+    protected PartiallyMatchedCrossover(bool deserializing) : base(deserializing) { }
+    protected PartiallyMatchedCrossover(PartiallyMatchedCrossover original, Cloner cloner) : base(original, cloner) { }
+    public PartiallyMatchedCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PartiallyMatchedCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs the partially matched crossover on <paramref name="parent1"/> and <paramref name="parent2"/>.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length or when the permutations are shorter than 4 elements.</exception>
+    /// <exception cref="InvalidOperationException">Thrown if the numbers in the permutation elements are not in the range [0,N) with N = length of the permutation.</exception>
+    /// <remarks>
+    /// Initially the new offspring is a clone of <paramref name="parent2"/>.
+    /// Then a segment is extracted from <paramref name="parent1"/> and copied to the offspring position by position.
+    /// Whenever a position is copied, the number at that position currently in the offspring is transfered to the position where the copied number has been.
+    /// E.g.: Position 15 is selected to be copied from <paramref name="parent1"/> to <paramref name="parent2"/>. At position 15 there is a '3' in <paramref name="parent1"/> and a '5' in the new offspring.
+    /// The '5' in the offspring is then moved to replace the '3' in the offspring and '3' is written at position 15.
+    /// </remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parent1">The first parent permutation to cross.</param>
+    /// <param name="parent2">The second parent permutation to cross.</param>
+    /// <returns>The new permutation resulting from the crossover.</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("PartiallyMatchedCrossover: The parent permutations are of unequal length.");
+      if (parent1.Length < 4) throw new ArgumentException("PartiallyMatchedCrossover: The parent permutation must be at least of size 4.");
+      int length = parent1.Length;
+      int[] result = new int[length];
+      int[] invResult = new int[length];
+
+      int breakPoint1, breakPoint2;
+      do {
+        breakPoint1 = random.Next(length - 1);
+        breakPoint2 = random.Next(breakPoint1 + 1, length);
+      } while (breakPoint2 - breakPoint1 >= length - 2); // prevent the case [0,length-1) -> clone of parent1
+
+      // clone parent2 and calculate inverse permutation (number -> index)
+      try {
+        for (int j = 0; j < length; j++) {
+          result[j] = parent2[j];
+          invResult[result[j]] = j;
+        }
+      }
+      catch (IndexOutOfRangeException) {
+        throw new InvalidOperationException("PartiallyMatchedCrossover: The permutation must consist of consecutive numbers from 0 to N-1 with N = length of the permutation.");
+      }
+
+      for (int j = breakPoint1; j <= breakPoint2; j++) {
+        int orig = result[j]; // save the former value
+        result[j] = parent1[j]; // overwrite the former value with the new value
+        int index = invResult[result[j]]; // look where the new value is in the offspring
+        result[index] = orig; // write the former value to this position
+        invResult[orig] = index; // update the inverse mapping
+        // it's not necessary to do 'invResult[result[j]] = j' as this will not be needed again
+      }
+
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">Thrown if there are not exactly two permutations in <paramref name="parents"/>.</exception>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="parents">An array containing the two permutations that should be crossed.</param>
+    /// <returns>The newly created permutation, resulting from the crossover operation.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("PartiallyMatchedCrossover: The number of parents is not equal to 2.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/PositionBasedCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/PositionBasedCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/PositionBasedCrossover.cs	(revision 13694)
@@ -0,0 +1,102 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Performs a cross over permutation between two permutation arrays based on randomly chosen positions.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Syswerda, G. (1991). Schedule Optimization Using Genetic Algorithms. In Davis, L. (Ed.) Handbook of Genetic Algorithms, Van Nostrand Reinhold, New York, pp 332-349.
+  /// </remarks>
+  [Item("PositionBasedCrossover", "An operator which performs the position based crossover on two permutations. It is implemented as described in Syswerda, G. (1991). Schedule Optimization Using Genetic Algorithms. In Davis, L. (Ed.) Handbook of Genetic Algorithms, Van Nostrand Reinhold, New York, pp 332-349.")]
+  [StorableClass]
+  public class PositionBasedCrossover : PermutationCrossover {
+    [StorableConstructor]
+    protected PositionBasedCrossover(bool deserializing) : base(deserializing) { }
+    protected PositionBasedCrossover(PositionBasedCrossover original, Cloner cloner) : base(original, cloner) { }
+    public PositionBasedCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PositionBasedCrossover(this, cloner);
+    }
+
+    /// <summary>
+    /// Performs a cross over permutation of <paramref name="parent1"/> and <paramref name="parent2"/>
+    /// based on randomly chosen positions to define which position to take from where.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="parent1">First parent</param>
+    /// <param name="parent2">Second Parent</param>
+    /// <returns>Child</returns>
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("PositionBasedCrossover: The parent permutations are of unequal length.");
+      int length = parent1.Length;
+      int[] result = new int[length];
+      bool[] randomPosition = new bool[length];
+      bool[] numberCopied = new bool[length];
+      int randomPosNumber = random.Next(length);
+
+      for (int i = 0; i < randomPosNumber; i++) {  // generate random bit mask
+        randomPosition[random.Next(length)] = true;
+      }
+
+      for (int i = 0; i < length; i++) {  // copy numbers masked as true from second permutation
+        if (randomPosition[i]) {
+          result[i] = parent2[i];
+          numberCopied[parent2[i]] = true;
+        }
+      }
+
+      int index = 0;
+      for (int i = 0; i < length; i++) {  // copy numbers masked as false from first permutation
+        if (!numberCopied[parent1[i]]) {
+          if (randomPosition[index]) {
+            while (randomPosition[index]) {
+              index++;
+            }
+          }
+          result[index] = parent1[i];
+          index++;
+        }
+      }
+
+      return new Permutation(parent1.PermutationType, result);
+    }
+
+    /// <summary>
+    /// Checks number of parents and calls <see cref="Apply(IRandom, Permutation, Permutation)"/>.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">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 permutations that should be crossed.</param>
+    /// <returns>The newly created permutation, resulting from the crossover operation.</returns>
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("ERROR in PositionBasedCrossover: The number of parents is not equal to 2");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/UniformLikeCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/UniformLikeCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/UniformLikeCrossover.cs	(revision 13694)
@@ -0,0 +1,84 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("UniformLikeCrossover", "The ULX crossover tries to maintain the position in the permutation. It randomly chooses from left to right one of its parents' alleles at each position. Missing entries are then filled randomly later. It is described in Tate, D. M. and Smith, A. E. 1995. A genetic approach to the quadratic assignment problem. Computers & Operations Research, vol. 22, pp. 73-83.")]
+  [StorableClass]
+  public sealed class UniformLikeCrossover : PermutationCrossover {
+    [StorableConstructor]
+    private UniformLikeCrossover(bool deserializing) : base(deserializing) { }
+    private UniformLikeCrossover(UniformLikeCrossover original, Cloner cloner) : base(original, cloner) { }
+    public UniformLikeCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UniformLikeCrossover(this, cloner);
+    }
+
+    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
+      if (parent1.Length != parent2.Length) throw new ArgumentException("parent1 and parent2 are of different length.");
+      int length = parent1.Length;
+      int[] child = new int[length];
+      bool[] numberCopied = new bool[length];
+      List<int> unoccupied = new List<int>();
+
+      for (int i = 0; i < length; i++) {
+        bool copied = true;
+        if (parent1[i] == parent2[i]) {
+          child[i] = parent1[i];
+        } else if (!numberCopied[parent1[i]] && !numberCopied[parent2[i]]) {
+          child[i] = (random.NextDouble() < 0.5) ? parent1[i] : parent2[i];
+        } else if (!numberCopied[parent1[i]]) {
+          child[i] = parent1[i];
+        } else if (!numberCopied[parent2[i]]) {
+          child[i] = parent2[i];
+        } else {
+          copied = false;
+          unoccupied.Add(i);
+        }
+        if (copied) numberCopied[child[i]] = true;
+      }
+
+      if (unoccupied.Count > 0) {
+        for (int i = 0; i < length; i++) {
+          if (!numberCopied[i]) {
+            int r = random.Next(unoccupied.Count);
+            child[unoccupied[r]] = i;
+            unoccupied.RemoveAt(r);
+          }
+          if (unoccupied.Count == 0) break;
+        }
+      }
+
+      return new Permutation(parent1.PermutationType, child);
+    }
+
+    protected override Permutation Cross(IRandom random, ItemArray<Permutation> parents) {
+      if (parents.Length != 2) throw new InvalidOperationException("UniformLikeCrossover: The number of parents is not equal to 2.");
+      return Apply(random, parents[0], parents[1]);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 13694)
@@ -0,0 +1,298 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{DBECB8B0-B166-4133-BAF1-ED67C3FD7FCA}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Encodings.PermutationEncoding</RootNamespace>
+    <AssemblyName>HeuristicLab.Encodings.PermutationEncoding-3.3</AssemblyName>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <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>..\..\..\..\trunk\sources\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>..\..\..\..\trunk\sources\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>..\..\..\..\trunk\sources\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>..\..\..\..\trunk\sources\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>..\..\..\..\trunk\sources\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>..\..\..\..\trunk\sources\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>
+  <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.Common.Resources-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-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.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Creators\RandomPermutationCreator.cs" />
+    <Compile Include="Crossovers\CosaCrossover.cs" />
+    <Compile Include="Crossovers\CyclicCrossover.cs" />
+    <Compile Include="Crossovers\CyclicCrossover2.cs" />
+    <Compile Include="Crossovers\EdgeRecombinationCrossover.cs" />
+    <Compile Include="Crossovers\MaximalPreservativeCrossover.cs" />
+    <Compile Include="Crossovers\MultiPermutationCrossover.cs" />
+    <Compile Include="Crossovers\OrderBasedCrossover.cs" />
+    <Compile Include="Crossovers\OrderCrossover.cs" />
+    <Compile Include="Crossovers\OrderCrossover2.cs" />
+    <Compile Include="Crossovers\PartiallyMatchedCrossover.cs" />
+    <Compile Include="Crossovers\PositionBasedCrossover.cs" />
+    <Compile Include="Crossovers\UniformLikeCrossover.cs" />
+    <Compile Include="Interfaces\IPermutationScrambleMoveOperator.cs" />
+    <Compile Include="Interfaces\IPermutationMultiNeighborhoodShakingOperator.cs" />
+    <Compile Include="Interfaces\IPermutationSwap2MoveOperator.cs" />
+    <Compile Include="Interfaces\IPermutationCreator.cs" />
+    <Compile Include="Interfaces\IPermutationCrossover.cs" />
+    <Compile Include="Interfaces\IPermutationManipulator.cs" />
+    <Compile Include="Interfaces\IPermutationMoveOperator.cs" />
+    <Compile Include="Interfaces\IPermutationOperator.cs" />
+    <Compile Include="Interfaces\IPermutationTranslocationMoveOperator.cs" />
+    <Compile Include="Interfaces\IPermutationInversionMoveOperator.cs" />
+    <Compile Include="Manipulators\InsertionManipulator.cs" />
+    <Compile Include="Manipulators\InversionManipulator.cs" />
+    <Compile Include="Manipulators\MultiPermutationManipulator.cs" />
+    <Compile Include="Manipulators\ScrambleManipulator.cs" />
+    <Compile Include="Manipulators\Swap2Manipulator.cs" />
+    <Compile Include="Manipulators\Swap3Manipulator.cs" />
+    <Compile Include="Manipulators\TranslocationInversionManipulator.cs" />
+    <Compile Include="Manipulators\TranslocationManipulator.cs" />
+    <Compile Include="Moves\Edge.cs" />
+    <Compile Include="Moves\PermutationMoveAttribute.cs" />
+    <Compile Include="Moves\Scramble\StochasticScrambleMultiMoveGenerator.cs" />
+    <Compile Include="Moves\Scramble\ScrambleMove.cs" />
+    <Compile Include="Moves\Scramble\ScrambleMoveGenerator.cs" />
+    <Compile Include="Moves\Scramble\ScrambleMoveMaker.cs" />
+    <Compile Include="Moves\StandardEdgeEqualityComparer.cs" />
+    <Compile Include="Moves\Swap2\ExhaustiveSwap2MoveGenerator.cs" />
+    <Compile Include="Moves\Swap2\StochasticSwap2MultiMoveGenerator.cs" />
+    <Compile Include="Moves\Swap2\StochasticSwap2SingleMoveGenerator.cs" />
+    <Compile Include="Moves\Swap2\Swap2Move.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveAbsoluteAttribute.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveGenerator.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveHardTabuCriterion.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveMaker.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveRelativeAttribute.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveSoftTabuCriterion.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveTabuMaker.cs" />
+    <Compile Include="Moves\ThreeIndexMove.cs" />
+    <Compile Include="Moves\ThreeOpt\StochasticSingleInsertionMoveGenerator.cs" />
+    <Compile Include="Moves\ThreeOpt\TranslocationMoveAbsoluteAttribute.cs" />
+    <Compile Include="Moves\ThreeOpt\ExhaustiveInsertionMoveGenerator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Moves\ThreeOpt\StochasticTranslocationMultiMoveGenerator.cs" />
+    <Compile Include="Moves\ThreeOpt\StochasticTranslocationSingleMoveGenerator.cs" />
+    <Compile Include="Moves\ThreeOpt\TranslocationMove.cs" />
+    <Compile Include="Moves\ThreeOpt\TranslocationMoveGenerator.cs" />
+    <Compile Include="Moves\ThreeOpt\TranslocationMoveHardTabuCriterion.cs" />
+    <Compile Include="Moves\ThreeOpt\TranslocationMoveMaker.cs" />
+    <Compile Include="Moves\ThreeOpt\TranslocationMoveRelativeAttribute.cs" />
+    <Compile Include="Moves\ThreeOpt\TranslocationMoveSoftTabuCriterion.cs" />
+    <Compile Include="Moves\ThreeOpt\TranslocationMoveTabuMaker.cs" />
+    <Compile Include="Moves\TwoIndexMove.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Moves\TwoOpt\InversionMoveAbsoluteAttribute.cs" />
+    <Compile Include="Moves\TwoOpt\ExhaustiveInversionMoveGenerator.cs" />
+    <Compile Include="Moves\TwoOpt\InversionMove.cs" />
+    <Compile Include="Moves\TwoOpt\InversionMoveHardTabuCriterion.cs" />
+    <Compile Include="Moves\TwoOpt\InversionMoveRelativeAttribute.cs" />
+    <Compile Include="Moves\TwoOpt\InversionMoveGenerator.cs" />
+    <Compile Include="Moves\TwoOpt\InversionMoveMaker.cs" />
+    <Compile Include="Moves\TwoOpt\InversionMoveSoftTabuCriterion.cs" />
+    <Compile Include="Moves\TwoOpt\InversionMoveTabuMaker.cs" />
+    <Compile Include="Moves\TwoOpt\StochasticInversionMultiMoveGenerator.cs" />
+    <Compile Include="Moves\TwoOpt\StochasticInversionSingleMoveGenerator.cs" />
+    <Compile Include="PermutationEncoding.cs" />
+    <Compile Include="PermutationEqualityComparer.cs" />
+    <Compile Include="PermutationManipulator.cs" />
+    <Compile Include="PermutationCrossover.cs" />
+    <Compile Include="Permutation.cs" />
+    <Compile Include="PermutationType.cs" />
+    <Compile Include="PermutationTypes.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShakingOperators\PermutationShakingOperator.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </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>
+  <Import Project="$(MSBuildBinPath)\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.PermutationEncoding/3.3/Interfaces/IPermutationCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationCreator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationCreator.cs	(revision 13694)
@@ -0,0 +1,35 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An interface which represents an operator for creating permutations.
+  /// </summary>
+  public interface IPermutationCreator : IPermutationOperator, ISolutionCreator {
+    IValueLookupParameter<IntValue> LengthParameter { get; }
+    ILookupParameter<Permutation> PermutationParameter { get; }
+    IValueParameter<PermutationType> PermutationTypeParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationCrossover.cs	(revision 13694)
@@ -0,0 +1,33 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An interface which represents an operator for crossing permutations.
+  /// </summary>
+  public interface IPermutationCrossover : IPermutationOperator, ICrossover {
+    ILookupParameter<ItemArray<Permutation>> ParentsParameter { get; }
+    ILookupParameter<Permutation> ChildParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationInversionMoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationInversionMoveOperator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationInversionMoveOperator.cs	(revision 13694)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public interface IPermutationInversionMoveOperator : IPermutationMoveOperator {
+    ILookupParameter<InversionMove> InversionMoveParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationManipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationManipulator.cs	(revision 13694)
@@ -0,0 +1,32 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An interface which represents an operator for manipulating solutions.
+  /// </summary>
+  public interface IPermutationManipulator : IPermutationOperator, IManipulator {
+    ILookupParameter<Permutation> PermutationParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationMoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationMoveOperator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationMoveOperator.cs	(revision 13694)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public interface IPermutationMoveOperator : IPermutationOperator, IMoveOperator {
+    ILookupParameter<Permutation> PermutationParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationMultiNeighborhoodShakingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationMultiNeighborhoodShakingOperator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationMultiNeighborhoodShakingOperator.cs	(revision 13694)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public interface IPermutationMultiNeighborhoodShakingOperator : IMultiNeighborhoodShakingOperator, IPermutationOperator {
+    ILookupParameter<Permutation> PermutationParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationOperator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationOperator.cs	(revision 13694)
@@ -0,0 +1,29 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An interface which represents an operator dealing with permutations.
+  /// </summary>
+  public interface IPermutationOperator : IOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationScrambleMoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationScrambleMoveOperator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationScrambleMoveOperator.cs	(revision 13694)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public interface IPermutationScrambleMoveOperator : IPermutationMoveOperator {
+    ILookupParameter<ScrambleMove> ScrambleMoveParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationSwap2MoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationSwap2MoveOperator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationSwap2MoveOperator.cs	(revision 13694)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public interface IPermutationSwap2MoveOperator : IPermutationMoveOperator {
+    ILookupParameter<Swap2Move> Swap2MoveParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationTranslocationMoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationTranslocationMoveOperator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationTranslocationMoveOperator.cs	(revision 13694)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public interface IPermutationTranslocationMoveOperator : IPermutationMoveOperator {
+    ILookupParameter<TranslocationMove> TranslocationMoveParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InsertionManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InsertionManipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InsertionManipulator.cs	(revision 13694)
@@ -0,0 +1,88 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Manipulates a permutation array by moving randomly one element to another position in the array.
+  /// </summary> 
+  /// <remarks>
+  /// It is implemented as described in Fogel, D.B. (1988). An Evolutionary Approach to the Traveling Salesman Problem, Biological Cybernetics, 60, pp. 139-144.
+  /// </remarks>
+  [Item("InsertionManipulator", "An operator which moves randomly one element to another position in the permutation (Insertion is a special case of Translocation). It is implemented as described in Fogel, D.B. (1988). An Evolutionary Approach to the Traveling Salesman Problem, Biological Cybernetics, 60, pp. 139-144.")]
+  [StorableClass]
+  public class InsertionManipulator : PermutationManipulator {
+    [StorableConstructor]
+    protected InsertionManipulator(bool deserializing) : base(deserializing) { }
+    protected InsertionManipulator(InsertionManipulator original, Cloner cloner) : base(original, cloner) { }
+    public InsertionManipulator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InsertionManipulator(this, cloner);
+    }
+
+    /// <summary>
+    /// Moves an randomly chosen element in the specified <paramref name="permutation"/> array 
+    /// to another randomly generated position.
+    /// </summary>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    public static void Apply(IRandom random, Permutation permutation) {
+      Permutation original = (Permutation)permutation.Clone();
+      int cutIndex, insertIndex, number;
+
+      cutIndex = random.Next(original.Length);
+      insertIndex = random.Next(original.Length);
+      number = original[cutIndex];
+
+      int i = 0;  // index in new permutation
+      int j = 0;  // index in old permutation
+      while (i < original.Length) {
+        if (j == cutIndex) {
+          j++;
+        }
+        if (i == insertIndex) {
+          permutation[i] = number;
+          i++;
+        }
+        if ((i < original.Length) && (j < original.Length)) {
+          permutation[i] = original[j];
+          i++;
+          j++;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Moves an randomly chosen element in the specified <paramref name="permutation"/> array 
+    /// to another randomly generated position.
+    /// </summary>
+    /// <remarks>Calls <see cref="Apply"/>.</remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    protected override void Manipulate(IRandom random, Permutation permutation) {
+      Apply(random, permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InversionManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InversionManipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InversionManipulator.cs	(revision 13694)
@@ -0,0 +1,78 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// An operator which inverts a randomly chosen part of a permutation.
+  /// </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.<br />
+  /// </remarks>
+  [Item("InversionManipulator", "An operator which inverts a randomly chosen part of a permutation. 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 class InversionManipulator : PermutationManipulator {
+    [StorableConstructor]
+    protected InversionManipulator(bool deserializing) : base(deserializing) { }
+    protected InversionManipulator(InversionManipulator original, Cloner cloner) : base(original, cloner) { }
+    public InversionManipulator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InversionManipulator(this, cloner);
+    }
+
+    /// <summary>
+    /// Inverts a randomly chosen part of a permutation.
+    /// </summary>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    public static void Apply(IRandom random, Permutation permutation) {
+      int breakPoint1, breakPoint2;
+
+      breakPoint1 = random.Next(permutation.Length - 1);
+      do {
+        breakPoint2 = random.Next(permutation.Length - 1);
+      } while (breakPoint2 == breakPoint1);
+      if (breakPoint2 < breakPoint1) { int h = breakPoint1; breakPoint1 = breakPoint2; breakPoint2 = h; }
+      Apply(permutation, breakPoint1, breakPoint2);
+    }
+
+    public static void Apply(Permutation permutation, int breakPoint1, int breakPoint2) {
+      for (int i = 0; i <= (breakPoint2 - breakPoint1) / 2; i++) {  // invert permutation between breakpoints
+        int temp = permutation[breakPoint1 + i];
+        permutation[breakPoint1 + i] = permutation[breakPoint2 - i];
+        permutation[breakPoint2 - i] = temp;
+      }
+    }
+
+    /// <summary>
+    /// Inverts a randomly chosen part of a permutation.
+    /// </summary>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    protected override void Manipulate(IRandom random, Permutation permutation) {
+      Apply(random, permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/MultiPermutationManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/MultiPermutationManipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/MultiPermutationManipulator.cs	(revision 13694)
@@ -0,0 +1,91 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("MultiPermutationManipulator", "Randomly selects and applies one of its manipulators every time it is called.")]
+  [StorableClass]
+  public class MultiPermutationManipulator : StochasticMultiBranch<IPermutationManipulator>, IPermutationManipulator, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    [StorableConstructor]
+    protected MultiPermutationManipulator(bool deserializing) : base(deserializing) { }
+    protected MultiPermutationManipulator(MultiPermutationManipulator original, Cloner cloner) : base(original, cloner) { }
+    public MultiPermutationManipulator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation that is being manipulated."));
+
+      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IPermutationManipulator))) {
+        if (!typeof(MultiOperator<IPermutationManipulator>).IsAssignableFrom(type))
+          Operators.Add((IPermutationManipulator)Activator.CreateInstance(type), true);
+      }
+
+      SelectedOperatorParameter.ActualName = "SelectedManipulationOperator";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiPermutationManipulator(this, cloner);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IPermutationManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeManipulators();
+    }
+
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IPermutationManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeManipulators();
+    }
+
+    private void ParameterizeManipulators() {
+      foreach (IPermutationManipulator manipulator in Operators.OfType<IPermutationManipulator>()) {
+        manipulator.PermutationParameter.ActualName = PermutationParameter.Name;
+      }
+      foreach (IStochasticOperator op in Operators.OfType<IStochasticOperator>()) {
+        op.RandomParameter.ActualName = RandomParameter.Name;
+      }
+    }
+
+    public override IOperation InstrumentedApply() {
+      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one permutation manipulator to choose from.");
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/ScrambleManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/ScrambleManipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/ScrambleManipulator.cs	(revision 13694)
@@ -0,0 +1,101 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Manipulates a permutation array by randomly scrambling the elements in a randomly chosen interval.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Syswerda, G. (1991). Schedule Optimization Using Genetic Algorithms. In Davis, L. (Ed.) Handbook of Genetic Algorithms, Van Nostrand Reinhold, New York, pp 332-349.
+  /// </remarks>
+  [Item("ScrambleManipulator", "An operator which manipulates a permutation array by randomly scrambling the elements in a randomly chosen interval. It is implemented as described in Syswerda, G. (1991). Schedule Optimization Using Genetic Algorithms. In Davis, L. (Ed.) Handbook of Genetic Algorithms, Van Nostrand Reinhold, New York, pp 332-349.")]
+  [StorableClass]
+  public class ScrambleManipulator : PermutationManipulator {
+    [StorableConstructor]
+    protected ScrambleManipulator(bool deserializing) : base(deserializing) { }
+    protected ScrambleManipulator(ScrambleManipulator original, Cloner cloner) : base(original, cloner) { }
+    public ScrambleManipulator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScrambleManipulator(this, cloner);
+    }
+
+    /// <summary>
+    /// Mixes the elements of the given <paramref name="permutation"/> randomly 
+    /// in a randomly chosen interval.
+    /// </summary>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    public static void Apply(IRandom random, Permutation permutation) {
+      int breakPoint1, breakPoint2;
+      int[] scrambledIndices, remainingIndices, temp;
+      int selectedIndex, index;
+
+      breakPoint1 = random.Next(permutation.Length - 1);
+      breakPoint2 = random.Next(breakPoint1 + 1, permutation.Length);
+
+      scrambledIndices = new int[breakPoint2 - breakPoint1 + 1];
+      remainingIndices = new int[breakPoint2 - breakPoint1 + 1];
+      for (int i = 0; i < remainingIndices.Length; i++) {  // initialise indices
+        remainingIndices[i] = i;
+      }
+      for (int i = 0; i < scrambledIndices.Length; i++) {  // generate permutation of indices
+        selectedIndex = random.Next(remainingIndices.Length);
+        scrambledIndices[i] = remainingIndices[selectedIndex];
+
+        temp = remainingIndices;
+        remainingIndices = new int[temp.Length - 1];
+        index = 0;
+        for (int j = 0; j < remainingIndices.Length; j++) {
+          if (index == selectedIndex) {
+            index++;
+          }
+          remainingIndices[j] = temp[index];
+          index++;
+        }
+      }
+
+      Apply(permutation, breakPoint1, scrambledIndices);
+    }
+
+    public static void Apply(Permutation permutation, int startIndex, int[] scrambleArray) {
+      Permutation original = (Permutation)permutation.Clone();
+      for (int i = 0; i < scrambleArray.Length; i++) {  // scramble permutation between breakpoints
+        permutation[startIndex + i] = original[startIndex + scrambleArray[i]];
+      }
+    }
+
+    /// <summary>
+    /// Mixes the elements of the given <paramref name="permutation"/> randomly 
+    /// in a randomly chosen interval.
+    /// </summary>
+    /// <remarks>Calls <see cref="Apply"/>.</remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    protected override void Manipulate(IRandom random, Permutation permutation) {
+      Apply(random, permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap2Manipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap2Manipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap2Manipulator.cs	(revision 13694)
@@ -0,0 +1,75 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Manipulates a permutation array by swapping to randomly chosen elements.
+  /// </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("Swap2Manipulator", "An operator which manipulates a permutation array by swapping to randomly chosen elements. 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 class Swap2Manipulator : PermutationManipulator {
+    [StorableConstructor]
+    protected Swap2Manipulator(bool deserializing) : base(deserializing) { }
+    protected Swap2Manipulator(Swap2Manipulator original, Cloner cloner) : base(original, cloner) { }
+    public Swap2Manipulator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2Manipulator(this, cloner);
+    }
+
+    /// <summary>
+    /// Swaps two randomly chosen elements in the given <paramref name="permutation"/> permutation.
+    /// </summary>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    public static void Apply(IRandom random, Permutation permutation) {
+      int index1, index2;
+
+      index1 = random.Next(permutation.Length);
+      index2 = random.Next(permutation.Length);
+
+      Apply(permutation, index1, index2);
+    }
+
+    public static void Apply(Permutation permutation, int index1, int index2) {
+      int temp = permutation[index1];
+      permutation[index1] = permutation[index2];
+      permutation[index2] = temp;
+    }
+
+    /// <summary>
+    /// Swaps two randomly chosen elements in the given <paramref name="permutation"/> array.
+    /// </summary>
+    /// <remarks>Calls <see cref="Apply"/>.</remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    protected override void Manipulate(IRandom random, Permutation permutation) {
+      Apply(random, permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap3Manipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap3Manipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap3Manipulator.cs	(revision 13694)
@@ -0,0 +1,87 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Manipulates a permutation array by swaping three randomly chosen elements.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented such that first 3 positions are randomly chosen in the interval [0;N) with N = length of the permutation with all positions being distinct from each other.
+  /// Then position 1 is put in place of position 3, position 2 is put in place of position 1 and position 3 is put in place of position 2.
+  /// </remarks>
+  [Item("Swap3Manipulator", "An operator which manipulates a permutation array by swaping three randomly chosen elements. It is implemented such that first 3 positions are randomly chosen in the interval [0;N) with N = length of the permutation with all positions being distinct from each other. Then position 1 is put in place of position 3, position 2 is put in place of position 1 and position 3 is put in place of position 2.")]
+  [StorableClass]
+  public class Swap3Manipulator : PermutationManipulator {
+    [StorableConstructor]
+    protected Swap3Manipulator(bool deserializing) : base(deserializing) { }
+    protected Swap3Manipulator(Swap3Manipulator original, Cloner cloner) : base(original, cloner) { }
+    public Swap3Manipulator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap3Manipulator(this, cloner);
+    }
+
+    /// <summary>
+    /// Swaps three randomly chosen elements of the given <paramref name="permutation"/> array.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when the <paramref name="permutation"/> contains less than 3 elements.</exception>
+    /// <remarks>
+    /// It is implemented such that first 3 positions are randomly chosen in the interval [0;N) with N = length of the permutation with all positions being distinct from each other.
+    /// Then position 1 is put in place of position 3, position 2 is put in place of position 1 and position 3 is put in place of position 2.
+    /// </remarks>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    public static void Apply(IRandom random, Permutation permutation) {
+      if (permutation.Length < 3) throw new ArgumentException("Swap3Manipulator: The permutation must be at least of size 3.", "permutation");
+      int index1, index2, index3, temp;
+
+      do {
+        index1 = random.Next(permutation.Length);
+        index2 = random.Next(permutation.Length);
+        index3 = random.Next(permutation.Length);
+      } while (index1 == index2 || index2 == index3 || index1 == index3);
+
+      // swap positions 1 and 2
+      temp = permutation[index1];
+      permutation[index1] = permutation[index2];
+      permutation[index2] = temp;
+      // swap positions 2 and 3
+      temp = permutation[index2];
+      permutation[index2] = permutation[index3];
+      permutation[index3] = temp;
+    }
+
+    /// <summary>
+    /// Swaps three randomly chosen elements of the given <paramref name="permutation"/> array.
+    /// </summary>
+    /// <remarks>Calls <see cref="Apply"/>.</remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    protected override void Manipulate(IRandom random, Permutation permutation) {
+      Apply(random, permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/TranslocationInversionManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/TranslocationInversionManipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/TranslocationInversionManipulator.cs	(revision 13694)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Manipulates a permutation array by moving and reversing a randomly chosen interval of elements to another 
+  /// (randomly chosen) position in the array.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Fogel, D.B. 1993. Applying Evolutionary Programming to Selected TSP Problems, Cybernetics and Systems, 22, pp 27-36.
+  /// </remarks>
+  [Item("TranslocationInversionManipulator", "An operator which inverts a randomly chosen part of a permutation and inserts it at a random position. It is implemented as described in Fogel, D.B. 1993. Applying Evolutionary Programming to Selected TSP Problems, Cybernetics and Systems, 22, pp. 27-36.")]
+  [StorableClass]
+  public class TranslocationInversionManipulator : PermutationManipulator {
+    [StorableConstructor]
+    protected TranslocationInversionManipulator(bool deserializing) : base(deserializing) { }
+    protected TranslocationInversionManipulator(TranslocationInversionManipulator original, Cloner cloner) : base(original, cloner) { }
+    public TranslocationInversionManipulator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TranslocationInversionManipulator(this, cloner);
+    }
+
+    /// <summary>
+    /// Moves a randomly chosen interval of elements to another (randomly chosen) position in the given
+    /// <paramref name="permutation"/> array and reverses it.
+    /// </summary>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="permutation">The permutation array to manipulate.</param>
+    public static void Apply(IRandom random, Permutation permutation) {
+      Permutation original = (Permutation)permutation.Clone();
+      int breakPoint1, breakPoint2, insertPoint, insertPointLimit;
+
+      breakPoint1 = random.Next(original.Length - 1);
+      breakPoint2 = random.Next(breakPoint1 + 1, original.Length);
+      insertPointLimit = original.Length - breakPoint2 + breakPoint1 - 1;  // get insertion point in remaining part
+      if (insertPointLimit > 0)
+        insertPoint = random.Next(insertPointLimit);
+      else
+        insertPoint = 0;
+
+      int i = 0;  // index in new permutation
+      int j = 0;  // index in old permutation
+      while (i < original.Length) {
+        if (i == insertPoint) {  // copy translocated area
+          for (int k = breakPoint2; k >= breakPoint1; k--) {
+            permutation[i] = original[k];
+            i++;
+          }
+        }
+        if (j == breakPoint1) {  // skip area between breakpoints
+          j = breakPoint2 + 1;
+        }
+        if ((i < original.Length) && (j < original.Length)) {
+          permutation[i] = original[j];
+          i++;
+          j++;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Moves a randomly chosen interval of elements to another (randomly chosen) position in the given
+    /// <paramref name="permutation"/> array and reverses it.
+    /// </summary>
+    /// <remarks>Calls <see cref="Apply"/>.</remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    protected override void Manipulate(IRandom random, Permutation permutation) {
+      Apply(random, permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/TranslocationManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/TranslocationManipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/TranslocationManipulator.cs	(revision 13694)
@@ -0,0 +1,100 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Manipulates a permutation array by moving a randomly chosen interval of elements to another 
+  /// (randomly chosen) position in the array.
+  /// </summary>
+  /// <remarks>
+  /// It is implemented as described in Michalewicz, Z. 1992. Genetic Algorithms + Data Structures = Evolution Programs, Springer Verlag, Berlin Heidelberg.
+  /// </remarks>
+  [Item("TranslocationManipulator", "An operator which Manipulates a permutation array by moving a randomly chosen interval of elements to another (randomly chosen) position in the array. It is implemented as described in Michalewicz, Z. 1992. Genetic Algorithms + Data Structures = Evolution Programs, Springer Verlag, Berlin Heidelberg.")]
+  [StorableClass]
+  public class TranslocationManipulator : PermutationManipulator {
+    [StorableConstructor]
+    protected TranslocationManipulator(bool deserializing) : base(deserializing) { }
+    protected TranslocationManipulator(TranslocationManipulator original, Cloner cloner) : base(original, cloner) { }
+    public TranslocationManipulator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TranslocationManipulator(this, cloner);
+    }
+
+    /// <summary>
+    /// Moves a randomly chosen interval of elements to another (randomly chosen) position in the given
+    /// <paramref name="permutation"/> array.
+    /// </summary>
+    /// <param name="random">The random number generator.</param>
+    /// <param name="permutation">The permutation array to manipulate.</param>
+    public static void Apply(IRandom random, Permutation permutation) {
+      int breakPoint1, breakPoint2, insertPoint, insertPointLimit;
+
+      breakPoint1 = random.Next(permutation.Length - 1);
+      breakPoint2 = random.Next(breakPoint1 + 1, permutation.Length);
+      insertPointLimit = permutation.Length - breakPoint2 + breakPoint1 - 1;  // get insertion point in remaining part
+      if (insertPointLimit > 0)
+        insertPoint = random.Next(insertPointLimit);
+      else
+        insertPoint = 0;
+
+      Apply(permutation, breakPoint1, breakPoint2, insertPoint);
+    }
+
+    public static void Apply(Permutation permutation, int breakPoint1, int breakPoint2, int insertPoint) {
+      Permutation original = (Permutation)permutation.Clone();
+
+      int i = 0;  // index in new permutation
+      int j = 0;  // index in old permutation
+      while (i < original.Length) {
+        if (i == insertPoint) {  // copy translocated area
+          for (int k = breakPoint1; k <= breakPoint2; k++) {
+            permutation[i] = original[k];
+            i++;
+          }
+        }
+        if (j == breakPoint1) {  // skip area between breakpoints
+          j = breakPoint2 + 1;
+        }
+        if ((i < original.Length) && (j < original.Length)) {
+          permutation[i] = original[j];
+          i++;
+          j++;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Moves a randomly chosen interval of elements to another (randomly chosen) position in the given
+    /// <paramref name="permutation"/> array.
+    /// </summary>
+    /// <remarks>Calls <see cref="Apply"/>.</remarks>
+    /// <param name="random">A random number generator.</param>
+    /// <param name="permutation">The permutation to manipulate.</param>
+    protected override void Manipulate(IRandom random, Permutation permutation) {
+      Apply(random, permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Edge.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Edge.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Edge.cs	(revision 13694)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Edge", "An edge between two integer nodes and a flag for the direction.")]
+  [StorableClass]
+  public class Edge : Item {
+    [Storable]
+    public int Source { get; private set; }
+    [Storable]
+    public int Target { get; private set; }
+    [Storable]
+    public bool Bidirectional { get; private set; }
+
+    [StorableConstructor]
+    protected Edge(bool deserializing) : base(deserializing) { }
+    protected Edge(Edge original, Cloner cloner)
+      : base(original, cloner) {
+      Source = original.Source;
+      Target = original.Target;
+      Bidirectional = original.Bidirectional;
+    }
+    public Edge(int source, int target, bool bidirectional)
+      : base() {
+      Source = source;
+      Target = target;
+      Bidirectional = bidirectional;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Edge(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/PermutationMoveAttribute.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/PermutationMoveAttribute.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/PermutationMoveAttribute.cs	(revision 13694)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("PermutationMoveAttribute", "Base class for specifying a move attribute")]
+  [StorableClass]
+  public class PermutationMoveAttribute : Item {
+    [Storable]
+    public double MoveQuality { get; protected set; }
+
+    [StorableConstructor]
+    protected PermutationMoveAttribute(bool deserializing) : base(deserializing) { }
+    protected PermutationMoveAttribute(PermutationMoveAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.MoveQuality = original.MoveQuality;
+    }
+    public PermutationMoveAttribute() : this(0) { }
+    public PermutationMoveAttribute(double moveQuality)
+      : base() {
+      MoveQuality = moveQuality;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PermutationMoveAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/ScrambleMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/ScrambleMove.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/ScrambleMove.cs	(revision 13694)
@@ -0,0 +1,54 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("ScrambleMove", "Item that describes a scramble move.")]
+  [StorableClass]
+  public sealed class ScrambleMove : Item {
+    [Storable]
+    public int StartIndex { get; private set; }
+    [Storable]
+    public int[] ScrambledIndices { get; private set; }
+
+    [StorableConstructor]
+    private ScrambleMove(bool deserializing) : base(deserializing) { }
+    private ScrambleMove(ScrambleMove original, Cloner cloner)
+      : base(original, cloner) {
+      this.StartIndex = original.StartIndex;
+      if (original.ScrambledIndices != null)
+        this.ScrambledIndices = (int[])original.ScrambledIndices.Clone();
+    }
+    public ScrambleMove() : this(-1, null) { }
+    public ScrambleMove(int startIndex, int[] scrambledIndices)
+      : base() {
+      this.StartIndex = startIndex;
+      this.ScrambledIndices = scrambledIndices;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScrambleMove(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/ScrambleMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/ScrambleMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/ScrambleMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,67 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("ScrambleMoveGenerator", "Base class for all scramble move generators.")]
+  [StorableClass]
+  public abstract class ScrambleMoveGenerator : SingleSuccessorOperator, IPermutationScrambleMoveOperator, IMoveGenerator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<ScrambleMove> ScrambleMoveParameter {
+      get { return (LookupParameter<ScrambleMove>)Parameters["ScrambleMove"]; }
+    }
+
+    [StorableConstructor]
+    protected ScrambleMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected ScrambleMoveGenerator(ScrambleMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public ScrambleMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation for which moves should be generated."));
+      Parameters.Add(new LookupParameter<ScrambleMove>("ScrambleMove", "The moves that should be generated in subscopes."));
+    }
+
+    public override IOperation Apply() {
+      IScope scope = ExecutionContext.Scope;
+      Permutation p = PermutationParameter.ActualValue;
+      ScrambleMove[] moves = GenerateMoves(p);
+      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(ScrambleMoveParameter.ActualName, moves[i]));
+      }
+      scope.SubScopes.AddRange(moveScopes);
+      return base.Apply();
+    }
+
+    protected abstract ScrambleMove[] GenerateMoves(Permutation permutation);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/ScrambleMoveMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/ScrambleMoveMaker.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/ScrambleMoveMaker.cs	(revision 13694)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("ScrambleMoveMaker", "Peforms a scramble move on a given permutation and updates the quality.")]
+  [StorableClass]
+  public class ScrambleMoveMaker : SingleSuccessorOperator, IPermutationScrambleMoveOperator, 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<ScrambleMove> ScrambleMoveParameter {
+      get { return (ILookupParameter<ScrambleMove>)Parameters["ScrambleMove"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    [StorableConstructor]
+    protected ScrambleMoveMaker(bool deserializing) : base(deserializing) { }
+    protected ScrambleMoveMaker(ScrambleMoveMaker original, Cloner cloner) : base(original, cloner) { }
+    public ScrambleMoveMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new LookupParameter<ScrambleMove>("ScrambleMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScrambleMoveMaker(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ScrambleMove move = ScrambleMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      DoubleValue moveQuality = MoveQualityParameter.ActualValue;
+      DoubleValue quality = QualityParameter.ActualValue;
+
+      ScrambleManipulator.Apply(permutation, move.StartIndex, move.ScrambledIndices);
+      quality.Value = moveQuality.Value;
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/StochasticScrambleMultiMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/StochasticScrambleMultiMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Scramble/StochasticScrambleMultiMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,106 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("StochasticScrambleMultiMoveGenerator", "Randomly samples n from all possible scramble moves from a given permutation.")]
+  [StorableClass]
+  public class StochasticScrambleMultiMoveGenerator : ScrambleMoveGenerator, 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 StochasticScrambleMultiMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticScrambleMultiMoveGenerator(StochasticScrambleMultiMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticScrambleMultiMoveGenerator()
+      : 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 StochasticScrambleMultiMoveGenerator(this, cloner);
+    }
+
+    public static ScrambleMove GenerateRandomMove(Permutation permutation, IRandom random) {
+      int breakPoint1, breakPoint2;
+      int[] scrambledIndices;
+
+      breakPoint1 = random.Next(permutation.Length);
+      do {
+        breakPoint2 = random.Next(permutation.Length);
+      } while (Math.Abs(breakPoint2 - breakPoint1) <= 1);
+      if (breakPoint2 < breakPoint1) { int h = breakPoint1; breakPoint1 = breakPoint2; breakPoint2 = h; }
+
+      scrambledIndices = new int[breakPoint2 - breakPoint1 + 1];
+      for (int i = 0; i < scrambledIndices.Length; i++)
+        scrambledIndices[i] = i;
+      bool[] moved = new bool[scrambledIndices.Length];
+      bool changed = false;
+      do {
+        for (int i = scrambledIndices.Length - 1; i > 0; i--) {
+          int j = random.Next(i + 1);
+          int t = scrambledIndices[j];
+          scrambledIndices[j] = scrambledIndices[i];
+          scrambledIndices[i] = t;
+          if (scrambledIndices[j] == j) moved[j] = false;
+          else moved[j] = true;
+          if (scrambledIndices[i] == i) moved[i] = false;
+          else moved[i] = true;
+        }
+        changed = moved.Any(x => x);
+      } while (!changed);
+
+      return new ScrambleMove(breakPoint1, scrambledIndices);
+    }
+
+    public static ScrambleMove[] Apply(Permutation permutation, IRandom random, int sampleSize) {
+      int length = permutation.Length;
+      ScrambleMove[] moves = new ScrambleMove[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        moves[i] = GenerateRandomMove(permutation, random);
+      }
+      return moves;
+    }
+
+    protected override ScrambleMove[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return Apply(permutation, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/StandardEdgeEqualityComparer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/StandardEdgeEqualityComparer.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/StandardEdgeEqualityComparer.cs	(revision 13694)
@@ -0,0 +1,36 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public class StandardEdgeEqualityComparer : EqualityComparer<Edge> {
+    public override bool Equals(Edge x, Edge y) {
+      bool inDirection = x.Source == y.Source && x.Target == y.Target;
+      if (!x.Bidirectional && !y.Bidirectional) return inDirection;
+      else return inDirection || x.Source == y.Target && x.Target == y.Source;
+    }
+
+    public override int GetHashCode(Edge edge) {
+      return (int)((long)edge.Source.GetHashCode() + (long)edge.Target.GetHashCode());
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/ExhaustiveSwap2MoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/ExhaustiveSwap2MoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/ExhaustiveSwap2MoveGenerator.cs	(revision 13694)
@@ -0,0 +1,67 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [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(Permutation permutation) {
+      int length = permutation.Length;
+      if (length == 1) throw new ArgumentException("ExhaustiveSwap2MoveGenerator: There cannot be an Swap move given a permutation of length 1.", "permutation");
+
+      for (int i = 0; i < length - 1; i++)
+        for (int j = i + 1; j < length; j++) {
+          yield return new Swap2Move(i, j);
+        }
+    }
+
+    public static Swap2Move[] Apply(Permutation permutation) {
+      int length = permutation.Length;
+      int totalMoves = (length) * (length - 1) / 2;
+      Swap2Move[] moves = new Swap2Move[totalMoves];
+      int count = 0;
+      foreach (Swap2Move move in Generate(permutation)) {
+        moves[count++] = move;
+      }
+      return moves;
+    }
+
+    protected override Swap2Move[] GenerateMoves(Permutation permutation) {
+      return Apply(permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2MultiMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2MultiMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2MultiMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,72 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("StochasticSwap2MultiMoveGenerator", "Randomly samples n from all possible swap-2 moves from a given permutation.")]
+  [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(Permutation permutation, IRandom random, int sampleSize) {
+      int length = permutation.Length;
+      Swap2Move[] moves = new Swap2Move[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        moves[i] = StochasticSwap2SingleMoveGenerator.Apply(permutation, random);
+      }
+      return moves;
+    }
+
+    protected override Swap2Move[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return Apply(permutation, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2SingleMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2SingleMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2SingleMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("StochasticSwap2SingleMoveGenerator", "Randomly samples a single from all possible swap-2 moves from a given permutation.")]
+  [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(Permutation permutation, IRandom random) {
+      int length = permutation.Length;
+      if (length < 2) throw new ArgumentException("StochasticSwap2SingleMoveGenerator: There cannot be a swap-2 move given a permutation of length less than 2.", "permutation");
+      int index1 = random.Next(length), index2 = 0;
+      do {
+        index2 = random.Next(length);
+      } while (index1 == index2);
+      return new Swap2Move(index1, index2);
+    }
+
+    protected override Swap2Move[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return new Swap2Move[] { Apply(permutation, random) };
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2Move.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2Move.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2Move.cs	(revision 13694)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Swap2Move", "Item that describes a swap-2 move.")]
+  [StorableClass]
+  public class Swap2Move : TwoIndexMove {
+    [StorableConstructor]
+    protected Swap2Move(bool deserializing) : base(deserializing) { }
+    protected Swap2Move(Swap2Move original, Cloner cloner) : base(original, cloner) { }
+    public Swap2Move() : base() { }
+    public Swap2Move(int index1, int index2) : base(index1, index2, null) { }
+    public Swap2Move(int index1, int index2, Permutation permutation) : base(index1, index2, permutation) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2Move(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveAbsoluteAttribute.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveAbsoluteAttribute.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveAbsoluteAttribute.cs	(revision 13694)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Swap2MoveAbsoluteAttribute", "Specifies the tabu attributes for a swap-2 move on an absolute position permutation.")]
+  [StorableClass]
+  public class Swap2MoveAbsoluteAttribute : PermutationMoveAttribute {
+    [Storable]
+    public int Index1 { get; private set; }
+    [Storable]
+    public int Number1 { get; private set; }
+    [Storable]
+    public int Index2 { get; private set; }
+    [Storable]
+    public int Number2 { get; private set; }
+
+    [StorableConstructor]
+    protected Swap2MoveAbsoluteAttribute(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveAbsoluteAttribute(Swap2MoveAbsoluteAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.Index1 = original.Index1;
+      this.Number1 = original.Number1;
+      this.Index2 = original.Index2;
+      this.Number2 = original.Number2;
+    }
+    public Swap2MoveAbsoluteAttribute() : this(-1, -1, -1, -1, -1) { }
+    public Swap2MoveAbsoluteAttribute(int index1, int number1, int index2, int number2, double moveQuality)
+      : base(moveQuality) {
+      Index1 = index1;
+      Number1 = number1;
+      Index2 = index2;
+      Number2 = number2;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveAbsoluteAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveGenerator.cs	(revision 13694)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("Swap2MoveGenerator", "Base class for all swap-2 move generators.")]
+  [StorableClass]
+  public abstract class Swap2MoveGenerator : SingleSuccessorOperator, IPermutationSwap2MoveOperator, IMoveGenerator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (LookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+    protected ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+
+    [StorableConstructor]
+    protected Swap2MoveGenerator(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveGenerator(Swap2MoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation for which moves should be generated."));
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "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() {
+      Permutation p = PermutationParameter.ActualValue;
+      Swap2Move[] moves = GenerateMoves(p);
+      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(Swap2MoveParameter.ActualName, moves[i]));
+      }
+      CurrentScopeParameter.ActualValue.SubScopes.AddRange(moveScopes);
+      return base.Apply();
+    }
+
+    protected abstract Swap2Move[] GenerateMoves(Permutation permutation);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveHardTabuCriterion.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveHardTabuCriterion.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveHardTabuCriterion.cs	(revision 13694)
@@ -0,0 +1,169 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+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.PermutationEncoding {
+  [Item("Swap2MoveHardTabuCriterion", @"For relative postion encoded permutations it prevents readding of previously deleted edges as well as deleting previously added edges.
+  For absolute position encoded permutations it prevents moving a number if it was previously moved.
+
+If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
+  [StorableClass]
+  public class Swap2MoveHardTabuCriterion : SingleSuccessorOperator, IPermutationSwap2MoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (LookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    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 Swap2MoveHardTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveHardTabuCriterion(Swap2MoveHardTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveHardTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "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 Swap2MoveHardTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      Swap2Move move = Swap2MoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      int length = permutation.Length;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool isTabu = false;
+
+      if (permutation.PermutationType != PermutationTypes.Absolute)
+        isTabu = EvaluateRelativeTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
+      else isTabu = EvaluateAbsoluteTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
+
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+
+    private static bool EvaluateRelativeTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
+      bool isTabu = false;
+      StandardEdgeEqualityComparer eq = new StandardEdgeEqualityComparer();
+      bool bidirectional = permutation.PermutationType == PermutationTypes.RelativeUndirected;
+      List<Edge> deleted = new List<Edge>();
+      deleted.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index1], bidirectional));
+      deleted.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index1 + 1), bidirectional));
+      deleted.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index2], bidirectional));
+      deleted.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index2 + 1), bidirectional));
+      List<Edge> added = new List<Edge>();
+      added.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index2], bidirectional));
+      added.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index1 + 1), bidirectional));
+      added.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index1], bidirectional));
+      added.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index2 + 1), bidirectional));
+
+      foreach (IItem tabuMove in tabuList) {
+        Swap2MoveRelativeAttribute relAttrib = (tabuMove as Swap2MoveRelativeAttribute);
+        if (relAttrib != null
+          && (!useAspiration
+              || maximization && moveQuality <= relAttrib.MoveQuality
+              || !maximization && moveQuality >= relAttrib.MoveQuality)) {
+          for (int i = 0; i < relAttrib.AddedEdges.Count; i++) {
+            isTabu = eq.Equals(relAttrib.AddedEdges[i], deleted[0])
+                  || eq.Equals(relAttrib.AddedEdges[i], deleted[1])
+                  || eq.Equals(relAttrib.AddedEdges[i], deleted[2])
+                  || eq.Equals(relAttrib.AddedEdges[i], deleted[3]);
+            if (isTabu) break;
+          }
+          if (isTabu) break;
+          for (int i = 0; i < relAttrib.DeletedEdges.Count; i++) {
+            isTabu = eq.Equals(relAttrib.DeletedEdges[i], added[0])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[1])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[2])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[3]);
+            if (isTabu) break;
+          }
+        }
+        if (isTabu) break;
+      }
+      return isTabu;
+    }
+
+    private bool EvaluateAbsoluteTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
+      bool isTabu = false;
+      foreach (IItem tabuMove in tabuList) {
+        Swap2MoveAbsoluteAttribute attrib = (tabuMove as Swap2MoveAbsoluteAttribute);
+        if (attrib != null
+          && (!useAspiration
+              || maximization && moveQuality <= attrib.MoveQuality
+              || !maximization && moveQuality >= attrib.MoveQuality)) {
+          int i1 = move.Index1;
+          int n1 = permutation[move.Index1];
+          int i2 = move.Index2;
+          int n2 = permutation[move.Index2];
+          if (attrib != null) {
+            if (attrib.Number1 == n1 || attrib.Number1 == n2
+              || attrib.Number2 == n2 || attrib.Number2 == n1)
+              isTabu = true;
+          }
+        }
+        if (isTabu) break;
+      }
+      return isTabu;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveMaker.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveMaker.cs	(revision 13694)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("Swap2MoveMaker", "Peforms a swap-2 move on a given permutation and updates the quality.")]
+  [StorableClass]
+  public class Swap2MoveMaker : SingleSuccessorOperator, IPermutationSwap2MoveOperator, 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<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    [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 evaluate."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveMaker(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      Swap2Move move = Swap2MoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      DoubleValue moveQuality = MoveQualityParameter.ActualValue;
+      DoubleValue quality = QualityParameter.ActualValue;
+
+      Swap2Manipulator.Apply(permutation, move.Index1, move.Index2);
+      quality.Value = moveQuality.Value;
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveRelativeAttribute.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveRelativeAttribute.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveRelativeAttribute.cs	(revision 13694)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Swap2MoveRelativeAttribute", "Specifies the tabu attributes for a swap-2 move on a relative position permutation.")]
+  [StorableClass]
+  public class Swap2MoveRelativeAttribute : PermutationMoveAttribute {
+    [Storable]
+    public ItemList<Edge> DeletedEdges { get; private set; }
+    [Storable]
+    public ItemList<Edge> AddedEdges { get; private set; }
+
+    [StorableConstructor]
+    protected Swap2MoveRelativeAttribute(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveRelativeAttribute(Swap2MoveRelativeAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.DeletedEdges = cloner.Clone(original.DeletedEdges);
+      this.AddedEdges = cloner.Clone(original.AddedEdges);
+    }
+    public Swap2MoveRelativeAttribute(double moveQuality)
+      : base(moveQuality) {
+      DeletedEdges = new ItemList<Edge>();
+      AddedEdges = new ItemList<Edge>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveRelativeAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveSoftTabuCriterion.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveSoftTabuCriterion.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveSoftTabuCriterion.cs	(revision 13694)
@@ -0,0 +1,154 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+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.PermutationEncoding {
+  [Item("Swap2MoveSoftTabuCriterion", @"For relative postion encoded permutations it just prevents readding of previously deleted edges, but allows deleting previously added edges.
+  For absolute position encoded permutations it prevents moving a number to a position it has previously occupied.
+
+If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
+  [StorableClass]
+  public class Swap2MoveSoftTabuCriterion : SingleSuccessorOperator, IPermutationSwap2MoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (LookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    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 Swap2MoveSoftTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveSoftTabuCriterion(Swap2MoveSoftTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveSoftTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "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 Swap2MoveSoftTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      Swap2Move move = Swap2MoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      int length = permutation.Length;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool isTabu = false;
+
+      if (permutation.PermutationType != PermutationTypes.Absolute)
+        isTabu = EvaluateRelativeTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
+      else isTabu = EvaluateAbsoluteTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
+
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+
+    private static bool EvaluateRelativeTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
+      bool isTabu = false;
+      StandardEdgeEqualityComparer eq = new StandardEdgeEqualityComparer();
+      bool bidirectional = permutation.PermutationType == PermutationTypes.RelativeUndirected;
+      List<Edge> added = new List<Edge>();
+      added.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index2], bidirectional));
+      added.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index1 + 1), bidirectional));
+      added.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index1], bidirectional));
+      added.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index2 + 1), bidirectional));
+
+      foreach (IItem tabuMove in tabuList) {
+        Swap2MoveRelativeAttribute relAttrib = (tabuMove as Swap2MoveRelativeAttribute);
+        if (relAttrib != null
+          && (!useAspiration
+              || maximization && moveQuality <= relAttrib.MoveQuality
+              || !maximization && moveQuality >= relAttrib.MoveQuality)) {
+          for (int i = 0; i < relAttrib.DeletedEdges.Count; i++) {
+            isTabu = eq.Equals(relAttrib.DeletedEdges[i], added[0])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[1])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[2])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[3]);
+            if (isTabu) break;
+          }
+        }
+        if (isTabu) break;
+      }
+      return isTabu;
+    }
+
+    private bool EvaluateAbsoluteTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
+      bool isTabu = false;
+      foreach (IItem tabuMove in tabuList) {
+        Swap2MoveAbsoluteAttribute attrib = (tabuMove as Swap2MoveAbsoluteAttribute);
+        if (attrib != null
+          && (!useAspiration
+              || maximization && moveQuality <= attrib.MoveQuality
+              || !maximization && moveQuality >= attrib.MoveQuality)) {
+          int i1 = move.Index1;
+          int n1 = permutation[move.Index1];
+          int i2 = move.Index2;
+          int n2 = permutation[move.Index2];
+          if ((attrib.Index1 == i1 || attrib.Index1 == i2) && (attrib.Number1 == n1 || attrib.Number1 == n2)
+            || (attrib.Index2 == i2 || attrib.Index2 == i1) && (attrib.Number2 == n2 || attrib.Number2 == n1))
+            isTabu = true;
+        }
+        if (isTabu) break;
+      }
+      return isTabu;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveTabuMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveTabuMaker.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveTabuMaker.cs	(revision 13694)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("Swap2MoveTabuMaker", "Declares a given swap-2 move as tabu, by adding its attributes to the tabu list and also store the solution quality or the move quality (whichever is better).")]
+  [StorableClass]
+  public class Swap2MoveTabuMaker : TabuMaker, IPermutationSwap2MoveOperator {
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (LookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+
+    [StorableConstructor]
+    protected Swap2MoveTabuMaker(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveTabuMaker(Swap2MoveTabuMaker original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveTabuMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The move that was made."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveTabuMaker(this, cloner);
+    }
+
+    protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality) {
+      Swap2Move move = Swap2MoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      double baseQuality = moveQuality;
+      if (maximization && quality > moveQuality || !maximization && quality < moveQuality) baseQuality = quality; // we make an uphill move, the lower bound is the solution quality
+      if (permutation.PermutationType == PermutationTypes.Absolute)
+        return new Swap2MoveAbsoluteAttribute(move.Index1, permutation[move.Index1], move.Index2, permutation[move.Index2], baseQuality);
+      else {
+        Swap2MoveRelativeAttribute attrib = new Swap2MoveRelativeAttribute(baseQuality);
+        bool bidirectional = permutation.PermutationType == PermutationTypes.RelativeUndirected;
+        attrib.DeletedEdges.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index1], bidirectional));
+        attrib.DeletedEdges.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index1 + 1), bidirectional));
+        attrib.DeletedEdges.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index2], bidirectional));
+        attrib.DeletedEdges.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index2 + 1), bidirectional));
+        attrib.AddedEdges.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index2], bidirectional));
+        attrib.AddedEdges.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index1 + 1), bidirectional));
+        attrib.AddedEdges.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index1], bidirectional));
+        attrib.AddedEdges.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index2 + 1), bidirectional));
+        return attrib;
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeIndexMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeIndexMove.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeIndexMove.cs	(revision 13694)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("ThreeIndexMove", "A move on a permutation that is specified by 3 indices.")]
+  [StorableClass]
+  public class ThreeIndexMove : Item {
+    [Storable]
+    public int Index1 { get; protected set; }
+    [Storable]
+    public int Index2 { get; protected set; }
+    [Storable]
+    public int Index3 { get; protected set; }
+    [Storable]
+    public Permutation Permutation { get; protected set; }
+
+    [StorableConstructor]
+    protected ThreeIndexMove(bool deserializing) : base(deserializing) { }
+    protected ThreeIndexMove(ThreeIndexMove original, Cloner cloner)
+      : base(original, cloner) {
+      this.Index1 = original.Index1;
+      this.Index2 = original.Index2;
+      this.Index3 = original.Index3;
+      if (original.Permutation != null)
+        this.Permutation = cloner.Clone(original.Permutation);
+    }
+    public ThreeIndexMove() : this(-1, -1, -1, null) { }
+    public ThreeIndexMove(int index1, int index2, int index3, Permutation permutation)
+      : base() {
+      Index1 = index1;
+      Index2 = index2;
+      Index3 = index3;
+      Permutation = permutation;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ThreeIndexMove(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ExhaustiveInsertionMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ExhaustiveInsertionMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ExhaustiveInsertionMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("ExhaustiveInsertionMoveGenerator", "Generates all possible insertion moves (3-opt) from a given permutation.")]
+  [StorableClass]
+  public class ExhaustiveInsertionMoveGenerator : TranslocationMoveGenerator, IExhaustiveMoveGenerator {
+    [StorableConstructor]
+    protected ExhaustiveInsertionMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected ExhaustiveInsertionMoveGenerator(ExhaustiveInsertionMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public ExhaustiveInsertionMoveGenerator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExhaustiveInsertionMoveGenerator(this, cloner);
+    }
+
+    public static IEnumerable<TranslocationMove> Generate(Permutation permutation) {
+      int length = permutation.Length;
+      if (length == 1) throw new ArgumentException("ExhaustiveInsertionMoveGenerator: There cannot be an insertion move given a permutation of length 1.", "permutation");
+
+      if (permutation.PermutationType == PermutationTypes.Absolute) {
+        for (int i = 0; i < length; i++) {
+          for (int j = 1; j <= length - 1; j++) {
+            yield return new TranslocationMove(i, i, (i + j) % length);
+          }
+        }
+      } else {
+        if (length > 2) {
+          for (int i = 0; i < length; i++) {
+            for (int j = 1; j <= length - 1; j++) {
+              if (i == 0 && j == length - 1
+                || i == length - 1 && j == 1) continue;
+              yield return new TranslocationMove(i, i, (i + j) % length);
+            }
+          }
+        } else { // doesn't make sense, but just create a dummy move to not crash the algorithms
+          yield return new TranslocationMove(0, 0, 1);
+        }
+      }
+    }
+
+    public static TranslocationMove[] Apply(Permutation permutation) {
+      return Generate(permutation).ToArray();
+    }
+
+    protected override TranslocationMove[] GenerateMoves(Permutation permutation) {
+      return Apply(permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticSingleInsertionMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticSingleInsertionMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticSingleInsertionMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,103 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("StochasticInsertionMultiMoveGenerator", "Generates all possible insertion moves (3-opt) from a few numbers in a given permutation.")]
+  [StorableClass]
+  public class StochasticInsertionMultiMoveGenerator : TranslocationMoveGenerator, 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 StochasticInsertionMultiMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticInsertionMultiMoveGenerator(StochasticInsertionMultiMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticInsertionMultiMoveGenerator() : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticInsertionMultiMoveGenerator(this, cloner);
+    }
+
+    public static TranslocationMove[] Apply(Permutation permutation, IRandom random, int sampleSize) {
+      int length = permutation.Length;
+      if (length == 1) throw new ArgumentException("ExhaustiveSingleInsertionMoveGenerator: There cannot be an insertion move given a permutation of length 1.", "permutation");
+      TranslocationMove[] moves = new TranslocationMove[sampleSize];
+      int count = 0;
+      HashSet<int> usedIndices = new HashSet<int>();
+      while (count < sampleSize) {
+
+        int index = random.Next(length);
+
+        if (usedIndices.Count != length)
+          while (usedIndices.Contains(index))
+            index = random.Next(length);
+        usedIndices.Add(index);
+
+        if (permutation.PermutationType == PermutationTypes.Absolute) {
+          for (int j = 1; j <= length - 1; j++) {
+            moves[count++] = new TranslocationMove(index, index, (index + j) % length);
+            if (count == sampleSize) break;
+          }
+        } else {
+          if (length > 2) {
+            for (int j = 1; j < length - 1; j++) {
+              int insertPoint = (index + j) % length;
+              if (index + j >= length) insertPoint++;
+              moves[count++] = new TranslocationMove(index, index, insertPoint);
+              if (count == sampleSize) break;
+            }
+          } else { // doesn't make sense, but just create a dummy move to not crash the algorithms
+            moves = new TranslocationMove[1];
+            moves[0] = new TranslocationMove(0, 0, 1);
+            count = sampleSize;
+          }
+        }
+      }
+      return moves;
+    }
+
+    protected override TranslocationMove[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      if (random == null) throw new InvalidOperationException(Name + ": No random number generator found.");
+      return Apply(permutation, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticTranslocationMultiMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticTranslocationMultiMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticTranslocationMultiMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,71 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("StochasticTranslocationMultiMoveGenerator", "Randomly samples n from all possible translocation and insertion moves (3-opt) from a given permutation.")]
+  [StorableClass]
+  public class StochasticTranslocationMultiMoveGenerator : TranslocationMoveGenerator, 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 StochasticTranslocationMultiMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticTranslocationMultiMoveGenerator(StochasticTranslocationMultiMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticTranslocationMultiMoveGenerator() : 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 StochasticTranslocationMultiMoveGenerator(this, cloner);
+    }
+
+    public static TranslocationMove[] Apply(Permutation permutation, IRandom random, int sampleSize) {
+      int length = permutation.Length;
+      TranslocationMove[] moves = new TranslocationMove[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        moves[i] = StochasticTranslocationSingleMoveGenerator.Apply(permutation, random);
+      }
+      return moves;
+    }
+
+    protected override TranslocationMove[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return Apply(permutation, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticTranslocationSingleMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticTranslocationSingleMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticTranslocationSingleMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,71 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("StochasticTranslocationSingleMoveGenerator", "Randomly samples one from all possible translocation and insertion moves (3-opt) from a given permutation.")]
+  [StorableClass]
+  public class StochasticTranslocationSingleMoveGenerator : TranslocationMoveGenerator, IStochasticOperator, ISingleMoveGenerator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected StochasticTranslocationSingleMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticTranslocationSingleMoveGenerator(StochasticTranslocationSingleMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticTranslocationSingleMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticTranslocationSingleMoveGenerator(this, cloner);
+    }
+
+    public static TranslocationMove Apply(Permutation permutation, IRandom random) {
+      int length = permutation.Length;
+      if (length == 1) throw new ArgumentException("StochasticThreeOptSingleMoveGenerator: There cannot be an insertion move given a permutation of length 1.", "permutation");
+      if (permutation.PermutationType != PermutationTypes.Absolute && length == 2) return new TranslocationMove(0, 0, 1);
+      int index1, index2, index3;
+      do {
+        index1 = random.Next(length);
+        do {
+          index2 = random.Next(index1, length);
+        } while (index2 - index1 >= length - 2);
+        do {
+          index3 = random.Next(length - index2 + index1);
+        } while (index3 == index1);
+      } while (permutation.PermutationType != PermutationTypes.Absolute && (index1 == 0 && index3 == length - 1 || index1 == length - 1 && index3 == 0));
+      return new TranslocationMove(index1, index2, index3);
+    }
+
+    protected override TranslocationMove[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return new TranslocationMove[] { Apply(permutation, random) };
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMove.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMove.cs	(revision 13694)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("TranslocationMove", "A move that changes three edges by performing a translocation.")]
+  [StorableClass]
+  public class TranslocationMove : ThreeIndexMove {
+    [StorableConstructor]
+    protected TranslocationMove(bool deserializing) : base(deserializing) { }
+    protected TranslocationMove(TranslocationMove original, Cloner cloner) : base(original, cloner) { }
+    public TranslocationMove() : base() { }
+    public TranslocationMove(int index1, int index2, int index3) : base(index1, index2, index3, null) { }
+    public TranslocationMove(int index1, int index2, int index3, Permutation permutation) : base(index1, index2, index3, permutation) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TranslocationMove(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveAbsoluteAttribute.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveAbsoluteAttribute.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveAbsoluteAttribute.cs	(revision 13694)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("TranslocationMoveAbsoluteAttribute", "Specifies the tabu attributes for a translocation and insertion move (3-opt) on absolute permutation encodings.")]
+  [StorableClass]
+  public class TranslocationMoveAbsoluteAttribute : PermutationMoveAttribute {
+    [Storable]
+    public int[] Number { get; private set; }
+    [Storable]
+    public int OldPosition { get; private set; }
+    [Storable]
+    public int NewPosition { get; private set; }
+
+    [StorableConstructor]
+    protected TranslocationMoveAbsoluteAttribute(bool deserializing) : base(deserializing) { }
+    protected TranslocationMoveAbsoluteAttribute(TranslocationMoveAbsoluteAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.Number = (int[])original.Number.Clone();
+      this.OldPosition = original.OldPosition;
+      this.NewPosition = original.NewPosition;
+    }
+    public TranslocationMoveAbsoluteAttribute(int[] number, int oldPosition, int newPosition, double moveQuality)
+      : base(moveQuality) {
+      Number = number;
+      OldPosition = oldPosition;
+      NewPosition = newPosition;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TranslocationMoveAbsoluteAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("TranslocationMoveGenerator", "Base class for move generators that produce translocation moves (3-opt).")]
+  [StorableClass]
+  public abstract class TranslocationMoveGenerator : SingleSuccessorOperator, IPermutationTranslocationMoveOperator, IMoveGenerator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<TranslocationMove> TranslocationMoveParameter {
+      get { return (LookupParameter<TranslocationMove>)Parameters["TranslocationMove"]; }
+    }
+    protected ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+
+    [StorableConstructor]
+    protected TranslocationMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected TranslocationMoveGenerator(TranslocationMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public TranslocationMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation for which moves should be generated."));
+      Parameters.Add(new LookupParameter<TranslocationMove>("TranslocationMove", "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() {
+      Permutation p = PermutationParameter.ActualValue;
+      TranslocationMove[] moves = GenerateMoves(p);
+      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(TranslocationMoveParameter.ActualName, moves[i]));
+      }
+      CurrentScopeParameter.ActualValue.SubScopes.AddRange(moveScopes);
+      return base.Apply();
+    }
+
+    protected abstract TranslocationMove[] GenerateMoves(Permutation permutation);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveHardTabuCriterion.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveHardTabuCriterion.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveHardTabuCriterion.cs	(revision 13694)
@@ -0,0 +1,182 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("TranslocationMoveHardTabuCriterion", @"For relative postion encoded permutations it prevents readding of previously deleted edges as well as deleting previously added edges.
+  For absolute position encoded permutations it prevents moving a number if it was previously moved.
+
+If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
+  [StorableClass]
+  public class TranslocationMoveHardTabuCriterion : SingleSuccessorOperator, IPermutationTranslocationMoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<TranslocationMove> TranslocationMoveParameter {
+      get { return (LookupParameter<TranslocationMove>)Parameters["TranslocationMove"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    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 TranslocationMoveHardTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected TranslocationMoveHardTabuCriterion(TranslocationMoveHardTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public TranslocationMoveHardTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<TranslocationMove>("TranslocationMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "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 TranslocationMoveHardTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      TranslocationMove move = TranslocationMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      int length = permutation.Length;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool isTabu = false;
+
+      if (permutation.PermutationType == PermutationTypes.Absolute) {
+        int count = move.Index2 - move.Index1 + 1;
+        int[] numbers = new int[count];
+        for (int i = move.Index1; i <= move.Index2; i++)
+          numbers[i - move.Index1] = permutation[i];
+
+        foreach (IItem tabuMove in tabuList) {
+          TranslocationMoveAbsoluteAttribute attribute = (tabuMove as TranslocationMoveAbsoluteAttribute);
+          if (attribute != null) {
+            if (!useAspiration
+              || maximization && moveQuality <= attribute.MoveQuality
+              || !maximization && moveQuality >= attribute.MoveQuality) { // if the move quality is improving beyond what was recorded when the move in the tabu list was recorded the move is regarded as okay
+
+              for (int i = 0; i < count; i++) {
+                for (int j = 0; j < attribute.Number.Length; j++) {
+                  if (attribute.Number[j] == numbers[i]) {
+                    isTabu = true;
+                    break;
+                  }
+                }
+                if (isTabu) break;
+              }
+            }
+          }
+          if (isTabu) break;
+        }
+      } else {
+        int E1S = permutation.GetCircular(move.Index1 - 1);
+        int E1T = permutation[move.Index1];
+        int E2S = permutation[move.Index2];
+        int E2T = permutation.GetCircular(move.Index2 + 1);
+        int E3S, E3T;
+        if (move.Index3 > move.Index1) {
+          E3S = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
+          E3T = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
+        } else {
+          E3S = permutation.GetCircular(move.Index3 - 1);
+          E3T = permutation[move.Index3];
+        }
+        foreach (IItem tabuMove in tabuList) {
+          TranslocationMoveRelativeAttribute attribute = (tabuMove as TranslocationMoveRelativeAttribute);
+          if (attribute != null) {
+            if (!useAspiration
+              || maximization && moveQuality <= attribute.MoveQuality
+              || !maximization && moveQuality >= attribute.MoveQuality) {
+
+              if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
+                if (// if previously added Edge3Source-Edge1Target is deleted
+                  attribute.Edge3Source == E1S && attribute.Edge1Target == E1T || attribute.Edge3Source == E1T && attribute.Edge1Target == E1S
+                  || attribute.Edge3Source == E2S && attribute.Edge1Target == E2T || attribute.Edge3Source == E2T && attribute.Edge1Target == E2S
+                  || attribute.Edge3Source == E3S && attribute.Edge1Target == E3T || attribute.Edge3Source == E3T && attribute.Edge1Target == E3S
+                  // if previously added Edge2Source-Edge3Target is deleted
+                  || attribute.Edge2Source == E1S && attribute.Edge3Target == E1T || attribute.Edge2Source == E1T && attribute.Edge3Target == E1S
+                  || attribute.Edge2Source == E2S && attribute.Edge3Target == E2T || attribute.Edge2Source == E2T && attribute.Edge3Target == E2S
+                  || attribute.Edge2Source == E3S && attribute.Edge3Target == E3T || attribute.Edge2Source == E3T && attribute.Edge3Target == E3S
+                  // if previously added Edge1Source-Edge2Target is deleted
+                  || attribute.Edge1Source == E1S && attribute.Edge2Target == E1T || attribute.Edge1Source == E1T && attribute.Edge2Target == E1S
+                  || attribute.Edge1Source == E2S && attribute.Edge2Target == E2T || attribute.Edge1Source == E2T && attribute.Edge2Target == E2S
+                  || attribute.Edge1Source == E3S && attribute.Edge2Target == E3T || attribute.Edge1Source == E3T && attribute.Edge2Target == E3S) {
+                  isTabu = true;
+                  break;
+                }
+              } else {
+                if (// if previously added Edge3Source-Edge1Target is deleted
+                  attribute.Edge3Source == E1S && attribute.Edge1Target == E1T
+                  || attribute.Edge3Source == E2S && attribute.Edge1Target == E2T
+                  || attribute.Edge3Source == E3S && attribute.Edge1Target == E3T
+                  // if previously added Edge2Source-Edge3Target is deleted
+                  || attribute.Edge2Source == E1S && attribute.Edge3Target == E1T
+                  || attribute.Edge2Source == E2S && attribute.Edge3Target == E2T
+                  || attribute.Edge2Source == E3S && attribute.Edge3Target == E3T
+                  // if previously added Edge1Source-Edge2Target is deleted
+                  || attribute.Edge1Source == E1S && attribute.Edge2Target == E1T
+                  || attribute.Edge1Source == E2S && attribute.Edge2Target == E2T
+                  || attribute.Edge1Source == E3S && attribute.Edge2Target == E3T) {
+                  isTabu = true;
+                  break;
+                }
+              }
+            }
+          }
+        }
+      }
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveMaker.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveMaker.cs	(revision 13694)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("TranslocationMoveMaker", "Peforms a translocation or insertion move (3-opt) on a given permutation and updates the quality.")]
+  [StorableClass]
+  public class TranslocationMoveMaker : SingleSuccessorOperator, IPermutationTranslocationMoveOperator, 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<TranslocationMove> TranslocationMoveParameter {
+      get { return (ILookupParameter<TranslocationMove>)Parameters["TranslocationMove"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    [StorableConstructor]
+    protected TranslocationMoveMaker(bool deserializing) : base(deserializing) { }
+    protected TranslocationMoveMaker(TranslocationMoveMaker original, Cloner cloner) : base(original, cloner) { }
+    public TranslocationMoveMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new LookupParameter<TranslocationMove>("TranslocationMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TranslocationMoveMaker(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      TranslocationMove move = TranslocationMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      DoubleValue moveQuality = MoveQualityParameter.ActualValue;
+      DoubleValue quality = QualityParameter.ActualValue;
+
+      TranslocationManipulator.Apply(permutation, move.Index1, move.Index2, move.Index3);
+      quality.Value = moveQuality.Value;
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveRelativeAttribute.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveRelativeAttribute.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveRelativeAttribute.cs	(revision 13694)
@@ -0,0 +1,69 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("TranslocationMoveRelativeAttribute", "Specifies the tabu attributes for a translocation and insertion move (3-opt) on relative permutation encodings.")]
+  [StorableClass]
+  public class TranslocationMoveRelativeAttribute : PermutationMoveAttribute {
+    [Storable]
+    public int Edge1Source { get; private set; }
+    [Storable]
+    public int Edge1Target { get; private set; }
+    [Storable]
+    public int Edge2Source { get; private set; }
+    [Storable]
+    public int Edge2Target { get; private set; }
+    [Storable]
+    public int Edge3Source { get; private set; }
+    [Storable]
+    public int Edge3Target { get; private set; }
+
+    [StorableConstructor]
+    protected TranslocationMoveRelativeAttribute(bool deserializing) : base(deserializing) { }
+    protected TranslocationMoveRelativeAttribute(TranslocationMoveRelativeAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.Edge1Source = original.Edge1Source;
+      this.Edge1Target = original.Edge1Target;
+      this.Edge2Source = original.Edge2Source;
+      this.Edge2Target = original.Edge2Target;
+      this.Edge3Source = original.Edge3Source;
+      this.Edge3Target = original.Edge3Target;
+    }
+    public TranslocationMoveRelativeAttribute() : this(-1, -1, -1, -1, -1, -1, -1) { }
+    public TranslocationMoveRelativeAttribute(int edge1Source, int edge1Target, int edge2Source, int edge2Target, int edge3Source, int edge3Target, double moveQuality)
+      : base(moveQuality) {
+      Edge1Source = edge1Source;
+      Edge1Target = edge1Target;
+      Edge2Source = edge2Source;
+      Edge2Target = edge2Target;
+      Edge3Source = edge3Source;
+      Edge3Target = edge3Target;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TranslocationMoveRelativeAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveSoftTabuCriterion.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveSoftTabuCriterion.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveSoftTabuCriterion.cs	(revision 13694)
@@ -0,0 +1,175 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("TranslocationMoveSoftTabuCriterion", @"For relative postion encoded permutations it just prevents readding of previously deleted edges, but allows deleting previously added edges.
+  For absolute position encoded permutations it prevents moving a number to a position it has previously occupied.
+
+If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
+  [StorableClass]
+  public class TranslocationMoveSoftTabuCriterion : SingleSuccessorOperator, IPermutationTranslocationMoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<TranslocationMove> TranslocationMoveParameter {
+      get { return (LookupParameter<TranslocationMove>)Parameters["TranslocationMove"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    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 TranslocationMoveSoftTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected TranslocationMoveSoftTabuCriterion(TranslocationMoveSoftTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public TranslocationMoveSoftTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<TranslocationMove>("TranslocationMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "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 TranslocationMoveSoftTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      TranslocationMove move = TranslocationMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      int length = permutation.Length;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool isTabu = false;
+
+      if (permutation.PermutationType == PermutationTypes.Absolute) {
+        int count = move.Index2 - move.Index1 + 1;
+        int[] numbers = new int[count];
+        for (int i = move.Index1; i <= move.Index2; i++)
+          numbers[i - move.Index1] = permutation[i];
+
+        foreach (IItem tabuMove in tabuList) {
+          TranslocationMoveAbsoluteAttribute attribute = (tabuMove as TranslocationMoveAbsoluteAttribute);
+          if (attribute != null) {
+            if (!useAspiration
+              || maximization && moveQuality <= attribute.MoveQuality
+              || !maximization && moveQuality >= attribute.MoveQuality) { // if the move quality is improving beyond what was recorded when the move in the tabu list was recorded the move is regarded as okay
+
+              for (int i = 0; i < count; i++) {
+                for (int j = 0; j < attribute.Number.Length; j++) {
+                  if (attribute.Number[j] == numbers[i] && attribute.OldPosition + j == move.Index3 + i) {
+                    isTabu = true;
+                    break;
+                  }
+                }
+                if (isTabu) break;
+              }
+            }
+          }
+          if (isTabu) break;
+        }
+      } else {
+        int E1S = permutation.GetCircular(move.Index1 - 1);
+        int E1T = permutation[move.Index1];
+        int E2S = permutation[move.Index2];
+        int E2T = permutation.GetCircular(move.Index2 + 1);
+        int E3S, E3T;
+        if (move.Index3 > move.Index1) {
+          E3S = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
+          E3T = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
+        } else {
+          E3S = permutation.GetCircular(move.Index3 - 1);
+          E3T = permutation[move.Index3];
+        }
+        foreach (IItem tabuMove in tabuList) {
+          TranslocationMoveRelativeAttribute attribute = (tabuMove as TranslocationMoveRelativeAttribute);
+          if (attribute != null) {
+            if (!useAspiration
+              || maximization && moveQuality <= attribute.MoveQuality
+              || !maximization && moveQuality >= attribute.MoveQuality) {
+
+              // if previously deleted Edge1Source-Target is readded
+              if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
+                if (attribute.Edge1Source == E3S && attribute.Edge1Target == E1T || attribute.Edge1Source == E1T && attribute.Edge1Target == E3S
+                  || attribute.Edge1Source == E2S && attribute.Edge1Target == E3T || attribute.Edge1Source == E3T && attribute.Edge1Target == E2S
+                  // if previously deleted Edge2Source-Target is readded
+                  || attribute.Edge2Source == E3S && attribute.Edge2Target == E1T || attribute.Edge2Source == E1T && attribute.Edge2Target == E3S
+                  || attribute.Edge2Source == E2S && attribute.Edge2Target == E3T || attribute.Edge2Source == E3T && attribute.Edge2Target == E2S
+                  // if previously deleted Edge3Source-Target is readded
+                  || attribute.Edge3Source == E3S && attribute.Edge3Target == E1T || attribute.Edge3Source == E1T && attribute.Edge3Target == E3S
+                  || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T || attribute.Edge3Source == E3T && attribute.Edge3Target == E2S) {
+                  isTabu = true;
+                  break;
+                }
+              } else {
+                if (attribute.Edge1Source == E3S && attribute.Edge1Target == E1T
+                  || attribute.Edge1Source == E2S && attribute.Edge1Target == E3T
+                  // if previously deleted Edge2Source-Target is readded
+                  || attribute.Edge2Source == E3S && attribute.Edge2Target == E1T
+                  || attribute.Edge2Source == E2S && attribute.Edge2Target == E3T
+                  // if previously deleted Edge3Source-Target is readded
+                  || attribute.Edge3Source == E3S && attribute.Edge3Target == E1T
+                  || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T) {
+                  isTabu = true;
+                  break;
+                }
+              }
+            }
+          }
+        }
+      }
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveTabuMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveTabuMaker.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveTabuMaker.cs	(revision 13694)
@@ -0,0 +1,83 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("TranslocationMoveTabuMaker", "Declares a given translocation or insertion move (3-opt) as tabu, by adding its attributes to the tabu list.")]
+  [StorableClass]
+  public class TranslocationMoveTabuMaker : TabuMaker, IPermutationTranslocationMoveOperator {
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<TranslocationMove> TranslocationMoveParameter {
+      get { return (LookupParameter<TranslocationMove>)Parameters["TranslocationMove"]; }
+    }
+
+    [StorableConstructor]
+    protected TranslocationMoveTabuMaker(bool deserializing) : base(deserializing) { }
+    protected TranslocationMoveTabuMaker(TranslocationMoveTabuMaker original, Cloner cloner) : base(original, cloner) { }
+    public TranslocationMoveTabuMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<TranslocationMove>("TranslocationMove", "The move that was made."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TranslocationMoveTabuMaker(this, cloner);
+    }
+
+    protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality) {
+      TranslocationMove move = TranslocationMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      double baseQuality = moveQuality;
+      if (maximization && quality > moveQuality || !maximization && quality < moveQuality) baseQuality = quality; // we make an uphill move, the lower bound is the solution quality
+      if (permutation.PermutationType == PermutationTypes.Absolute) {
+        int[] numbers = new int[move.Index2 - move.Index1 + 1];
+        for (int i = 0; i < numbers.Length; i++) {
+          numbers[i] = permutation[i + move.Index1];
+        }
+        return new TranslocationMoveAbsoluteAttribute(numbers, move.Index1, move.Index3, baseQuality); ;
+      } else {
+        if (move.Index3 > move.Index1)
+          return new TranslocationMoveRelativeAttribute(permutation.GetCircular(move.Index1 - 1),
+          permutation[move.Index1],
+          permutation[move.Index2],
+          permutation.GetCircular(move.Index2 + 1),
+          permutation.GetCircular(move.Index3 + move.Index2 - move.Index1),
+          permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1),
+          baseQuality);
+        else
+          return new TranslocationMoveRelativeAttribute(permutation.GetCircular(move.Index1 - 1),
+          permutation[move.Index1],
+          permutation[move.Index2],
+          permutation.GetCircular(move.Index2 + 1),
+          permutation.GetCircular(move.Index3 - 1),
+          permutation.GetCircular(move.Index3),
+          baseQuality);
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoIndexMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoIndexMove.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoIndexMove.cs	(revision 13694)
@@ -0,0 +1,58 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("TwoIndexMove", "A move on a permutation that is specified by 2 indices.")]
+  [StorableClass]
+  public class TwoIndexMove : Item {
+    [Storable]
+    public int Index1 { get; protected set; }
+    [Storable]
+    public int Index2 { get; protected set; }
+    [Storable]
+    public Permutation Permutation { get; protected set; }
+
+    [StorableConstructor]
+    protected TwoIndexMove(bool deserializing) : base(deserializing) { }
+    protected TwoIndexMove(TwoIndexMove original, Cloner cloner)
+      : base(original, cloner) {
+      this.Index1 = original.Index1;
+      this.Index2 = original.Index2;
+      if (original.Permutation != null)
+        this.Permutation = cloner.Clone(original.Permutation);
+    }
+    public TwoIndexMove() : this(-1, -1, null) { }
+    public TwoIndexMove(int index1, int index2, Permutation permutation)
+      : base() {
+      Index1 = index1;
+      Index2 = index2;
+      Permutation = permutation;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TwoIndexMove(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/ExhaustiveInversionMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/ExhaustiveInversionMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/ExhaustiveInversionMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("ExhaustiveInversionMoveGenerator", "Generates all possible inversion moves (2-opt) from a given permutation.")]
+  [StorableClass]
+  public class ExhaustiveInversionMoveGenerator : InversionMoveGenerator, IExhaustiveMoveGenerator {
+    [StorableConstructor]
+    protected ExhaustiveInversionMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected ExhaustiveInversionMoveGenerator(ExhaustiveInversionMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public ExhaustiveInversionMoveGenerator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExhaustiveInversionMoveGenerator(this, cloner);
+    }
+
+    public static InversionMove[] Apply(Permutation permutation) {
+      return Generate(permutation).ToArray();
+    }
+
+    public static IEnumerable<InversionMove> Generate(Permutation permutation) {
+      int length = permutation.Length;
+      if (length == 1) throw new ArgumentException("ExhaustiveInversionMoveGenerator: There cannot be an inversion move given a permutation of length 1.", "permutation");
+      int totalMoves = (length) * (length - 1) / 2;
+
+      if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
+        if (totalMoves - 3 > 0) {
+          for (int i = 0; i < length - 1; i++) {
+            for (int j = i + 1; j < length; j++) {
+              // doesn't make sense to inverse the whole permutation or the whole but one in case of relative undirected permutations
+              if (j - i >= length - 2) continue;
+              yield return new InversionMove(i, j);
+            }
+          }
+        } else { // when length is 3 or less, there's actually no difference, but for the sake of not crashing the algorithm create a dummy move
+          yield return new InversionMove(0, 1);
+        }
+      } else {
+        for (int i = 0; i < length - 1; i++)
+          for (int j = i + 1; j < length; j++) {
+            yield return new InversionMove(i, j);
+          }
+      }
+    }
+
+    protected override InversionMove[] GenerateMoves(Permutation permutation) {
+      return Apply(permutation);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMove.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMove.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMove.cs	(revision 13694)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("InversionMove", "Item that describes an inversion move (2-opt).")]
+  [StorableClass]
+  public class InversionMove : TwoIndexMove {
+    [StorableConstructor]
+    protected InversionMove(bool deserializing) : base(deserializing) { }
+    protected InversionMove(InversionMove original, Cloner cloner) : base(original, cloner) { }
+    public InversionMove() : base() { }
+    public InversionMove(int index1, int index2) : base(index1, index2, null) { }
+    public InversionMove(int index1, int index2, Permutation permutation) : base(index1, index2, permutation) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InversionMove(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveAbsoluteAttribute.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveAbsoluteAttribute.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveAbsoluteAttribute.cs	(revision 13694)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("InversionMoveAbsoluteAttribute", "Specifies the tabu attributes for an inversion move (2-opt) on an absolute position permutation.")]
+  [StorableClass]
+  public class InversionMoveAbsoluteAttribute : PermutationMoveAttribute {
+    [Storable]
+    public int Index1 { get; private set; }
+    [Storable]
+    public int Number1 { get; private set; }
+    [Storable]
+    public int Index2 { get; private set; }
+    [Storable]
+    public int Number2 { get; private set; }
+
+    [StorableConstructor]
+    protected InversionMoveAbsoluteAttribute(bool deserializing) : base(deserializing) { }
+    protected InversionMoveAbsoluteAttribute(InversionMoveAbsoluteAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.Index1 = original.Index1;
+      this.Number1 = original.Number1;
+      this.Index2 = original.Index2;
+      this.Number2 = original.Number2;
+    }
+    public InversionMoveAbsoluteAttribute() : this(-1, -1, -1, -1, -1) { }
+    public InversionMoveAbsoluteAttribute(int index1, int number1, int index2, int number2, double moveQuality)
+      : base(moveQuality) {
+      Index1 = index1;
+      Number1 = number1;
+      Index2 = index2;
+      Number2 = number2;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InversionMoveAbsoluteAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("InversionMoveGenerator", "Base class for all inversion (2-opt) move generators.")]
+  [StorableClass]
+  public abstract class InversionMoveGenerator : SingleSuccessorOperator, IPermutationInversionMoveOperator, IMoveGenerator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<InversionMove> InversionMoveParameter {
+      get { return (LookupParameter<InversionMove>)Parameters["InversionMove"]; }
+    }
+    protected ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+
+    [StorableConstructor]
+    protected InversionMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected InversionMoveGenerator(InversionMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public InversionMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation for which moves should be generated."));
+      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "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() {
+      Permutation p = PermutationParameter.ActualValue;
+      InversionMove[] moves = GenerateMoves(p);
+      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(InversionMoveParameter.ActualName, moves[i]));
+      }
+      CurrentScopeParameter.ActualValue.SubScopes.AddRange(moveScopes);
+      return base.Apply();
+    }
+
+    protected abstract InversionMove[] GenerateMoves(Permutation permutation);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveHardTabuCriterion.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveHardTabuCriterion.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveHardTabuCriterion.cs	(revision 13694)
@@ -0,0 +1,161 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+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.PermutationEncoding {
+  [Item("InversionMoveHardTabuCriterion", @"For relative postion encoded permutations it prevents readding of previously deleted edges as well as deleting previously added edges.
+  For absolute position encoded permutations it prevents moving a number if it was previously moved.
+
+If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
+  [StorableClass]
+  public class InversionMoveHardTabuCriterion : SingleSuccessorOperator, IPermutationInversionMoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<InversionMove> InversionMoveParameter {
+      get { return (LookupParameter<InversionMove>)Parameters["InversionMove"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    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 InversionMoveHardTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected InversionMoveHardTabuCriterion(InversionMoveHardTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public InversionMoveHardTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "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 InversionMoveHardTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      InversionMove move = InversionMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      int length = permutation.Length;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool isTabu = false;
+
+      foreach (IItem tabuMove in tabuList) {
+        PermutationMoveAttribute attrib = (tabuMove as PermutationMoveAttribute);
+        if (!useAspiration
+          || maximization && moveQuality <= attrib.MoveQuality
+          || !maximization && moveQuality >= attrib.MoveQuality) {
+          switch (permutation.PermutationType) {
+            case PermutationTypes.RelativeUndirected: {
+                int E1S = permutation.GetCircular(move.Index1 - 1);
+                int E1T = permutation[move.Index1];
+                int E2S = permutation[move.Index2];
+                int E2T = permutation.GetCircular(move.Index2 + 1);
+                InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
+                if (relAttrib != null) {
+                  if (relAttrib.Edge1Source == E1S && relAttrib.Edge2Source == E1T || relAttrib.Edge1Source == E1T && relAttrib.Edge2Source == E1S
+                    || relAttrib.Edge1Source == E2S && relAttrib.Edge2Source == E2T || relAttrib.Edge1Source == E2T && relAttrib.Edge2Source == E2S
+                    // if previously added Edge1Target-Edge2Target is deleted
+                    || relAttrib.Edge1Target == E2S && relAttrib.Edge2Target == E2T || relAttrib.Edge1Target == E2T && relAttrib.Edge2Target == E2S
+                    || relAttrib.Edge1Target == E1S && relAttrib.Edge2Target == E1T || relAttrib.Edge1Target == E1T && relAttrib.Edge2Target == E1S) {
+                    isTabu = true;
+                  }
+                }
+              }
+              break;
+            case PermutationTypes.RelativeDirected: {
+                int E1S = permutation.GetCircular(move.Index1 - 1);
+                int E1T = permutation[move.Index1];
+                int E2S = permutation[move.Index2];
+                int E2T = permutation.GetCircular(move.Index2 + 1);
+                InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
+                if (relAttrib != null) {
+                  if (relAttrib.Edge1Source == E1S && relAttrib.Edge2Source == E1T
+                    || relAttrib.Edge1Source == E2S && relAttrib.Edge2Source == E2T
+                    // if previously added Edge1Target-Edge2Target is deleted
+                    || relAttrib.Edge1Target == E2S && relAttrib.Edge2Target == E2T
+                    || relAttrib.Edge1Target == E1S && relAttrib.Edge2Target == E1T) {
+                    isTabu = true;
+                  }
+                }
+              }
+              break;
+            case PermutationTypes.Absolute: {
+                int i1 = move.Index1;
+                int n1 = permutation[move.Index1];
+                int i2 = move.Index2;
+                int n2 = permutation[move.Index2];
+                InversionMoveAbsoluteAttribute absAttrib = (attrib as InversionMoveAbsoluteAttribute);
+                if (absAttrib != null) {
+                  if (absAttrib.Number1 == n1 || absAttrib.Number1 == n2
+                    || absAttrib.Number2 == n2 || absAttrib.Number2 == n1)
+                    isTabu = true;
+
+                }
+              }
+              break;
+            default: {
+                throw new InvalidOperationException(Name + ": Unknown permutation type.");
+              }
+          }
+        }
+        if (isTabu) break;
+      }
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveMaker.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveMaker.cs	(revision 13694)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("InversionMoveMaker", "Peforms an inversion move (2-opt) on a given permutation and updates the quality.")]
+  [StorableClass]
+  public class InversionMoveMaker : SingleSuccessorOperator, IPermutationInversionMoveOperator, 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<InversionMove> InversionMoveParameter {
+      get { return (ILookupParameter<InversionMove>)Parameters["InversionMove"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    [StorableConstructor]
+    protected InversionMoveMaker(bool deserializing) : base(deserializing) { }
+    protected InversionMoveMaker(InversionMoveMaker original, Cloner cloner) : base(original, cloner) { }
+    public InversionMoveMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InversionMoveMaker(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      InversionMove move = InversionMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      DoubleValue moveQuality = MoveQualityParameter.ActualValue;
+      DoubleValue quality = QualityParameter.ActualValue;
+
+      InversionManipulator.Apply(permutation, move.Index1, move.Index2);
+      quality.Value = moveQuality.Value;
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveRelativeAttribute.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveRelativeAttribute.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveRelativeAttribute.cs	(revision 13694)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("InversionMoveRelativeAttribute", "Specifies the tabu attributes for an inversion move (2-opt) on a relative position permutation.")]
+  [StorableClass]
+  public class InversionMoveRelativeAttribute : PermutationMoveAttribute {
+    [Storable]
+    public int Edge1Source { get; private set; }
+    [Storable]
+    public int Edge1Target { get; private set; }
+    [Storable]
+    public int Edge2Source { get; private set; }
+    [Storable]
+    public int Edge2Target { get; private set; }
+
+    [StorableConstructor]
+    protected InversionMoveRelativeAttribute(bool deserializing) : base(deserializing) { }
+    protected InversionMoveRelativeAttribute(InversionMoveRelativeAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.Edge1Source = original.Edge1Source;
+      this.Edge1Target = original.Edge1Target;
+      this.Edge2Source = original.Edge2Source;
+      this.Edge2Target = original.Edge2Target;
+    }
+    public InversionMoveRelativeAttribute() : this(-1, -1, -1, -1, -1) { }
+    public InversionMoveRelativeAttribute(int edge1Source, int edge1Target, int edge2Source, int edge2Target, double moveQuality)
+      : base(moveQuality) {
+      Edge1Source = edge1Source;
+      Edge1Target = edge1Target;
+      Edge2Source = edge2Source;
+      Edge2Target = edge2Target;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InversionMoveRelativeAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveSoftTabuCriterion.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveSoftTabuCriterion.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveSoftTabuCriterion.cs	(revision 13694)
@@ -0,0 +1,162 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+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.PermutationEncoding {
+  [Item("InversionMoveSoftTabuCriterion", @"For relative postion encoded permutations it just prevents readding of previously deleted edges, but allows deleting previously added edges.
+  For absolute position encoded permutations it prevents moving a number to a position it has previously occupied.
+
+If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
+  [StorableClass]
+  public class InversionMoveSoftTabuCriterion : SingleSuccessorOperator, IPermutationInversionMoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<InversionMove> InversionMoveParameter {
+      get { return (LookupParameter<InversionMove>)Parameters["InversionMove"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    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 InversionMoveSoftTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected InversionMoveSoftTabuCriterion(InversionMoveSoftTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public InversionMoveSoftTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "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 InversionMoveSoftTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      InversionMove move = InversionMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      int length = permutation.Length;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool isTabu = false;
+
+      foreach (IItem tabuMove in tabuList) {
+        PermutationMoveAttribute attrib = (tabuMove as PermutationMoveAttribute);
+        if (!useAspiration
+          || maximization && moveQuality <= attrib.MoveQuality
+          || !maximization && moveQuality >= attrib.MoveQuality) {
+          switch (permutation.PermutationType) {
+            case PermutationTypes.RelativeUndirected: {
+                int E1S = permutation.GetCircular(move.Index1 - 1);
+                int E1T = permutation[move.Index1];
+                int E2S = permutation[move.Index2];
+                int E2T = permutation.GetCircular(move.Index2 + 1);
+                InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
+                if (relAttrib != null) {
+                  // if previously deleted Edge1Source-Target is readded
+                  if (relAttrib.Edge1Source == E1S && relAttrib.Edge1Target == E2S || relAttrib.Edge1Source == E2S && relAttrib.Edge1Target == E1S
+                    || relAttrib.Edge1Source == E1T && relAttrib.Edge1Target == E2T || relAttrib.Edge1Source == E2T && relAttrib.Edge1Target == E1T
+                    // if previously deleted Edge2Source-Target is readded
+                    || relAttrib.Edge2Source == E1T && relAttrib.Edge2Target == E2T || relAttrib.Edge2Source == E2T && relAttrib.Edge2Target == E1T
+                    || relAttrib.Edge2Source == E1S && relAttrib.Edge2Target == E2S || relAttrib.Edge2Source == E2S && relAttrib.Edge2Target == E1S) {
+                    isTabu = true;
+                  }
+                }
+              }
+              break;
+            case PermutationTypes.RelativeDirected: {
+                int E1S = permutation.GetCircular(move.Index1 - 1);
+                int E1T = permutation[move.Index1];
+                int E2S = permutation[move.Index2];
+                int E2T = permutation.GetCircular(move.Index2 + 1);
+                InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
+                if (relAttrib != null) {
+                  if (relAttrib.Edge1Source == E1S && relAttrib.Edge1Target == E2S
+                    || relAttrib.Edge1Source == E1T && relAttrib.Edge1Target == E2T
+                    // if previously deleted Edge2Source-Target is readded
+                    || relAttrib.Edge2Source == E1T && relAttrib.Edge2Target == E2T
+                    || relAttrib.Edge2Source == E1S && relAttrib.Edge2Target == E2S) {
+                    isTabu = true;
+                  }
+                }
+              }
+              break;
+            case PermutationTypes.Absolute: {
+                int i1 = move.Index1;
+                int n1 = permutation[move.Index1];
+                int i2 = move.Index2;
+                int n2 = permutation[move.Index2];
+                InversionMoveAbsoluteAttribute absAttrib = (attrib as InversionMoveAbsoluteAttribute);
+                if (absAttrib != null) {
+                  if ((absAttrib.Index1 == i1 || absAttrib.Index1 == i2) && (absAttrib.Number1 == n1 || absAttrib.Number1 == n2)
+                    || (absAttrib.Index2 == i2 || absAttrib.Index2 == i1) && (absAttrib.Number2 == n2 || absAttrib.Number2 == n1))
+                    isTabu = true;
+
+                }
+              }
+              break;
+            default: {
+                throw new InvalidOperationException(Name + ": Unknown permutation type.");
+              }
+          }
+        }
+        if (isTabu) break;
+      }
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveTabuMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveTabuMaker.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveTabuMaker.cs	(revision 13694)
@@ -0,0 +1,67 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("InversionMoveTabuMaker", "Declares a given inversion move (2-opt) as tabu, by adding its attributes to the tabu list and also store the solution quality or the move quality (whichever is better).")]
+  [StorableClass]
+  public class InversionMoveTabuMaker : TabuMaker, IPermutationInversionMoveOperator {
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<InversionMove> InversionMoveParameter {
+      get { return (LookupParameter<InversionMove>)Parameters["InversionMove"]; }
+    }
+
+    [StorableConstructor]
+    protected InversionMoveTabuMaker(bool deserializing) : base(deserializing) { }
+    protected InversionMoveTabuMaker(InversionMoveTabuMaker original, Cloner cloner) : base(original, cloner) { }
+    public InversionMoveTabuMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "The move that was made."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InversionMoveTabuMaker(this, cloner);
+    }
+
+    protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality) {
+      InversionMove move = InversionMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      double baseQuality = moveQuality;
+      if (maximization && quality > moveQuality || !maximization && quality < moveQuality) baseQuality = quality; // we make an uphill move, the lower bound is the solution quality
+      if (permutation.PermutationType == PermutationTypes.Absolute)
+        return new InversionMoveAbsoluteAttribute(move.Index1, permutation[move.Index1], move.Index2, permutation[move.Index2], baseQuality);
+      else
+        return new InversionMoveRelativeAttribute(permutation.GetCircular(move.Index1 - 1),
+          permutation[move.Index1],
+          permutation[move.Index2],
+          permutation.GetCircular(move.Index2 + 1),
+          baseQuality);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/StochasticInversionMultiMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/StochasticInversionMultiMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/StochasticInversionMultiMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,72 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("StochasticInversionMultiMoveGenerator", "Randomly samples n from all possible inversion moves (2-opt) from a given permutation.")]
+  [StorableClass]
+  public class StochasticInversionMultiMoveGenerator : InversionMoveGenerator, 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 StochasticInversionMultiMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticInversionMultiMoveGenerator(StochasticInversionMultiMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticInversionMultiMoveGenerator()
+      : 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 StochasticInversionMultiMoveGenerator(this, cloner);
+    }
+
+    public static InversionMove[] Apply(Permutation permutation, IRandom random, int sampleSize) {
+      int length = permutation.Length;
+      InversionMove[] moves = new InversionMove[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        moves[i] = StochasticInversionSingleMoveGenerator.Apply(permutation, random);
+      }
+      return moves;
+    }
+
+    protected override InversionMove[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return Apply(permutation, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/StochasticInversionSingleMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/StochasticInversionSingleMoveGenerator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/StochasticInversionSingleMoveGenerator.cs	(revision 13694)
@@ -0,0 +1,68 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("StochasticInversionSingleMoveGenerator", "Randomly samples a single from all possible inversion moves (2-opt) from a given permutation.")]
+  [StorableClass]
+  public class StochasticInversionSingleMoveGenerator : InversionMoveGenerator, IStochasticOperator, ISingleMoveGenerator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected StochasticInversionSingleMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticInversionSingleMoveGenerator(StochasticInversionSingleMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticInversionSingleMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticInversionSingleMoveGenerator(this, cloner);
+    }
+
+    public static InversionMove Apply(Permutation permutation, IRandom random) {
+      int length = permutation.Length;
+      if (length == 1) throw new ArgumentException("StochasticInversionSingleMoveGenerator: There cannot be an inversion move given a permutation of length 1.", "permutation");
+      int index1 = random.Next(length - 1);
+      int index2 = random.Next(index1 + 1, length);
+      if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
+        if (length > 3) {
+          while (index2 - index1 >= length - 2)
+            index2 = random.Next(index1 + 1, length);
+        }
+      }
+      return new InversionMove(index1, index2);
+    }
+
+    protected override InversionMove[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return new InversionMove[] { Apply(permutation, random) };
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Permutation.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Permutation.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Permutation.cs	(revision 13694)
@@ -0,0 +1,130 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("Permutation", "Represents a permutation of integer values.")]
+  [StorableClass]
+  public class Permutation : IntArray {
+    [Storable]
+    private PermutationTypes permutationType;
+    /// <summary>
+    /// Gets the type of the permutation (see <see cref="PermutationType"/>).
+    /// </summary>
+    public PermutationTypes PermutationType {
+      get { return permutationType; }
+      set {
+        bool changed = (permutationType != value);
+        permutationType = value;
+        if (changed) OnPermutationTypeChanged();
+      }
+    }
+
+    [StorableConstructor]
+    protected Permutation(bool deserializing) : base(deserializing) { }
+    protected Permutation(Permutation original, Cloner cloner)
+      : base(original, cloner) {
+      this.permutationType = original.permutationType;
+    }
+    public Permutation() : this(PermutationTypes.RelativeUndirected) { }
+    public Permutation(PermutationTypes type)
+      : base() {
+      permutationType = type;
+    }
+    public Permutation(PermutationTypes type, int length)
+      : base(length) {
+      for (int i = 0; i < length; i++)
+        this[i] = i;
+      permutationType = type;
+    }
+    public Permutation(PermutationTypes type, int length, IRandom random)
+      : this(type, length) {
+      Randomize(random);
+    }
+    public Permutation(PermutationTypes type, int[] elements)
+      : base(elements) {
+      permutationType = type;
+    }
+    public Permutation(PermutationTypes type, IntArray elements)
+      : this(type, elements.Length) {
+      for (int i = 0; i < array.Length; i++)
+        array[i] = elements[i];
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Permutation(this, cloner);
+    }
+
+    public virtual bool Validate() {
+      bool[] values = new bool[Length];
+      int value;
+
+      for (int i = 0; i < values.Length; i++)
+        values[i] = false;
+      for (int i = 0; i < Length; i++) {
+        value = this[i];
+        if ((value < 0) || (value >= values.Length)) return false;
+        if (values[value]) return false;
+        values[value] = true;
+      }
+      return true;
+    }
+
+    public virtual void Randomize(IRandom random, int startIndex, int length) {
+      if (length > 1) {
+        // Knuth shuffle
+        int index1, index2;
+        int val;
+        for (int i = length - 1; i > 0; i--) {
+          index1 = startIndex + i;
+          index2 = startIndex + random.Next(i + 1);
+          if (index1 != index2) {
+            val = array[index1];
+            array[index1] = array[index2];
+            array[index2] = val;
+          }
+        }
+        OnReset();
+      }
+    }
+    public void Randomize(IRandom random) {
+      Randomize(random, 0, Length);
+    }
+
+    public virtual int GetCircular(int position) {
+      if (position >= Length) position = position % Length;
+      while (position < 0) position += Length;
+      return this[position];
+    }
+
+    public event EventHandler PermutationTypeChanged;
+
+    protected virtual void OnPermutationTypeChanged() {
+      var handler = PermutationTypeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationCrossover.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationCrossover.cs	(revision 13694)
@@ -0,0 +1,69 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  /// <summary>
+  /// A base class for permutation crossover operators.
+  /// </summary>
+  [Item("PermutationCrossover", "A base class for permutation crossover operators.")]
+  [StorableClass]
+  public abstract class PermutationCrossover : InstrumentedOperator, IPermutationCrossover, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<ItemArray<Permutation>> ParentsParameter {
+      get { return (ScopeTreeLookupParameter<Permutation>)Parameters["Parents"]; }
+    }
+    public ILookupParameter<Permutation> ChildParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Child"]; }
+    }
+
+    [StorableConstructor]
+    protected PermutationCrossover(bool deserializing) : base(deserializing) { }
+    protected PermutationCrossover(PermutationCrossover original, Cloner cloner) : base(original, cloner) { }
+    protected PermutationCrossover()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic crossover operators."));
+      Parameters.Add(new ScopeTreeLookupParameter<Permutation>("Parents", "The parent permutations which should be crossed."));
+      ParentsParameter.ActualName = "Permutation";
+      Parameters.Add(new LookupParameter<Permutation>("Child", "The child permutation resulting from the crossover."));
+      ChildParameter.ActualName = "Permutation";
+    }
+
+    public sealed override IOperation InstrumentedApply() {
+      ChildParameter.ActualValue = Cross(RandomParameter.ActualValue, ParentsParameter.ActualValue);
+      return base.InstrumentedApply();
+    }
+
+    protected abstract Permutation Cross(IRandom random, ItemArray<Permutation> parents);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEncoding.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEncoding.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEncoding.cs	(revision 13694)
@@ -0,0 +1,236 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  [Item("PermutationEncoding", "Describes a permutation encoding.")]
+  [StorableClass]
+  public sealed class PermutationEncoding : Encoding<IPermutationCreator> {
+    #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();
+      }
+    }
+
+    [Storable]
+    private IFixedValueParameter<PermutationType> permutationTypeParameter;
+    public IFixedValueParameter<PermutationType> PermutationTypeParameter {
+      get { return permutationTypeParameter; }
+      set {
+        if (value == null) throw new ArgumentNullException("Permutation type parameter must not be null.");
+        if (value.Value == null) throw new ArgumentNullException("Permutation type parameter value must not be null.");
+        if (permutationTypeParameter == value) return;
+
+        if (permutationTypeParameter != null) Parameters.Remove(permutationTypeParameter);
+        permutationTypeParameter = value;
+        Parameters.Add(permutationTypeParameter);
+        OnPermutationTypeParameterChanged();
+      }
+    }
+    #endregion
+
+    public int Length {
+      get { return LengthParameter.Value.Value; }
+      set { LengthParameter.Value.Value = value; }
+    }
+
+    public PermutationTypes Type {
+      get { return PermutationTypeParameter.Value.Value; }
+      set { PermutationTypeParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    private PermutationEncoding(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+      DiscoverOperators();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) { return new PermutationEncoding(this, cloner); }
+    private PermutationEncoding(PermutationEncoding original, Cloner cloner)
+      : base(original, cloner) {
+      lengthParameter = cloner.Clone(original.lengthParameter);
+      permutationTypeParameter = cloner.Clone(original.permutationTypeParameter);
+      RegisterParameterEvents();
+    }
+
+
+    public PermutationEncoding() : this("Permutation", 10, PermutationTypes.Absolute) { }
+    public PermutationEncoding(string name) : this(name, 10, PermutationTypes.Absolute) { }
+    public PermutationEncoding(int length) : this("Permutation", length, PermutationTypes.Absolute) { }
+    public PermutationEncoding(string name, int length, PermutationTypes type)
+      : base(name) {
+      lengthParameter = new FixedValueParameter<IntValue>(Name + ".Length", new IntValue(length));
+      permutationTypeParameter = new FixedValueParameter<PermutationType>(Name + ".Type", new PermutationType(type));
+      Parameters.Add(lengthParameter);
+      Parameters.Add(permutationTypeParameter);
+
+      SolutionCreator = new RandomPermutationCreator();
+      RegisterParameterEvents();
+      DiscoverOperators();
+    }
+
+    private void OnLengthParameterChanged() {
+      RegisterLengthParameterEvents();
+      ConfigureOperators(Operators);
+    }
+
+    private void OnPermutationTypeParameterChanged() {
+      RegisterPermutationTypeParameterEvents();
+      ConfigureOperators(Operators);
+    }
+
+    private void RegisterParameterEvents() {
+      RegisterLengthParameterEvents();
+      RegisterPermutationTypeParameterEvents();
+    }
+    private void RegisterLengthParameterEvents() {
+      LengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
+    }
+    private void RegisterPermutationTypeParameterEvents() {
+      PermutationTypeParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators);
+    }
+
+    #region Operator Discovery
+    private static readonly IEnumerable<Type> encodingSpecificOperatorTypes;
+    static PermutationEncoding() {
+      encodingSpecificOperatorTypes = new List<Type>() {
+          typeof (IPermutationOperator),
+          typeof (IPermutationCreator),
+          typeof (IPermutationCrossover),
+          typeof (IPermutationManipulator),
+          typeof (IPermutationMultiNeighborhoodShakingOperator),
+          typeof (IPermutationMoveOperator),
+          typeof (IPermutationInversionMoveOperator),
+          typeof (IPermutationScrambleMoveOperator),
+          typeof (IPermutationSwap2MoveOperator),                    
+          typeof (IPermutationTranslocationMoveOperator)
+      };
+    }
+    private void DiscoverOperators() {
+      var assembly = typeof(IPermutationOperator).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<IPermutationCreator>());
+      ConfigureCrossovers(operators.OfType<IPermutationCrossover>());
+      ConfigureManipulators(operators.OfType<IPermutationManipulator>());
+      ConfigureShakingOperators(operators.OfType<IPermutationMultiNeighborhoodShakingOperator>());
+      ConfigureMoveOperators(operators.OfType<IPermutationMoveOperator>());
+      ConfigureInversionMoveOperators(operators.OfType<IPermutationInversionMoveOperator>());
+      ConfigureScrambleMoveOperators(operators.OfType<IPermutationScrambleMoveOperator>());
+      ConfigureSwap2MoveOperators(operators.OfType<IPermutationSwap2MoveOperator>());
+      ConfigureTranslocationMoveOperators(operators.OfType<IPermutationTranslocationMoveOperator>());
+    }
+
+    #region specific operator wiring
+    private void ConfigureCreators(IEnumerable<IPermutationCreator> creators) {
+      foreach (var creator in creators) {
+        creator.LengthParameter.ActualName = LengthParameter.Name;
+        creator.PermutationParameter.ActualName = Name;
+        creator.PermutationTypeParameter.Value.Value = Type;
+      }
+    }
+    private void ConfigureCrossovers(IEnumerable<IPermutationCrossover> crossovers) {
+      foreach (var crossover in crossovers) {
+        crossover.ChildParameter.ActualName = Name;
+        crossover.ParentsParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureManipulators(IEnumerable<IPermutationManipulator> manipulators) {
+      foreach (var manipulator in manipulators) {
+        manipulator.PermutationParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureShakingOperators(IEnumerable<IPermutationMultiNeighborhoodShakingOperator> shakingOperators) {
+      foreach (var shakingOperator in shakingOperators) {
+        shakingOperator.PermutationParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureMoveOperators(IEnumerable<IPermutationMoveOperator> moveOperators) {
+      foreach (var moveOperator in moveOperators) {
+        moveOperator.PermutationParameter.ActualName = Name;
+      }
+    }
+    private void ConfigureInversionMoveOperators(IEnumerable<IPermutationInversionMoveOperator> inversionMoveOperators) {
+      foreach (var inversionMoveOperator in inversionMoveOperators) {
+        inversionMoveOperator.InversionMoveParameter.ActualName = Name + ".InversionMove";
+      }
+    }
+    private void ConfigureScrambleMoveOperators(IEnumerable<IPermutationScrambleMoveOperator> scrambleMoveOperators) {
+      foreach (var scrambleMoveOperator in scrambleMoveOperators) {
+        scrambleMoveOperator.ScrambleMoveParameter.ActualName = Name + ".ScrambleMove";
+      }
+    }
+    private void ConfigureSwap2MoveOperators(IEnumerable<IPermutationSwap2MoveOperator> swap2MoveOperators) {
+      foreach (var swap2MoveOperator in swap2MoveOperators) {
+        swap2MoveOperator.Swap2MoveParameter.ActualName = Name + ".Swap2Move";
+      }
+    }
+    private void ConfigureTranslocationMoveOperators(IEnumerable<IPermutationTranslocationMoveOperator> translocationMoveOperators) {
+      foreach (var translocationMoveOperator in translocationMoveOperators) {
+        translocationMoveOperator.TranslocationMoveParameter.ActualName = Name + ".TranslocationMove";
+      }
+    }
+
+    #endregion
+  }
+
+  public static class IndividualExtensionMethods {
+    public static Permutation Permutation(this Individual individual) {
+      var encoding = individual.GetEncoding<PermutationEncoding>();
+      return individual.Permutation(encoding.Name);
+    }
+    public static Permutation Permutation(this Individual individual, string name) {
+      return (Permutation)individual[name];
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEqualityComparer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEqualityComparer.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEqualityComparer.cs	(revision 13694)
@@ -0,0 +1,95 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [NonDiscoverableType]
+  public class PermutationEqualityComparer : EqualityComparer<Permutation> {
+    public override bool Equals(Permutation x, Permutation y) {
+      if (x.PermutationType != y.PermutationType) return false;
+      if (x.Length != y.Length) return false;
+      switch (x.PermutationType) {
+        case PermutationTypes.Absolute:
+          return EqualsAbsolute(x, y);
+        case PermutationTypes.RelativeDirected:
+          return EqualsRelative(x, y, true);
+        case PermutationTypes.RelativeUndirected:
+          return EqualsRelative(x, y, false);
+        default:
+          throw new InvalidOperationException("unknown permutation type");
+      }
+    }
+
+    private bool EqualsAbsolute(Permutation x, Permutation y) {
+      return x.SequenceEqual(y);
+    }
+
+    private bool EqualsRelative(Permutation x, Permutation y, bool directed) {
+      int[] edgesX = CalculateEdgesVector(x);
+      int[] edgesY = CalculateEdgesVector(y);
+      for (int i = 0; i < x.Length; i++)
+        if ((edgesX[i] != edgesY[i]) && (directed || edgesX[edgesY[i]] != i))
+          return false;
+      return true;
+    }
+
+    private int[] CalculateEdgesVector(Permutation permutation) {
+      // transform path representation into adjacency representation
+      int[] edgesVector = new int[permutation.Length];
+      for (int i = 0; i < permutation.Length - 1; i++)
+        edgesVector[permutation[i]] = permutation[i + 1];
+      edgesVector[permutation[permutation.Length - 1]] = permutation[0];
+      return edgesVector;
+    }
+
+    public override int GetHashCode(Permutation obj) {
+      if (obj == null) return 0;
+      return GenerateHashString(obj).GetHashCode();
+    }
+
+    private string GenerateHashString(Permutation p) {
+      StringBuilder sb = new StringBuilder();
+      if (p.PermutationType == PermutationTypes.Absolute) {
+        for (int i = 0; i < p.Length; i++)
+          sb.Append(p[i].ToString() + ";");
+      } else {
+        int i = 0;
+        while (p[i] != 0) i++; // always start at element 0
+        if (p.PermutationType == PermutationTypes.RelativeDirected) {
+          for (int j = 0; j < p.Length; j++)
+            sb.Append(p.GetCircular(i + j).ToString() + ";");
+        } else {
+          bool goLeft = p.GetCircular(i - 1) < p.GetCircular(i + 1); // go in direction of the lowest edge so that the total inversion and its original return the same hash code
+          for (int j = 0; j < p.Length; j++) {
+            if (goLeft) sb.Append(p.GetCircular(i - j).ToString() + ";");
+            else sb.Append(p.GetCircular(i + j).ToString() + ";");
+          }
+        }
+      }
+      return sb.ToString();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationManipulator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationManipulator.cs	(revision 13694)
@@ -0,0 +1,63 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  /// <summary>
+  /// A base class for permutation manipulation operators.
+  /// </summary>
+  [Item("PermutationManipulator", "A base class for permutation manipulation operators.")]
+  [StorableClass]
+  public abstract class PermutationManipulator : InstrumentedOperator, IPermutationManipulator, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    [StorableConstructor]
+    protected PermutationManipulator(bool deserializing) : base(deserializing) { }
+    protected PermutationManipulator(PermutationManipulator original, Cloner cloner) : base(original, cloner) { }
+    protected PermutationManipulator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation which should be manipulated."));
+    }
+
+    public sealed override IOperation InstrumentedApply() {
+      Manipulate(RandomParameter.ActualValue, PermutationParameter.ActualValue);
+      return base.InstrumentedApply();
+    }
+
+    protected abstract void Manipulate(IRandom random, Permutation permutation);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationType.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationType.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationType.cs	(revision 13694)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("PermutationType", "Represents a certain type of permutation.")]
+  [StorableClass]
+  public class PermutationType : ValueTypeValue<PermutationTypes> {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Enum; }
+    }
+
+    [StorableConstructor]
+    protected PermutationType(bool deserializing) : base(deserializing) { }
+    protected PermutationType(PermutationType original, Cloner cloner) : base(original, cloner) { }
+    public PermutationType() : base() { }
+    public PermutationType(PermutationTypes type) : base(type) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PermutationType(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationTypes.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationTypes.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationTypes.cs	(revision 13694)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public enum PermutationTypes {
+    RelativeDirected,
+    RelativeUndirected,
+    Absolute
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Plugin.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Plugin.cs.frame	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Plugin.cs.frame	(revision 13694)
@@ -0,0 +1,42 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Encodings.PermutationEncoding plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Encodings.PermutationEncoding", "3.3.13.$WCREV$")]
+  [PluginFile("HeuristicLab.Encodings.PermutationEncoding-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "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 HeuristicLabEncodingsPermutationEncodingPlugin : PluginBase {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Properties/AssemblyInfo.cs.frame	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/Properties/AssemblyInfo.cs.frame	(revision 13694)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding")]
+[assembly: AssemblyDescription("HeuristicLab permutation encoding and related operators")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("8819e533-c557-42e0-8cee-09dda7686cd2")]
+
+// 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.13.$WCREV$")]
Index: /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/ShakingOperators/PermutationShakingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/ShakingOperators/PermutationShakingOperator.cs	(revision 13694)
+++ /branches/PerformanceComparison/HeuristicLab.Encodings.PermutationEncoding/3.3/ShakingOperators/PermutationShakingOperator.cs	(revision 13694)
@@ -0,0 +1,84 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <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.PermutationEncoding {
+  /// <summary>
+  /// A shaking operator for VNS.
+  /// </summary>
+  [Item("PermutationShakingOperator", "A shaking operator for VNS which uses available manipulation operators to perform the shaking.")]
+  [StorableClass]
+  public class PermutationShakingOperator : ShakingOperator<IPermutationManipulator>, IPermutationMultiNeighborhoodShakingOperator, IStochasticOperator {
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected PermutationShakingOperator(bool deserializing) : base(deserializing) { }
+    protected PermutationShakingOperator(PermutationShakingOperator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PermutationShakingOperator(this, cloner);
+    }
+    public PermutationShakingOperator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation to shake."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that will be used for stochastic shaking operators."));
+      foreach (IPermutationManipulator shaker in ApplicationManager.Manager.GetInstances<IPermutationManipulator>().OrderBy(x => x.Name))
+        if (!(shaker is MultiPermutationManipulator)) Operators.Add(shaker);
+    }
+
+    #region Wiring of some parameters
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IPermutationManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IPermutationManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    private void ParameterizeOperators(IEnumerable<IndexedItem<IPermutationManipulator>> items) {
+      if (items.Any()) {
+        foreach (IStochasticOperator op in items.Select(x => x.Value).OfType<IStochasticOperator>())
+          op.RandomParameter.ActualName = RandomParameter.Name;
+        foreach (IPermutationManipulator op in items.Select(x => x.Value).OfType<IPermutationManipulator>())
+          op.PermutationParameter.ActualName = PermutationParameter.Name;
+      }
+    }
+    #endregion
+  }
+}
