Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPSolutionStructuralEqualityComparer.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPSolutionStructuralEqualityComparer.cs	(revision 7425)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPSolutionStructuralEqualityComparer.cs	(revision 7425)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Problems.GeneralizedQuadraticAssignment {
+  public class GQAPSolutionStructuralEqualityComparer : EqualityComparer<GQAPSolution> {
+
+    public override bool Equals(GQAPSolution x, GQAPSolution y) {
+      return GQAPIntegerVectorProximityCalculator.CalculateGenotypeSimilarity(x.Assignment, y.Assignment) >= 1.0;
+    }
+
+    public override int GetHashCode(GQAPSolution obj) {
+      return obj.GetHashCode();
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPPathRelinking.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPPathRelinking.cs	(revision 7424)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPPathRelinking.cs	(revision 7425)
@@ -29,6 +29,7 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
 
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
   [Item("GQAPPathRelinking", "Operator that performs path relinking between two solutions. It is described in Mateus, G., Resende, M., and Silva, R. 2011. GRASP with path-relinking for the generalized quadratic assignment problem. Journal of Heuristics 17, Springer Netherlands, pp. 527-565.")]
   [StorableClass]
@@ -110,11 +111,12 @@
       var target = parents[1];
 
+      var nu = 1.0;
       var pi_prime = (IntegerVector)source.Clone();
       var fix = new HashSet<int>();
       var nonFix = new HashSet<int>(Enumerable.Range(0, demands.Length));
-      var phi = GQAPIntegerVectorProximityCalculator.GetDifference(pi_prime, target);
+      var phi = new HashSet<int>(GQAPIntegerVectorProximityCalculator.GetDifference(pi_prime, target));
 
       while (phi.Any()) {
-        var B = new HashSet<IntegerVector>();
+        var B = new HashSet<GQAPSolution>(new GQAPSolutionStructuralEqualityComparer());
         foreach (var v in phi) {
           pi_prime[v] = target[v];
@@ -124,4 +126,27 @@
           GQAPEvaluator.Evaluate(pi2, weights, distances, installationCosts, demands, capacities,
             out flowDistanceQuality, out installationQuality, out overbookedCapacity);
+
+          if (overbookedCapacity <= 0.0) {
+            var quality = GQAPEvaluator.GetCombinedQuality(flowDistanceQuality, installationQuality, overbookedCapacity,
+                transportationCosts.Value, overbookedCapacityPenalty.Value);
+            var solution = new GQAPSolution(pi2, new DoubleValue(quality), new DoubleValue(flowDistanceQuality), new DoubleValue(installationQuality), new DoubleValue(overbookedCapacity));
+            if (B.Count >= nu * phi.Count) {
+              if (!B.Contains(solution) && quality <= B.Select(x => x.Quality.Value).Max()) {
+                // TODO: replace most similar element in B with worse cost
+              }
+            } else if (!B.Contains(solution)) {
+              B.Add(solution);
+            }
+          }
+        }
+        if (B.Any()) {
+          var pi = B.ChooseRandom(random);
+          var diff = GQAPIntegerVectorProximityCalculator.GetDifference(pi.Assignment, target);
+          var I = phi.Except(phi.Intersect(diff));
+          var i = I.ChooseRandom(random);
+          fix.Add(i);
+          nonFix.Remove(i);
+          pi_prime = pi.Assignment;
+          // TODO
         }
       }
