Index: /branches/GeneralizedQAP/GeneralizedQAP.sln
===================================================================
--- /branches/GeneralizedQAP/GeneralizedQAP.sln	(revision 7411)
+++ /branches/GeneralizedQAP/GeneralizedQAP.sln	(revision 7412)
@@ -10,5 +10,17 @@
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common-3.3", "HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common\3.3\HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common-3.3.csproj", "{DA367BE5-4F53-4243-933B-32AAB86189D5}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{68C6C157-08DA-414F-9256-CCCA13038399}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7275B9B0-0E8D-471E-9F64-067E1F85BB71}"
+	ProjectSection(SolutionItems) = preProject
+		GeneralizedQAP.vsmdi = GeneralizedQAP.vsmdi
+		Local.testsettings = Local.testsettings
+		TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
+	EndProjectSection
+EndProject
 Global
+	GlobalSection(TestCaseManagementSettings) = postSolution
+		CategoryFile = GeneralizedQAP.vsmdi
+	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -52,4 +64,12 @@
 		{DA367BE5-4F53-4243-933B-32AAB86189D5}.Release|x64.ActiveCfg = Release|Any CPU
 		{DA367BE5-4F53-4243-933B-32AAB86189D5}.Release|x86.ActiveCfg = Release|Any CPU
