Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/BestGQAPSolutionAnalyzer.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/BestGQAPSolutionAnalyzer.cs	(revision 7419)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/BestGQAPSolutionAnalyzer.cs	(revision 7423)
@@ -113,23 +113,23 @@
     public BestGQAPSolutionAnalyzer()
       : base() {
-      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", "The distances between the locations."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", "The weights between the equipments."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("InstallationCosts", "The cost of installing equipment x at location y."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Demands", "The demands of the equipments."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", "The capacities at the locations."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", "The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights matrix already."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", "The multiplier for the constraint violation when added to the quality."));
-      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Assignment", "The GQAP solutions from which the best solution should be analyzed."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the GQAP solutions which should be analyzed."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("FlowDistanceQuality", "The flow-distance qualities of the GQAP solutions which should be analyzed."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("InstallationQuality", "The installation qualities of the GQAP solutions which should be analyzed."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("OverbookedCapacity", "The overbooked capacities of the GQAP solutions which should be analyzed."));
-      Parameters.Add(new LookupParameter<GQAPAssignment>("BestSolution", "The best GQAP solution."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", GeneralizedQuadraticAssignmentProblem.DistancesDescription));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", GeneralizedQuadraticAssignmentProblem.WeightsDescription));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("InstallationCosts", GeneralizedQuadraticAssignmentProblem.InstallationCostsDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("FlowDistanceQuality", GQAPEvaluator.FlowDistanceQualityDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("InstallationQuality", GQAPEvaluator.InstallationQualityDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("OverbookedCapacity", GQAPEvaluator.OverbookedCapacityDescription));
+      Parameters.Add(new LookupParameter<StringArray>("EquipmentNames", GeneralizedQuadraticAssignmentProblem.EquipmentNamesDescription));
+      Parameters.Add(new LookupParameter<StringArray>("LocationNames", GeneralizedQuadraticAssignmentProblem.LocationNamesDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", GeneralizedQuadraticAssignmentProblem.BestKnownQualityDescription));
+      Parameters.Add(new LookupParameter<IntegerVector>("BestKnownSolution", GeneralizedQuadraticAssignmentProblem.BestKnownSolutionDescription));
+      Parameters.Add(new LookupParameter<GQAPAssignment>("BestSolution", "The best GQAP solution found so far."));
       Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the best GQAP solution should be stored."));
-      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this GQAP instance."));
-      Parameters.Add(new LookupParameter<IntegerVector>("BestKnownSolution", "The best known solution of this GQAP instance."));
-      Parameters.Add(new LookupParameter<StringArray>("EquipmentNames", "A list of names that describes the equipments."));
-      Parameters.Add(new LookupParameter<StringArray>("LocationNames", "A list of names that describes the locations."));
     }
 
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/GQAPSolutionArchiveAnalyzer.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/GQAPSolutionArchiveAnalyzer.cs	(revision 7419)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/GQAPSolutionArchiveAnalyzer.cs	(revision 7423)
@@ -96,7 +96,4 @@
       get { return (ILookupParameter<IntegerVector>)Parameters["BestKnownSolution"]; }
     }
-    public ILookupParameter<GQAPAssignment> BestSolutionParameter {
-      get { return (ILookupParameter<GQAPAssignment>)Parameters["BestSolution"]; }
-    }
     public IValueLookupParameter<ResultCollection> ResultsParameter {
       get { return (IValueLookupParameter<ResultCollection>)Parameters["Results"]; }
@@ -111,23 +108,22 @@
     public GQAPSolutionArchiveAnalyzer()
       : base() {
-      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", "The distances between the locations."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", "The weights between the equipments."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("InstallationCosts", "The cost of installing equipment x at location y."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Demands", "The demands of the equipments."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", "The capacities at the locations."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", "The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights matrix already."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", "The multiplier for the constraint violation when added to the quality."));
-      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Assignment", "The GQAP solutions from which the best solution should be analyzed."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the GQAP solutions which should be analyzed."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("FlowDistanceQuality", "The flow-distance qualities of the GQAP solutions which should be analyzed."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("InstallationQuality", "The installation qualities of the GQAP solutions which should be analyzed."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("OverbookedCapacity", "The overbooked capacities of the GQAP solutions which should be analyzed."));
-      Parameters.Add(new LookupParameter<GQAPAssignment>("BestSolution", "The best GQAP solution."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", GeneralizedQuadraticAssignmentProblem.DistancesDescription));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", GeneralizedQuadraticAssignmentProblem.WeightsDescription));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("InstallationCosts", GeneralizedQuadraticAssignmentProblem.InstallationCostsDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("FlowDistanceQuality", GQAPEvaluator.FlowDistanceQualityDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("InstallationQuality", GQAPEvaluator.InstallationQualityDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("OverbookedCapacity", GQAPEvaluator.OverbookedCapacityDescription));
+      Parameters.Add(new LookupParameter<StringArray>("EquipmentNames", GeneralizedQuadraticAssignmentProblem.EquipmentNamesDescription));
+      Parameters.Add(new LookupParameter<StringArray>("LocationNames", GeneralizedQuadraticAssignmentProblem.LocationNamesDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", GeneralizedQuadraticAssignmentProblem.BestKnownQualityDescription));
+      Parameters.Add(new LookupParameter<IntegerVector>("BestKnownSolution", GeneralizedQuadraticAssignmentProblem.BestKnownSolutionDescription));
       Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the best GQAP solution should be stored."));
-      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this GQAP instance."));
-      Parameters.Add(new LookupParameter<IntegerVector>("BestKnownSolution", "The best known solution of this GQAP instance."));
-      Parameters.Add(new LookupParameter<StringArray>("EquipmentNames", "A list of names that describes the equipments."));
-      Parameters.Add(new LookupParameter<StringArray>("LocationNames", "A list of names that describes the locations."));
     }
 
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPIntegerVectorProximityCalculator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPIntegerVectorProximityCalculator.cs	(revision 7419)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPIntegerVectorProximityCalculator.cs	(revision 7423)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using HeuristicLab.Encodings.IntegerVectorEncoding;
 
@@ -35,4 +36,9 @@
       return 1.0 - CalculateGenotypeSimilarity(a, b);
     }
+
+    public static IEnumerable<int> GetDifference(IntegerVector a, IntegerVector b) {
+      for (int i = 0; i < a.Length; i++)
+        if (a[i] != b[i]) yield return i;
+    }
   }
 }
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7419)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7423)
@@ -53,5 +53,6 @@
     public static readonly string TransportationCostsDescription = "The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights matrix already.";
     public static readonly string OverbookedCapacityPenaltyDescription = "The multiplier for the constraint violation when added to the quality.";
-    public static readonly string BestKnownSolutionDescription = "The best known solution (if available)";
+    public static readonly string BestKnownQualityDescription = "The best known quality (if available).";
+    public static readonly string BestKnownSolutionDescription = "The best known solution (if available).";
     public static readonly string EquipmentNamesDescription = "Optional: A list of names that describes the equipments.";
     public static readonly string LocationNamesDescription = "Optional: A list of names that describes the locations.";
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPPathRelinking.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPPathRelinking.cs	(revision 7419)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPPathRelinking.cs	(revision 7423)
@@ -21,13 +21,56 @@
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
-  [Item("GQAPPathRelinking", "Operator that performs path relinking between two solutions.")]
+  [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]
-  public class GQAPPathRelinking : GQAPCrossover {
+  public class GQAPPathRelinking : GQAPCrossover, IQualitiesAwareGQAPOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator,
+  IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator, IInstallationCostsAwareGQAPOperator, ITransportationCostsAwareGQAPOperator,
+  IOverbookedCapacityPenaltyAwareGQAPOperator {
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public IScopeTreeLookupParameter<DoubleValue> FlowDistanceQualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["FlowDistanceQuality"]; }
+    }
+    public IScopeTreeLookupParameter<DoubleValue> InstallationQualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["InstallationQuality"]; }
+    }
+    public IScopeTreeLookupParameter<DoubleValue> OverbookedCapacityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["OverbookedCapacity"]; }
+    }
+    public ILookupParameter<DoubleArray> DemandsParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
+    }
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+    public ILookupParameter<DoubleMatrix> WeightsParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Weights"]; }
+    }
+    public ILookupParameter<DoubleMatrix> DistancesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Distances"]; }
+    }
+    public ILookupParameter<DoubleMatrix> InstallationCostsParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["InstallationCosts"]; }
+    }
+    public IValueLookupParameter<DoubleValue> TransportationCostsParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
+    }
+    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    }
 
     [StorableConstructor]
