Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/ExtensionMethods.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/ExtensionMethods.cs	(revision 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/ExtensionMethods.cs	(revision 7407)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -26,4 +27,38 @@
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common {
   public static class ExtensionMethods {
+
+    /// <summary>
+    /// Simply enumerates the sequence by moving over all elements.
+    /// </summary>
+    /// <typeparam name="T">The type of the items that are to be enumerated.</typeparam>
+    /// <param name="source">The enumerable that contains the items.</param>
+    public static void Enumerate<T>(this IEnumerable<T> source) {
+      var enumerator = source.GetEnumerator();
+      while (enumerator.MoveNext()) ;
+    }
+
+    /// <summary>
+    /// Selects an element from an enumerable randomly with equal probability for each element. If the sequence is empty, selected will be false and default(T) will be returned.
+    /// </summary>
+    /// <typeparam name="T">The type of the items that are to be selected.</typeparam>
+    /// <param name="source">The enumerable that contains the items.</param>
+    /// <param name="random">The random number generator, its NextDouble() method must return a value in the range [0;1).</param>
+    /// <param name="selected">True if an element was selected, false otherwise (only because of an empty sequence).</param>
+    /// <returns>The selected item.</returns>
+    public static T ChooseRandomOrDefault<T>(this IEnumerable<T> source, IRandom random, out bool selected) {
+      if (source == null) throw new ArgumentNullException("SelectRandomOrDefault: source is null");
+      uint counter = 1;
+      selected = false;
+      T selectedItem = default(T);
+      foreach (T item in source) {
+        if (counter * random.NextDouble() < 1.0) { // use multiplication instead of division
+          selectedItem = item;
+          selected = true;
+        }
+        counter++;
+      }
+      return selectedItem;
+    }
+
     /// <summary>
     /// Selects an element from an enumerable randomly with equal probability for each element.
@@ -32,15 +67,14 @@
     /// <param name="source">The enumerable that contains the items.</param>
     /// <param name="random">The random number generator, its NextDouble() method must return a value in the range [0;1).</param>
-    /// <param name="selected">True if an element was selected, false otherwise (mainly because of an empty sequence).</param>
     /// <returns>The selected item.</returns>
-    public static T SelectRandomOrDefault<T>(this IEnumerable<T> source, IRandom random, out bool selected) {
-      int counter = 1;
-      selected = false;
+    public static T ChooseRandom<T>(this IEnumerable<T> source, IRandom random) {
+      if (source == null) throw new ArgumentNullException("SelectRandom: source is null");
+      if (!source.Any()) throw new ArgumentException("SelectRandom: sequence is empty.");
+      uint counter = 1;
       T selectedItem = default(T);
       foreach (T item in source) {
-        if (random.NextDouble() < 1.0 / counter) {
+        if (counter * random.NextDouble() < 1.0) // use multiplication instead of division
           selectedItem = item;
-          selected = true;
-        }
+        counter++;
       }
       return selectedItem;
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPEvaluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPEvaluator.cs	(revision 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPEvaluator.cs	(revision 7407)
@@ -87,4 +87,22 @@
     }
 
+    public static DoubleValue Evaluate(IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances,
+      DoubleMatrix installCosts, double transportCosts, DoubleArray demands, DoubleArray capacities,
+      out double infeasibility) {
+      double quality = 0;
+      int len = assignment.Length;
+      var slack = (DoubleArray)capacities.Clone();
+      for (int i = 0; i < len; i++) {
+        quality += installCosts[i, assignment[i]];
+        for (int j = 0; j < len; j++) {
+          quality += transportCosts * weights[i, j] * distances[assignment[i], assignment[j]];
+        }
+        slack[assignment[i]] -= demands[i];
+      }
+
+      infeasibility = -slack.Where(x => x < 0).Sum();
+      return new DoubleValue(quality);
+    }
+
     public override IOperation Apply() {
       IntegerVector assignment = AssignmentParameter.ActualValue;
@@ -96,6 +114,4 @@
       DoubleArray capacities = (DoubleArray)CapacitiesParameter.ActualValue.Clone();
       double penalty = PenaltyParameter.ActualValue.Value;
-      double quality = 0;
-      double infeasibility = 0;
 
       if (weights.Rows != weights.Columns || distances.Rows != distances.Columns
@@ -104,17 +120,9 @@
         throw new InvalidOperationException("ERROR: The problem configuration is not valid! Check the sizes of the weights (NxN), distances (MxM) and installation costs (NxM) matrices as well as the length of the demand (N) and capacities (M) vectors.");
 
-      int len = assignment.Length;
-      for (int i = 0; i < len; i++) {
-        quality += installCosts[i, assignment[i]];
-        for (int j = 0; j < len; j++) {
-          quality += transportCosts * weights[i, j] * distances[assignment[i], assignment[j]];
-        }
-        capacities[assignment[i]] -= demands[i];
-      }
-
-      infeasibility = -capacities.Where(x => x < 0).Sum();
+      double infeasibility;
+      var quality = Evaluate(assignment, weights, distances, installCosts, transportCosts, demands, capacities, out infeasibility);
 
       InfeasibilityParameter.ActualValue = new DoubleValue(infeasibility);
-      QualityParameter.ActualValue = new DoubleValue(quality + penalty * infeasibility);
+      QualityParameter.ActualValue = new DoubleValue(quality.Value + penalty * infeasibility);
       return base.Apply();
     }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPNMoveEvaluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPNMoveEvaluator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPNMoveEvaluator.cs	(revision 7407)
@@ -0,0 +1,142 @@
+﻿#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;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("GQAPNMoveEvaluator", "Evaluates an n-move.")]
+  [StorableClass]
+  public class GQAPNMoveEvaluator : SingleSuccessorOperator, IGQAPNMoveEvaluator {
+
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<NMove> MoveParameter {
+      get { return (ILookupParameter<NMove>)Parameters["Move"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveInfeasibilityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveInfeasibility"]; }
+    }
+    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<DoubleValue> TransportationCostsParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
+    }
+    public ILookupParameter<DoubleArray> DemandsParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
+    }
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+
+    [StorableConstructor]
+    protected GQAPNMoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected GQAPNMoveEvaluator(GQAPNMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public GQAPNMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", "The equipment-location assignment vector."));
+      Parameters.Add(new LookupParameter<NMove>("Move", "The move to perform."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The solution quality."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the move if it would be applied."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveInfeasibility", "The infeasibility of the move if it would be applied."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", "The weights matrix describes the flows between the equipments."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", "The distances matrix describes the distances between the locations at which the equipment can be installed."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("InstallationCosts", "The installation costs matrix describes the installation costs of installing equipment i at location j"));
+      Parameters.Add(new LookupParameter<DoubleValue>("TransportationCosts", "The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights matrix already."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Demands", "The demands vector describes the space requirements of the equipments."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", "The capacities vector describes the available space at the locations."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GQAPNMoveEvaluator(this, cloner);
+    }
+
+    public static DoubleValue Evaluate(NMove move, IntegerVector assignment, DoubleValue quality,
+                                  DoubleArray demands, DoubleArray capacities,
+                                  DoubleMatrix weights, DoubleMatrix distances,
+                                  DoubleMatrix installationCosts,
+                                  DoubleValue transportationCosts,
+                                  out DoubleValue moveInfeasibility) {
+      double moveQuality = quality.Value;
+      int moves = move.N;
+      var slack = (DoubleArray)capacities.Clone();
+      Dictionary<int, int> moving = new Dictionary<int, int>();
+      for (int i = 0; i < moves; i++) moving.Add(move.Equipments[i], move.Locations[i]);
+
+      for (int i = 0; i < moves; i++) {
+        int equip = move.Equipments[i];
+        int newLoc = move.Locations[i];
+        moveQuality -= installationCosts[equip, assignment[equip]];
+        moveQuality += installationCosts[equip, newLoc];
+        for (int j = 0; j < assignment.Length; j++) {
+          if (!moving.ContainsKey(j)) {
+            moveQuality += transportationCosts.Value * weights[equip, j] * (distances[newLoc, assignment[j]] - distances[assignment[equip], assignment[j]]);
+            moveQuality += transportationCosts.Value * weights[j, equip] * (distances[assignment[j], newLoc] - distances[assignment[j], assignment[equip]]);
+            if (i == 0) { // only once for each untouched equipment deduct the demand from the capacity
+              slack[assignment[j]] -= demands[j];
+            }
+          } else {
+            moveQuality += transportationCosts.Value * weights[equip, j] * (distances[newLoc, moving[j]] - distances[assignment[equip], assignment[j]]);
+            moveQuality += transportationCosts.Value * weights[j, equip] * (distances[moving[j], newLoc] - distances[assignment[j], assignment[equip]]);
+          }
+        }
+        slack[newLoc] -= demands[equip];
+      }
+
+      moveInfeasibility = new DoubleValue(-slack.Where(x => x < 0).Sum());
+      return new DoubleValue(moveQuality);
+
+    }
+
+    public override IOperation Apply() {
+      DoubleValue moveInfeasibility;
+      MoveQualityParameter.ActualValue = Evaluate(MoveParameter.ActualValue,
+                 AssignmentParameter.ActualValue, QualityParameter.ActualValue,
+                 DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
+                 WeightsParameter.ActualValue, DistancesParameter.ActualValue,
+                 InstallationCostsParameter.ActualValue,
+                 TransportationCostsParameter.ActualValue, out moveInfeasibility);
+      MoveInfeasibilityParameter.ActualValue = moveInfeasibility;
+      return base.Apply();
+    }
+  }
+}
Index: anches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/ExtensionMethods.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/ExtensionMethods.cs	(revision 7406)
+++ 	(revision )
@@ -1,104 +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.Core;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  public static class ExtensionMethods {
-    /// <summary>
-    /// Selects an element from an enumerable randomly with equal probability for each element.
-    /// </summary>
-    /// <typeparam name="T">The type of the items that are to be selected.</typeparam>
-    /// <param name="source">The enumerable that contains the items.</param>
-    /// <param name="random">The random number generator, its NextDouble() method must return a value in the range [0;1).</param>
-    /// <param name="selected">True if an element was selected, false otherwise (mainly because of an empty sequence).</param>
-    /// <returns>The selected item.</returns>
-    public static T SelectRandomOrDefault<T>(this IEnumerable<T> source, IRandom random, out bool selected) {
-      int counter = 1;
-      selected = false;
-      T selectedItem = default(T);
-      foreach (T item in source) {
-        if (random.NextDouble() < 1.0 / counter) {
-          selectedItem = item;
-          selected = true;
-        }
-      }
-      return selectedItem;
-    }
-
-    /// <summary>
-    /// Shuffles an enumerable and returns an new enumerable according to the Fisher-Yates shuffle.
-    /// </summary>
-    /// <remarks>
-    /// Source code taken from http://stackoverflow.com/questions/1287567/c-is-using-random-and-orderby-a-good-shuffle-algorithm.
-    /// Note that this is an online shuffle, but the source enumerable is transformed into an array.
-    /// </remarks>
-    /// <typeparam name="T">The type of the items that are to be shuffled.</typeparam>
-    /// <param name="source">The enumerable that contains the items.</param>
-    /// <param name="random">The random number generator, its Next(int) method must deliver uniformly distributed random numbers.</param>
-    /// <returns>An enumerable with the elements shuffled.</returns>
-    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, IRandom random) {
-      T[] elements = source.ToArray();
-      // Note i > 0 to avoid final pointless iteration
-      for (int i = elements.Length - 1; i > 0; i--) {
-        // Swap element "i" with a random earlier element it (or itself)
-        int swapIndex = random.Next(i + 1);
-        yield return elements[swapIndex];
-        elements[swapIndex] = elements[i];
-        // we don't actually perform the swap, we can forget about the
-        // swapped element because we already returned it.
-      }
-
-      // there is one item remaining that was not returned - we return it now
-      yield return elements[0];
-    }
-
-    /// <summary>
-    /// Walks an operator graph in that it jumps from one operator to all its operator parameters and yields each operator it touches.
-    /// Cycles are detected and not walked twice.
-    /// </summary>
-    /// <param name="initial">The operator where the walk starts (is also yielded).</param>
-    /// <returns>An enumeration of all the operators that could be found.</returns>
-    public static IEnumerable<IOperator> Walk(this IOperator initial) {
-      var open = new Stack<IOperator>();
-      var visited = new HashSet<IOperator>();
-      open.Push(initial);
-
-      while (open.Any()) {
-        IOperator current = open.Pop();
-        if (visited.Contains(current)) continue;
-        visited.Add(current);
-
-        foreach (var parameter in current.Parameters.OfType<IValueParameter>()) {
-          if (typeof(IOperator).IsAssignableFrom(parameter.DataType)) {
-            if (parameter.Value != null)
-              open.Push((IOperator)parameter.Value);
-          }
-        }
-
-        yield return current;
-      }
-    }
-
-  }
-}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7407)
@@ -170,5 +170,5 @@
       base.OnSolutionCreatorChanged();
       Parameterize();
-      SolutionCreator.IntegerVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_IntegerVectorParameter_ActualNameChanged);
+      SolutionCreator.AssignmentParameter.ActualNameChanged += new EventHandler(SolutionCreator_IntegerVectorParameter_ActualNameChanged);
     }
 
@@ -212,4 +212,40 @@
       SolutionCreator.CapacitiesParameter.ActualName = CapacitiesParameter.Name;
 
+      foreach (var op in Operators.OfType<IEquipmentAwareGQAPOperator>()) {
+        op.DemandsParameter.ActualName = DemandsParameter.Name;
+      }
+      foreach (var op in Operators.OfType<IGQAPCrossover>()) {
+        op.ParentsParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.ChildParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+      }
+      foreach (var op in Operators.OfType<IGQAPEvaluationOperator>()) {
+        op.WeightsParameter.ActualName = WeightsParameter.Name;
+        op.DistancesParameter.ActualName = DistancesParameter.Name;
+        op.InstallationCostsParameter.ActualName = InstallationCostsParameter.Name;
+        op.TransportationCostsParameter.ActualName = TransportationCostsParameter.Name;
+        op.DemandsParameter.ActualName = DemandsParameter.Name;
+        op.CapacitiesParameter.ActualName = CapacitiesParameter.Name;
+        op.AssignmentParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+      }
+      foreach (var op in Operators.OfType<IGQAPLocalImprovementOperator>()) {
+        op.WeightsParameter.ActualName = WeightsParameter.Name;
+        op.DistancesParameter.ActualName = DistancesParameter.Name;
+        op.InstallationCostsParameter.ActualName = InstallationCostsParameter.Name;
+        op.TransportationCostsParameter.ActualName = TransportationCostsParameter.Name;
+        op.DemandsParameter.ActualName = DemandsParameter.Name;
+        op.CapacitiesParameter.ActualName = CapacitiesParameter.Name;
+        op.AssignmentParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.InfeasibilityParameter.ActualName = Evaluator.InfeasibilityParameter.ActualName;
+      }
+      foreach (var op in Operators.OfType<IGQAPManipulator>()) {
+        op.IntegerVectorParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+      }
+      foreach (var op in Operators.OfType<IGQAPMoveOperator>()) {
+        op.AssignmentParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+      }
+      foreach (var op in Operators.OfType<ILocationAwareGQAPOperator>()) {
+        op.CapacitiesParameter.ActualName = CapacitiesParameter.Name;
+      }
+
       foreach (var op in Operators.OfType<IIntegerVectorCrossover>()) {
         op.ParentsParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
@@ -218,17 +254,4 @@
       foreach (var op in Operators.OfType<IIntegerVectorManipulator>()) {
         op.IntegerVectorParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
-      }
-      foreach (var op in Operators.OfType<IGQAPCrossover>()) {
-        op.ParentsParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
-        op.ChildParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
-      }
-      foreach (var op in Operators.OfType<IGQAPManipulator>()) {
-        op.IntegerVectorParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
-      }
-      foreach (var op in Operators.OfType<ILocationAwareGQAPOperator>()) {
-        op.CapacitiesParameter.ActualName = CapacitiesParameter.Name;
-      }
-      foreach (var op in Operators.OfType<IEquipmentAwareGQAPOperator>()) {
-        op.DemandsParameter.ActualName = DemandsParameter.Name;
       }
 
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 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj	(revision 7407)
@@ -89,18 +89,36 @@
   <ItemGroup>
     <Compile Include="Analyzers\BestGQAPSolutionAnalyzer.cs" />
-    <Compile Include="ExtensionMethods.cs" />
+    <Compile Include="Evaluators\GQAPNMoveEvaluator.cs" />
     <Compile Include="GQAPAssignment.cs" />
     <None Include="Plugin.cs.frame" />
     <Compile Include="Evaluators\GQAPEvaluator.cs" />
     <Compile Include="GeneralizedQuadraticAssignmentProblem.cs" />
+    <Compile Include="Interfaces\IGQAPNMoveEvaluator.cs" />
     <Compile Include="Interfaces\IEquipmentAwareGQAPOperator.cs" />
     <Compile Include="Interfaces\IGQAPCrossover.cs" />
+    <Compile Include="Interfaces\IGQAPEvaluationOperator.cs" />
     <Compile Include="Interfaces\IGQAPEvaluator.cs" />
+    <Compile Include="Interfaces\IGQAPLocalImprovementOperator.cs" />
     <Compile Include="Interfaces\IGQAPManipulator.cs" />
+    <Compile Include="Interfaces\IGQAPMoveEvaluator.cs" />
+    <Compile Include="Interfaces\IGQAPMoveOperator.cs" />
+    <Compile Include="Interfaces\IGQAPNMoveOperator.cs" />
     <Compile Include="Interfaces\IGQAPOperator.cs" />
+    <Compile Include="Interfaces\IGQAPSolutionCreator.cs" />
     <Compile Include="Interfaces\ILocationAwareGQAPOperator.cs" />
+    <Compile Include="Moves\NMove.cs" />
+    <Compile Include="Moves\GQAPMoveGenerator.cs" />
+    <Compile Include="Moves\GQAPNMoveGenerator.cs" />
+    <Compile Include="Moves\NMoveMaker.cs" />
+    <Compile Include="Moves\StochasticNMoveMultiMoveGenerator.cs" />
+    <Compile Include="Moves\StochasticNMoveSingleMoveGenerator.cs" />
+    <Compile Include="Operators\ApproximateLocalSearch.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\RandomSolutionCreator.cs" />
     <Compile Include="Operators\RelocateEquipmentManipluator.cs" />
     <Compile Include="Operators\GQAPManipulator.cs" />
@@ -120,4 +138,5 @@
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluationOperator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluationOperator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluationOperator.cs	(revision 7407)
@@ -0,0 +1,36 @@
+﻿#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public interface IGQAPEvaluationOperator : IGQAPOperator { // full evaluators as well as move evaluators
+    ILookupParameter<DoubleMatrix> WeightsParameter { get; }
+    ILookupParameter<DoubleMatrix> DistancesParameter { get; }
+    ILookupParameter<DoubleMatrix> InstallationCostsParameter { get; }
+    ILookupParameter<DoubleValue> TransportationCostsParameter { get; }
+    ILookupParameter<DoubleArray> DemandsParameter { get; }
+    ILookupParameter<DoubleArray> CapacitiesParameter { get; }
+    ILookupParameter<IntegerVector> AssignmentParameter { get; }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluator.cs	(revision 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluator.cs	(revision 7407)
@@ -22,16 +22,9 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
 using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  public interface IGQAPEvaluator : ISingleObjectiveEvaluator {
-    ILookupParameter<DoubleMatrix> WeightsParameter { get; }
-    ILookupParameter<DoubleMatrix> DistancesParameter { get; }
-    ILookupParameter<DoubleMatrix> InstallationCostsParameter { get; }
-    ILookupParameter<DoubleValue> TransportationCostsParameter { get; }
-    ILookupParameter<DoubleArray> DemandsParameter { get; }
-    ILookupParameter<DoubleArray> CapacitiesParameter { get; }
-    ILookupParameter<IntegerVector> AssignmentParameter { get; }
+  public interface IGQAPEvaluator : IGQAPEvaluationOperator, ISingleObjectiveEvaluator {
+    ILookupParameter<DoubleValue> InfeasibilityParameter { get; }
   }
 }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPLocalImprovementOperator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPLocalImprovementOperator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPLocalImprovementOperator.cs	(revision 7407)
@@ -0,0 +1,42 @@
+﻿#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public interface IGQAPLocalImprovementOperator : IGQAPOperator, ILocalImprovementOperator {
+    ILookupParameter<DoubleValue> QualityParameter { get; }
+    ILookupParameter<DoubleValue> InfeasibilityParameter { get; }
+    ILookupParameter<ResultCollection> ResultsParameter { get; }
+    IValueLookupParameter<IntValue> MaximumCandidateListSizeParameter { get; }
+    IValueLookupParameter<IntValue> MaximumSampleSizeParameter { get; }
+    ILookupParameter<IntegerVector> AssignmentParameter { get; }
+    ILookupParameter<DoubleMatrix> WeightsParameter { get; }
+    ILookupParameter<DoubleMatrix> DistancesParameter { get; }
+    ILookupParameter<DoubleMatrix> InstallationCostsParameter { get; }
+    ILookupParameter<DoubleValue> TransportationCostsParameter { get; }
+    ILookupParameter<DoubleArray> DemandsParameter { get; }
+    ILookupParameter<DoubleArray> CapacitiesParameter { get; }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMoveEvaluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMoveEvaluator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMoveEvaluator.cs	(revision 7407)
@@ -0,0 +1,26 @@
+﻿#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.Optimization;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public interface IGQAPMoveEvaluator : IGQAPEvaluationOperator, ISingleObjectiveMoveEvaluator { }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMoveOperator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMoveOperator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMoveOperator.cs	(revision 7407)
@@ -0,0 +1,30 @@
+﻿#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.Core;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public interface IGQAPMoveOperator : IGQAPOperator, IMoveOperator {
+    ILookupParameter<IntegerVector> AssignmentParameter { get; }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPNMoveEvaluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPNMoveEvaluator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPNMoveEvaluator.cs	(revision 7407)
@@ -0,0 +1,24 @@
+﻿#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
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public interface IGQAPNMoveEvaluator : IGQAPMoveEvaluator, IGQAPNMoveOperator { }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPNMoveOperator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPNMoveOperator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPNMoveOperator.cs	(revision 7407)
@@ -0,0 +1,28 @@
+﻿#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.Core;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public interface IGQAPNMoveOperator : IGQAPMoveOperator {
+    ILookupParameter<NMove> MoveParameter { get; }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/GQAPMoveGenerator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/GQAPMoveGenerator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/GQAPMoveGenerator.cs	(revision 7407)
@@ -0,0 +1,49 @@
+﻿#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.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("GQAPMoveGenerator", "Base class for move generators for the Generalized Quadratic Assignment Problem.")]
+  [StorableClass]
+  public class GQAPMoveGenerator : SingleSuccessorOperator, IMoveGenerator {
+
+    [StorableConstructor]
+    protected GQAPMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected GQAPMoveGenerator(GQAPMoveGenerator original, Cloner cloner)
+      : base(original, cloner) {
+      // TODO: All fields, especially storable fields, need to be deep-cloned here
+      // myField = cloner.Clone(original.myField);
+    }
+    public GQAPMoveGenerator()
+      : base() {
+      // TODO: Add construction logic here
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GQAPMoveGenerator(this, cloner);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/GQAPNMoveGenerator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/GQAPNMoveGenerator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/GQAPNMoveGenerator.cs	(revision 7407)
@@ -0,0 +1,71 @@
+﻿#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;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("GQAPNMoveGenerator", "Base class for move operators that generate n-move moves.")]
+  [StorableClass]
+  public abstract class GQAPNMoveGenerator : GQAPMoveGenerator, IGQAPNMoveOperator {
+
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<NMove> MoveParameter {
+      get { return (ILookupParameter<NMove>)Parameters["Move"]; }
+    }
+    public IValueLookupParameter<IntValue> NParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["N"]; }
+    }
+
+    [StorableConstructor]
+    protected GQAPNMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected GQAPNMoveGenerator(GQAPNMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public GQAPNMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", "The current equipment-location assignment."));
+      Parameters.Add(new LookupParameter<NMove>("Move", "The move to generate."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("N", "The maximum number of equipment(s) that should be moved.", new IntValue(2)));
+    }
+
+    public override IOperation Apply() {
+      List<Scope> scopes = new List<Scope>();
+      int counter = 0;
+      string name = MoveParameter.TranslatedName;
+      foreach (var move in GenerateMoves(AssignmentParameter.ActualValue, NParameter.ActualValue.Value)) {
+        scopes.Add(new Scope(counter.ToString()));
+        scopes.Last().Variables.Add(new Variable(name, move));
+        counter++;
+      }
+      ExecutionContext.Scope.SubScopes.AddRange(scopes);
+      return base.Apply();
+    }
+
+    public abstract IEnumerable<NMove> GenerateMoves(IntegerVector assignment, int n);
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/NMove.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/NMove.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/NMove.cs	(revision 7407)
@@ -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 System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("n-move", "An n-move describes moving n equipments to n locations.")]
+  [StorableClass]
+  public class NMove : Item {
+    [Storable]
+    public int[] Equipments { get; private set; }
+    [Storable]
+    public int[] Locations { get; private set; }
+    [Storable]
+    public IntegerVector OriginalVector { get; private set; }
+
+    public int N { get { return Equipments.Length; } }
+
+    [StorableConstructor]
+    protected NMove(bool deserializing) : base(deserializing) { }
+    protected NMove(NMove original, Cloner cloner)
+      : base(original, cloner) {
+      Equipments = (int[])original.Equipments.Clone();
+      Locations = (int[])original.Locations.Clone();
+      if (original.OriginalVector != null)
+        OriginalVector = cloner.Clone(original.OriginalVector);
+    }
+    public NMove() : this(new int[0], new int[0], null) { }
+    public NMove(int[] equipments, int[] locations) : this(equipments, locations, null) { }
+    public NMove(int[] equipments, int[] locations, IntegerVector originalVector)
+      : base() {
+      if (equipments == null) throw new ArgumentNullException("equipments", "NMove: Equipments must not be null.");
+      if (locations == null) throw new ArgumentNullException("locations", "NMove: Locations must not be null.");
+      if (equipments.Length != locations.Length) throw new ArgumentException("NMove: Length of equipments and locations is not identical.");
+      Equipments = equipments;
+      Locations = locations;
+      OriginalVector = originalVector;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NMove(this, cloner);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/NMoveMaker.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/NMoveMaker.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/NMoveMaker.cs	(revision 7407)
@@ -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.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("NMoveMaker", "Performs an n-move.")]
+  [StorableClass]
+  public class NMoveMaker : SingleSuccessorOperator, IGQAPNMoveOperator {
+
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<NMove> MoveParameter {
+      get { return (ILookupParameter<NMove>)Parameters["Move"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> InfeasibilityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Infeasibility"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveInfeasibilityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveInfeasibility"]; }
+    }
+
+    [StorableConstructor]
+    protected NMoveMaker(bool deserializing) : base(deserializing) { }
+    protected NMoveMaker(NMoveMaker original, Cloner cloner) : base(original, cloner) { }
+    public NMoveMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", "The equipment-location assignment vector."));
+      Parameters.Add(new LookupParameter<NMove>("Move", "The move to perform."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The solution quality."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Infeasibility", "The infeasibility of a solution."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the move if it would be applied."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveInfeasibility", "The infeasibility of the move if it would be applied."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NMoveMaker(this, cloner);
+    }
+
+    public static void Apply(IntegerVector vector, NMove move) {
+      for (int i = 0; i < move.N; i++) {
+        vector[move.Equipments[i]] = move.Locations[i];
+      }
+    }
+
+    public override IOperation Apply() {
+      Apply(AssignmentParameter.ActualValue, MoveParameter.ActualValue);
+      QualityParameter.ActualValue.Value = MoveQualityParameter.ActualValue.Value;
+      InfeasibilityParameter.ActualValue.Value = MoveInfeasibilityParameter.ActualValue.Value;
+      return base.Apply();
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveMultiMoveGenerator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveMultiMoveGenerator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveMultiMoveGenerator.cs	(revision 7407)
@@ -0,0 +1,69 @@
+﻿#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 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("Stochastic 1-move MultiMoveGenerator", "Randomly samples a number of moves according to the 1-move 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 StochasticNMoveMultiMoveGenerator : GQAPNMoveGenerator, ILocationAwareGQAPOperator, IMultiMoveGenerator, IStochasticOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+    public IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    [StorableConstructor]
+    protected StochasticNMoveMultiMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticNMoveMultiMoveGenerator(StochasticNMoveMultiMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticNMoveMultiMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that should be used."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", "Capacities of the locations."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticNMoveMultiMoveGenerator(this, cloner);
+    }
+
+    public static IEnumerable<NMove> Generate(IRandom random, IntegerVector assignment, int n, DoubleArray capacities, int sampleSize) {
+      for (int i = 0; i < sampleSize; i++)
+        yield return StochasticNMoveSingleMoveGenerator.Generate(random, assignment, n, capacities);
+    }
+
+    public override IEnumerable<NMove> GenerateMoves(IntegerVector assignment, int n) {
+      return Generate(RandomParameter.ActualValue, assignment, n, CapacitiesParameter.ActualValue, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveSingleMoveGenerator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveSingleMoveGenerator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveSingleMoveGenerator.cs	(revision 7407)
@@ -0,0 +1,76 @@
+﻿#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 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("Stochastic 1-move and 2-move SingleMoveGenerator", "Randomly samples a single 1-move or 2-move as 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 StochasticNMoveSingleMoveGenerator : GQAPNMoveGenerator, ILocationAwareGQAPOperator, ISingleMoveGenerator, IStochasticOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+
+    [StorableConstructor]
+    protected StochasticNMoveSingleMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticNMoveSingleMoveGenerator(StochasticNMoveSingleMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticNMoveSingleMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that should be used."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", "Capacities of the locations."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticNMoveSingleMoveGenerator(this, cloner);
+    }
+
+    public static NMove Generate(IRandom random, IntegerVector assignment, int n, DoubleArray capacities) {
+      int moving = random.Next(n) + 1;
+      int[] equipments = new int[moving], locations = new int[moving];
+      HashSet<int> chosenEquipments = new HashSet<int>();
+      for (int i = 0; i < moving; i++) {
+        do {
+          equipments[i] = random.Next(assignment.Length);
+        } while (chosenEquipments.Contains(equipments[i]));
+        chosenEquipments.Add(equipments[i]);
+        do {
+          locations[i] = random.Next(capacities.Length);
+        } while (locations[i] == assignment[equipments[i]]);
+      }
+      return new NMove(equipments, locations);
+    }
+
+    public override IEnumerable<NMove> GenerateMoves(IntegerVector assignment, int n) {
+      yield return Generate(RandomParameter.ActualValue, assignment, n, CapacitiesParameter.ActualValue);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/ApproximateLocalSearch.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/ApproximateLocalSearch.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/ApproximateLocalSearch.cs	(revision 7407)
@@ -0,0 +1,191 @@
+﻿#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.
+
+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.")]
+  [StorableClass]
+  public class ApproximateLocalSearch : SingleSuccessorOperator, IGQAPLocalImprovementOperator, IStochasticOperator {
+    public IProblem Problem { get; set; }
+    public Type ProblemType {
+      get { return typeof(GeneralizedQuadraticAssignmentProblem); }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> InfeasibilityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Infeasibility"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public IValueLookupParameter<IntValue> MaximumCandidateListSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumCandidateListSize"]; }
+    }
+    public IValueLookupParameter<IntValue> MaximumSampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumSampleSize"]; }
+    }
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    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<DoubleValue> TransportationCostsParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
+    }
+    public ILookupParameter<DoubleArray> DemandsParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Demands"]; }
+    }
+    public ILookupParameter<DoubleArray> CapacitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+
+
+    [StorableConstructor]
+    protected ApproximateLocalSearch(bool deserializing) : base(deserializing) { }
+    protected ApproximateLocalSearch(ApproximateLocalSearch original, Cloner cloner) : base(original, cloner) { }
+    public ApproximateLocalSearch()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      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<DoubleValue>("Quality", "The solution quality."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Infeasibility", "The infeasibility describes the sum of the overbooked capacities."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection that stores the results."));
+      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<IntValue>("MaximumSampleSize", "The maximum number of candidates that should be sampled in each step.", new IntValue(100)));
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", "The equipment-location assignment vector."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", "The weights matrix describes the flows between the equipments."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", "The distances matrix describes the distances between the locations at which the equipment can be installed."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("InstallationCosts", "The installation costs matrix describes the installation costs of installing equipment i at location j."));
+      Parameters.Add(new LookupParameter<DoubleValue>("TransportationCosts", "The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights matrix already."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Demands", "The demands vector describes the space requirements of the equipments."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Capacities", "The capacities vector describes the available space at the locations."));
+    }
+
+    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="infeasibility">The infeasibility describes the sum of the overbooked capacities.</param>
+    /// <param name="maxCLS">The maximum number of candidates that should be found in each step.</param>
+    /// <param name="maxSampleSize">The maximum number of candidates that should be sampled in each step.</param>
+    /// <param name="maximumIterations">The maximum number of iterations that should be performed.</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="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="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>
+    public static void Apply(IRandom random, IntegerVector assignment, DoubleValue quality, DoubleValue infeasibility,
+                             IntValue maxCLS, IntValue maxSampleSize, IntValue maximumIterations,
+                             DoubleArray demands, DoubleArray capacities,
+                             DoubleMatrix weights, DoubleMatrix distances,
+                             DoubleMatrix installationCosts,
+                             DoubleValue transportationCosts) {
+      for (int i = 0; i < maximumIterations.Value; i++) {
+        int count = 0;
+        var CLS = new List<Tuple<NMove, DoubleValue, DoubleValue>>();
+        double sum = 0.0;
+        do {
+          var move = StochasticNMoveSingleMoveGenerator.Generate(random, assignment, 2, capacities);
+          DoubleValue moveInfeasibility;
+          var moveQuality = GQAPNMoveEvaluator.Evaluate(move, assignment, quality,
+            demands, capacities, weights, distances,
+            installationCosts, transportationCosts, out moveInfeasibility);
+          if (moveInfeasibility.Value <= 0.0 && moveQuality.Value < quality.Value) {
+            CLS.Add(Tuple.Create(move, moveQuality, moveInfeasibility));
+            sum += 1.0 / moveQuality.Value;
+          }
+          count++;
+        } while (CLS.Count < maxCLS.Value && count < maxSampleSize.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.Value;
+            if (ball <= 0.0) {
+              selected = candidate;
+              break;
+            }
+          }
+          NMoveMaker.Apply(assignment, selected.Item1);
+          quality.Value = selected.Item2.Value;
+          infeasibility.Value = selected.Item3.Value;
+        }
+      }
+    }
+
+    public override IOperation Apply() {
+      Apply(RandomParameter.ActualValue,
+        AssignmentParameter.ActualValue,
+        QualityParameter.ActualValue,
+        InfeasibilityParameter.ActualValue,
+        MaximumCandidateListSizeParameter.ActualValue,
+        MaximumSampleSizeParameter.ActualValue,
+        MaximumIterationsParameter.ActualValue,
+        DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
+        WeightsParameter.ActualValue, DistancesParameter.ActualValue,
+        InstallationCostsParameter.ActualValue,
+        TransportationCostsParameter.ActualValue);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DemandEquivalentSwapEquipmentManipluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DemandEquivalentSwapEquipmentManipluator.cs	(revision 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DemandEquivalentSwapEquipmentManipluator.cs	(revision 7407)
@@ -29,4 +29,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
@@ -79,5 +80,5 @@
           groupedLocations[location2].Remove(equipment2);
           bool selected;
-          equipment2 = groupedLocations[location2].SelectRandomOrDefault(random, out selected);
+          equipment2 = groupedLocations[location2].ChooseRandomOrDefault(random, out selected);
           if (!selected) break;
         }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DiscreteLocationCrossover.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DiscreteLocationCrossover.cs	(revision 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/DiscreteLocationCrossover.cs	(revision 7407)
@@ -28,6 +28,7 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
 
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
   [Item("DiscreteLocationCrossover", "Combines the assignment to locations from various parents.")]
   [StorableClass]
@@ -52,5 +53,5 @@
 
     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 })
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPStochasticSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPStochasticSolutionCreator.cs	(revision 7407)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPStochasticSolutionCreator.cs	(revision 7407)
@@ -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/Operators/GreedyRandomizedSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GreedyRandomizedSolutionCreator.cs	(revision 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GreedyRandomizedSolutionCreator.cs	(revision 7407)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -26,16 +27,13 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
 
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
+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 : GQAPSolutionCreator, IStochasticOperator {
+  public class GreedyRandomizedSolutionCreator : GQAPStochasticSolutionCreator {
 
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
-    }
     public IValueLookupParameter<IntValue> MaximumTriesParameter {
       get { return (IValueLookupParameter<IntValue>)Parameters["MaximumTries"]; }
@@ -48,6 +46,5 @@
     public GreedyRandomizedSolutionCreator()
       : base() {
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumTries", "The maximum number of tries to create a feasible solution."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumTries", "The maximum number of tries to create a feasible solution.", new IntValue(10000)));
     }
 
@@ -56,13 +53,61 @@
     }
 
-    protected override IntegerVector CreateSolution(DoubleArray demands, DoubleArray capacities) {
-      int k = 0, t = MaximumTriesParameter.ActualValue.Value;
-      HashSet<int> F = new HashSet<int>(Enumerable.Range(0, demands.Length));
-      while (k < t && F.Any()) {
+    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();
+        demands.Select((v, i) => slack[i] = v).Enumerate();
+        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.ChooseRandom(random);
+            L.Remove(l);
+            CL.Add(l);
+            T = new HashSet<int>(WithDemandEqualOrLess(F, GetMaximumSlack(slack, CL), demands));
+          }
+          if (T.Any()) {
+            int f = T.ChooseRandom(random);
+            T.Remove(f);
+            F.Remove(f);
+            CF.Add(f);
+            int l = WithSlackGreaterOrEqual(CL, demands[f], slack).ChooseRandom(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;
       }
 
-      // TODO: return actual solution
-      return UniformRandomIntegerVectorCreator.Apply(RandomParameter.ActualValue, demands.Length, 0, capacities.Length);
+      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/RandomSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/RandomSolutionCreator.cs	(revision 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/RandomSolutionCreator.cs	(revision 7407)
@@ -24,6 +24,4 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -31,18 +29,10 @@
   [Item("RandomSolutionCreator", "Creates a completely random solution to the Generalized Quadratic Assignment Problem.")]
   [StorableClass]
-  public class RandomSolutionCreator : GQAPSolutionCreator, IStochasticOperator {
-
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
-    }
+  public class RandomSolutionCreator : GQAPStochasticSolutionCreator {
 
     [StorableConstructor]
     protected RandomSolutionCreator(bool deserializing) : base(deserializing) { }
-    protected RandomSolutionCreator(RandomSolutionCreator original, Cloner cloner)
-      : base(original, cloner) { }
-    public RandomSolutionCreator()
-      : base() {
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
-    }
+    protected RandomSolutionCreator(RandomSolutionCreator original, Cloner cloner) : base(original, cloner) { }
+    public RandomSolutionCreator() : base() { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -50,6 +40,6 @@
     }
 
-    protected override IntegerVector CreateSolution(DoubleArray demands, DoubleArray capacities) {
-      return UniformRandomIntegerVectorCreator.Apply(RandomParameter.ActualValue, demands.Length, 0, capacities.Length);
+    protected override IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities) {
+      return UniformRandomIntegerVectorCreator.Apply(random, demands.Length, 0, capacities.Length);
     }
   }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/RelocateEquipmentManipluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/RelocateEquipmentManipluator.cs	(revision 7406)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/RelocateEquipmentManipluator.cs	(revision 7407)
@@ -29,4 +29,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
@@ -34,5 +35,5 @@
   [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, ILocationAwareGQAPOperator, IEquipmentAwareGQAPManipulator {
+  public class RelocateEquipmentManipluator : GQAPManipulator, ILocationAwareGQAPOperator, IEquipmentAwareGQAPOperator {
 
     public ILookupParameter<DoubleArray> CapacitiesParameter {
@@ -60,5 +61,5 @@
       if (locations < 2) throw new InvalidOperationException("There are not enough locations for relocation operations.");
 
-      Dictionary<int, double> usedCapacities = new Dictionary<int,double>();
+      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++) {
@@ -72,13 +73,13 @@
 
       bool selected;
-      var overstuffedLocation = usedCapacities.Where(x => capacities[x.Key] < x.Value).SelectRandomOrDefault(random, out selected);
+      var overstuffedLocation = usedCapacities.Where(x => capacities[x.Key] < x.Value).ChooseRandomOrDefault(random, out selected);
       if (selected) {
-        int equipment = groupedLocations[overstuffedLocation.Key].SelectRandomOrDefault(random, out selected);
+        int equipment = groupedLocations[overstuffedLocation.Key].ChooseRandomOrDefault(random, out selected);
         var freeLocations = usedCapacities.Where(x => capacities[x.Key] > x.Value).ToList();
-        var location = freeLocations.Where(x => capacities[x.Key] > x.Value + demands[equipment]).SelectRandomOrDefault(random, out selected);
+        var location = freeLocations.Where(x => capacities[x.Key] > x.Value + demands[equipment]).ChooseRandomOrDefault(random, out selected);
         if (selected) {
           assignment[equipment] = location.Key;
         } else {
-          location = freeLocations.SelectRandomOrDefault(random, out selected);
+          location = freeLocations.ChooseRandomOrDefault(random, out selected);
           if (selected) assignment[equipment] = location.Key;
           else assignment[equipment] = random.Next(locations);