+		{68C6C157-08DA-414F-9256-CCCA13038399}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{68C6C157-08DA-414F-9256-CCCA13038399}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{68C6C157-08DA-414F-9256-CCCA13038399}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{68C6C157-08DA-414F-9256-CCCA13038399}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{68C6C157-08DA-414F-9256-CCCA13038399}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{68C6C157-08DA-414F-9256-CCCA13038399}.Release|Any CPU.Build.0 = Release|Any CPU
+		{68C6C157-08DA-414F-9256-CCCA13038399}.Release|x64.ActiveCfg = Release|Any CPU
+		{68C6C157-08DA-414F-9256-CCCA13038399}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /branches/GeneralizedQAP/GeneralizedQAP.vsmdi
===================================================================
--- /branches/GeneralizedQAP/GeneralizedQAP.vsmdi	(revision 7412)
+++ /branches/GeneralizedQAP/GeneralizedQAP.vsmdi	(revision 7412)
@@ -0,0 +1,6 @@
+﻿<?xml version="1.0" encoding="UTF-8"?>
+<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
+  <TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
+    <RunConfiguration id="0c5645ea-4f25-4faf-bdb6-6c685aa774f5" name="Local" storage="local.testsettings" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  </TestList>
+</TestLists>
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/GRASPWithPathRelinking.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/GRASPWithPathRelinking.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/GRASPWithPathRelinking.cs	(revision 7412)
@@ -61,4 +61,7 @@
       get { return (IValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
     }
+    public IValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
     private IFixedValueParameter<IntValue> EliteSetSizeParameter {
       get { return (IFixedValueParameter<IntValue>)Parameters["EliteSetSize"]; }
@@ -76,5 +79,5 @@
       get { return (ConstrainedValueParameter<ICrossover>)Parameters["PathRelinking"]; }
     }
-    public ConstrainedValueParameter<IMerger> EliteSetReplacerParameter {
+    public ConstrainedValueParameter<IMerger> EliteSetMergerParameter {
       get { return (ConstrainedValueParameter<IMerger>)Parameters["EliteSetMerger"]; }
     }
@@ -106,5 +109,11 @@
       get { return (RandomCreator)OperatorGraph.InitialOperator; }
     }
-    #endregion
+    private GRASPWithPathRelinkingMainLoop MainLoop {
+      get { return RandomCreator.Successor as GRASPWithPathRelinkingMainLoop; }
+    }
+    #endregion
+
+    [Storable]
+    private BestAverageWorstQualityAnalyzer analyzer;
 
     [StorableConstructor]
@@ -112,4 +121,5 @@
     private GRASPWithPathRelinking(GRASPWithPathRelinking original, Cloner cloner)
       : base(original, cloner) {
+      analyzer = cloner.Clone(original.analyzer);
       RegisterEventHandlers();
     }
@@ -119,10 +129,14 @@
       Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator."));
       Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each iteration.", new MultiAnalyzer()));
+      Parameters.Add(new ValueParameter<IntValue>("MaximumIterations", "The maximum number of iterations that the algorithm should run.", new IntValue(1000)));
       Parameters.Add(new FixedValueParameter<IntValue>("EliteSetSize", "The elite set stores the best found solutions.", new IntValue(10)));
-      Parameters.Add(new FixedValueParameter<IntValue>("LocalImprovementMaximumIterations", "The maximum number of iterations performed by the local improvement operator.", new IntValue(100)));
+      Parameters.Add(new FixedValueParameter<IntValue>("LocalImprovementMaximumIterations", "The maximum number of iterations performed by the local improvement operator.", new IntValue(1000)));
       Parameters.Add(new ConstrainedValueParameter<ILocalImprovementOperator>("LocalImprovement", "Performs a local search on the solution."));
-      Parameters.Add(new FixedValueParameter<IntValue>("MinimumEliteSetSize", "(ρ) The minimum amount of elites for performing path relinking.", new IntValue(1)));
+      Parameters.Add(new FixedValueParameter<IntValue>("MinimumEliteSetSize", "(ρ) The minimum amount of elites for performing path relinking.", new IntValue(2)));
       Parameters.Add(new ConstrainedValueParameter<ICrossover>("PathRelinking", "The operator that performs the path relinking."));
       Parameters.Add(new ConstrainedValueParameter<IMerger>("EliteSetMerger", "The operator that merges new solutions into the elite set."));
+
+      analyzer = new BestAverageWorstQualityAnalyzer();
+      Analyzer.Operators.Add(analyzer);
 
       RandomCreator randomCreator = new RandomCreator();
@@ -136,4 +150,12 @@
 
       var mainLoop = new GRASPWithPathRelinkingMainLoop();
+      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
+      mainLoop.EliteSetMergerParameter.ActualName = EliteSetMergerParameter.Name;
+      mainLoop.EliteSetSizeParameter.ActualName = EliteSetSizeParameter.Name;
+      mainLoop.EvaluatedSolutionsParameter.ActualName = "EvaluatedSolutions";
+      mainLoop.LocalImprovementParameter.ActualName = LocalImprovementParameter.Name;
+      mainLoop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
+      mainLoop.PathRelinkingParameter.ActualName = PathRelinkingParameter.Name;
+      mainLoop.ResultsParameter.ActualName = "Results";
       randomCreator.Successor = mainLoop;
 
@@ -185,17 +207,18 @@
       Analyzer.Operators.Clear();
       if (Problem != null) {
-        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>()) {
-          foreach (var param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
+        foreach (IAnalyzer a in Problem.Operators.OfType<IAnalyzer>()) {
+          foreach (var param in a.Parameters.OfType<IScopeTreeLookupParameter>())
             param.Depth = 1;
-          Analyzer.Operators.Add(analyzer);
+          Analyzer.Operators.Add(a);
         }
         InitializeFromInstallation(LocalImprovementParameter, x => x.ProblemType.IsAssignableFrom(Problem.GetType()));
         InitializeFromProblem(PathRelinkingParameter);
-        InitializeFromProblem(EliteSetReplacerParameter);
+        InitializeFromProblem(EliteSetMergerParameter);
       } else {
         LocalImprovementParameter.ValidValues.Clear();
         PathRelinkingParameter.ValidValues.Clear();
-        EliteSetReplacerParameter.ValidValues.Clear();
-      }
+        EliteSetMergerParameter.ValidValues.Clear();
+      }
+      Analyzer.Operators.Add(analyzer);
 
       Parameterize();
@@ -203,4 +226,10 @@
 
     private void Parameterize() {
+      if (Problem != null) {
+        MainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+        MainLoop.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
+
+        analyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+      }
       foreach (var localImprovement in LocalImprovementParameter.ValidValues) {
         localImprovement.MaximumIterationsParameter.ActualName = LocalImprovementMaximumIterationsParameter.Name;
@@ -210,8 +239,11 @@
           localImprovement.Problem = Problem;
       }
+      foreach (var merger in EliteSetMergerParameter.ValidValues) {
+        merger.PopulationSizeParameter.ActualName = EliteSetSizeParameter.Name;
+      }
     }
 
     private void InitializeFromProblem<T>(ConstrainedValueParameter<T> parameter) where T : class, INamedItem {
-      InitializeFromProblem(parameter, x => true);
+      InitializeFromProblem<T>(parameter, x => true);
     }
     private void InitializeFromProblem<T>(ConstrainedValueParameter<T> parameter, Func<T, bool> condition) where T : class, INamedItem {
@@ -228,5 +260,5 @@
     }
     private void InitializeFromInstallation<T>(ConstrainedValueParameter<T> parameter) where T : class, INamedItem {
-      InitializeFromInstallation(parameter, x => true);
+      InitializeFromInstallation<T>(parameter, x => true);
     }
     private void InitializeFromInstallation<T>(ConstrainedValueParameter<T> parameter, Func<T, bool> condition) where T : class, INamedItem {
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/GRASPWithPathRelinkingMainLoop.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/GRASPWithPathRelinkingMainLoop.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/GRASPWithPathRelinkingMainLoop.cs	(revision 7412)
@@ -89,4 +89,8 @@
       variableCreator1.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
 
+      var resultsCollector = new ResultsCollector();
+      resultsCollector.CopyValue = new BoolValue(false);
+      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Iterations"));
+
       var variableCreator2 = new VariableCreator();
       variableCreator2.Name = "ActualEliteSetSize = 0";
@@ -157,4 +161,8 @@
       placeholder2.OperatorParameter.ActualName = PathRelinkingParameter.Name;
 
+      var placeholder3 = new Placeholder();
+      placeholder3.Name = "(Evaluator)";
+      placeholder3.OperatorParameter.ActualName = EvaluatorParameter.Name;
+
       var subScopesRemover = new SubScopesRemover();
       subScopesRemover.RemoveAllSubScopes = true;
@@ -162,11 +170,11 @@
       var ssp4 = new SubScopesProcessor();
 
-      var placeholder3 = new Placeholder();
-      placeholder3.Name = "(LocalImprovement)";
-      placeholder3.OperatorParameter.ActualName = LocalImprovementParameter.Name;
-
       var placeholder4 = new Placeholder();
-      placeholder4.Name = "(EliteSetMerger)";
-      placeholder4.OperatorParameter.ActualName = EliteSetMergerParameter.Name;
+      placeholder4.Name = "(LocalImprovement)";
+      placeholder4.OperatorParameter.ActualName = LocalImprovementParameter.Name;
+
+      var placeholder5 = new Placeholder();
+      placeholder5.Name = "(EliteSetMerger)";
+      placeholder5.OperatorParameter.ActualName = EliteSetMergerParameter.Name;
 
       var counter = new IntCounter();
@@ -191,5 +199,6 @@
 
       OperatorGraph.InitialOperator = variableCreator1;
-      variableCreator1.Successor = variableCreator2;
+      variableCreator1.Successor = resultsCollector;
+      resultsCollector.Successor = variableCreator2;
       variableCreator2.Successor = subScopesCounter1;
       subScopesCounter1.Successor = comparator1;
@@ -200,5 +209,5 @@
       ssp1.Operators.Add(eo1);
       ssp1.Operators.Add(solutionsCreator);
-      ssp1.Successor = placeholder4;
+      ssp1.Successor = placeholder5;
       eo1.Successor = null;
       solutionsCreator.Successor = subScopesCounter2;
@@ -216,9 +225,10 @@
       ssp3.Operators.Add(placeholder2);
       ssp3.Successor = null;
-      placeholder2.Successor = subScopesRemover;
+      placeholder2.Successor = placeholder3;
+      placeholder3.Successor = subScopesRemover;
       subScopesRemover.Successor = null;
-      ssp4.Operators.Add(placeholder3);
+      ssp4.Operators.Add(placeholder4);
       ssp4.Successor = null;
-      placeholder4.Successor = counter;
+      placeholder5.Successor = counter;
       counter.Successor = analyzer1;
       analyzer1.Successor = comparator3;
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common-3.3.csproj
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common-3.3.csproj	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common-3.3.csproj	(revision 7412)
@@ -90,4 +90,5 @@
     <Compile Include="ExtensionMethods.cs" />
     <Compile Include="IMerger.cs" />
+    <Compile Include="IntegerVectorEqualityComparer.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/IMerger.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/IMerger.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/IMerger.cs	(revision 7412)
@@ -21,7 +21,9 @@
 
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common {
   public interface IMerger : IOperator {
+    ILookupParameter<IntValue> PopulationSizeParameter { get; }
   }
 }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/IntegerVectorEqualityComparer.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/IntegerVectorEqualityComparer.cs	(revision 7412)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/IntegerVectorEqualityComparer.cs	(revision 7412)
@@ -0,0 +1,41 @@
+﻿#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.Encodings.IntegerVectorEncoding;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common {
+  public class IntegerVectorEqualityComparer : EqualityComparer<IntegerVector> {
+    public override bool Equals(IntegerVector x, IntegerVector y) {
+      if (x == null || y == null) return false;
+      if (x.Length != y.Length) return false;
+
+      for (int i = 0; i < x.Length; i++)
+        if (x[i] != y[i]) return false;
+
+      return true;
+    }
+
+    public override int GetHashCode(IntegerVector obj) {
+      return obj.GetHashCode();
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentView.Designer.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentView.Designer.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentView.Designer.cs	(revision 7412)
@@ -56,8 +56,9 @@
                   | System.Windows.Forms.AnchorStyles.Left)
                   | System.Windows.Forms.AnchorStyles.Right)));
-      this.assignmentTreeView.Location = new System.Drawing.Point(3, 52);
+      this.assignmentTreeView.Location = new System.Drawing.Point(3, 50);
+      this.assignmentTreeView.Margin = new System.Windows.Forms.Padding(3, 6, 3, 3);
       this.assignmentTreeView.Name = "assignmentTreeView";
-      this.assignmentTreeView.Size = new System.Drawing.Size(349, 329);
-      this.assignmentTreeView.TabIndex = 0;
+      this.assignmentTreeView.Size = new System.Drawing.Size(349, 331);
+      this.assignmentTreeView.TabIndex = 3;
       // 
       // label1
@@ -67,5 +68,5 @@
       this.label1.Name = "label1";
       this.label1.Size = new System.Drawing.Size(42, 13);
-      this.label1.TabIndex = 1;
+      this.label1.TabIndex = 0;
       this.label1.Text = "Quality:";
       // 
