Index: trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/UniformLikeCrossover.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/UniformLikeCrossover.cs	(revision 6506)
+++ trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/UniformLikeCrossover.cs	(revision 6507)
@@ -29,5 +29,5 @@
   [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 class UniformLikeCrossover : PermutationCrossover {
+  public sealed class UniformLikeCrossover : PermutationCrossover {
     [StorableConstructor]
     protected UniformLikeCrossover(bool deserializing) : base(deserializing) { }
Index: trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEqualityComparer.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEqualityComparer.cs	(revision 6506)
+++ trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationEqualityComparer.cs	(revision 6507)
@@ -22,10 +22,12 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
+using System.Text;
 using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Encodings.PermutationEncoding {
   [NonDiscoverableType]
-  public class PermutationEqualityComparer : IEqualityComparer<Permutation> {
-    public bool Equals(Permutation x, Permutation y) {
+  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;
@@ -43,7 +45,5 @@
 
     private bool EqualsAbsolute(Permutation x, Permutation y) {
-      for (int i = 0; i < x.Length; i++)
-        if (x[i] != y[i]) return false;
-      return true;
+      return x.SequenceEqual(y);
     }
 
@@ -66,7 +66,29 @@
     }
 
-    public int GetHashCode(Permutation obj) {
+    public override int GetHashCode(Permutation obj) {
       if (obj == null) return 0;
-      return obj.GetHashCode();
+      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: trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Tests/HeuristicLab.Encodings.PermutationEncoding-3.3.Tests.csproj
===================================================================
--- trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Tests/HeuristicLab.Encodings.PermutationEncoding-3.3.Tests.csproj	(revision 6506)
+++ trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Tests/HeuristicLab.Encodings.PermutationEncoding-3.3.Tests.csproj	(revision 6507)
@@ -112,4 +112,5 @@
     <Compile Include="OrderCrossoverTest.cs" />
     <Compile Include="PartiallyMatchedCrossoverTest.cs" />
+    <Compile Include="PermutationEqualityComparerTest.cs" />
     <Compile Include="PositionBasedCrossoverTest.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Tests/PermutationEqualityComparerTest.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Tests/PermutationEqualityComparerTest.cs	(revision 6507)
+++ trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Tests/PermutationEqualityComparerTest.cs	(revision 6507)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Encodings.PermutationEncoding;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace HeuristicLab.Encodings.PermutationEncoding_33.Tests {
+  [TestClass]
+  public class PermutationEqualityComparerTest {
+    [TestMethod]
+    public void TestPermutationEqualityComparer() {
+      PermutationEqualityComparer comparer = new PermutationEqualityComparer();
+      Permutation p = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 3, 2, 0, 1, 4 });
+      Permutation q = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 1, 0, 2, 3, 4 });
+      Assert.IsTrue(comparer.Equals(p, q));
+      Assert.IsTrue(comparer.GetHashCode(p) == comparer.GetHashCode(q));
+      Permutation p2 = new Permutation(PermutationTypes.RelativeDirected, new int[] { 2, 3, 4, 1, 0 });
+      Permutation q2 = new Permutation(PermutationTypes.RelativeDirected, new int[] { 1, 0, 2, 3, 4 });
+      Assert.IsTrue(comparer.Equals(p2, q2));
+      Assert.IsTrue(comparer.GetHashCode(p2) == comparer.GetHashCode(q2));
+
+      Assert.IsFalse(comparer.Equals(p, q2));
+      Assert.IsFalse(comparer.Equals(p2, q));
+
+      Permutation p3 = new Permutation(PermutationTypes.Absolute, new int[] { 2, 3, 0, 4, 1 });
+      Permutation q3 = new Permutation(PermutationTypes.Absolute, new int[] { 2, 3, 0, 4, 1 });
+      Assert.IsTrue(comparer.Equals(p3, q3));
+      Assert.IsTrue(comparer.GetHashCode(p3) == comparer.GetHashCode(q3));
+
+      Assert.IsFalse(comparer.Equals(p3, q));
+      Assert.IsFalse(comparer.Equals(p2, q3));
+
+      Permutation p4 = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 3, 2, 0, 1, 4, 5 });
+      Assert.IsFalse(comparer.Equals(p, p4));
+      Assert.IsFalse(comparer.Equals(p4, q));
+    }
+  }
+}
