Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/ProblemInstanceProviderView.Designer.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/ProblemInstanceProviderView.Designer.cs	(revision 7522)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/ProblemInstanceProviderView.Designer.cs	(revision 7523)
@@ -72,4 +72,6 @@
       // instancesComboBox
       // 
+      this.instancesComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.instancesComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
       this.instancesComboBox.FormattingEnabled = true;
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/ProblemView.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/ProblemView.cs	(revision 7522)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/ProblemView.cs	(revision 7523)
@@ -65,5 +65,4 @@
         provider.SetConsumer((IProblemInstanceConsumer)Content);
         problemInstanceProviderViewHost.Content = provider;
-        toolTip.SetToolTip(problemInstanceProviderComboBox, GetProviderToolTip(provider));
       }
     }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/ToolTipComboBox.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/ToolTipComboBox.cs	(revision 7522)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/ToolTipComboBox.cs	(revision 7523)
@@ -51,6 +51,6 @@
     protected override void OnDrawItem(DrawItemEventArgs e) {
       base.OnDrawItem(e);
-      var args = new ToolTipRequiredEventArgs(e.Index, Items[e.Index]);
-      OnToolTipRequired(args);
+      var args = new ToolTipRequiredEventArgs(e.Index, e.Index >= 0 ? Items[e.Index] : null);
+      if (e.Index >= 0) OnToolTipRequired(args);
       if (!e.State.HasFlag(DrawItemState.ComboBoxEdit) && !string.IsNullOrEmpty(args.ToolTip)) {
         var ttRect = TextRenderer.MeasureText(args.ToolTip, Font);
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7522)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7523)
@@ -38,5 +38,10 @@
   [Creatable("Problems")]
   [StorableClass]