@@ -77,13 +78,13 @@
       this.qualityTextBox.Name = "qualityTextBox";
       this.qualityTextBox.Size = new System.Drawing.Size(301, 20);
-      this.qualityTextBox.TabIndex = 2;
+      this.qualityTextBox.TabIndex = 1;
       // 
       // label2
       // 
       this.label2.AutoSize = true;
-      this.label2.Location = new System.Drawing.Point(3, 36);
+      this.label2.Location = new System.Drawing.Point(3, 31);
       this.label2.Name = "label2";
       this.label2.Size = new System.Drawing.Size(64, 13);
-      this.label2.TabIndex = 1;
+      this.label2.TabIndex = 2;
       this.label2.Text = "Assignment:";
       // 
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentView.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentView.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentView.cs	(revision 7412)
@@ -66,6 +66,6 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
-      qualityTextBox.Enabled = !ReadOnly && !Locked && Content != null;
-      assignmentTreeView.Enabled = !ReadOnly && !Locked && Content != null;
+      qualityTextBox.Enabled = false;
+      assignmentTreeView.Enabled = true;
     }
 
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views-3.3.csproj
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views-3.3.csproj	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views-3.3.csproj	(revision 7412)
@@ -38,6 +38,10 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
-    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
@@ -49,5 +53,7 @@
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
     </Reference>
-    <Reference Include="HeuristicLab.Encodings.IntegerVectorEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Encodings.IntegerVectorEncoding-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.IntegerVectorEncoding-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.MainForm-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
@@ -56,8 +62,16 @@
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
     </Reference>
-    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
-    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
-    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
-    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/BestGQAPSolutionAnalyzer.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/BestGQAPSolutionAnalyzer.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/BestGQAPSolutionAnalyzer.cs	(revision 7412)
@@ -98,5 +98,5 @@
 
     [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserializationHook() {
+    private void AfterDeserialization() {
       // BackwardsCompatibility3.3
       #region Backwards compatible code, remove with 3.4
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPEvaluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPEvaluator.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPEvaluator.cs	(revision 7412)
@@ -38,9 +38,18 @@
       get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
     }
-    public ILookupParameter<DoubleValue> InfeasibilityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Infeasibility"]; }
+    public ILookupParameter<DoubleValue> FlowDistanceQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["FlowDistanceQuality"]; }
     }