@@ -36,4 +79,16 @@
     public GQAPPathRelinking()
       : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("FlowDistanceQuality", GQAPEvaluator.FlowDistanceQualityDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("InstallationQuality", GQAPEvaluator.InstallationQualityDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("OverbookedCapacity", GQAPEvaluator.OverbookedCapacityDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", GeneralizedQuadraticAssignmentProblem.WeightsDescription));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", GeneralizedQuadraticAssignmentProblem.DistancesDescription));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("InstallationCosts", GeneralizedQuadraticAssignmentProblem.InstallationCostsDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
     }
 
@@ -42,6 +97,47 @@
     }
 
+    public static IntegerVector Apply(IRandom random, ItemArray<IntegerVector> parents, ItemArray<DoubleValue> qualities, DoubleArray demands,
+      DoubleArray capacities, DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts, DoubleValue transportationCosts,
+      DoubleValue overbookedCapacityPenalty) {
+      if (random == null) throw new ArgumentNullException("random", "No IRandom provider is given.");
+      if (parents == null || !parents.Any()) throw new ArgumentException("No parents given for path relinking.", "parents");
+      if (parents.Length != 2) throw new ArgumentException(String.Format("Two parents were expected for path relinking, but {0} was/were given.", parents.Length.ToString()), "parents");
+      if (parents[0].Length != parents[1].Length) throw new ArgumentException("The length of the parents is not equal.", "parents");
+      if (qualities == null || qualities.Length == 0) throw new ArgumentException("The qualities are not given.", "qualities");
+      if (qualities.Length != parents.Length) throw new ArgumentException(String.Format("There are a different number of parents ({0}) than quality values ({1})", parents.Length.ToString(), qualities.Length.ToString()));
+
+      var source = parents[0];
+      var target = parents[1];
+
+      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);
+
+      while (phi.Any()) {
+        var B = new HashSet<IntegerVector>();
+        foreach (var v in phi) {
+          pi_prime[v] = target[v];
+          var pi2 = makeFeasible(pi_prime, v);
+
+          double flowDistanceQuality, installationQuality, overbookedCapacity;
+          GQAPEvaluator.Evaluate(pi2, weights, distances, installationCosts, demands, capacities,
+            out flowDistanceQuality, out installationQuality, out overbookedCapacity);
+        }
+      }
+
+      return pi_prime;
+    }
+
     protected override IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents) {
-      throw new NotImplementedException();
+      return Apply(random, parents, QualityParameter.ActualValue, DemandsParameter.ActualValue,
+        CapacitiesParameter.ActualValue, WeightsParameter.ActualValue, DistancesParameter.ActualValue,
+        InstallationCostsParameter.ActualValue, TransportationCostsParameter.ActualValue,
+        OverbookedCapacityPenaltyParameter.ActualValue);
+    }
+
+    private static IntegerVector makeFeasible(IntegerVector assignment, int equipment) {
+      // TODO: implement
+      return assignment;
     }
   }