-  public sealed class GeneralizedQuadraticAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<IGQAPEvaluator, IGQAPSolutionCreator>, IStorableContent, IProblemInstanceConsumer<IQAPInstance>, IProblemInstanceConsumer<ICTAPInstance>, IProblemInstanceConsumer<ITSPInstance>, IProblemInstanceConsumer<IATSPInstance> {
+  public sealed class GeneralizedQuadraticAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<IGQAPEvaluator, IGQAPSolutionCreator>, IStorableContent,
+    IProblemInstanceConsumer<IQAPInstance>,
+    IProblemInstanceConsumer<ICTAPInstance>,
+    IProblemInstanceConsumer<ITSPInstance>,
+    IProblemInstanceConsumer<IATSPInstance>,
+    IProblemInstanceConsumer<IGQAPInstance> {
 
     public override Image ItemImage {
@@ -208,4 +213,5 @@
     }
 
+    #region Problem Instance Consumptions
     public bool LoadFrom(IQAPInstance instance) {
       try {
@@ -330,9 +336,43 @@
     }
 
+    public bool LoadFrom(IGQAPInstance instance) {
+      try {
+        Name = instance.Name;
+        Description = instance.Description;
+
+        Capacities = new DoubleArray(instance.Capacities);
+        Demands = new DoubleArray(instance.Demands);
+        InstallationCosts = new DoubleMatrix(instance.InstallationCosts);
+        Weights = new DoubleMatrix(instance.Weights);
+        Distances = new DoubleMatrix(instance.Distances);
+        TransportationCosts.Value = instance.TransportationCosts;
+
+        if (instance.BestKnownAssignment != null) {
+          EvaluateAndLoadAssignment(instance.BestKnownAssignment);
+        } else if (instance.BestKnownQuality.HasValue) {
+          BestKnownQuality = new DoubleValue(instance.BestKnownQuality.Value);
+          BestKnownSolution = null;
+          BestKnownSolutions = null;
+        } else {
+          BestKnownQuality = null;
+          BestKnownSolution = null;
+          BestKnownSolutions = null;
+        }
+      } catch {
+        return false;
+      }
+      return true;
+    }
+    #endregion
+
     private void EvaluateAndLoadAssignment(int[] vector) {
       EvaluateAndLoadAssignment(new IntegerVector(vector));
     }
     private void EvaluateAndLoadAssignment(IntegerVector assignment) {
-      if (!IsConfigurationValid()) return;
+      if (!IsConfigurationValid()) {
+        BestKnownQuality = null;
+        BestKnownSolution = null;
+        BestKnownSolutions = null;
+      }
       double flowDistanceQuality, installationQuality, overbookedCapacity;
       GQAPEvaluator.Evaluate(assignment, Weights, Distances, InstallationCosts, Demands, Capacities,
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj	(revision 7522)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj	(revision 7523)
@@ -99,4 +99,9 @@
     <Compile Include="Evaluators\GQAPNMoveEvaluator.cs" />
     <Compile Include="GQAPAssignment.cs" />
+    <Compile Include="Operators\Crossovers\CordeauCrossover.cs" />
+    <Compile Include="SolutionCreators\GQAPSolutionCreator.cs" />
+    <Compile Include="SolutionCreators\GQAPStochasticSolutionCreator.cs" />
+    <Compile Include="SolutionCreators\GreedyRandomizedSolutionCreator.cs" />
+    <Compile Include="SolutionCreators\RandomSolutionCreator.cs" />
     <None Include="Plugin.cs.frame" />
     <Compile Include="Evaluators\GQAPEvaluator.cs" />
@@ -140,21 +145,17 @@
     <Compile Include="Moves\StochasticNMoveMultiMoveGenerator.cs" />
     <Compile Include="Moves\StochasticNMoveSingleMoveGenerator.cs" />
-    <Compile Include="Operators\ApproximateLocalSearch.cs" />
-    <Compile Include="Operators\MultiGQAPCrossover.cs" />
-    <Compile Include="Operators\GQAPPathRelinking.cs" />
-    <Compile Include="Operators\GQAPStochasticSolutionCreator.cs" />
-    <Compile Include="Operators\DemandEquivalentSwapEquipmentManipluator.cs" />
-    <Compile Include="Operators\GQAPCrossover.cs" />
-    <Compile Include="Operators\DiscreteLocationCrossover.cs" />
-    <Compile Include="Operators\GQAPSolutionCreator.cs" />
-    <Compile Include="Operators\GreedyRandomizedSolutionCreator.cs" />
-    <Compile Include="Operators\MultiGQAPManipulator.cs" />
-    <Compile Include="Operators\NMoveShakingOperator.cs" />
-    <Compile Include="Operators\GQAPQualitySimilarityReducer.cs" />
-    <Compile Include="Operators\RandomSolutionCreator.cs" />
-    <Compile Include="Operators\RelocateEquipmentManipluator.cs" />
-    <Compile Include="Operators\GQAPManipulator.cs" />
-    <Compile Include="Operators\SwapEquipmentManipluator.cs" />
-    <Compile Include="Operators\SwapLocationManipulator.cs" />
+    <Compile Include="Operators\Crossovers\DiscreteLocationCrossover.cs" />
+    <Compile Include="Operators\Crossovers\GQAPCrossover.cs" />
+    <Compile Include="Operators\Crossovers\GQAPPathRelinking.cs" />
+    <Compile Include="Operators\Crossovers\MultiGQAPCrossover.cs" />
+    <Compile Include="Operators\LocalImprovers\ApproximateLocalSearch.cs" />
+    <Compile Include="Operators\Manipulators\DemandEquivalentSwapEquipmentManipluator.cs" />
+    <Compile Include="Operators\Manipulators\GQAPManipulator.cs" />
+    <Compile Include="Operators\Manipulators\MultiGQAPManipulator.cs" />
+    <Compile Include="Operators\Manipulators\RelocateEquipmentManipluator.cs" />
+    <Compile Include="Operators\Manipulators\SwapEquipmentManipluator.cs" />
+    <Compile Include="Operators\Manipulators\SwapLocationManipulator.cs" />
+    <Compile Include="Operators\PopulationReducers\GQAPQualitySimilarityReducer.cs" />
+    <Compile Include="Operators\Shakers\NMoveShakingOperator.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/ApproximateLocalSearch.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/ApproximateLocalSearch.cs	(revision 7522)
+++ 	(revision )
@@ -1,223 +1,0 @@
-﻿#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;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
-  [Item("ApproximateLocalSearch", "The approximate local search 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 ApproximateLocalSearch : SingleSuccessorOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator,
-    IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator, IInstallationCostsAwareGQAPOperator,
-    ITransportationCostsAwareGQAPOperator, IOverbookedCapacityPenaltyAwareGQAPOperator,
-    IAssignmentAwareGQAPOperator, IQualityAwareGQAPOperator, IGQAPLocalImprovementOperator, IStochasticOperator {
-    public IProblem Problem { get; set; }
-    public Type ProblemType {
-      get { return typeof(GeneralizedQuadraticAssignmentProblem); }
-    }
-
-    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"]; }
-    }
-    public ILookupParameter<IntegerVector> AssignmentParameter {
-      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
-    }
-    public ILookupParameter<BoolValue> MaximizationParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-    public ILookupParameter<DoubleValue> QualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
-    }
-    public ILookupParameter<DoubleValue> FlowDistanceQualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["FlowDistanceQuality"]; }
-    }
-    public ILookupParameter<DoubleValue> InstallationQualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["InstallationQuality"]; }
-    }
-    public ILookupParameter<DoubleValue> OverbookedCapacityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["OverbookedCapacity"]; }
-    }
-    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
-    }
-    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
-    }
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
-    }
-    public IValueLookupParameter<IntValue> MaximumCandidateListSizeParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumCandidateListSize"]; }
-    }
-    public IValueLookupParameter<PercentValue> OneMoveProbabilityParameter {
-      get { return (IValueLookupParameter<PercentValue>)Parameters["OneMoveProbability"]; }
-    }
-    public ILookupParameter<ResultCollection> ResultsParameter {
-      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
-    }
-
-    [StorableConstructor]
-    protected ApproximateLocalSearch(bool deserializing) : base(deserializing) { }
-    protected ApproximateLocalSearch(ApproximateLocalSearch original, Cloner cloner) : base(original, cloner) { }
-    public ApproximateLocalSearch()
-      : base() {
-      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));
-      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
-      Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription));
-      Parameters.Add(new LookupParameter<DoubleValue>("FlowDistanceQuality", GQAPEvaluator.FlowDistanceQualityDescription));
-      Parameters.Add(new LookupParameter<DoubleValue>("InstallationQuality", GQAPEvaluator.InstallationQualityDescription));
-      Parameters.Add(new LookupParameter<DoubleValue>("OverbookedCapacity", GQAPEvaluator.OverbookedCapacityDescription));
-      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of iterations that should be performed."));
-      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated solution equivalents."));
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumCandidateListSize", "The maximum number of candidates that should be found in each step.", new IntValue(10)));
-      Parameters.Add(new ValueLookupParameter<PercentValue>("OneMoveProbability", "The probability for performing a 1-move, which is the opposite of performing a 2-move.", new PercentValue(.5)));
-      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection that stores the results."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ApproximateLocalSearch(this, cloner);
-    }
-
-    /// <summary>
-    /// The implementation differs slightly from Mateus et al. in that the maximumIterations parameter defines a cap
-    /// on the number of steps that the local search can perform. While the maxSampleSize parameter corresponds to
-    /// the maxItr parameter defined by Mateus et al.
-    /// </summary>
-    /// <param name="random">The random number generator to use.</param>
-    /// <param name="assignment">The equipment-location assignment vector.</param>
-    /// <param name="quality">The solution quality.</param>
-    /// <param name="flowDistanceQuality">The quality regarding the flow-distance criteria.</param>
-    /// <param name="installationQuality">The quality regarding the installation costs.</param>
-    /// <param name="overbookedCapacity">The sum of the overbooked capacities relative to the capacity of each location.</param>
-    /// <param name="maxCLS">The maximum number of candidates that should be found in each step.</param>
-    /// <param name="maximumIterations">The maximum number of iterations that should be performed each time the candidate list is generated.</param>
-    /// <param name="weights">The weights matrix describes the flows between the equipments.</param>
-    /// <param name="distances">The distances matrix describes the distances between the locations at which the equipment can be installed.</param>
-    /// <param name="installationCosts">The installation costs matrix describes the installation costs of installing equipment i at location j</param>
-    /// <param name="demands">The demands vector describes the space requirements of the equipments.</param>
-    /// <param name="capacities">The capacities vector describes the available space at the locations.</param>
-    /// <param name="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.</param>
-    /// <param name="overbookedCapacityPenalty"></param>
-    /// <param name="oneMoveProbability">The probability for performing a 1-move, which is the opposite of performing a 2-move.</param>
-    public static void Apply(IRandom random, IntegerVector assignment,
-      DoubleValue quality, DoubleValue flowDistanceQuality, DoubleValue installationQuality, DoubleValue overbookedCapacity,
-      IntValue maxCLS, IntValue maximumIterations,
-      DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts, DoubleArray demands, DoubleArray capacities,
-      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty, PercentValue oneMoveProbability) {
-
-      while (true) {
-        int count = 0;
-        var CLS = new List<Tuple<NMove, double, double, double, double>>();
-        double sum = 0.0;
-        do {
-          NMove move;
-          if (random.NextDouble() < oneMoveProbability.Value)
-            move = StochasticNMoveSingleMoveGenerator.GenerateExactlyN(random, assignment, 1, capacities);
-          else move = StochasticNMoveSingleMoveGenerator.GenerateExactlyN(random, assignment, 2, capacities);
-
-          double moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity;
-          GQAPNMoveEvaluator.Evaluate(move, assignment, weights, distances, installationCosts,
-            demands, capacities, out moveFlowDistanceQuality, out moveInstallationQuality, out moveOverbookedCapacity);
-          double moveQuality = GQAPEvaluator.GetCombinedQuality(moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity,
-            transportationCosts.Value, overbookedCapacityPenalty.Value);
-
-          if (moveOverbookedCapacity <= 0.0 && moveQuality < 0.0) {
-            CLS.Add(Tuple.Create(move, moveQuality, moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity));
-            sum += 1.0 / moveQuality;
-          }
-          count++;
-        } while (CLS.Count < maxCLS.Value && count < maximumIterations.Value);
-
-        if (CLS.Count == 0)
-          return; // END
-        else {
-          var ball = random.NextDouble() * sum;
-          var selected = CLS.Last();
-          foreach (var candidate in CLS) {
-            ball -= 1.0 / candidate.Item2;
-            if (ball <= 0.0) {
-              selected = candidate;
-              break;
-            }
-          }
-          NMoveMaker.Apply(assignment, selected.Item1);
-          quality.Value += selected.Item2;
-          flowDistanceQuality.Value += selected.Item3;
-          installationQuality.Value += selected.Item4;
-          overbookedCapacity.Value += selected.Item5;
-        }
-      }
-    }
-
-    public override IOperation Apply() {
-      Apply(RandomParameter.ActualValue,
-        AssignmentParameter.ActualValue,
-        QualityParameter.ActualValue,
-        FlowDistanceQualityParameter.ActualValue,
-        InstallationQualityParameter.ActualValue,
-        OverbookedCapacityParameter.ActualValue,
-        MaximumCandidateListSizeParameter.ActualValue,
-        MaximumIterationsParameter.ActualValue,
-        WeightsParameter.ActualValue, DistancesParameter.ActualValue,
-        InstallationCostsParameter.ActualValue,
-        DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
-        TransportationCostsParameter.ActualValue,
-        OverbookedCapacityPenaltyParameter.ActualValue,
-        OneMoveProbabilityParameter.ActualValue);
-      return base.Apply();
-    }
-  }
-}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/CordeauCrossover.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/CordeauCrossover.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/CordeauCrossover.cs	(revision 7523)
@@ -0,0 +1,276 @@
+﻿#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;
+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 {
+  [Item("CordeauCrossover", "The merge procedure that is described in Cordeau, J.-F., Gaudioso, M., Laporte, G., Moccia, L. 2006. A memetic heuristic for the generalized quadratic assignment problem. INFORMS Journal on Computing, 18, pp. 433–443.")]
+  [StorableClass]
+  public class CordeauCrossover : GQAPCrossover,
+    IQualitiesAwareGQAPOperator, IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator, IInstallationCostsAwareGQAPOperator,
+    IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator, 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<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 ILookupParameter<DoubleArray> DemandsParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
+    }
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+    public IValueLookupParameter<DoubleValue> TransportationCostsParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
+    }
+    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    }
+
+    [StorableConstructor]
+    protected CordeauCrossover(bool deserializing) : base(deserializing) { }
+    protected CordeauCrossover(CordeauCrossover original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public CordeauCrossover()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription, 1));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("FlowDistanceQuality", GQAPEvaluator.FlowDistanceQualityDescription, 1));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("InstallationQuality", GQAPEvaluator.InstallationQualityDescription, 1));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("OverbookedCapacity", GQAPEvaluator.OverbookedCapacityDescription, 1));
+      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 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));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CordeauCrossover(this, cloner);
+    }
+
+    public static IntegerVector Apply(IRandom random, BoolValue maximization,
+      IntegerVector parent1, DoubleValue quality1,
+      IntegerVector parent2, DoubleValue quality2,
+      DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
+      DoubleArray demands, DoubleArray capacities,
+      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty) {
+      var mediana = Inizialize(distances);
+      int m = capacities.Length;
+      int n = demands.Length;
+      int i, j, k, ik1, ik2;
+      int control;
+      bool nofound = false, onefound = false;
+      double fbest;
+      IntegerVector son = new IntegerVector(parent1.Length), result = null;
+
+      fbest = quality1.Value;
+      if (maximization.Value && quality1.Value < quality2.Value
+        || !maximization.Value && quality1.Value > quality2.Value) {
+        var temp = parent1;
+        parent1 = parent2;
+        parent2 = temp;
+        fbest = quality2.Value;
+      }
+      var cap = new double[m];
+      for (i = 0; i < m; i++) {
+
+        for (j = 0; j < m; j++) cap[j] = 0;
+
+        for (k = 0; k < n; k++) {
+          son[k] = -1;
+          ik1 = parent1[k];
+          ik2 = parent2[k];
+          if (distances[i, ik1] < mediana[i]) {
+            son[k] = ik1;
+            cap[ik1] += demands[k];
+          } else if (distances[i, ik2] > mediana[i]) {
+            son[k] = ik2;
+            cap[ik2] += demands[k];
+          }
+        }
+        k = 0;
+        nofound = false;
+        while (k < n && !nofound) {
+          if (son[k] < 0) {
+            control = 0;
+            do {
+              j = random.Next(m);
+              control++;
+            }
+            while (cap[j] + demands[k] > capacities[j] && control < 3 * m);
+            if (cap[j] + demands[k] <= capacities[j]) {
+              son[k] = j;
+              cap[j] += demands[k];
+            } else {
+              nofound = true;
+            }
+          }
+          k++;
+        }
+        if (!nofound) {
+          double sonQual = GQAPEvaluator.Evaluate(son, weights, distances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+          if (sonQual < fbest) {
+            fbest = sonQual;
+            result = (IntegerVector)son.Clone();
+            onefound = true;
+          }
+        }/* else {
+          abortedmerge++;
+          printf("aborted merge %8d\n", abortedmerge);
+        } */
+      }
+      if (!onefound && !nofound) {
+        i = random.Next(m);
+        for (j = 0; j < m; j++) {
+          cap[j] = 0.0;
+        }
+        for (k = 0; k < n; k++) {
+          son[k] = -1;
+          ik1 = parent1[k];
+          ik2 = parent2[k];
+          if (distances[i, ik1] < mediana[i]) {
+            son[k] = ik1;
+            cap[ik1] += demands[k];
+          } else if (distances[i, ik2] > mediana[i]) {
+            son[k] = ik2;
+            cap[ik2] += demands[k];
+          }
+        }
+        for (k = 0; k < n; k++) {
+          if (son[k] < 0) {
+            j = random.Next(m);
+            son[k] = j;
+            cap[j] += demands[k];
+          }
+        }
+        if (result == null) {
+          result = (IntegerVector)son.Clone();
+          onefound = true;
+        } else {
+          double sonQual = GQAPEvaluator.Evaluate(son, weights, distances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+          if (sonQual < fbest) {
+            fbest = sonQual;
+            result = (IntegerVector)son.Clone();
+            onefound = true;
+          }
+        }
+        /*if (tabufix(&son, 0.5 * sqrt(n * m), round(n * m * log10(n)), &tabufix_it)) {
+          solution_cost(&son);
+          if (son.cost < fbest) {
+            fbest = son.cost;
+            *sptr = son;
+            onefound = TRUE;
+            merge_fixed++;
+          }*/
+      }
+      if (result == null) throw new InvalidOperationException("Child could not be created.");
+      return result;
+    }
+
+    protected override IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents) {
+      if (parents == null) throw new ArgumentNullException("parents");
+      if (parents.Length != 2) throw new ArgumentException(Name + " works only with exactly two parents.");
+
+      var qualities = QualityParameter.ActualValue;
+      return Apply(random, MaximizationParameter.ActualValue,
+        parents[0], qualities[0],
+        parents[1], qualities[1],
+        WeightsParameter.ActualValue, DistancesParameter.ActualValue, InstallationCostsParameter.ActualValue,
+        DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
+        TransportationCostsParameter.ActualValue, OverbookedCapacityPenaltyParameter.ActualValue);
+    }
+
+    private static double[] Inizialize(DoubleMatrix distances) {
+      int i, j;
+      double mdi;
+      double delta;
+      int ilow, ihigh;
+      bool balance;
+      int operation;
+      int count;
+      int m = distances.Rows;
+
+      double[] mediana = new double[distances.Rows];
+
+      for (i = 0; i < m; i++) {
+        mdi = 0;
+        for (j = 0; j < m; j++) {
+          mdi += distances[i, j];
+        }
+        mediana[i] = mdi / m;
+        balance = false;
+        delta = 1;
+        operation = 0;
+        count = 0;
+        while (!balance && count < 200) {
+          ilow = 0;
+          ihigh = 0;
+          count++;
+          for (j = 0; j < m; j++) {
+            if (distances[i, j] < mediana[i]) ilow++;
+            else if (distances[i, j] > mediana[i]) ihigh++;
+          }
+          if (ilow > ((m + 1) / 2)) {
+            mediana[i] = mediana[i] - delta;
+            if (operation == 1) delta = delta / 2;
+            operation = -1;
+          } else if (ihigh > ((m + 1) / 2)) {
+            mediana[i] = mediana[i] + delta;
+            if (operation == -1) delta = delta / 2;
+            operation = 1;
+          } else balance = true;
+        }
+      }
+      return mediana;
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/DiscreteLocationCrossover.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/DiscreteLocationCrossover.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/DiscreteLocationCrossover.cs	(revision 7523)
@@ -0,0 +1,94 @@
+﻿#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;
+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;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("DiscreteLocationCrossover", "Combines the assignment to locations from various parents.")]
+  [StorableClass]
+  public class DiscreteLocationCrossover : GQAPCrossover, ICapacitiesAwareGQAPOperator {
+
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+
+    [StorableConstructor]
+    protected DiscreteLocationCrossover(bool deserializing) : base(deserializing) { }
+    protected DiscreteLocationCrossover(DiscreteLocationCrossover original, Cloner cloner)
+      : base(original, cloner) { }
+    public DiscreteLocationCrossover()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DiscreteLocationCrossover(this, cloner);
+    }
+
+    public static IntegerVector Apply(IRandom random, ItemArray<IntegerVector> parents, DoubleArray capacities) {
+
+      var groupedLocations = parents
+              .Select(p => p.Select((value, index) => new { Equipment = index, Location = value })
+              .GroupBy(x => x.Location)
+              .ToDictionary(x => x.Key, y => y.AsEnumerable())).ToArray();
+
+      IntegerVector child = new IntegerVector(parents[0].Length);
+      HashSet<int> remainingEquipment = new HashSet<int>(Enumerable.Range(0, child.Length));
+      int locations = capacities.Length;
+      foreach (var i in Enumerable.Range(0, locations).Shuffle(random)) {
+        int parent = random.Next(parents.Length);
+        if (!groupedLocations[parent].ContainsKey(i)) {
+          int tmp = parent;
+          do {
+            tmp = (tmp + 1) % parents.Length;
+          } while (tmp != parent && !groupedLocations[tmp].ContainsKey(i));
+          if (parent == tmp) continue;
+          else parent = tmp;
+        }
+        foreach (var item in groupedLocations[parent][i]) {
+          if (remainingEquipment.Contains(item.Equipment)) {
+            child[item.Equipment] = i;
+            remainingEquipment.Remove(item.Equipment);
+          }
+        }
+      }
+
+      foreach (var equipment in remainingEquipment) {
+        int parent = random.Next(parents.Length);
+        child[equipment] = parents[parent][equipment];
+      }
+
+      return child;
+    }
+
+    protected override IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents) {
+      return Apply(random, parents, CapacitiesParameter.ActualValue);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPCrossover.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPCrossover.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPCrossover.cs	(revision 7523)
@@ -0,0 +1,66 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+
+  [Item("GQAPCrossover", "A base class for operators that cross assignment vectors of the GeneralizedQuadraticAssignment problems.")]
+  [StorableClass]
+  public abstract class GQAPCrossover : SingleSuccessorOperator, IGQAPCrossover, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    public IScopeTreeLookupParameter<IntegerVector> ParentsParameter {
+      get { return (ScopeTreeLookupParameter<IntegerVector>)Parameters["Parents"]; }
+    }
+    public ILookupParameter<IntegerVector> ChildParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Child"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected GQAPCrossover(bool deserializing) : base(deserializing) { }
+    protected GQAPCrossover(GQAPCrossover original, Cloner cloner) : base(original, cloner) { }
+    protected GQAPCrossover()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Parents", "The parent vectors which should be crossed.", "Assignment"));
+      Parameters.Add(new LookupParameter<IntegerVector>("Child", "The child vector resulting from the crossover.", "Assignment"));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic crossover operators."));
+    }
+
+    public sealed override IOperation Apply() {
+      ChildParameter.ActualValue = Cross(RandomParameter.ActualValue, ParentsParameter.ActualValue);
+      return base.Apply();
+    }
+
+    protected abstract IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents);
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs	(revision 7523)
@@ -0,0 +1,252 @@
+﻿#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;
+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;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
+
+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]
+  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"]; }
+    }
+
+    public IValueParameter<PercentValue> CandidateSizeFactorParameter {
+      get { return (IValueParameter<PercentValue>)Parameters["CandidateSizeFactor"]; }
+    }
+
+    [StorableConstructor]
+    protected GQAPPathRelinking(bool deserializing) : base(deserializing) { }
+    protected GQAPPathRelinking(GQAPPathRelinking original, Cloner cloner) : base(original, cloner) { }
+    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));
+      Parameters.Add(new ValueParameter<PercentValue>("CandidateSizeFactor", "(η) Determines the size of the set of feasible moves in each path-relinking step relative to the maximum size. A value of 50% means that only half of all possible moves are considered each step.", new PercentValue(0.5)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GQAPPathRelinking(this, cloner);
+    }
+
+    public static IntegerVector Apply(IRandom random, ItemArray<IntegerVector> parents, BoolValue maximization, ItemArray<DoubleValue> qualities,
+      ItemArray<DoubleValue> flowDistanceQualities, ItemArray<DoubleValue> installationQualities, ItemArray<DoubleValue> overbookedCapacities,
+      DoubleArray demands, DoubleArray capacities, DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
+      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty, DoubleValue candidateSizeFactor) {
+      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];
+      IntegerVector result;
+      double resultQuality, resultFDQ, resultIQ, resultOC;
+
+      int betterParent = 1;
+      if ((maximization.Value && qualities[0].Value >= qualities[1].Value)
+        || (!maximization.Value && qualities[0].Value <= qualities[1].Value))
+        betterParent = 0;
+
+      result = (IntegerVector)parents[betterParent].Clone();
+      resultQuality = qualities[betterParent].Value;
+      resultFDQ = flowDistanceQualities[betterParent].Value;
+      resultIQ = installationQualities[betterParent].Value;
+      resultOC = overbookedCapacities[betterParent].Value;
+
+      var pi_prime = (IntegerVector)source.Clone();
+      var fix = new HashSet<int>();
+      var nonFix = new HashSet<int>(Enumerable.Range(0, demands.Length));
+      var phi = new HashSet<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target));
+
+      while (phi.Any()) {
+        var B = new List<GQAPSolution>();
+        foreach (var v in phi) {
+          int oldLocation = pi_prime[v];
+          pi_prime[v] = target[v];
+          var pi2 = makeFeasible(random, pi_prime, v, nonFix, demands, capacities);
+          pi_prime[v] = oldLocation;
+
+          double currentFDQ, currentIQ, currentOC;
+          GQAPEvaluator.Evaluate(pi2, weights, distances, installationCosts, demands, capacities,
+            out currentFDQ, out currentIQ, out currentOC);
+
+          if (currentOC <= 0.0) {
+            var quality = GQAPEvaluator.GetCombinedQuality(currentFDQ, currentIQ, currentOC,
+                transportationCosts.Value, overbookedCapacityPenalty.Value);
+            var solution = new GQAPSolution(pi2, new DoubleValue(quality), new DoubleValue(currentFDQ),
+              new DoubleValue(currentIQ), new DoubleValue(currentOC));
+            if (B.Count >= candidateSizeFactor.Value * phi.Count) {
+              int mostSimilarIndex = -1;
+              double mostSimilarValue = 1.0;
+              for (int i = 0; i < B.Count; i++) {
+                if (IsBetter(maximization.Value, solution.Quality.Value, B[i].Quality.Value)) {
+                  var similarity = IntegerVectorEqualityComparer.GetSimilarity(solution.Assignment, B[i].Assignment);
+                  if (similarity == 1.0) {
+                    mostSimilarIndex = -1;
+                    break;
+                  } else if (similarity < mostSimilarValue) {
+                    mostSimilarValue = similarity;
+                    mostSimilarIndex = i;
+                  }
+                }
+              }
+              if (mostSimilarIndex >= 0)
+                B[mostSimilarIndex] = solution;
+            } else {
+              bool contains = false;
+              foreach (var b in B) {
+                if (!IntegerVectorEqualityComparer.GetDifferingIndices(solution.Assignment, b.Assignment).Any()) {
+                  contains = true;
+                  break;
+                }
+              }
+              if (!contains) B.Add(solution);
+            }
+          }
+        }
+        if (B.Any()) {
+          GQAPSolution pi;
+          if (maximization.Value) pi = B.ChooseProportionalRandom(random, 1, x => x.Quality.Value, false, true).First();
+          else pi = B.ChooseProportionalRandom(random, 1, x => 1.0 / x.Quality.Value, false, true).First();
+          var diff = IntegerVectorEqualityComparer.GetDifferingIndices(pi.Assignment, target);
+          var I = phi.Except(diff);
+          var i = I.ChooseUniformRandom(random);
+          fix.Add(i);
+          nonFix.Remove(i);
+          pi_prime = pi.Assignment;
+          if (IsBetter(maximization.Value, pi.Quality.Value, resultQuality)) {
+            result = pi.Assignment;
+            resultQuality = pi.Quality.Value;
+            resultFDQ = pi.FlowDistanceQuality.Value;
+            resultIQ = pi.InstallationQuality.Value;
+            resultOC = pi.OverbookedCapacity.Value;
+          }
+        } else return result;
+        phi = new HashSet<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target));
+      }
+
+      return result;
+    }
+
+    protected override IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents) {
+      return Apply(random, parents, MaximizationParameter.ActualValue, QualityParameter.ActualValue, FlowDistanceQualityParameter.ActualValue,
+        InstallationQualityParameter.ActualValue, OverbookedCapacityParameter.ActualValue, DemandsParameter.ActualValue,
+        CapacitiesParameter.ActualValue, WeightsParameter.ActualValue, DistancesParameter.ActualValue,
+        InstallationCostsParameter.ActualValue, TransportationCostsParameter.ActualValue,
+        OverbookedCapacityPenaltyParameter.ActualValue, CandidateSizeFactorParameter.Value);
+    }
+
+    private static IntegerVector makeFeasible(IRandom random, IntegerVector assignment, int equipment, HashSet<int> nonFix, DoubleArray demands, DoubleArray capacities, int maximumTries = 1000) {
+      int l = assignment[equipment];
+      var slack = ComputeSlack(assignment, demands, capacities);
+      if (slack[l] >= 0) return (IntegerVector)assignment.Clone();
+
+      IntegerVector result = null;
+      int k = 0;
+      while (k < maximumTries && slack[l] < 0) {
+        result = (IntegerVector)assignment.Clone();
+        do {
+          var maxSlack = slack.Max();
+          var T = nonFix.Where(x => x != equipment && assignment[x] == l && demands[x] <= maxSlack);
+          if (T.Any()) {
+            int i = T.ChooseProportionalRandom(random, 1, x => demands[x], false, true).First();
+            var j = Enumerable.Range(0, capacities.Length).Where(x => slack[x] >= demands[i]).ChooseUniformRandom(random);
+            result[i] = j;
+            slack[j] -= demands[i];
+            slack[l] += demands[i];
+          } else break;
+        } while (slack[l] < 0);
+        k++;
+      }
+      return result;
+    }
+
+    private static DoubleArray ComputeSlack(IntegerVector assignment, DoubleArray demands, DoubleArray capacities) {
+      var slack = (DoubleArray)capacities.Clone();
+      for (int i = 0; i < assignment.Length; i++) {
+        slack[assignment[i]] -= demands[i];
+      }
+      return slack;
+    }
+
+    private static bool IsBetter(bool maximization, double quality, double otherQuality) {
+      return maximization && quality > otherQuality || !maximization && quality < otherQuality;
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/MultiGQAPCrossover.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/MultiGQAPCrossover.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/MultiGQAPCrossover.cs	(revision 7523)
@@ -0,0 +1,93 @@
+﻿#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;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("MultiGQAPCrossover", "Randomly selects and applies one of its crossovers every time it is called.")]
+  [StorableClass]
+  public class MultiGQAPCrossover : StochasticMultiBranch<IGQAPCrossover>, IGQAPCrossover {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+
+    public IScopeTreeLookupParameter<IntegerVector> ParentsParameter {
+      get { return (ScopeTreeLookupParameter<IntegerVector>)Parameters["Parents"]; }
+    }
+    public ILookupParameter<IntegerVector> ChildParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Child"]; }
+    }
+
+    [StorableConstructor]
+    protected MultiGQAPCrossover(bool deserializing) : base(deserializing) { }
+    protected MultiGQAPCrossover(MultiGQAPCrossover original, Cloner cloner) : base(original, cloner) { }
+    public MultiGQAPCrossover()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Parents", "The parent vectors which should be crossed.", "Assignment"));
+      Parameters.Add(new LookupParameter<IntegerVector>("Child", "The child vector resulting from the crossover.", "Assignment"));
+      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IGQAPCrossover))) {
+        if (!typeof(MultiOperator<IGQAPCrossover>).IsAssignableFrom(type))
+          Operators.Add((IGQAPCrossover)Activator.CreateInstance(type), true);
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiGQAPCrossover(this, cloner);
+    }
+
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IGQAPCrossover>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      Parameterize();
+    }
+    protected override void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IGQAPCrossover>> e) {
+      base.Operators_ItemsRemoved(sender, e);
+      Parameterize();
+    }
+
+    private void Parameterize() {
+      foreach (var op in Operators.OfType<IGQAPCrossover>()) {
+        op.ParentsParameter.ActualName = ParentsParameter.Name;
+        op.ChildParameter.ActualName = ChildParameter.Name;
+      }
+      foreach (var op in Operators.OfType<IStochasticOperator>()) {
+        op.RandomParameter.ActualName = RandomParameter.Name;
+      }
+    }
+
+    public override IOperation Apply() {
+      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one crossover to choose from.");
+      return base.Apply();
+    }
+  }
+}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DemandEquivalentSwapEquipmentManipluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DemandEquivalentSwapEquipmentManipluator.cs	(revision 7522)
+++ 	(revision )
@@ -1,91 +1,0 @@
-﻿#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;
-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;
-using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-
-  [Item("DemandEquivalentSwapEquipmentManipluator", "Swaps equipment X from location A with as much equipments from location B that the demand of X is less than or equal to the demand of the swapped equipments in B.")]
-  [StorableClass]
-  public class DemandEquivalentSwapEquipmentManipluator : GQAPManipulator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator {
-
-    public ILookupParameter<DoubleArray> DemandsParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
-    }
-    public ILookupParameter<DoubleArray> CapacitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
-    }
-
-    [StorableConstructor]
-    protected DemandEquivalentSwapEquipmentManipluator(bool deserializing) : base(deserializing) { }
-    protected DemandEquivalentSwapEquipmentManipluator(DemandEquivalentSwapEquipmentManipluator original, Cloner cloner) : base(original, cloner) { }
-    public DemandEquivalentSwapEquipmentManipluator()
-      : base() {
-      Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
-      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new DemandEquivalentSwapEquipmentManipluator(this, cloner);
-    }
-
-    public static void Apply(IRandom random, IntegerVector assignment, DoubleArray capacities, DoubleArray demands) {
-      if (assignment.Length < 2) throw new InvalidOperationException("Vector is too small for swap operation.");
-      int equipment1 = random.Next(assignment.Length), equipment2 = random.Next(assignment.Length);
-      int counter = 1;
-      while (assignment[equipment1] == assignment[equipment2] && counter < assignment.Length) {
-        equipment2 = random.Next(assignment.Length);
-        counter++;
-      }
-      if (assignment[equipment1] != assignment[equipment2]) {
-        var groupedLocations = assignment
-              .Select((value, index) => new { Index = index, Value = value })
-              .GroupBy(x => x.Value)
-              .ToDictionary(x => x.Key, y => new HashSet<int>(y.Select(x => x.Index)));
-        double demand = demands[equipment1];
-        int location1 = assignment[equipment1];
-        int location2 = assignment[equipment2];
-
-        assignment[equipment1] = location2;
-        while (demand > 0) {
-          demand -= demands[equipment2];
-          assignment[equipment2] = location1;
-          groupedLocations[location2].Remove(equipment2);
-          if (!groupedLocations[location2].Any()) break;
-          equipment2 = groupedLocations[location2].ChooseUniformRandom(random);
-        }
-      }
-    }
-
-    protected override void Manipulate(IRandom random, IntegerVector vector) {
-      Apply(random, vector, CapacitiesParameter.ActualValue, DemandsParameter.ActualValue);
-    }
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DiscreteLocationCrossover.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DiscreteLocationCrossover.cs	(revision 7522)
+++ 	(revision )
@@ -1,94 +1,0 @@
-﻿#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;
-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;
-using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  [Item("DiscreteLocationCrossover", "Combines the assignment to locations from various parents.")]
-  [StorableClass]
-  public class DiscreteLocationCrossover : GQAPCrossover, ICapacitiesAwareGQAPOperator {
-
-    public ILookupParameter<DoubleArray> CapacitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
-    }
-
-    [StorableConstructor]
-    protected DiscreteLocationCrossover(bool deserializing) : base(deserializing) { }
-    protected DiscreteLocationCrossover(DiscreteLocationCrossover original, Cloner cloner)
-      : base(original, cloner) { }
-    public DiscreteLocationCrossover()
-      : base() {
-      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new DiscreteLocationCrossover(this, cloner);
-    }
-
-    public static IntegerVector Apply(IRandom random, ItemArray<IntegerVector> parents, DoubleArray capacities) {
-
-      var groupedLocations = parents
-              .Select(p => p.Select((value, index) => new { Equipment = index, Location = value })
-              .GroupBy(x => x.Location)
-              .ToDictionary(x => x.Key, y => y.AsEnumerable())).ToArray();
-
-      IntegerVector child = new IntegerVector(parents[0].Length);
-      HashSet<int> remainingEquipment = new HashSet<int>(Enumerable.Range(0, child.Length));
-      int locations = capacities.Length;
-      foreach (var i in Enumerable.Range(0, locations).Shuffle(random)) {
-        int parent = random.Next(parents.Length);
-        if (!groupedLocations[parent].ContainsKey(i)) {
-          int tmp = parent;
-          do {
-            tmp = (tmp + 1) % parents.Length;
-          } while (tmp != parent && !groupedLocations[tmp].ContainsKey(i));
-          if (parent == tmp) continue;
-          else parent = tmp;
-        }
-        foreach (var item in groupedLocations[parent][i]) {
-          if (remainingEquipment.Contains(item.Equipment)) {
-            child[item.Equipment] = i;
-            remainingEquipment.Remove(item.Equipment);
-          }
-        }
-      }
-
-      foreach (var equipment in remainingEquipment) {
-        int parent = random.Next(parents.Length);
-        child[equipment] = parents[parent][equipment];
-      }
-
-      return child;
-    }
-
-    protected override IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents) {
-      return Apply(random, parents, CapacitiesParameter.ActualValue);
-    }
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPCrossover.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPCrossover.cs	(revision 7522)
+++ 	(revision )
@@ -1,66 +1,0 @@
-﻿#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 HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-
-  [Item("GQAPCrossover", "A base class for operators that cross assignment vectors of the GeneralizedQuadraticAssignment problems.")]
-  [StorableClass]
-  public abstract class GQAPCrossover : SingleSuccessorOperator, IGQAPCrossover, IStochasticOperator {
-    public override bool CanChangeName {
-      get { return false; }
-    }
-
-    public IScopeTreeLookupParameter<IntegerVector> ParentsParameter {
-      get { return (ScopeTreeLookupParameter<IntegerVector>)Parameters["Parents"]; }
-    }
-    public ILookupParameter<IntegerVector> ChildParameter {
-      get { return (ILookupParameter<IntegerVector>)Parameters["Child"]; }
-    }
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
-    }
-
-    [StorableConstructor]
-    protected GQAPCrossover(bool deserializing) : base(deserializing) { }
-    protected GQAPCrossover(GQAPCrossover original, Cloner cloner) : base(original, cloner) { }
-    protected GQAPCrossover()
-      : base() {
-      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Parents", "The parent vectors which should be crossed.", "Assignment"));
-      Parameters.Add(new LookupParameter<IntegerVector>("Child", "The child vector resulting from the crossover.", "Assignment"));
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic crossover operators."));
-    }
-
-    public sealed override IOperation Apply() {
-      ChildParameter.ActualValue = Cross(RandomParameter.ActualValue, ParentsParameter.ActualValue);
-      return base.Apply();
-    }
-
-    protected abstract IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents);
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPManipulator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPManipulator.cs	(revision 7522)
+++ 	(revision )
@@ -1,61 +1,0 @@
-﻿#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 HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  [Item("GQAPManipulator", "A base class for operators that manipulate assignment vectors of the GeneralizedQuadraticAssignment problems.")]
-  [StorableClass]
-  public abstract class GQAPManipulator : SingleSuccessorOperator, IGQAPManipulator, IAssignmentAwareGQAPOperator, IStochasticOperator {
-    public override bool CanChangeName {
-      get { return false; }
-    }
-
-    public ILookupParameter<IntegerVector> AssignmentParameter {
-      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
-    }
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
-    }
-
-    [StorableConstructor]
-    protected GQAPManipulator(bool deserializing) : base(deserializing) { }
-    protected GQAPManipulator(GQAPManipulator original, Cloner cloner) : base(original, cloner) { }
-    protected GQAPManipulator()
-      : base() {
-      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
-    }
-
-    public sealed override IOperation Apply() {
-      Manipulate(RandomParameter.ActualValue, AssignmentParameter.ActualValue);
-      return base.Apply();
-    }
-
-    protected abstract void Manipulate(IRandom random, IntegerVector integerVector);
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPPathRelinking.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPPathRelinking.cs	(revision 7522)
+++ 	(revision )
@@ -1,252 +1,0 @@
-﻿#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;
-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;
-using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
-
-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]
-  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"]; }
-    }
-
-    public IValueParameter<PercentValue> CandidateSizeFactorParameter {
-      get { return (IValueParameter<PercentValue>)Parameters["CandidateSizeFactor"]; }
-    }
-
-    [StorableConstructor]
-    protected GQAPPathRelinking(bool deserializing) : base(deserializing) { }
-    protected GQAPPathRelinking(GQAPPathRelinking original, Cloner cloner) : base(original, cloner) { }
-    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));
-      Parameters.Add(new ValueParameter<PercentValue>("CandidateSizeFactor", "(η) Determines the size of the set of feasible moves in each path-relinking step relative to the maximum size. A value of 50% means that only half of all possible moves are considered each step.", new PercentValue(0.5)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new GQAPPathRelinking(this, cloner);
-    }
-
-    public static IntegerVector Apply(IRandom random, ItemArray<IntegerVector> parents, BoolValue maximization, ItemArray<DoubleValue> qualities,
-      ItemArray<DoubleValue> flowDistanceQualities, ItemArray<DoubleValue> installationQualities, ItemArray<DoubleValue> overbookedCapacities,
-      DoubleArray demands, DoubleArray capacities, DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
-      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty, DoubleValue candidateSizeFactor) {
-      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];
-      IntegerVector result;
-      double resultQuality, resultFDQ, resultIQ, resultOC;
-
-      int betterParent = 1;
-      if ((maximization.Value && qualities[0].Value >= qualities[1].Value)
-        || (!maximization.Value && qualities[0].Value <= qualities[1].Value))
-        betterParent = 0;
-
-      result = (IntegerVector)parents[betterParent].Clone();
-      resultQuality = qualities[betterParent].Value;
-      resultFDQ = flowDistanceQualities[betterParent].Value;
-      resultIQ = installationQualities[betterParent].Value;
-      resultOC = overbookedCapacities[betterParent].Value;
-
-      var pi_prime = (IntegerVector)source.Clone();
-      var fix = new HashSet<int>();
-      var nonFix = new HashSet<int>(Enumerable.Range(0, demands.Length));
-      var phi = new HashSet<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target));
-
-      while (phi.Any()) {
-        var B = new List<GQAPSolution>();
-        foreach (var v in phi) {
-          int oldLocation = pi_prime[v];
-          pi_prime[v] = target[v];
-          var pi2 = makeFeasible(random, pi_prime, v, nonFix, demands, capacities);
-          pi_prime[v] = oldLocation;
-
-          double currentFDQ, currentIQ, currentOC;
-          GQAPEvaluator.Evaluate(pi2, weights, distances, installationCosts, demands, capacities,
-            out currentFDQ, out currentIQ, out currentOC);
-
-          if (currentOC <= 0.0) {
-            var quality = GQAPEvaluator.GetCombinedQuality(currentFDQ, currentIQ, currentOC,
-                transportationCosts.Value, overbookedCapacityPenalty.Value);
-            var solution = new GQAPSolution(pi2, new DoubleValue(quality), new DoubleValue(currentFDQ),
-              new DoubleValue(currentIQ), new DoubleValue(currentOC));
-            if (B.Count >= candidateSizeFactor.Value * phi.Count) {
-              int mostSimilarIndex = -1;
-              double mostSimilarValue = 1.0;
-              for (int i = 0; i < B.Count; i++) {
-                if (IsBetter(maximization.Value, solution.Quality.Value, B[i].Quality.Value)) {
-                  var similarity = IntegerVectorEqualityComparer.GetSimilarity(solution.Assignment, B[i].Assignment);
-                  if (similarity == 1.0) {
-                    mostSimilarIndex = -1;
-                    break;
-                  } else if (similarity < mostSimilarValue) {
-                    mostSimilarValue = similarity;
-                    mostSimilarIndex = i;
-                  }
-                }
-              }
-              if (mostSimilarIndex >= 0)
-                B[mostSimilarIndex] = solution;
-            } else {
-              bool contains = false;
-              foreach (var b in B) {
-                if (!IntegerVectorEqualityComparer.GetDifferingIndices(solution.Assignment, b.Assignment).Any()) {
-                  contains = true;
-                  break;
-                }
-              }
-              if (!contains) B.Add(solution);
-            }
-          }
-        }
-        if (B.Any()) {
-          GQAPSolution pi;
-          if (maximization.Value) pi = B.ChooseProportionalRandom(random, 1, x => x.Quality.Value, false, true).First();
-          else pi = B.ChooseProportionalRandom(random, 1, x => 1.0 / x.Quality.Value, false, true).First();
-          var diff = IntegerVectorEqualityComparer.GetDifferingIndices(pi.Assignment, target);
-          var I = phi.Except(diff);
-          var i = I.ChooseUniformRandom(random);
-          fix.Add(i);
-          nonFix.Remove(i);
-          pi_prime = pi.Assignment;
-          if (IsBetter(maximization.Value, pi.Quality.Value, resultQuality)) {
-            result = pi.Assignment;
-            resultQuality = pi.Quality.Value;
-            resultFDQ = pi.FlowDistanceQuality.Value;
-            resultIQ = pi.InstallationQuality.Value;
-            resultOC = pi.OverbookedCapacity.Value;
-          }
-        } else return result;
-        phi = new HashSet<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target));
-      }
-
-      return result;
-    }
-
-    protected override IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents) {
-      return Apply(random, parents, MaximizationParameter.ActualValue, QualityParameter.ActualValue, FlowDistanceQualityParameter.ActualValue,
-        InstallationQualityParameter.ActualValue, OverbookedCapacityParameter.ActualValue, DemandsParameter.ActualValue,
-        CapacitiesParameter.ActualValue, WeightsParameter.ActualValue, DistancesParameter.ActualValue,
-        InstallationCostsParameter.ActualValue, TransportationCostsParameter.ActualValue,
-        OverbookedCapacityPenaltyParameter.ActualValue, CandidateSizeFactorParameter.Value);
-    }
-
-    private static IntegerVector makeFeasible(IRandom random, IntegerVector assignment, int equipment, HashSet<int> nonFix, DoubleArray demands, DoubleArray capacities, int maximumTries = 1000) {
-      int l = assignment[equipment];
-      var slack = ComputeSlack(assignment, demands, capacities);
-      if (slack[l] >= 0) return (IntegerVector)assignment.Clone();
-
-      IntegerVector result = null;
-      int k = 0;
-      while (k < maximumTries && slack[l] < 0) {
-        result = (IntegerVector)assignment.Clone();
-        do {
-          var maxSlack = slack.Max();
-          var T = nonFix.Where(x => x != equipment && assignment[x] == l && demands[x] <= maxSlack);
-          if (T.Any()) {
-            int i = T.ChooseProportionalRandom(random, 1, x => demands[x], false, true).First();
-            var j = Enumerable.Range(0, capacities.Length).Where(x => slack[x] >= demands[i]).ChooseUniformRandom(random);
-            result[i] = j;
-            slack[j] -= demands[i];
-            slack[l] += demands[i];
-          } else break;
-        } while (slack[l] < 0);
-        k++;
-      }
-      return result;
-    }
-
-    private static DoubleArray ComputeSlack(IntegerVector assignment, DoubleArray demands, DoubleArray capacities) {
-      var slack = (DoubleArray)capacities.Clone();
-      for (int i = 0; i < assignment.Length; i++) {
-        slack[assignment[i]] -= demands[i];
-      }
-      return slack;
-    }
-
-    private static bool IsBetter(bool maximization, double quality, double otherQuality) {
-      return maximization && quality > otherQuality || !maximization && quality < otherQuality;
-    }
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPQualitySimilarityReducer.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPQualitySimilarityReducer.cs	(revision 7522)
+++ 	(revision )
@@ -1,138 +1,0 @@
-﻿#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;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
-  [Item("GQAPQualitySimilarityReducer", "Reduces two populations two one by using quality and similarity information to obtain a population of high quality, but also diverse solutions.")]
-  [StorableClass]
-  public class GQAPQualitySimilarityReducer : SingleSuccessorOperator, IAssignmentAwareGQAPOperator, IQualityAwareGQAPOperator, IPopulationReducer {
-    public ILookupParameter<IntegerVector> AssignmentParameter {
-      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
-    }
-    public ILookupParameter<BoolValue> MaximizationParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-    public ILookupParameter<DoubleValue> QualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
-    }
-    public ILookupParameter<DoubleValue> FlowDistanceQualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["FlowDistanceQuality"]; }
-    }
-    public ILookupParameter<DoubleValue> InstallationQualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["InstallationQuality"]; }
-    }
-    public ILookupParameter<DoubleValue> OverbookedCapacityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["OverbookedCapacity"]; }
-    }
-    public ILookupParameter<IntValue> MinimumPopulationSizeParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["MinimumPopulationSize"]; }
-    }
-    public ILookupParameter<IntValue> MaximumPopulationSizeParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["MaximumPopulationSize"]; }
-    }
-
-    [StorableConstructor]
-    protected GQAPQualitySimilarityReducer(bool deserializing) : base(deserializing) { }
-    protected GQAPQualitySimilarityReducer(GQAPQualitySimilarityReducer original, Cloner cloner) : base(original, cloner) { }
-    public GQAPQualitySimilarityReducer()
-      : base() {
-      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
-      Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription));
-      Parameters.Add(new LookupParameter<DoubleValue>("FlowDistanceQuality", GQAPEvaluator.FlowDistanceQualityDescription));
-      Parameters.Add(new LookupParameter<DoubleValue>("InstallationQuality", GQAPEvaluator.InstallationQualityDescription));
-      Parameters.Add(new LookupParameter<DoubleValue>("OverbookedCapacity", GQAPEvaluator.OverbookedCapacityDescription));
-      Parameters.Add(new LookupParameter<IntValue>("MinimumPopulationSize", "The size of the population that should not be undershot."));
-      Parameters.Add(new LookupParameter<IntValue>("MaximumPopulationSize", "The size of the population that should not be surpassed."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new GQAPQualitySimilarityReducer(this, cloner);
-    }
-
-    public override IOperation Apply() {
-      string vectorName = AssignmentParameter.TranslatedName;
-      string qualityName = QualityParameter.TranslatedName;
-      int populationSize = MaximumPopulationSizeParameter.ActualValue.Value;
-      bool maximization = MaximizationParameter.ActualValue.Value;
-
-      IScope remaining = ExecutionContext.Scope.SubScopes[0];
-      IScope selected = ExecutionContext.Scope.SubScopes[1];
-
-      List<Individual> population =
-        remaining.SubScopes.Select(x => new Individual((IntegerVector)x.Variables[vectorName].Value,
-                                                      ((DoubleValue)x.Variables[qualityName].Value).Value,
-                                                      x)).ToList();
-      HashSet<Individual> candidates = new HashSet<Individual>(
-        selected.SubScopes.Select(x => new Individual((IntegerVector)x.Variables[vectorName].Value,
-                                                     ((DoubleValue)x.Variables[qualityName].Value).Value,
-                                                     x)));
-
-      foreach (var candidate in candidates) {
-        double[] similarities = population.Select(x => IntegerVectorEqualityComparer.GetSimilarity(x.Solution, candidate.Solution)).ToArray();
-        if (!similarities.Any()) {
-          population.Add(candidate);
-          break;
-        }
-        if (similarities.Max() == 1.0) break;
-        if (population.Count < populationSize) {
-          population.Add(candidate);
-        } else {
-          var replacement = population.Select((v, i) => new { V = v, Index = i })
-                                      .Where(x => (maximization && x.V.Quality < candidate.Quality)
-                                               || (!maximization && x.V.Quality > candidate.Quality));
-          if (replacement.Any()) {
-            replacement.OrderBy(x => similarities[x.Index]).ToArray();
-            population.Remove(replacement.Last().V);
-            population.Add(candidate);
-          }
-        }
-      }
-
-      ExecutionContext.Scope.SubScopes.Clear();
-      ExecutionContext.Scope.SubScopes.AddRange(population.Select(x => x.Scope));
-
-      return base.Apply();
-    }
-
-    private class Individual {
-      internal IntegerVector Solution { get; set; }
-      internal double Quality { get; set; }
-      internal IScope Scope { get; set; }
-
-      internal Individual(IntegerVector vector, double quality, IScope scope) {
-        Solution = vector;
-        Quality = quality;
-        Scope = scope;
-      }
-    }
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPSolutionCreator.cs	(revision 7522)
+++ 	(revision )
@@ -1,67 +1,0 @@
-﻿#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 HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  [Item("GQAPSolutionCreator", "Base class for solution creators of the Generalized Quadratic Assignment Problem.")]
-  [StorableClass]
-  public abstract class GQAPSolutionCreator : SingleSuccessorOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator, IGQAPSolutionCreator {
-
-    #region Parameter Descriptions
-    public static readonly string AssignmentDescription = "The vector that encodes the assignment.";
-    #endregion
-
-    public ILookupParameter<IntegerVector> AssignmentParameter {
-      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
-    }
-    public ILookupParameter<DoubleArray> DemandsParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
-    }
-    public ILookupParameter<DoubleArray> CapacitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
-    }
-
-    [StorableConstructor]
-    protected GQAPSolutionCreator(bool deserializing) : base(deserializing) { }
-    protected GQAPSolutionCreator(GQAPSolutionCreator original, Cloner cloner)
-      : base(original, cloner) { }
-    public GQAPSolutionCreator()
-      : base() {
-      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", AssignmentDescription));
-      Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
-      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
-    }
-
-    public override IOperation Apply() {
-      AssignmentParameter.ActualValue = CreateSolution(DemandsParameter.ActualValue, CapacitiesParameter.ActualValue);
-      return base.Apply();
-    }
-
-    protected abstract IntegerVector CreateSolution(DoubleArray demands, DoubleArray capacities);
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPStochasticSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPStochasticSolutionCreator.cs	(revision 7522)
+++ 	(revision )
@@ -1,54 +1,0 @@
-﻿#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 HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  [Item("GQAPStochasticSolutionCreator", "Base class for stochastic solution creators of the Generalized Quadratic Assignment Problem.")]
-  [StorableClass]
-  public abstract class GQAPStochasticSolutionCreator : GQAPSolutionCreator, IStochasticOperator {
-
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
-    }
-
-    [StorableConstructor]
-    protected GQAPStochasticSolutionCreator(bool deserializing) : base(deserializing) { }
-    protected GQAPStochasticSolutionCreator(GQAPStochasticSolutionCreator original, Cloner cloner)
-      : base(original, cloner) { }
-    public GQAPStochasticSolutionCreator()
-      : base() {
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
-    }
-
-    protected sealed override IntegerVector CreateSolution(DoubleArray demands, DoubleArray capacities) {
-      return CreateRandomSolution(RandomParameter.ActualValue, demands, capacities);
-    }
-
-    protected abstract IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities);
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GreedyRandomizedSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GreedyRandomizedSolutionCreator.cs	(revision 7522)
+++ 	(revision )
@@ -1,114 +1,0 @@
-﻿#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;
-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;
-using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  [Item("GreedyRandomizedSolutionCreator", "Creates a solution according to the procedure 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 GreedyRandomizedSolutionCreator : GQAPStochasticSolutionCreator {
-
-    public IValueLookupParameter<IntValue> MaximumTriesParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumTries"]; }
-    }
-
-    [StorableConstructor]
-    protected GreedyRandomizedSolutionCreator(bool deserializing) : base(deserializing) { }
-    protected GreedyRandomizedSolutionCreator(GreedyRandomizedSolutionCreator original, Cloner cloner)
-      : base(original, cloner) { }
-    public GreedyRandomizedSolutionCreator()
-      : base() {
-      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumTries", "The maximum number of tries to create a feasible solution.", new IntValue(10000)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new GreedyRandomizedSolutionCreator(this, cloner);
-    }
-
-    protected override IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities) {
-      int tries = 0, maxTries = MaximumTriesParameter.ActualValue.Value;
-      var assignment = new Dictionary<int, int>();
-      var slack = new Dictionary<int, double>();
-
-      while (tries < maxTries) {
-        assignment.Clear();
-        slack = capacities.Select((v, i) => new { Index = i, Value = v }).ToDictionary(x => x.Index, y => y.Value);
-        HashSet<int> CF = new HashSet<int>(), // set of chosen facilities / equipments
-          T = new HashSet<int>(), // set of facilities / equpiments that can be assigned to the set of chosen locations (CL)
-          CL = new HashSet<int>(), // set of chosen locations
-          F = new HashSet<int>(Enumerable.Range(0, demands.Length)), // set of (initially) all facilities / equipments
-          L = new HashSet<int>(Enumerable.Range(0, capacities.Length)); // set of (initially) all locations
-
-        double threshold = 1.0;
-        do {
-          if (L.Any() && random.NextDouble() < threshold) {
-            int l = L.ChooseUniformRandom(random);
-            L.Remove(l);
-            CL.Add(l);
-            T = new HashSet<int>(WithDemandEqualOrLess(F, GetMaximumSlack(slack, CL), demands));
-          }
-          if (T.Any()) {
-            int f = T.ChooseUniformRandom(random);
-            T.Remove(f);
-            F.Remove(f);
-            CF.Add(f);
-            int l = WithSlackGreaterOrEqual(CL, demands[f], slack).ChooseUniformRandom(random);
-            assignment.Add(f, l);
-            slack[l] -= demands[f];
-            T = new HashSet<int>(WithDemandEqualOrLess(F, GetMaximumSlack(slack, CL), demands));
-            threshold = 1.0 - (double)T.Count / Math.Max(F.Count, 1.0);
-          }
-        } while (T.Any() || L.Any());
-        tries++;
-        if (!F.Any()) break;
-      }
-
-      if (assignment.Count != demands.Length) throw new InvalidOperationException(String.Format("No solution could be found in {0} tries.", maxTries));
-
-      return new IntegerVector(assignment.OrderBy(x => x.Key).Select(x => x.Value).ToArray());
-    }
-
-    private static IEnumerable<int> WithDemandEqualOrLess(IEnumerable<int> facilities, double maximum, DoubleArray demands) {
-      foreach (int f in facilities) {
-        if (demands[f] <= maximum) yield return f;
-      }
-    }
-
-    private static double GetMaximumSlack(Dictionary<int, double> slack, HashSet<int> CL) {
-      return slack.Where(x => CL.Contains(x.Key)).Select(x => x.Value).Max();
-    }
-
-    private static IEnumerable<int> WithSlackGreaterOrEqual(HashSet<int> locations, double minimum, Dictionary<int, double> slack) {
-      foreach (int l in locations) {
-        if (slack[l] >= minimum) yield return l;
-      }
-    }
-  }
-}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/LocalImprovers/ApproximateLocalSearch.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/LocalImprovers/ApproximateLocalSearch.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/LocalImprovers/ApproximateLocalSearch.cs	(revision 7523)
@@ -0,0 +1,223 @@
+﻿#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;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
+  [Item("ApproximateLocalSearch", "The approximate local search 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 ApproximateLocalSearch : SingleSuccessorOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator,
+    IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator, IInstallationCostsAwareGQAPOperator,
+    ITransportationCostsAwareGQAPOperator, IOverbookedCapacityPenaltyAwareGQAPOperator,
+    IAssignmentAwareGQAPOperator, IQualityAwareGQAPOperator, IGQAPLocalImprovementOperator, IStochasticOperator {
+    public IProblem Problem { get; set; }
+    public Type ProblemType {
+      get { return typeof(GeneralizedQuadraticAssignmentProblem); }
+    }
+
+    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"]; }
+    }
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> FlowDistanceQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["FlowDistanceQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> InstallationQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["InstallationQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> OverbookedCapacityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["OverbookedCapacity"]; }
+    }
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<IntValue> MaximumCandidateListSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumCandidateListSize"]; }
+    }
+    public IValueLookupParameter<PercentValue> OneMoveProbabilityParameter {
+      get { return (IValueLookupParameter<PercentValue>)Parameters["OneMoveProbability"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    [StorableConstructor]
+    protected ApproximateLocalSearch(bool deserializing) : base(deserializing) { }
+    protected ApproximateLocalSearch(ApproximateLocalSearch original, Cloner cloner) : base(original, cloner) { }
+    public ApproximateLocalSearch()
+      : base() {
+      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));
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("FlowDistanceQuality", GQAPEvaluator.FlowDistanceQualityDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("InstallationQuality", GQAPEvaluator.InstallationQualityDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("OverbookedCapacity", GQAPEvaluator.OverbookedCapacityDescription));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of iterations that should be performed."));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated solution equivalents."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumCandidateListSize", "The maximum number of candidates that should be found in each step.", new IntValue(10)));
+      Parameters.Add(new ValueLookupParameter<PercentValue>("OneMoveProbability", "The probability for performing a 1-move, which is the opposite of performing a 2-move.", new PercentValue(.5)));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection that stores the results."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ApproximateLocalSearch(this, cloner);
+    }
+
+    /// <summary>
+    /// The implementation differs slightly from Mateus et al. in that the maximumIterations parameter defines a cap
+    /// on the number of steps that the local search can perform. While the maxSampleSize parameter corresponds to
+    /// the maxItr parameter defined by Mateus et al.
+    /// </summary>
+    /// <param name="random">The random number generator to use.</param>
+    /// <param name="assignment">The equipment-location assignment vector.</param>
+    /// <param name="quality">The solution quality.</param>
+    /// <param name="flowDistanceQuality">The quality regarding the flow-distance criteria.</param>
+    /// <param name="installationQuality">The quality regarding the installation costs.</param>
+    /// <param name="overbookedCapacity">The sum of the overbooked capacities relative to the capacity of each location.</param>
+    /// <param name="maxCLS">The maximum number of candidates that should be found in each step.</param>
+    /// <param name="maximumIterations">The maximum number of iterations that should be performed each time the candidate list is generated.</param>
+    /// <param name="weights">The weights matrix describes the flows between the equipments.</param>
+    /// <param name="distances">The distances matrix describes the distances between the locations at which the equipment can be installed.</param>
+    /// <param name="installationCosts">The installation costs matrix describes the installation costs of installing equipment i at location j</param>
+    /// <param name="demands">The demands vector describes the space requirements of the equipments.</param>
+    /// <param name="capacities">The capacities vector describes the available space at the locations.</param>
+    /// <param name="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.</param>
+    /// <param name="overbookedCapacityPenalty"></param>
+    /// <param name="oneMoveProbability">The probability for performing a 1-move, which is the opposite of performing a 2-move.</param>
+    public static void Apply(IRandom random, IntegerVector assignment,
+      DoubleValue quality, DoubleValue flowDistanceQuality, DoubleValue installationQuality, DoubleValue overbookedCapacity,
+      IntValue maxCLS, IntValue maximumIterations,
+      DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts, DoubleArray demands, DoubleArray capacities,
+      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty, PercentValue oneMoveProbability) {
+
+      while (true) {
+        int count = 0;
+        var CLS = new List<Tuple<NMove, double, double, double, double>>();
+        double sum = 0.0;
+        do {
+          NMove move;
+          if (random.NextDouble() < oneMoveProbability.Value)
+            move = StochasticNMoveSingleMoveGenerator.GenerateExactlyN(random, assignment, 1, capacities);
+          else move = StochasticNMoveSingleMoveGenerator.GenerateExactlyN(random, assignment, 2, capacities);
+
+          double moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity;
+          GQAPNMoveEvaluator.Evaluate(move, assignment, weights, distances, installationCosts,
+            demands, capacities, out moveFlowDistanceQuality, out moveInstallationQuality, out moveOverbookedCapacity);
+          double moveQuality = GQAPEvaluator.GetCombinedQuality(moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity,
+            transportationCosts.Value, overbookedCapacityPenalty.Value);
+
+          if (moveOverbookedCapacity <= 0.0 && moveQuality < 0.0) {
+            CLS.Add(Tuple.Create(move, moveQuality, moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity));
+            sum += 1.0 / moveQuality;
+          }
+          count++;
+        } while (CLS.Count < maxCLS.Value && count < maximumIterations.Value);
+
+        if (CLS.Count == 0)
+          return; // END
+        else {
+          var ball = random.NextDouble() * sum;
+          var selected = CLS.Last();
+          foreach (var candidate in CLS) {
+            ball -= 1.0 / candidate.Item2;
+            if (ball <= 0.0) {
+              selected = candidate;
+              break;
+            }
+          }
+          NMoveMaker.Apply(assignment, selected.Item1);
+          quality.Value += selected.Item2;
+          flowDistanceQuality.Value += selected.Item3;
+          installationQuality.Value += selected.Item4;
+          overbookedCapacity.Value += selected.Item5;
+        }
+      }
+    }
+
+    public override IOperation Apply() {
+      Apply(RandomParameter.ActualValue,
+        AssignmentParameter.ActualValue,
+        QualityParameter.ActualValue,
+        FlowDistanceQualityParameter.ActualValue,
+        InstallationQualityParameter.ActualValue,
+        OverbookedCapacityParameter.ActualValue,
+        MaximumCandidateListSizeParameter.ActualValue,
+        MaximumIterationsParameter.ActualValue,
+        WeightsParameter.ActualValue, DistancesParameter.ActualValue,
+        InstallationCostsParameter.ActualValue,
+        DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
+        TransportationCostsParameter.ActualValue,
+        OverbookedCapacityPenaltyParameter.ActualValue,
+        OneMoveProbabilityParameter.ActualValue);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/DemandEquivalentSwapEquipmentManipluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/DemandEquivalentSwapEquipmentManipluator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/DemandEquivalentSwapEquipmentManipluator.cs	(revision 7523)
@@ -0,0 +1,91 @@
+﻿#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;
+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;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+
+  [Item("DemandEquivalentSwapEquipmentManipluator", "Swaps equipment X from location A with as much equipments from location B that the demand of X is less than or equal to the demand of the swapped equipments in B.")]
+  [StorableClass]
+  public class DemandEquivalentSwapEquipmentManipluator : GQAPManipulator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator {
+
+    public ILookupParameter<DoubleArray> DemandsParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
+    }
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+
+    [StorableConstructor]
+    protected DemandEquivalentSwapEquipmentManipluator(bool deserializing) : base(deserializing) { }
+    protected DemandEquivalentSwapEquipmentManipluator(DemandEquivalentSwapEquipmentManipluator original, Cloner cloner) : base(original, cloner) { }
+    public DemandEquivalentSwapEquipmentManipluator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DemandEquivalentSwapEquipmentManipluator(this, cloner);
+    }
+
+    public static void Apply(IRandom random, IntegerVector assignment, DoubleArray capacities, DoubleArray demands) {
+      if (assignment.Length < 2) throw new InvalidOperationException("Vector is too small for swap operation.");
+      int equipment1 = random.Next(assignment.Length), equipment2 = random.Next(assignment.Length);
+      int counter = 1;
+      while (assignment[equipment1] == assignment[equipment2] && counter < assignment.Length) {
+        equipment2 = random.Next(assignment.Length);
+        counter++;
+      }
+      if (assignment[equipment1] != assignment[equipment2]) {
+        var groupedLocations = assignment
+              .Select((value, index) => new { Index = index, Value = value })
+              .GroupBy(x => x.Value)
+              .ToDictionary(x => x.Key, y => new HashSet<int>(y.Select(x => x.Index)));
+        double demand = demands[equipment1];
+        int location1 = assignment[equipment1];
+        int location2 = assignment[equipment2];
+
+        assignment[equipment1] = location2;
+        while (demand > 0) {
+          demand -= demands[equipment2];
+          assignment[equipment2] = location1;
+          groupedLocations[location2].Remove(equipment2);
+          if (!groupedLocations[location2].Any()) break;
+          equipment2 = groupedLocations[location2].ChooseUniformRandom(random);
+        }
+      }
+    }
+
+    protected override void Manipulate(IRandom random, IntegerVector vector) {
+      Apply(random, vector, CapacitiesParameter.ActualValue, DemandsParameter.ActualValue);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/GQAPManipulator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/GQAPManipulator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/GQAPManipulator.cs	(revision 7523)
@@ -0,0 +1,61 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("GQAPManipulator", "A base class for operators that manipulate assignment vectors of the GeneralizedQuadraticAssignment problems.")]
+  [StorableClass]
+  public abstract class GQAPManipulator : SingleSuccessorOperator, IGQAPManipulator, IAssignmentAwareGQAPOperator, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected GQAPManipulator(bool deserializing) : base(deserializing) { }
+    protected GQAPManipulator(GQAPManipulator original, Cloner cloner) : base(original, cloner) { }
+    protected GQAPManipulator()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
+    }
+
+    public sealed override IOperation Apply() {
+      Manipulate(RandomParameter.ActualValue, AssignmentParameter.ActualValue);
+      return base.Apply();
+    }
+
+    protected abstract void Manipulate(IRandom random, IntegerVector integerVector);
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/MultiGQAPManipulator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/MultiGQAPManipulator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/MultiGQAPManipulator.cs	(revision 7523)
@@ -0,0 +1,86 @@
+﻿#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;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("MultiGQAPManipulator", "Randomly selects and applies one of its manipulators every time it is called.")]
+  [StorableClass]
+  public class MultiGQAPManipulator : StochasticMultiBranch<IGQAPManipulator>, IGQAPManipulator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+
+    [StorableConstructor]
+    protected MultiGQAPManipulator(bool deserializing) : base(deserializing) { }
+    protected MultiGQAPManipulator(MultiGQAPManipulator original, Cloner cloner) : base(original, cloner) { }
+    public MultiGQAPManipulator()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
+      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IGQAPManipulator))) {
+        if (!typeof(MultiOperator<IGQAPManipulator>).IsAssignableFrom(type))
+          Operators.Add((IGQAPManipulator)Activator.CreateInstance(type), true);
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiGQAPManipulator(this, cloner);
+    }
+
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IGQAPManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      Parameterize();
+    }
+    protected override void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IGQAPManipulator>> e) {
+      base.Operators_ItemsRemoved(sender, e);
+      Parameterize();
+    }
+
+    private void Parameterize() {
+      foreach (var op in Operators.OfType<IGQAPManipulator>())
+        op.AssignmentParameter.ActualName = AssignmentParameter.Name;
+      foreach (var op in Operators.OfType<IStochasticOperator>())
+        op.RandomParameter.ActualName = RandomParameter.Name;
+    }
+
+    public override IOperation Apply() {
+      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one manipulator to choose from.");
+      return base.Apply();
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/RelocateEquipmentManipluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/RelocateEquipmentManipluator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/RelocateEquipmentManipluator.cs	(revision 7523)
@@ -0,0 +1,98 @@
+﻿#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;
+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;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+
+  [Item("RelocateEquipmentManipluator", "Relocates a random equipment from an overstuffed location to a random one with space or a random equipment if constraints are satisfied.")]
+  [StorableClass]
+  public class RelocateEquipmentManipluator : GQAPManipulator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator {
+
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+    public ILookupParameter<DoubleArray> DemandsParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
+    }
+
+    [StorableConstructor]
+    protected RelocateEquipmentManipluator(bool deserializing) : base(deserializing) { }
+    protected RelocateEquipmentManipluator(RelocateEquipmentManipluator original, Cloner cloner) : base(original, cloner) { }
+    public RelocateEquipmentManipluator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RelocateEquipmentManipluator(this, cloner);
+    }
+
+    public static void Apply(IRandom random, IntegerVector assignment, DoubleArray capacities, DoubleArray demands) {
+      int locations = capacities.Length;
+      if (locations < 2) throw new InvalidOperationException("There are not enough locations for relocation operations.");
+
+      Dictionary<int, double> usedCapacities = new Dictionary<int, double>();
+      Dictionary<int, List<int>> groupedLocations = new Dictionary<int, List<int>>();
+      for (int i = 0; i < locations; i++) {
+        usedCapacities[i] = 0.0;
+        groupedLocations.Add(i, new List<int>());
+      }
+      for (int i = 0; i < assignment.Length; i++) {
+        usedCapacities[assignment[i]] += demands[i];
+        groupedLocations[assignment[i]].Add(i);
+      }
+
+      var overbookedLocations = usedCapacities.Where(x => capacities[x.Key] < x.Value);
+      var freeLocations = usedCapacities.Where(x => capacities[x.Key] > x.Value);
+      if (!overbookedLocations.Any() || !freeLocations.Any()) { // perform a random relocation
+        assignment[random.Next(assignment.Length)] = random.Next(locations);
+        return;
+      }
+
+      var sourceLocation = overbookedLocations.ChooseUniformRandom(random);
+      int equipmentToRelocate = groupedLocations[sourceLocation.Key].ChooseUniformRandom(random);
+      var bestFreeLocations = freeLocations.Where(x => capacities[x.Key] > x.Value + demands[equipmentToRelocate]);
+
+      if (bestFreeLocations.Any()) { // a feasible solution will still be feasible, an infeasible solution might become feasible
+        var selected = bestFreeLocations.ChooseUniformRandom(random);
+        assignment[equipmentToRelocate] = sourceLocation.Key;
+      } else { // the solution will become infeasible
+        sourceLocation = freeLocations.ChooseUniformRandom(random);
+        assignment[equipmentToRelocate] = sourceLocation.Key;
+      }
+    }
+
+    protected override void Manipulate(IRandom random, IntegerVector vector) {
+      Apply(random, vector, CapacitiesParameter.ActualValue, DemandsParameter.ActualValue);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/SwapEquipmentManipluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/SwapEquipmentManipluator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/SwapEquipmentManipluator.cs	(revision 7523)
@@ -0,0 +1,62 @@
+﻿#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;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+
+  [Item("SwapEquipmentManipluator", "Swaps two equipments by placing each in the location of the other.")]
+  [StorableClass]
+  public class SwapEquipmentManipluator : GQAPManipulator {
+
+    [StorableConstructor]
+    protected SwapEquipmentManipluator(bool deserializing) : base(deserializing) { }
+    protected SwapEquipmentManipluator(SwapEquipmentManipluator original, Cloner cloner) : base(original, cloner) { }
+    public SwapEquipmentManipluator()
+      : base() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SwapEquipmentManipluator(this, cloner);
+    }
+
+    public static void Apply(IRandom random, IntegerVector assignment) {
+      if (assignment.Length < 2) throw new InvalidOperationException("Vector is too small for swap operation.");
+      int equipment1 = random.Next(assignment.Length), equipment2 = random.Next(assignment.Length);
+      int counter = 1;
+      while (assignment[equipment1] == assignment[equipment2] && counter < assignment.Length) {
+        equipment2 = random.Next(assignment.Length);
+        counter++;
+      }
+      int location = assignment[equipment1];
+      assignment[equipment1] = assignment[equipment2];
+      assignment[equipment2] = location;
+    }
+
+    protected override void Manipulate(IRandom random, IntegerVector vector) {
+      Apply(random, vector);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/SwapLocationManipulator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/SwapLocationManipulator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Manipulators/SwapLocationManipulator.cs	(revision 7523)
@@ -0,0 +1,78 @@
+﻿#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;
+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 {
+
+  [Item("SwapLocationManipluator", "Swaps two locations by exchanging all equipments between the locations.")]
+  [StorableClass]
+  public class SwapLocationManipluator : GQAPManipulator, ICapacitiesAwareGQAPOperator {
+
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+
+    [StorableConstructor]
+    protected SwapLocationManipluator(bool deserializing) : base(deserializing) { }
+    protected SwapLocationManipluator(SwapLocationManipluator original, Cloner cloner) : base(original, cloner) { }
+    public SwapLocationManipluator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SwapLocationManipluator(this, cloner);
+    }
+
+    public static void Apply(IRandom random, IntegerVector assignment, int locations) {
+      if (assignment.Length < 2) throw new InvalidOperationException("Vector is too small for swap operation.");
+      var groupedLocations = assignment
+        .Select((value, index) => new { Index = index, Value = value })
+        .GroupBy(x => x.Value)
+        .ToDictionary(x => x.Key, y => y.AsEnumerable());
+      if (locations < 2) throw new InvalidOperationException("There doesn't exist more than one location.");
+
+      int location1 = random.Next(locations), location2 = random.Next(locations);
+      while (location1 == location2) location2 = random.Next(locations);
+
+      if (groupedLocations.ContainsKey(location1)) {
+        foreach (var index in groupedLocations[location1])
+          assignment[index.Index] = location2;
+      }
+      if (groupedLocations.ContainsKey(location2)) {
+        foreach (var index in groupedLocations[location2])
+          assignment[index.Index] = location1;
+      }
+    }
+
+    protected override void Manipulate(IRandom random, IntegerVector vector) {
+      Apply(random, vector, CapacitiesParameter.ActualValue.Length);
+    }
+  }
+}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/MultiGQAPCrossover.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/MultiGQAPCrossover.cs	(revision 7522)
+++ 	(revision )
@@ -1,93 +1,0 @@
-﻿#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;
-using System.Linq;
-using HeuristicLab.Collections;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.PluginInfrastructure;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  [Item("MultiGQAPCrossover", "Randomly selects and applies one of its crossovers every time it is called.")]
-  [StorableClass]
-  public class MultiGQAPCrossover : StochasticMultiBranch<IGQAPCrossover>, IGQAPCrossover {
-    public override bool CanChangeName {
-      get { return false; }
-    }
-    protected override bool CreateChildOperation {
-      get { return true; }
-    }
-
-    public IScopeTreeLookupParameter<IntegerVector> ParentsParameter {
-      get { return (ScopeTreeLookupParameter<IntegerVector>)Parameters["Parents"]; }
-    }
-    public ILookupParameter<IntegerVector> ChildParameter {
-      get { return (ILookupParameter<IntegerVector>)Parameters["Child"]; }
-    }
-
-    [StorableConstructor]
-    protected MultiGQAPCrossover(bool deserializing) : base(deserializing) { }
-    protected MultiGQAPCrossover(MultiGQAPCrossover original, Cloner cloner) : base(original, cloner) { }
-    public MultiGQAPCrossover()
-      : base() {
-      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Parents", "The parent vectors which should be crossed.", "Assignment"));
-      Parameters.Add(new LookupParameter<IntegerVector>("Child", "The child vector resulting from the crossover.", "Assignment"));
-      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IGQAPCrossover))) {
-        if (!typeof(MultiOperator<IGQAPCrossover>).IsAssignableFrom(type))
-          Operators.Add((IGQAPCrossover)Activator.CreateInstance(type), true);
-      }
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MultiGQAPCrossover(this, cloner);
-    }
-
-    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IGQAPCrossover>> e) {
-      base.Operators_ItemsAdded(sender, e);
-      Parameterize();
-    }
-    protected override void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IGQAPCrossover>> e) {
-      base.Operators_ItemsRemoved(sender, e);
-      Parameterize();
-    }
-
-    private void Parameterize() {
-      foreach (var op in Operators.OfType<IGQAPCrossover>()) {
-        op.ParentsParameter.ActualName = ParentsParameter.Name;
-        op.ChildParameter.ActualName = ChildParameter.Name;
-      }
-      foreach (var op in Operators.OfType<IStochasticOperator>()) {
-        op.RandomParameter.ActualName = RandomParameter.Name;
-      }
-    }
-
-    public override IOperation Apply() {
-      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one crossover to choose from.");
-      return base.Apply();
-    }
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/MultiGQAPManipulator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/MultiGQAPManipulator.cs	(revision 7522)
+++ 	(revision )
@@ -1,86 +1,0 @@
-﻿#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;
-using System.Linq;
-using HeuristicLab.Collections;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.PluginInfrastructure;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  [Item("MultiGQAPManipulator", "Randomly selects and applies one of its manipulators every time it is called.")]
-  [StorableClass]
-  public class MultiGQAPManipulator : StochasticMultiBranch<IGQAPManipulator>, IGQAPManipulator {
-    public override bool CanChangeName {
-      get { return false; }
-    }
-    protected override bool CreateChildOperation {
-      get { return true; }
-    }
-
-    public ILookupParameter<IntegerVector> AssignmentParameter {
-      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
-    }
-
-    [StorableConstructor]
-    protected MultiGQAPManipulator(bool deserializing) : base(deserializing) { }
-    protected MultiGQAPManipulator(MultiGQAPManipulator original, Cloner cloner) : base(original, cloner) { }
-    public MultiGQAPManipulator()
-      : base() {
-      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
-      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IGQAPManipulator))) {
-        if (!typeof(MultiOperator<IGQAPManipulator>).IsAssignableFrom(type))
-          Operators.Add((IGQAPManipulator)Activator.CreateInstance(type), true);
-      }
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MultiGQAPManipulator(this, cloner);
-    }
-
-    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IGQAPManipulator>> e) {
-      base.Operators_ItemsAdded(sender, e);
-      Parameterize();
-    }
-    protected override void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IGQAPManipulator>> e) {
-      base.Operators_ItemsRemoved(sender, e);
-      Parameterize();
-    }
-
-    private void Parameterize() {
-      foreach (var op in Operators.OfType<IGQAPManipulator>())
-        op.AssignmentParameter.ActualName = AssignmentParameter.Name;
-      foreach (var op in Operators.OfType<IStochasticOperator>())
-        op.RandomParameter.ActualName = RandomParameter.Name;
-    }
-
-    public override IOperation Apply() {
-      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one manipulator to choose from.");
-      return base.Apply();
-    }
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/NMoveShakingOperator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/NMoveShakingOperator.cs	(revision 7522)
+++ 	(revision )
@@ -1,84 +1,0 @@
-﻿#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 HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
-  [Item("NMoveShakingOperator", "Performs a number of shaking operations that increase in strength.")]
-  [StorableClass]
-  public class NMoveShakingOperator : SingleSuccessorOperator, IAssignmentAwareGQAPOperator, ICapacitiesAwareGQAPOperator, IMultiNeighborhoodShakingOperator, IStochasticOperator {
-
-    public ILookupParameter<IntegerVector> AssignmentParameter {
-      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
-    }
-    public ILookupParameter<DoubleArray> CapacitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
-    }
-    public IValueLookupParameter<IntValue> CurrentNeighborhoodIndexParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["CurrentNeighborhoodIndex"]; }
-    }
-    public ILookupParameter<IntValue> NeighborhoodCountParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["NeighborhoodCount"]; }
-    }
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
-    }
-
-    [StorableConstructor]
-    protected NMoveShakingOperator(bool deserializing) : base(deserializing) { }
-    protected NMoveShakingOperator(NMoveShakingOperator original, Cloner cloner) : base(original, cloner) { }
-    public NMoveShakingOperator() {
-      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
-      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
-      Parameters.Add(new ValueLookupParameter<IntValue>("CurrentNeighborhoodIndex", "The index of the operator that should be applied (k)."));
-      Parameters.Add(new LookupParameter<IntValue>("NeighborhoodCount", "The number of operators that are available."));
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new NMoveShakingOperator(this, cloner);
-    }
-
-    public override IOperation Apply() {
-      var random = RandomParameter.ActualValue;
-      var assignment = AssignmentParameter.ActualValue;
-      var capacities = CapacitiesParameter.ActualValue;
-
-      if (NeighborhoodCountParameter.ActualValue == null)
-        NeighborhoodCountParameter.ActualValue = new IntValue(assignment.Length);
-      else NeighborhoodCountParameter.ActualValue.Value = assignment.Length;
-
-      int index = CurrentNeighborhoodIndexParameter.ActualValue.Value;
-
-      var move = StochasticNMoveSingleMoveGenerator.GenerateUpToN(random, assignment, index + 1, capacities);
-      NMoveMaker.Apply(assignment, move);
-
-      return base.Apply();
-    }
-  }
-}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/PopulationReducers/GQAPQualitySimilarityReducer.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/PopulationReducers/GQAPQualitySimilarityReducer.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/PopulationReducers/GQAPQualitySimilarityReducer.cs	(revision 7523)
@@ -0,0 +1,138 @@
+﻿#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;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
+  [Item("GQAPQualitySimilarityReducer", "Reduces two populations two one by using quality and similarity information to obtain a population of high quality, but also diverse solutions.")]
+  [StorableClass]
+  public class GQAPQualitySimilarityReducer : SingleSuccessorOperator, IAssignmentAwareGQAPOperator, IQualityAwareGQAPOperator, IPopulationReducer {
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> FlowDistanceQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["FlowDistanceQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> InstallationQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["InstallationQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> OverbookedCapacityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["OverbookedCapacity"]; }
+    }
+    public ILookupParameter<IntValue> MinimumPopulationSizeParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["MinimumPopulationSize"]; }
+    }
+    public ILookupParameter<IntValue> MaximumPopulationSizeParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["MaximumPopulationSize"]; }
+    }
+
+    [StorableConstructor]
+    protected GQAPQualitySimilarityReducer(bool deserializing) : base(deserializing) { }
+    protected GQAPQualitySimilarityReducer(GQAPQualitySimilarityReducer original, Cloner cloner) : base(original, cloner) { }
+    public GQAPQualitySimilarityReducer()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("FlowDistanceQuality", GQAPEvaluator.FlowDistanceQualityDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("InstallationQuality", GQAPEvaluator.InstallationQualityDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("OverbookedCapacity", GQAPEvaluator.OverbookedCapacityDescription));
+      Parameters.Add(new LookupParameter<IntValue>("MinimumPopulationSize", "The size of the population that should not be undershot."));
+      Parameters.Add(new LookupParameter<IntValue>("MaximumPopulationSize", "The size of the population that should not be surpassed."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GQAPQualitySimilarityReducer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      string vectorName = AssignmentParameter.TranslatedName;
+      string qualityName = QualityParameter.TranslatedName;
+      int populationSize = MaximumPopulationSizeParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+
+      IScope remaining = ExecutionContext.Scope.SubScopes[0];
+      IScope selected = ExecutionContext.Scope.SubScopes[1];
+
+      List<Individual> population =
+        remaining.SubScopes.Select(x => new Individual((IntegerVector)x.Variables[vectorName].Value,
+                                                      ((DoubleValue)x.Variables[qualityName].Value).Value,
+                                                      x)).ToList();
+      HashSet<Individual> candidates = new HashSet<Individual>(
+        selected.SubScopes.Select(x => new Individual((IntegerVector)x.Variables[vectorName].Value,
+                                                     ((DoubleValue)x.Variables[qualityName].Value).Value,
+                                                     x)));
+
+      foreach (var candidate in candidates) {
+        double[] similarities = population.Select(x => IntegerVectorEqualityComparer.GetSimilarity(x.Solution, candidate.Solution)).ToArray();
+        if (!similarities.Any()) {
+          population.Add(candidate);
+          break;
+        }
+        if (similarities.Max() == 1.0) break;
+        if (population.Count < populationSize) {
+          population.Add(candidate);
+        } else {
+          var replacement = population.Select((v, i) => new { V = v, Index = i })
+                                      .Where(x => (maximization && x.V.Quality < candidate.Quality)
+                                               || (!maximization && x.V.Quality > candidate.Quality));
+          if (replacement.Any()) {
+            replacement.OrderBy(x => similarities[x.Index]).ToArray();
+            population.Remove(replacement.Last().V);
+            population.Add(candidate);
+          }
+        }
+      }
+
+      ExecutionContext.Scope.SubScopes.Clear();
+      ExecutionContext.Scope.SubScopes.AddRange(population.Select(x => x.Scope));
+
+      return base.Apply();
+    }
+
+    private class Individual {
+      internal IntegerVector Solution { get; set; }
+      internal double Quality { get; set; }
+      internal IScope Scope { get; set; }
+
+      internal Individual(IntegerVector vector, double quality, IScope scope) {
+        Solution = vector;
+        Quality = quality;
+        Scope = scope;
+      }
+    }
+  }
+}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/RandomSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/RandomSolutionCreator.cs	(revision 7522)
+++ 	(revision )
@@ -1,46 +1,0 @@
-﻿#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 HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  [Item("RandomSolutionCreator", "Creates a completely random solution to the Generalized Quadratic Assignment Problem.")]
-  [StorableClass]
-  public class RandomSolutionCreator : GQAPStochasticSolutionCreator {
-
-    [StorableConstructor]
-    protected RandomSolutionCreator(bool deserializing) : base(deserializing) { }
-    protected RandomSolutionCreator(RandomSolutionCreator original, Cloner cloner) : base(original, cloner) { }
-    public RandomSolutionCreator() : base() { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new RandomSolutionCreator(this, cloner);
-    }
-
-    protected override IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities) {
-      return UniformRandomIntegerVectorCreator.Apply(random, demands.Length, 0, capacities.Length);
-    }
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/RelocateEquipmentManipluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/RelocateEquipmentManipluator.cs	(revision 7522)
+++ 	(revision )
@@ -1,98 +1,0 @@
-﻿#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;
-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;
-using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-
-  [Item("RelocateEquipmentManipluator", "Relocates a random equipment from an overstuffed location to a random one with space or a random equipment if constraints are satisfied.")]
-  [StorableClass]
-  public class RelocateEquipmentManipluator : GQAPManipulator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator {
-
-    public ILookupParameter<DoubleArray> CapacitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
-    }
-    public ILookupParameter<DoubleArray> DemandsParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
-    }
-
-    [StorableConstructor]
-    protected RelocateEquipmentManipluator(bool deserializing) : base(deserializing) { }
-    protected RelocateEquipmentManipluator(RelocateEquipmentManipluator original, Cloner cloner) : base(original, cloner) { }
-    public RelocateEquipmentManipluator()
-      : base() {
-      Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
-      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new RelocateEquipmentManipluator(this, cloner);
-    }
-
-    public static void Apply(IRandom random, IntegerVector assignment, DoubleArray capacities, DoubleArray demands) {
-      int locations = capacities.Length;
-      if (locations < 2) throw new InvalidOperationException("There are not enough locations for relocation operations.");
-
-      Dictionary<int, double> usedCapacities = new Dictionary<int, double>();
-      Dictionary<int, List<int>> groupedLocations = new Dictionary<int, List<int>>();
-      for (int i = 0; i < locations; i++) {
-        usedCapacities[i] = 0.0;
-        groupedLocations.Add(i, new List<int>());
-      }
-      for (int i = 0; i < assignment.Length; i++) {
-        usedCapacities[assignment[i]] += demands[i];
-        groupedLocations[assignment[i]].Add(i);
-      }
-
-      var overbookedLocations = usedCapacities.Where(x => capacities[x.Key] < x.Value);
-      var freeLocations = usedCapacities.Where(x => capacities[x.Key] > x.Value);
-      if (!overbookedLocations.Any() || !freeLocations.Any()) { // perform a random relocation
-        assignment[random.Next(assignment.Length)] = random.Next(locations);
-        return;
-      }
-
-      var sourceLocation = overbookedLocations.ChooseUniformRandom(random);
-      int equipmentToRelocate = groupedLocations[sourceLocation.Key].ChooseUniformRandom(random);
-      var bestFreeLocations = freeLocations.Where(x => capacities[x.Key] > x.Value + demands[equipmentToRelocate]);
-
-      if (bestFreeLocations.Any()) { // a feasible solution will still be feasible, an infeasible solution might become feasible
-        var selected = bestFreeLocations.ChooseUniformRandom(random);
-        assignment[equipmentToRelocate] = sourceLocation.Key;
-      } else { // the solution will become infeasible
-        sourceLocation = freeLocations.ChooseUniformRandom(random);
-        assignment[equipmentToRelocate] = sourceLocation.Key;
-      }
-    }
-
-    protected override void Manipulate(IRandom random, IntegerVector vector) {
-      Apply(random, vector, CapacitiesParameter.ActualValue, DemandsParameter.ActualValue);
-    }
-  }
-}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Shakers/NMoveShakingOperator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Shakers/NMoveShakingOperator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Shakers/NMoveShakingOperator.cs	(revision 7523)
@@ -0,0 +1,84 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
+  [Item("NMoveShakingOperator", "Performs a number of shaking operations that increase in strength.")]
+  [StorableClass]
+  public class NMoveShakingOperator : SingleSuccessorOperator, IAssignmentAwareGQAPOperator, ICapacitiesAwareGQAPOperator, IMultiNeighborhoodShakingOperator, IStochasticOperator {
+
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+    public IValueLookupParameter<IntValue> CurrentNeighborhoodIndexParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["CurrentNeighborhoodIndex"]; }
+    }
+    public ILookupParameter<IntValue> NeighborhoodCountParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["NeighborhoodCount"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected NMoveShakingOperator(bool deserializing) : base(deserializing) { }
+    protected NMoveShakingOperator(NMoveShakingOperator original, Cloner cloner) : base(original, cloner) { }
+    public NMoveShakingOperator() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+      Parameters.Add(new ValueLookupParameter<IntValue>("CurrentNeighborhoodIndex", "The index of the operator that should be applied (k)."));
+      Parameters.Add(new LookupParameter<IntValue>("NeighborhoodCount", "The number of operators that are available."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NMoveShakingOperator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var random = RandomParameter.ActualValue;
+      var assignment = AssignmentParameter.ActualValue;
+      var capacities = CapacitiesParameter.ActualValue;
+
+      if (NeighborhoodCountParameter.ActualValue == null)
+        NeighborhoodCountParameter.ActualValue = new IntValue(assignment.Length);
+      else NeighborhoodCountParameter.ActualValue.Value = assignment.Length;
+
+      int index = CurrentNeighborhoodIndexParameter.ActualValue.Value;
+
+      var move = StochasticNMoveSingleMoveGenerator.GenerateUpToN(random, assignment, index + 1, capacities);
+      NMoveMaker.Apply(assignment, move);
+
+      return base.Apply();
+    }
+  }
+}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/SwapEquipmentManipluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/SwapEquipmentManipluator.cs	(revision 7522)
+++ 	(revision )
@@ -1,62 +1,0 @@
-﻿#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;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-
-  [Item("SwapEquipmentManipluator", "Swaps two equipments by placing each in the location of the other.")]
-  [StorableClass]
-  public class SwapEquipmentManipluator : GQAPManipulator {
-
-    [StorableConstructor]
-    protected SwapEquipmentManipluator(bool deserializing) : base(deserializing) { }
-    protected SwapEquipmentManipluator(SwapEquipmentManipluator original, Cloner cloner) : base(original, cloner) { }
-    public SwapEquipmentManipluator()
-      : base() {
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SwapEquipmentManipluator(this, cloner);
-    }
-
-    public static void Apply(IRandom random, IntegerVector assignment) {
-      if (assignment.Length < 2) throw new InvalidOperationException("Vector is too small for swap operation.");
-      int equipment1 = random.Next(assignment.Length), equipment2 = random.Next(assignment.Length);
-      int counter = 1;
-      while (assignment[equipment1] == assignment[equipment2] && counter < assignment.Length) {
-        equipment2 = random.Next(assignment.Length);
-        counter++;
-      }
-      int location = assignment[equipment1];
-      assignment[equipment1] = assignment[equipment2];
-      assignment[equipment2] = location;
-    }
-
-    protected override void Manipulate(IRandom random, IntegerVector vector) {
-      Apply(random, vector);
-    }
-  }
-}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/SwapLocationManipulator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/SwapLocationManipulator.cs	(revision 7522)
+++ 	(revision )
@@ -1,78 +1,0 @@
-﻿#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;
-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 {
-
-  [Item("SwapLocationManipluator", "Swaps two locations by exchanging all equipments between the locations.")]
-  [StorableClass]
-  public class SwapLocationManipluator : GQAPManipulator, ICapacitiesAwareGQAPOperator {
-
-    public ILookupParameter<DoubleArray> CapacitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
-    }
-
-    [StorableConstructor]
-    protected SwapLocationManipluator(bool deserializing) : base(deserializing) { }
-    protected SwapLocationManipluator(SwapLocationManipluator original, Cloner cloner) : base(original, cloner) { }
-    public SwapLocationManipluator()
-      : base() {
-      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SwapLocationManipluator(this, cloner);
-    }
-
-    public static void Apply(IRandom random, IntegerVector assignment, int locations) {
-      if (assignment.Length < 2) throw new InvalidOperationException("Vector is too small for swap operation.");
-      var groupedLocations = assignment
-        .Select((value, index) => new { Index = index, Value = value })
-        .GroupBy(x => x.Value)
-        .ToDictionary(x => x.Key, y => y.AsEnumerable());
-      if (locations < 2) throw new InvalidOperationException("There doesn't exist more than one location.");
-
-      int location1 = random.Next(locations), location2 = random.Next(locations);
-      while (location1 == location2) location2 = random.Next(locations);
-
-      if (groupedLocations.ContainsKey(location1)) {
-        foreach (var index in groupedLocations[location1])
-          assignment[index.Index] = location2;
-      }
-      if (groupedLocations.ContainsKey(location2)) {
-        foreach (var index in groupedLocations[location2])
-          assignment[index.Index] = location1;
-      }
-    }
-
-    protected override void Manipulate(IRandom random, IntegerVector vector) {
-      Apply(random, vector, CapacitiesParameter.ActualValue.Length);
-    }
-  }
-}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GQAPSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GQAPSolutionCreator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GQAPSolutionCreator.cs	(revision 7523)
@@ -0,0 +1,67 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("GQAPSolutionCreator", "Base class for solution creators of the Generalized Quadratic Assignment Problem.")]
+  [StorableClass]
+  public abstract class GQAPSolutionCreator : SingleSuccessorOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator, IGQAPSolutionCreator {
+
+    #region Parameter Descriptions
+    public static readonly string AssignmentDescription = "The vector that encodes the assignment.";
+    #endregion
+
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<DoubleArray> DemandsParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
+    }
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+
+    [StorableConstructor]
+    protected GQAPSolutionCreator(bool deserializing) : base(deserializing) { }
+    protected GQAPSolutionCreator(GQAPSolutionCreator original, Cloner cloner)
+      : base(original, cloner) { }
+    public GQAPSolutionCreator()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", AssignmentDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+    }
+
+    public override IOperation Apply() {
+      AssignmentParameter.ActualValue = CreateSolution(DemandsParameter.ActualValue, CapacitiesParameter.ActualValue);
+      return base.Apply();
+    }
+
+    protected abstract IntegerVector CreateSolution(DoubleArray demands, DoubleArray capacities);
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GQAPStochasticSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GQAPStochasticSolutionCreator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GQAPStochasticSolutionCreator.cs	(revision 7523)
@@ -0,0 +1,54 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("GQAPStochasticSolutionCreator", "Base class for stochastic solution creators of the Generalized Quadratic Assignment Problem.")]
+  [StorableClass]
+  public abstract class GQAPStochasticSolutionCreator : GQAPSolutionCreator, IStochasticOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected GQAPStochasticSolutionCreator(bool deserializing) : base(deserializing) { }
+    protected GQAPStochasticSolutionCreator(GQAPStochasticSolutionCreator original, Cloner cloner)
+      : base(original, cloner) { }
+    public GQAPStochasticSolutionCreator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+    }
+
+    protected sealed override IntegerVector CreateSolution(DoubleArray demands, DoubleArray capacities) {
+      return CreateRandomSolution(RandomParameter.ActualValue, demands, capacities);
+    }
+
+    protected abstract IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities);
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GreedyRandomizedSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GreedyRandomizedSolutionCreator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GreedyRandomizedSolutionCreator.cs	(revision 7523)
@@ -0,0 +1,114 @@
+﻿#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;
+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;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("GreedyRandomizedSolutionCreator", "Creates a solution according to the procedure 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 GreedyRandomizedSolutionCreator : GQAPStochasticSolutionCreator {
+
+    public IValueLookupParameter<IntValue> MaximumTriesParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumTries"]; }
+    }
+
+    [StorableConstructor]
+    protected GreedyRandomizedSolutionCreator(bool deserializing) : base(deserializing) { }
+    protected GreedyRandomizedSolutionCreator(GreedyRandomizedSolutionCreator original, Cloner cloner)
+      : base(original, cloner) { }
+    public GreedyRandomizedSolutionCreator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumTries", "The maximum number of tries to create a feasible solution.", new IntValue(10000)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GreedyRandomizedSolutionCreator(this, cloner);
+    }
+
+    protected override IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities) {
+      int tries = 0, maxTries = MaximumTriesParameter.ActualValue.Value;
+      var assignment = new Dictionary<int, int>();
+      var slack = new Dictionary<int, double>();
+
+      while (tries < maxTries) {
+        assignment.Clear();
+        slack = capacities.Select((v, i) => new { Index = i, Value = v }).ToDictionary(x => x.Index, y => y.Value);
+        HashSet<int> CF = new HashSet<int>(), // set of chosen facilities / equipments
+          T = new HashSet<int>(), // set of facilities / equpiments that can be assigned to the set of chosen locations (CL)
+          CL = new HashSet<int>(), // set of chosen locations
+          F = new HashSet<int>(Enumerable.Range(0, demands.Length)), // set of (initially) all facilities / equipments
+          L = new HashSet<int>(Enumerable.Range(0, capacities.Length)); // set of (initially) all locations
+
+        double threshold = 1.0;
+        do {
+          if (L.Any() && random.NextDouble() < threshold) {
+            int l = L.ChooseUniformRandom(random);
+            L.Remove(l);
+            CL.Add(l);
+            T = new HashSet<int>(WithDemandEqualOrLess(F, GetMaximumSlack(slack, CL), demands));
+          }
+          if (T.Any()) {
+            int f = T.ChooseUniformRandom(random);
+            T.Remove(f);
+            F.Remove(f);
+            CF.Add(f);
+            int l = WithSlackGreaterOrEqual(CL, demands[f], slack).ChooseUniformRandom(random);
+            assignment.Add(f, l);
+            slack[l] -= demands[f];
+            T = new HashSet<int>(WithDemandEqualOrLess(F, GetMaximumSlack(slack, CL), demands));
+            threshold = 1.0 - (double)T.Count / Math.Max(F.Count, 1.0);
+          }
+        } while (T.Any() || L.Any());
+        tries++;
+        if (!F.Any()) break;
+      }
+
+      if (assignment.Count != demands.Length) throw new InvalidOperationException(String.Format("No solution could be found in {0} tries.", maxTries));
+
+      return new IntegerVector(assignment.OrderBy(x => x.Key).Select(x => x.Value).ToArray());
+    }
+
+    private static IEnumerable<int> WithDemandEqualOrLess(IEnumerable<int> facilities, double maximum, DoubleArray demands) {
+      foreach (int f in facilities) {
+        if (demands[f] <= maximum) yield return f;
+      }
+    }
+
+    private static double GetMaximumSlack(Dictionary<int, double> slack, HashSet<int> CL) {
+      return slack.Where(x => CL.Contains(x.Key)).Select(x => x.Value).Max();
+    }
+
+    private static IEnumerable<int> WithSlackGreaterOrEqual(HashSet<int> locations, double minimum, Dictionary<int, double> slack) {
+      foreach (int l in locations) {
+        if (slack[l] >= minimum) yield return l;
+      }
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/RandomSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/RandomSolutionCreator.cs	(revision 7523)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/RandomSolutionCreator.cs	(revision 7523)
@@ -0,0 +1,46 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("RandomSolutionCreator", "Creates a completely random solution to the Generalized Quadratic Assignment Problem.")]
+  [StorableClass]
+  public class RandomSolutionCreator : GQAPStochasticSolutionCreator {
+
+    [StorableConstructor]
+    protected RandomSolutionCreator(bool deserializing) : base(deserializing) { }
+    protected RandomSolutionCreator(RandomSolutionCreator original, Cloner cloner) : base(original, cloner) { }
+    public RandomSolutionCreator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RandomSolutionCreator(this, cloner);
+    }
+
+    protected override IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities) {
+      return UniformRandomIntegerVectorCreator.Apply(random, demands.Length, 0, capacities.Length);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.Instances.CordeauGQAP/3.3/CordeauGQAPInstance.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.Instances.CordeauGQAP/3.3/CordeauGQAPInstance.cs	(revision 7522)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.Instances.CordeauGQAP/3.3/CordeauGQAPInstance.cs	(revision 7523)
@@ -34,4 +34,7 @@
 
     public double TransportationCosts { get; set; }
+
+    public int[] BestKnownAssignment { get; set; }
+    public double? BestKnownQuality { get; set; }
   }
 }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.Instances.CordeauGQAP/3.3/CordeauGQAPInstanceProvider.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.Instances.CordeauGQAP/3.3/CordeauGQAPInstanceProvider.cs	(revision 7522)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.Instances.CordeauGQAP/3.3/CordeauGQAPInstanceProvider.cs	(revision 7523)