-    public IValueLookupParameter<DoubleValue> PenaltyParameter {
-      get { return (IValueLookupParameter<DoubleValue>)Parameters["Penalty"]; }
+    public ILookupParameter<DoubleValue> InstallationQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["InstallationQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> OverbookedCapacityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["OverbookedCapacity"]; }
+    }
+    public IValueLookupParameter<DoubleValue> TransportationCostsParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
+    }
+    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
     }
     public ILookupParameter<DoubleMatrix> WeightsParameter {
@@ -52,7 +61,4 @@
     public ILookupParameter<DoubleMatrix> InstallationCostsParameter {
       get { return (ILookupParameter<DoubleMatrix>)Parameters["InstallationCosts"]; }
-    }
-    public ILookupParameter<DoubleValue> TransportationCostsParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
     public ILookupParameter<DoubleArray> DemandsParameter {
@@ -71,11 +77,13 @@
     public GQAPEvaluator()
       : base() {
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality a.k.a. fitness of the solution."));
-      Parameters.Add(new LookupParameter<DoubleValue>("Infeasibility", "The infeasibility describes the sum of the overbooked capacities."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("Penalty", "The multiplier for the constraint violation when added to the quality.", new DoubleValue(1000)));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new LookupParameter<DoubleValue>("FlowDistanceQuality", "The quality regarding the flow-distance criteria."));
+      Parameters.Add(new LookupParameter<DoubleValue>("InstallationQuality", "The quality regarding the installation costs."));
+      Parameters.Add(new LookupParameter<DoubleValue>("OverbookedCapacity", "The sum of the overbooked capacities relative to the capacity of each location."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", "The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights or distance matrix already."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", "The multiplier for the constraint violation when added to the quality."));
       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."));
@@ -87,31 +95,47 @@
     }
 
-    public static DoubleValue Evaluate(IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances,
-      DoubleMatrix installCosts, double transportCosts, DoubleArray demands, DoubleArray capacities,
-      out double infeasibility) {
-      double quality = 0;
+    public static double Evaluate(IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances,
+                                  DoubleMatrix installCosts, DoubleArray demands, DoubleArray capacities,
+                                  DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty) {
+      double flowDistanceQuality, installationQuality, overbookedCapacity;
+      Evaluate(assignment, weights, distances, installCosts, demands, capacities,
+        out flowDistanceQuality, out installationQuality, out overbookedCapacity);
+      return GetCombinedQuality(flowDistanceQuality, installationQuality, overbookedCapacity,
+        transportationCosts.Value, overbookedCapacityPenalty.Value);
+    }
+
+    public static void Evaluate(IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances,
+                                DoubleMatrix installCosts, DoubleArray demands, DoubleArray capacities,
+                                out double flowDistanceQuality, out double installationQuality, out double overbookedCapacity) {
+      flowDistanceQuality = 0;
+      installationQuality = 0;
       int len = assignment.Length;
       var slack = (DoubleArray)capacities.Clone();
       for (int i = 0; i < len; i++) {
-        quality += installCosts[i, assignment[i]];
+        installationQuality += installCosts[i, assignment[i]];
         for (int j = 0; j < len; j++) {
-          quality += transportCosts * weights[i, j] * distances[assignment[i], assignment[j]];
+          flowDistanceQuality += weights[i, j] * distances[assignment[i], assignment[j]];
         }
         slack[assignment[i]] -= demands[i];
       }
+      overbookedCapacity = slack.Select((v, i) => new { V = v, Index = i }).Where(x => x.V < 0.0).Select(x => -x.V / capacities[x.Index]).Sum();
+    }
 
-      infeasibility = -slack.Where(x => x < 0).Sum();
-      return new DoubleValue(quality);
+    public static double GetCombinedQuality(double flowDistanceQuality, double installationQuality, double overbookedCapacity,
+      double transportationCosts, double overbookedCapacityPenalty) {
+      return installationQuality
+        + transportationCosts * flowDistanceQuality
+        + overbookedCapacityPenalty * overbookedCapacity;
     }
 
     public override IOperation Apply() {
-      IntegerVector assignment = AssignmentParameter.ActualValue;
-      DoubleMatrix weights = WeightsParameter.ActualValue;
-      DoubleMatrix distances = DistancesParameter.ActualValue;
-      DoubleMatrix installCosts = InstallationCostsParameter.ActualValue;
-      double transportCosts = TransportationCostsParameter.ActualValue.Value;
-      DoubleArray demands = DemandsParameter.ActualValue;
-      DoubleArray capacities = (DoubleArray)CapacitiesParameter.ActualValue.Clone();
-      double penalty = PenaltyParameter.ActualValue.Value;
+      var assignment = AssignmentParameter.ActualValue;
+      var weights = WeightsParameter.ActualValue;
+      var distances = DistancesParameter.ActualValue;
+      var installCosts = InstallationCostsParameter.ActualValue;
+      var demands = DemandsParameter.ActualValue;
+      var capacities = CapacitiesParameter.ActualValue;
+      var transportCosts = TransportationCostsParameter.ActualValue.Value;
+      double penalty = OverbookedCapacityPenaltyParameter.ActualValue.Value;
 
       if (weights.Rows != weights.Columns || distances.Rows != distances.Columns
@@ -120,9 +144,13 @@
         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.");
 
-      double infeasibility;
-      var quality = Evaluate(assignment, weights, distances, installCosts, transportCosts, demands, capacities, out infeasibility);
+      double flowDistanceQuality, installationQuality, overbookedCapacity;
+      Evaluate(assignment, weights, distances, installCosts, demands, capacities,
+        out flowDistanceQuality, out installationQuality, out overbookedCapacity);
 
-      InfeasibilityParameter.ActualValue = new DoubleValue(infeasibility);
-      QualityParameter.ActualValue = new DoubleValue(quality.Value + penalty * infeasibility);
+      FlowDistanceQualityParameter.ActualValue = new DoubleValue(flowDistanceQuality);
+      InstallationQualityParameter.ActualValue = new DoubleValue(installationQuality);
+      OverbookedCapacityParameter.ActualValue = new DoubleValue(overbookedCapacity);
+
+      QualityParameter.ActualValue = new DoubleValue(GetCombinedQuality(flowDistanceQuality, installationQuality, overbookedCapacity, transportCosts, penalty));
       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 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPNMoveEvaluator.cs	(revision 7412)
@@ -44,9 +44,30 @@
       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<DoubleValue> MoveQualityParameter {
       get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
     }
-    public ILookupParameter<DoubleValue> MoveInfeasibilityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["MoveInfeasibility"]; }
+    public ILookupParameter<DoubleValue> MoveFlowDistanceQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveFlowDistanceQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveInstallationQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveInstallationQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveOverbookedCapacityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveOverbookedCapacity"]; }
+    }
+    public IValueLookupParameter<DoubleValue> TransportationCostsParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
+    }
+    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
     }
     public ILookupParameter<DoubleMatrix> WeightsParameter {
@@ -58,7 +79,4 @@
     public ILookupParameter<DoubleMatrix> InstallationCostsParameter {
       get { return (ILookupParameter<DoubleMatrix>)Parameters["InstallationCosts"]; }
-    }
-    public ILookupParameter<DoubleValue> TransportationCostsParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
     public ILookupParameter<DoubleArray> DemandsParameter {
@@ -77,10 +95,16 @@
       Parameters.Add(new LookupParameter<NMove>("Move", "The move to perform."));
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The solution quality."));
+      Parameters.Add(new LookupParameter<DoubleValue>("FlowDistanceQuality", "The quality regarding the flow-distance criteria."));
+      Parameters.Add(new LookupParameter<DoubleValue>("InstallationQuality", "The quality regarding the installation costs."));
+      Parameters.Add(new LookupParameter<DoubleValue>("OverbookedCapacity", "The sum of the overbooked capacities relative to the capacity of each location."));
       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<DoubleValue>("MoveFlowDistanceQuality", "The quality of the move regarding the flow-distance criteria."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveInstallationQuality", "The quality of the move regarding the installation costs."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveOverbookedCapacity", "The sum of the overbooked capacities of the move relative to the capacity of each location."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", "The multiplier for the constraint violation when added to the quality."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", "The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights or distance matrix already."));
       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."));
@@ -91,13 +115,19 @@
     }
 
-    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;
+    public static double Evaluate(NMove move, IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
+      DoubleArray demands, DoubleArray capacities, DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty) {
+      double moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity;
+      Evaluate(move, assignment, weights, distances, installationCosts, demands, capacities,
+        out moveFlowDistanceQuality, out moveInstallationQuality, out moveOverbookedCapacity);
+      return GQAPEvaluator.GetCombinedQuality(moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity,
+        transportationCosts.Value, overbookedCapacityPenalty.Value);
+    }
+
+    public static void Evaluate(NMove move, IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
+      DoubleArray demands, DoubleArray capacities, out double moveFlowDistanceQuality, out double moveInstallationQuality, out double moveOverbookedCapacity) {
+      moveFlowDistanceQuality = moveInstallationQuality = moveOverbookedCapacity = 0.0;
       int moves = move.N;
       var slack = (DoubleArray)capacities.Clone();
+      var oldSlack = (DoubleArray)slack.Clone();
       Dictionary<int, int> moving = new Dictionary<int, int>();
       for (int i = 0; i < moves; i++) moving.Add(move.Equipments[i], move.Locations[i]);
@@ -106,35 +136,56 @@
         int equip = move.Equipments[i];
         int newLoc = move.Locations[i];
-        moveQuality -= installationCosts[equip, assignment[equip]];
-        moveQuality += installationCosts[equip, newLoc];
+        moveInstallationQuality -= installationCosts[equip, assignment[equip]];
+        moveInstallationQuality += 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]]);
+            moveFlowDistanceQuality += weights[equip, j] * distances[newLoc, assignment[j]];
+            moveFlowDistanceQuality -= weights[equip, j] * distances[assignment[equip], assignment[j]];
+            moveFlowDistanceQuality += weights[j, equip] * distances[assignment[j], newLoc];
+            moveFlowDistanceQuality -= weights[j, equip] * 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];
+              oldSlack[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]]);
+            moveFlowDistanceQuality += weights[equip, j] * distances[newLoc, moving[j]];
+            moveFlowDistanceQuality -= weights[equip, j] * distances[assignment[equip], assignment[j]];
           }
         }
         slack[newLoc] -= demands[equip];
+        oldSlack[assignment[equip]] -= demands[equip];
       }
 
-      moveInfeasibility = new DoubleValue(-slack.Where(x => x < 0).Sum());
-      return new DoubleValue(moveQuality);
-
+      moveOverbookedCapacity = slack.Select((v, i) => new { V = v, Index = i }).Where(x => x.V < 0.0).Select(x => -x.V / capacities[x.Index]).Sum()
+                               - oldSlack.Select((v, i) => new { V = v, Index = i }).Where(x => x.V < 0.0).Select(x => -x.V / capacities[x.Index]).Sum();
     }
 
     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;
+      double moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity;
+      double quality = QualityParameter.ActualValue.Value;
+      double transportationCosts = TransportationCostsParameter.ActualValue.Value;
+      double overbookedCapacityPenalty = OverbookedCapacityPenaltyParameter.ActualValue.Value;
+
+      double flowDistanceQuality = FlowDistanceQualityParameter.ActualValue.Value;
+      double installationQuality = InstallationQualityParameter.ActualValue.Value;
+      double overbookedCapacity = OverbookedCapacityParameter.ActualValue.Value;
+
+      Evaluate(MoveParameter.ActualValue,
+               AssignmentParameter.ActualValue,
+               WeightsParameter.ActualValue, DistancesParameter.ActualValue,
+               InstallationCostsParameter.ActualValue,
+               DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
+               out moveFlowDistanceQuality, out moveInstallationQuality, out moveOverbookedCapacity);
+
+      MoveFlowDistanceQualityParameter.ActualValue = new DoubleValue(flowDistanceQuality + moveFlowDistanceQuality);
+      MoveInstallationQualityParameter.ActualValue = new DoubleValue(installationQuality + moveInstallationQuality);
+      MoveOverbookedCapacityParameter.ActualValue = new DoubleValue(moveOverbookedCapacity);
+
+      MoveQualityParameter.ActualValue = new DoubleValue(GQAPEvaluator.GetCombinedQuality(
+        flowDistanceQuality + moveFlowDistanceQuality,
+        installationQuality + moveInstallationQuality,
+        moveOverbookedCapacity,
+        transportationCosts,
+        overbookedCapacityPenalty));
       return base.Apply();
     }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPIntegerVectorProximityCalculator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPIntegerVectorProximityCalculator.cs	(revision 7412)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPIntegerVectorProximityCalculator.cs	(revision 7412)
@@ -0,0 +1,38 @@
+﻿#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.Encodings.IntegerVectorEncoding;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public static class GQAPIntegerVectorProximityCalculator {
+    public static double CalculateGenotypeSimilarity(IntegerVector a, IntegerVector b) {
+      int similar = 0;
+      for (int i = 0; i < a.Length; i++) {
+        if (a[i] == b[i]) similar++;
+      }
+      return similar / (double)a.Length;
+    }
+
+    public static double CalculateGenotypeDistance(IntegerVector a, IntegerVector b) {
+      return 1.0 - CalculateGenotypeSimilarity(a, b);
+    }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7412)
@@ -53,12 +53,15 @@
       get { return (ValueParameter<DoubleMatrix>)Parameters["InstallationCosts"]; }
     }
+    public ValueParameter<DoubleArray> DemandsParameter {
+      get { return (ValueParameter<DoubleArray>)Parameters["Demands"]; }
+    }
+    public ValueParameter<DoubleArray> CapacitiesParameter {
+      get { return (ValueParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
     public FixedValueParameter<DoubleValue> TransportationCostsParameter {
       get { return (FixedValueParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
-    public ValueParameter<DoubleArray> DemandsParameter {
-      get { return (ValueParameter<DoubleArray>)Parameters["Demands"]; }
-    }
-    public ValueParameter<DoubleArray> CapacitiesParameter {
-      get { return (ValueParameter<DoubleArray>)Parameters["Capacities"]; }
+    public FixedValueParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
+      get { return (FixedValueParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
     }
     public OptionalValueParameter<IItem> BestKnownSolutionParameter {
@@ -80,15 +83,19 @@
       set { InstallationCostsParameter.Value = value; }
     }
+    public DoubleArray Demands {
+      get { return DemandsParameter.Value; }
+      set { DemandsParameter.Value = value; }
+    }
+    public DoubleArray Capacities {
+      get { return CapacitiesParameter.Value; }
+      set { CapacitiesParameter.Value = value; }
+    }
     public double TransportationCosts {
       get { return TransportationCostsParameter.Value.Value; }
       set { TransportationCostsParameter.Value.Value = value; }
     }
-    public DoubleArray Demands {
-      get { return DemandsParameter.Value; }
-      set { DemandsParameter.Value = value; }
-    }
-    public DoubleArray Capacities {
-      get { return CapacitiesParameter.Value; }
-      set { CapacitiesParameter.Value = value; }
+    public double OverbookedCapacityPenalty {
+      get { return TransportationCostsParameter.Value.Value; }
+      set { TransportationCostsParameter.Value.Value = value; }
     }
     #endregion
@@ -114,4 +121,5 @@
       Parameters.Add(new ValueParameter<DoubleMatrix>("InstallationCosts", "The installation costs matrix describes the installation costs of installing equipment i at location j", new DoubleMatrix()));
       Parameters.Add(new FixedValueParameter<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.", new DoubleValue(1)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>("OverbookedCapacityPenalty", "The multiplier for the constraint violation when added to the quality.", new DoubleValue(1000)));
       Parameters.Add(new ValueParameter<DoubleArray>("Demands", "The demands vector describes the space requirements of the equipments.", new DoubleArray()));
       Parameters.Add(new ValueParameter<DoubleArray>("Capacities", "The capacities vector describes the available space at the locations.", new DoubleArray()));
@@ -183,5 +191,5 @@
     #region Helpers
     [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserializationHook() {
+    private void AfterDeserialization() {
       AttachEventHandlers();
     }
@@ -220,24 +228,34 @@
       }
       foreach (var op in Operators.OfType<IGQAPEvaluationOperator>()) {
+        op.AssignmentParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.TransportationCostsParameter.ActualName = TransportationCostsParameter.Name;
+        op.OverbookedCapacityPenaltyParameter.ActualName = OverbookedCapacityPenaltyParameter.Name;
         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.AssignmentParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+        op.FlowDistanceQualityParameter.ActualName = Evaluator.FlowDistanceQualityParameter.ActualName;
+        op.InstallationQualityParameter.ActualName = Evaluator.InstallationQualityParameter.ActualName;
+        op.OverbookedCapacityParameter.ActualName = Evaluator.OverbookedCapacityParameter.ActualName;
+        op.TransportationCostsParameter.ActualName = TransportationCostsParameter.Name;
+        op.OverbookedCapacityPenaltyParameter.ActualName = OverbookedCapacityPenaltyParameter.Name;
         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<IGQAPMerger>()) {
+        op.AssignmentParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+        op.MaximizationParameter.ActualName = MaximizationParameter.Name;
       }
       foreach (var op in Operators.OfType<IGQAPMoveOperator>()) {
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 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj	(revision 7412)
@@ -94,4 +94,6 @@
     <Compile Include="Evaluators\GQAPEvaluator.cs" />
     <Compile Include="GeneralizedQuadraticAssignmentProblem.cs" />
+    <Compile Include="GQAPIntegerVectorProximityCalculator.cs" />
+    <Compile Include="Interfaces\IGQAPMerger.cs" />
     <Compile Include="Interfaces\IGQAPNMoveEvaluator.cs" />
     <Compile Include="Interfaces\IEquipmentAwareGQAPOperator.cs" />
@@ -120,4 +122,5 @@
     <Compile Include="Operators\GQAPSolutionCreator.cs" />
     <Compile Include="Operators\GreedyRandomizedSolutionCreator.cs" />
+    <Compile Include="Operators\QualitySimilarityMerger.cs" />
     <Compile Include="Operators\RandomSolutionCreator.cs" />
     <Compile Include="Operators\RelocateEquipmentManipluator.cs" />
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluationOperator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluationOperator.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluationOperator.cs	(revision 7412)
@@ -29,8 +29,10 @@
     ILookupParameter<DoubleMatrix> DistancesParameter { get; }
     ILookupParameter<DoubleMatrix> InstallationCostsParameter { get; }
-    ILookupParameter<DoubleValue> TransportationCostsParameter { get; }
     ILookupParameter<DoubleArray> DemandsParameter { get; }
     ILookupParameter<DoubleArray> CapacitiesParameter { get; }
     ILookupParameter<IntegerVector> AssignmentParameter { get; }
+
+    IValueLookupParameter<DoubleValue> TransportationCostsParameter { get; }
+    IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter { get; }
   }
 }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluator.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluator.cs	(revision 7412)
@@ -26,5 +26,7 @@
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
   public interface IGQAPEvaluator : IGQAPEvaluationOperator, ISingleObjectiveEvaluator {
-    ILookupParameter<DoubleValue> InfeasibilityParameter { get; }
+    ILookupParameter<DoubleValue> FlowDistanceQualityParameter { get; }
+    ILookupParameter<DoubleValue> InstallationQualityParameter { get; }
+    ILookupParameter<DoubleValue> OverbookedCapacityParameter { get; }
   }
 }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPLocalImprovementOperator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPLocalImprovementOperator.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPLocalImprovementOperator.cs	(revision 7412)
@@ -28,6 +28,7 @@
   public interface IGQAPLocalImprovementOperator : IGQAPOperator, ILocalImprovementOperator {
     ILookupParameter<DoubleValue> QualityParameter { get; }
-    ILookupParameter<DoubleValue> InfeasibilityParameter { get; }
-    ILookupParameter<ResultCollection> ResultsParameter { get; }
+    ILookupParameter<DoubleValue> FlowDistanceQualityParameter { get; }
+    ILookupParameter<DoubleValue> InstallationQualityParameter { get; }
+    ILookupParameter<DoubleValue> OverbookedCapacityParameter { get; }
     IValueLookupParameter<IntValue> MaximumCandidateListSizeParameter { get; }
     IValueLookupParameter<IntValue> MaximumSampleSizeParameter { get; }
@@ -36,7 +37,8 @@
     ILookupParameter<DoubleMatrix> DistancesParameter { get; }
     ILookupParameter<DoubleMatrix> InstallationCostsParameter { get; }
-    ILookupParameter<DoubleValue> TransportationCostsParameter { get; }
     ILookupParameter<DoubleArray> DemandsParameter { get; }
     ILookupParameter<DoubleArray> CapacitiesParameter { get; }
+    IValueLookupParameter<DoubleValue> TransportationCostsParameter { get; }
+    IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter { get; }
   }
 }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMerger.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMerger.cs	(revision 7412)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMerger.cs	(revision 7412)
@@ -0,0 +1,33 @@
+﻿#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.Problems.GeneralizedQuadraticAssignment.Common;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public interface IGQAPMerger : IMerger, IGQAPOperator {
+    ILookupParameter<IntegerVector> AssignmentParameter { get; }
+    ILookupParameter<DoubleValue> QualityParameter { get; }
+    IValueLookupParameter<BoolValue> MaximizationParameter { get; }
+  }
+}
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMoveEvaluator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMoveEvaluator.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPMoveEvaluator.cs	(revision 7412)
@@ -20,7 +20,13 @@
 #endregion
 
+using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  public interface IGQAPMoveEvaluator : IGQAPEvaluationOperator, ISingleObjectiveMoveEvaluator { }
+  public interface IGQAPMoveEvaluator : IGQAPEvaluationOperator, ISingleObjectiveMoveEvaluator {
+    ILookupParameter<DoubleValue> FlowDistanceQualityParameter { get; }
+    ILookupParameter<DoubleValue> InstallationQualityParameter { get; }
+    ILookupParameter<DoubleValue> OverbookedCapacityParameter { get; }
+  }
 }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/NMoveMaker.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/NMoveMaker.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/NMoveMaker.cs	(revision 7412)
@@ -42,12 +42,24 @@
       get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
     }
-    public ILookupParameter<DoubleValue> InfeasibilityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Infeasibility"]; }
+    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<DoubleValue> MoveQualityParameter {
       get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
     }
-    public ILookupParameter<DoubleValue> MoveInfeasibilityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["MoveInfeasibility"]; }
+    public ILookupParameter<DoubleValue> MoveFlowDistanceQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveFlowDistanceQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveInstallationQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveInstallationQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveOverbookedCapacityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveOverbookedCapacity"]; }
     }
 
@@ -60,7 +72,11 @@
       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>("FlowDistanceQuality", "The quality regarding the flow-distance criteria."));
+      Parameters.Add(new LookupParameter<DoubleValue>("InstallationQuality", "The quality regarding the installation costs."));
+      Parameters.Add(new LookupParameter<DoubleValue>("OverbookedCapacity", "The sum of the overbooked capacities relative to the capacity of each location."));
       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<DoubleValue>("MoveFlowDistanceQuality", "The quality of the move regarding the flow-distance criteria."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveInstallationQuality", "The quality of the move regarding the installation costs."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveOverbookedCapacity", "The sum of the overbooked capacities of the move relative to the capacity of each location."));
     }
 