@@ -61,13 +61,15 @@
       using (var stream = Assembly.GetExecutingAssembly()
         .GetManifestResourceStream(descriptor.InstanceIdentifier)) {
-        var datParser = new CordeauGQAPParser();
-        datParser.Parse(stream);
-        if (datParser.Error != null) throw datParser.Error;
-        instance.Equipments = datParser.Equipments;
-        instance.Locations = datParser.Locations;
-        instance.Weights = datParser.Weights;
-        instance.Distances = datParser.Distances;
-        instance.InstallationCosts = datParser.InstallationCosts;
-        instance.TransportationCosts = datParser.TransportationCosts;
+        var parser = new CordeauGQAPParser();
+        parser.Parse(stream);
+        if (parser.Error != null) throw parser.Error;
+        instance.Equipments = parser.Equipments;
+        instance.Locations = parser.Locations;
+        instance.Demands = parser.Demands;
+        instance.Capacities = parser.Capacities;
+        instance.Weights = parser.Weights;
+        instance.Distances = parser.Distances;
+        instance.InstallationCosts = parser.InstallationCosts;
+        instance.TransportationCosts = parser.TransportationCosts;
 
         instance.Name = id.Name;
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBParser.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBParser.cs	(revision 7522)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBParser.cs	(revision 7523)
@@ -467,5 +467,5 @@
     /// terminates the section.
     /// So the parser peeks at the next character after a -1. If the next character
-    /// is an E as in EOF or the stream ends, the parser breaks. Otherwise it will
+    /// is an E as in EOF or the stream ends, the parser ends. Otherwise it will
     /// continue to read tours until a -1 is followed by a -1.
     /// </remarks>
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.Instances/3.3/Instances/IGQAPInstance.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.Instances/3.3/Instances/IGQAPInstance.cs	(revision 7522)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.Instances/3.3/Instances/IGQAPInstance.cs	(revision 7523)
@@ -20,19 +20,59 @@
 #endregion
 
-namespace HeuristicLab.Problems.Instances{
+namespace HeuristicLab.Problems.Instances {
+  /// <summary>
+  /// Describes an instance of the Generalized Quadratic Assignment Problem (GQAP).
+  /// </summary>
   public interface IGQAPInstance {
-
+    /// <summary>
+    /// The name of the instance.
+    /// </summary>
     string Name { get; }
+    /// <summary>
+    /// A description of the instance.
+    /// </summary>
     string Description { get; }
 
+    /// <summary>
+    /// |E| = The number of equipments are to be assigned in this instance.
+    /// </summary>
     int Equipments { get; }
+    /// <summary>
+    /// |L| = The number of locations that are available for the equipments.
+    /// </summary>
     int Locations { get; }
+    /// <summary>
+    /// Vector of length |E| that describes the space demand for the equipments.
+    /// </summary>
     double[] Demands { get; }
+    /// <summary>
+    /// Vector of length |L| that describes the space capacity for the locations.
+    /// </summary>
     double[] Capacities { get; }
+    /// <summary>
+    /// |E|x|E| matrix with the weights (flows) between the equipments. These describe the strength of the respective bonding.
+    /// </summary>
     double[,] Weights { get; }
+    /// <summary>
+    /// |L|x|L| matrix with the distances between the locations.
+    /// </summary>
     double[,] Distances { get; }
+    /// <summary>
+    /// |E|x|L| matrix that describes the costs of installing equipment x at location y.
+    /// </summary>
     double[,] InstallationCosts { get; }
+    /// <summary>
+    /// A factor that scales the weights.
+    /// </summary>
+    double TransportationCosts { get; }
 
-    double TransportationCosts { get; }
+    /// <summary>
+    /// Optional! The best-known assignment is a vector of length |E| with numbers ranging from 0 to |L| - 1
+    /// </summary>
+    int[] BestKnownAssignment { get; }
+    /// <summary>
+    /// Optional! The quality of the best-known assignment.
+    /// </summary>
+    double? BestKnownQuality { get; }
   }
 }
Index: /branches/GeneralizedQAP/UnitTests/CordeauCrossoverTest.cs
===================================================================
--- /branches/GeneralizedQAP/UnitTests/CordeauCrossoverTest.cs	(revision 7523)
+++ /branches/GeneralizedQAP/UnitTests/CordeauCrossoverTest.cs	(revision 7523)
@@ -0,0 +1,58 @@
+﻿#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.Linq;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment;
+using HeuristicLab.Problems.Instances.CordeauGQAP;
+using HeuristicLab.Random;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace UnitTests {
+  [TestClass]
+  public class CordeauCrossoverTest {
+    [TestMethod]
+    public void CordeauCrossoverFunctionalityTest() {
+      var provider = new CordeauGQAPInstanceProvider();
+      var instance = provider.GetInstance(provider.GetInstanceDescriptors().First());
+      var gqap = new GeneralizedQuadraticAssignmentProblem();
+      gqap.LoadFrom(instance);
+
+      var random = new MersenneTwister();
+      for (int i = 0; i < 100; i++) {
+        var parent1 = new IntegerVector(gqap.Demands.Length, random, 0, gqap.Capacities.Length);
+        var parent2 = new IntegerVector(gqap.Demands.Length, random, 0, gqap.Capacities.Length);
+
+        try {
+          CordeauCrossover.Apply(random, gqap.Maximization,
+            parent1,
+            new DoubleValue(GQAPEvaluator.Evaluate(parent1, gqap.Weights, gqap.Distances, gqap.InstallationCosts, gqap.Demands, gqap.Capacities, gqap.TransportationCosts, gqap.OverbookedCapacityPenalty)),
+            parent2,
+            new DoubleValue(GQAPEvaluator.Evaluate(parent2, gqap.Weights, gqap.Distances, gqap.InstallationCosts, gqap.Demands, gqap.Capacities, gqap.TransportationCosts, gqap.OverbookedCapacityPenalty)),
+            gqap.Weights, gqap.Distances, gqap.InstallationCosts, gqap.Demands, gqap.Capacities, gqap.TransportationCosts, gqap.OverbookedCapacityPenalty);
+        } catch {
+          Assert.Fail("Error during crossover");
+        }
+      }
+    }
+  }
+}
Index: /branches/GeneralizedQAP/UnitTests/QAPLIBInstanceProviderTest.cs
===================================================================
--- /branches/GeneralizedQAP/UnitTests/QAPLIBInstanceProviderTest.cs	(revision 7522)
+++ /branches/GeneralizedQAP/UnitTests/QAPLIBInstanceProviderTest.cs	(revision 7523)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Text;
 using HeuristicLab.Problems.Instances.QAPLIB;
@@ -45,4 +46,23 @@
       Assert.IsTrue(erroneousInstances.Length == 0, "Some instances could not be parsed: " + Environment.NewLine + erroneousInstances.ToString());
     }
+
+    /// <summary>
+    ///A test for GetInstance
+    ///</summary>
+    [TestMethod()]
+    public void GetInstanceTest() {
+      List<string> nonZeroDiagonalInstances = new List<string>();
+      var target = new QAPLIBInstanceProvider();
+      foreach (var id in target.GetInstanceDescriptors()) {
+        var instance = target.GetInstance(id);
+        for (int i = 0; i < instance.Dimension; i++)
+          if (instance.Distances[i, i] != 0 || instance.Weights[i, i] != 0) {
+            nonZeroDiagonalInstances.Add(instance.Name);
+            break;
+          }
+      }
+
+      Assert.IsTrue(nonZeroDiagonalInstances.Count == 0, string.Join(Environment.NewLine, nonZeroDiagonalInstances));
+    }
   }
 }
Index: /branches/GeneralizedQAP/UnitTests/UnitTests.csproj
===================================================================
--- /branches/GeneralizedQAP/UnitTests/UnitTests.csproj	(revision 7522)
+++ /branches/GeneralizedQAP/UnitTests/UnitTests.csproj	(revision 7523)
@@ -97,4 +97,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="CordeauCrossoverTest.cs" />
     <Compile Include="CordeauGQAPInstanceProviderTest.cs" />
     <Compile Include="ElloumiCTAPInstanceProviderTest.cs" />