@@ -78,5 +94,7 @@
       Apply(AssignmentParameter.ActualValue, MoveParameter.ActualValue);
       QualityParameter.ActualValue.Value = MoveQualityParameter.ActualValue.Value;
-      InfeasibilityParameter.ActualValue.Value = MoveInfeasibilityParameter.ActualValue.Value;
+      FlowDistanceQualityParameter.ActualValue.Value = MoveFlowDistanceQualityParameter.ActualValue.Value;
+      InstallationQualityParameter.ActualValue.Value = MoveInstallationQualityParameter.ActualValue.Value;
+      OverbookedCapacityParameter.ActualValue.Value = MoveOverbookedCapacityParameter.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 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveMultiMoveGenerator.cs	(revision 7412)
@@ -60,5 +60,5 @@
     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);
+        yield return StochasticNMoveSingleMoveGenerator.GenerateUpToN(random, assignment, n, capacities);
     }
 
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveSingleMoveGenerator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveSingleMoveGenerator.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveSingleMoveGenerator.cs	(revision 7412)
@@ -54,9 +54,12 @@
     }
 
-    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];
+    public static NMove GenerateUpToN(IRandom random, IntegerVector assignment, int n, DoubleArray capacities) {
+      return GenerateExactlyN(random, assignment, random.Next(n) + 1, capacities);
+    }
+
+    public static NMove GenerateExactlyN(IRandom random, IntegerVector assignment, int n, DoubleArray capacities) {
+      int[] equipments = new int[n], locations = new int[n];
       HashSet<int> chosenEquipments = new HashSet<int>();
-      for (int i = 0; i < moving; i++) {
+      for (int i = 0; i < n; i++) {
         do {
           equipments[i] = random.Next(assignment.Length);
@@ -71,5 +74,5 @@
 
     public override IEnumerable<NMove> GenerateMoves(IntegerVector assignment, int n) {
-      yield return Generate(RandomParameter.ActualValue, assignment, n, CapacitiesParameter.ActualValue);
+      yield return GenerateUpToN(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 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/ApproximateLocalSearch.cs	(revision 7412)
@@ -55,6 +55,12 @@
       get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
     }
-    public ILookupParameter<DoubleValue> InfeasibilityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Infeasibility"]; }
+    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<ResultCollection> ResultsParameter {
@@ -79,7 +85,4 @@
       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"]; }
@@ -88,5 +91,13 @@
       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"]; }
+    }
+    public IValueLookupParameter<PercentValue> OneMoveProbabilityParameter {
+      get { return (IValueLookupParameter<PercentValue>)Parameters["OneMoveProbability"]; }
+    }
 
     [StorableConstructor]
@@ -99,5 +110,7 @@
       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<DoubleValue>("FlowDistanceQuality", "The quality regarding the flow-distance criteria."));
+      Parameters.Add(new LookupParameter<DoubleValue>("InstallationQuality", "The quality regarding the installation costs."));
+      Parameters.Add(new LookupParameter<DoubleValue>("OverbookedCapacity", "The sum of the overbooked capacities relative to the capacity of each location."));
       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)));
@@ -107,7 +120,9 @@
       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."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", "The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights matrix already."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", "The multiplier for the constraint violation when added to the quality."));
+      Parameters.Add(new ValueLookupParameter<PercentValue>("OneMoveProbability", "The probability for performing a 1-move, which is the opposite of performing a 2-move.", new PercentValue(.5)));
     }
 
@@ -124,42 +139,54 @@
     /// <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="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="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="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>
-    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) {
+    /// <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 maxSampleSize, IntValue maximumIterations,
+      DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts, DoubleArray demands, DoubleArray capacities,
+      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty, PercentValue oneMoveProbability) {
+
       for (int i = 0; i < maximumIterations.Value; i++) {
         int count = 0;
-        var CLS = new List<Tuple<NMove, DoubleValue, DoubleValue>>();
+        var CLS = new List<Tuple<NMove, double, double, double, double>>();
         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;
+          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 < maxSampleSize.Value);
-        if (CLS.Count == 0) return; // END
+
+        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;
+            ball -= 1.0 / candidate.Item2;
             if (ball <= 0.0) {
               selected = candidate;
@@ -168,6 +195,8 @@
           }
           NMoveMaker.Apply(assignment, selected.Item1);
-          quality.Value = selected.Item2.Value;
-          infeasibility.Value = selected.Item3.Value;
+          quality.Value += selected.Item2;
+          flowDistanceQuality.Value += selected.Item3;
+          installationQuality.Value += selected.Item4;
+          overbookedCapacity.Value += selected.Item5;
         }
       }
@@ -178,12 +207,16 @@
         AssignmentParameter.ActualValue,
         QualityParameter.ActualValue,
-        InfeasibilityParameter.ActualValue,
+        FlowDistanceQualityParameter.ActualValue,
+        InstallationQualityParameter.ActualValue,
+        OverbookedCapacityParameter.ActualValue,
         MaximumCandidateListSizeParameter.ActualValue,
         MaximumSampleSizeParameter.ActualValue,
         MaximumIterationsParameter.ActualValue,
-        DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
         WeightsParameter.ActualValue, DistancesParameter.ActualValue,
         InstallationCostsParameter.ActualValue,
-        TransportationCostsParameter.ActualValue);
+        DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
+        TransportationCostsParameter.ActualValue,
+        OverbookedCapacityPenaltyParameter.ActualValue,
+        OneMoveProbabilityParameter.ActualValue);
       return base.Apply();
     }
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GreedyRandomizedSolutionCreator.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GreedyRandomizedSolutionCreator.cs	(revision 7411)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GreedyRandomizedSolutionCreator.cs	(revision 7412)
@@ -60,5 +60,5 @@
       while (tries < maxTries) {
         assignment.Clear();
-        demands.Select((v, i) => slack[i] = v).Enumerate();
+        capacities.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)
Index: /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/QualitySimilarityMerger.cs
===================================================================
--- /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/QualitySimilarityMerger.cs	(revision 7412)
+++ /branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/QualitySimilarityMerger.cs	(revision 7412)
@@ -0,0 +1,120 @@
+﻿#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.Operators {
+  [Item("QualitySimilarityMerger", "Merges two populations by using quality and similarity information to maintain a population of high quality, but also diverse solutions.")]
+  [StorableClass]
+  public class QualitySimilarityMerger : SingleSuccessorOperator, IGQAPMerger {
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<IntValue> PopulationSizeParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["PopulationSize"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    [StorableConstructor]
+    protected QualitySimilarityMerger(bool deserializing) : base(deserializing) { }
+    protected QualitySimilarityMerger(QualitySimilarityMerger original, Cloner cloner) : base(original, cloner) { }
+    public QualitySimilarityMerger()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", "The equipment-location assignment."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of a solution."));
+      Parameters.Add(new LookupParameter<IntValue>("PopulationSize", "The size of the population that should not be surpassed."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is to be maximized, false otherwise."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QualitySimilarityMerger(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      string vectorName = AssignmentParameter.TranslatedName;
+      string qualityName = QualityParameter.TranslatedName;
+      int populationSize = PopulationSizeParameter.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 => GQAPIntegerVectorProximityCalculator.CalculateGenotypeSimilarity(x.Solution, candidate.Solution)).ToArray();
+        if (!similarities.Any()) {
+          population.Add(candidate);
+        } else if (population.Count < populationSize) {
+          double maxSimilarity = similarities.Max();
+          if (maxSimilarity < 1.0)
+            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: /branches/GeneralizedQAP/Local.testsettings
===================================================================
--- /branches/GeneralizedQAP/Local.testsettings	(revision 7412)
+++ /branches/GeneralizedQAP/Local.testsettings	(revision 7412)
@@ -0,0 +1,10 @@
+﻿<?xml version="1.0" encoding="UTF-8"?>
+<TestSettings name="Local" id="0c5645ea-4f25-4faf-bdb6-6c685aa774f5" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
+  <Description>These are default test settings for a local test run.</Description>
+  <Deployment enabled="false" />
+  <Execution>
+    <TestTypeSpecific />
+    <AgentRule name="Execution Agents">
+    </AgentRule>
+  </Execution>
+</TestSettings>
Index: /branches/GeneralizedQAP/TraceAndTestImpact.testsettings
===================================================================
--- /branches/GeneralizedQAP/TraceAndTestImpact.testsettings	(revision 7412)
+++ /branches/GeneralizedQAP/TraceAndTestImpact.testsettings	(revision 7412)
@@ -0,0 +1,21 @@
+﻿<?xml version="1.0" encoding="UTF-8"?>
+<TestSettings name="Trace and Test Impact" id="1b0a510d-00b5-4c99-ad69-f328d7dff428" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
+  <Description>These are test settings for Trace and Test Impact.</Description>
+  <Execution>
+    <TestTypeSpecific />
+    <AgentRule name="Execution Agents">
+      <DataCollectors>
+        <DataCollector uri="datacollector://microsoft/SystemInfo/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo.SystemInfoDataCollector, Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="System Information">
+        </DataCollector>
+        <DataCollector uri="datacollector://microsoft/ActionLog/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TestTools.ManualTest.ActionLog.ActionLogPlugin, Microsoft.VisualStudio.TestTools.ManualTest.ActionLog, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="Actions">
+        </DataCollector>
+        <DataCollector uri="datacollector://microsoft/HttpProxy/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.HttpProxyCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="ASP.NET Client Proxy for IntelliTrace and Test Impact">
+        </DataCollector>
+        <DataCollector uri="datacollector://microsoft/TestImpact/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.TestImpactDataCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="Test Impact">
+        </DataCollector>
+        <DataCollector uri="datacollector://microsoft/TraceDebugger/1.0" assemblyQualifiedName="Microsoft.VisualStudio.TraceCollector.TraceDebuggerDataCollector, Microsoft.VisualStudio.TraceCollector, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" friendlyName="IntelliTrace">
+        </DataCollector>
+      </DataCollectors>
+    </AgentRule>
+  </Execution>
+</TestSettings>
Index: /branches/GeneralizedQAP/UnitTests/GQAPNMoveEvaluatorTest.cs
===================================================================
--- /branches/GeneralizedQAP/UnitTests/GQAPNMoveEvaluatorTest.cs	(revision 7412)
+++ /branches/GeneralizedQAP/UnitTests/GQAPNMoveEvaluatorTest.cs	(revision 7412)
@@ -0,0 +1,145 @@
+﻿#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.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Problems.GeneralizedQuadraticAssignment;
+using HeuristicLab.Random;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace UnitTests {
+  /// <summary>
+  ///This is a test class for GQAPNMoveEvaluatorTest and is intended
+  ///to contain all GQAPNMoveEvaluatorTest Unit Tests
+  ///</summary>
+  [TestClass()]
+  public class GQAPNMoveEvaluatorTest {
+    private const int Equipments = 10, Locations = 5;
+    private static DoubleMatrix symmetricWeights, asymmetricWeights, nonZeroDiagonalWeights;
+    private static DoubleMatrix symmetricDistances, asymmetricDistances, nonZeroDiagonalDistances;
+    private static DoubleMatrix installationCosts;
+    private static DoubleArray demands, capacities;
+    private static DoubleValue transportationCosts, overbookedCapacityPenalty;
+    private static IntegerVector assignment;
+    private static MersenneTwister random;
+
+    private TestContext testContextInstance;
+
+    /// <summary>
+    ///Gets or sets the test context which provides
+    ///information about and functionality for the current test run.
+    ///</summary>
+    public TestContext TestContext {
+      get { return testContextInstance; }
+      set { testContextInstance = value; }
+    }
+
+    #region Additional test attributes
+    [ClassInitialize()]
+    public static void MyClassInitialize(TestContext testContext) {
+      random = new MersenneTwister();
+      symmetricDistances = new DoubleMatrix(Locations, Locations);
+      symmetricWeights = new DoubleMatrix(Equipments, Equipments);
+      asymmetricDistances = new DoubleMatrix(Locations, Locations);
+      asymmetricWeights = new DoubleMatrix(Equipments, Equipments);
+      nonZeroDiagonalDistances = new DoubleMatrix(Locations, Locations);
+      nonZeroDiagonalWeights = new DoubleMatrix(Equipments, Equipments);
+      for (int i = 0; i < Equipments - 1; i++) {
+        for (int j = i + 1; j < Equipments; j++) {
+          symmetricWeights[i, j] = random.Next(Equipments * 100);
+          symmetricWeights[j, i] = symmetricWeights[i, j];
+          asymmetricWeights[i, j] = random.Next(Equipments * 100);
+          asymmetricWeights[j, i] = random.Next(Equipments * 100);
+          nonZeroDiagonalWeights[i, j] = random.Next(Equipments * 100);
+          nonZeroDiagonalWeights[j, i] = random.Next(Equipments * 100);
+        }
+        nonZeroDiagonalWeights[i, i] = random.Next(Equipments * 100);
+      }
+      for (int i = 0; i < Locations - 1; i++) {
+        for (int j = i + 1; j < Locations; j++) {
+          symmetricDistances[i, j] = random.Next(Locations * 100);
+          symmetricDistances[j, i] = symmetricDistances[i, j];
+          asymmetricDistances[i, j] = random.Next(Locations * 100);
+          asymmetricDistances[j, i] = random.Next(Locations * 100);
+          nonZeroDiagonalDistances[i, j] = random.Next(Locations * 100);
+          nonZeroDiagonalDistances[j, i] = random.Next(Locations * 100);
+        }
+        nonZeroDiagonalDistances[i, i] = random.Next(Locations * 100);
+      }
+      installationCosts = new DoubleMatrix(Equipments, Locations);
+      for (int i = 0; i < Equipments; i++) {
+        for (int j = 0; j < Locations; j++) {
+          installationCosts[i, j] = random.Next(0, 10);
+        }
+      }
+      demands = new DoubleArray(Equipments);
+      for (int i = 0; i < Equipments; i++) {
+        demands[i] = random.Next(1, 10);
+      }
+      capacities = new DoubleArray(Locations);
+      for (int j = 0; j < Locations; j++) {
+        capacities[j] = random.Next(1, 10) * ((double)Equipments / (double)Locations) * 1.5;
+      }
+      int index = random.Next(Locations);
+      if (nonZeroDiagonalDistances[index, index] == 0)
+        nonZeroDiagonalDistances[index, index] = random.Next(1, Equipments * 100);
+      index = random.Next(Equipments);
+      if (nonZeroDiagonalWeights[index, index] == 0)
+        nonZeroDiagonalWeights[index, index] = random.Next(1, Equipments * 100);
+
+      transportationCosts = new DoubleValue(random.NextDouble() * 10);
+      overbookedCapacityPenalty = new DoubleValue(1000 * random.NextDouble() + 100);
+      assignment = new IntegerVector(Equipments, random, 0, Locations);
+    }
+    #endregion
+
+
+    /// <summary>
+    ///A test for Evaluate
+    ///</summary>
+    [TestMethod()]
+    public void EvaluateTest() {
+      for (int i = 0; i < 500; i++) {
+        NMove currentMove = StochasticNMoveSingleMoveGenerator.GenerateUpToN(random, assignment, 3, capacities);
+        IntegerVector prevAssignment = (IntegerVector)assignment.Clone();
+        NMoveMaker.Apply(assignment, currentMove);
+        double before = GQAPEvaluator.Evaluate(prevAssignment, symmetricWeights, symmetricDistances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        double after = GQAPEvaluator.Evaluate(assignment, symmetricWeights, symmetricDistances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        double moveDiff = GQAPNMoveEvaluator.Evaluate(currentMove, prevAssignment, symmetricWeights, symmetricDistances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        Assert.IsTrue(Math.Abs(moveDiff - (after - before)) < 1e-07, "Failed on symmetric matrices: " + Environment.NewLine
+          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveDiff + ".");
+
+        before = GQAPEvaluator.Evaluate(prevAssignment, asymmetricWeights, asymmetricDistances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        after = GQAPEvaluator.Evaluate(assignment, asymmetricWeights, asymmetricDistances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        moveDiff = GQAPNMoveEvaluator.Evaluate(currentMove, prevAssignment, asymmetricWeights, asymmetricDistances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        Assert.IsTrue(Math.Abs(moveDiff - (after - before)) < 1e-07, "Failed on asymmetric matrices: " + Environment.NewLine
+          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveDiff + ".");
+
+        before = GQAPEvaluator.Evaluate(prevAssignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        after = GQAPEvaluator.Evaluate(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        moveDiff = GQAPNMoveEvaluator.Evaluate(currentMove, prevAssignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        Assert.IsTrue(Math.Abs(moveDiff - (after - before)) < 1e-07, "Failed on non-zero diagonal matrices: " + Environment.NewLine
+          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveDiff + ".");
+      }
+    }
+  }
+}
Index: /branches/GeneralizedQAP/UnitTests/Properties/AssemblyInfo.cs
===================================================================
--- /branches/GeneralizedQAP/UnitTests/Properties/AssemblyInfo.cs	(revision 7412)
+++ /branches/GeneralizedQAP/UnitTests/Properties/AssemblyInfo.cs	(revision 7412)
@@ -0,0 +1,35 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("UnitTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("UnitTests")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d1aed2b9-c97a-4b01-a5eb-7495664d1e5c")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: /branches/GeneralizedQAP/UnitTests/UnitTests.csproj
===================================================================
--- /branches/GeneralizedQAP/UnitTests/UnitTests.csproj	(revision 7412)
+++ /branches/GeneralizedQAP/UnitTests/UnitTests.csproj	(revision 7412)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>
+    </ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{68C6C157-08DA-414F-9256-CCCA13038399}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>UnitTests</RootNamespace>
+    <AssemblyName>UnitTests</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.IntegerVectorEncoding-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Encodings.IntegerVectorEncoding-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+  </ItemGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="GQAPNMoveEvaluatorTest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common\3.3\HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common-3.3.csproj">
+      <Project>{DA367BE5-4F53-4243-933B-32AAB86189D5}</Project>
+      <Name>HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Problems.GeneralizedQuadraticAssignment\3.3\HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj">
+      <Project>{C739E6D2-5680-4804-A810-8017DA0C238F}</Project>
+      <Name>HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
