Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentArchiveView.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentArchiveView.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentArchiveView.cs	(revision 7970)
@@ -101,5 +101,5 @@
       if (h.ChartElementType == ChartElementType.DataPoint) {
         var solution = (GQAPSolution)((DataPoint)h.Object).Tag;
-        var assignment = new GQAPAssignment(solution.Assignment, solution.Quality, solution.FlowDistanceQuality, solution.InstallationQuality, solution.OverbookedCapacity, Content.EquipmentNames, Content.LocationNames, Content.Distances, Content.Weights, Content.InstallationCosts, Content.Demands, Content.Capacities, Content.TransportationCosts, Content.OverbookedCapacityPenalty);
+        var assignment = new GQAPAssignment(solution.Assignment, solution.Quality, solution.FlowDistanceQuality, solution.InstallationQuality, solution.OverbookedCapacity, Content.EquipmentNames, Content.LocationNames, Content.Distances, Content.Weights, Content.InstallationCosts, Content.Demands, Content.Capacities, Content.TransportationCosts, Content.ExpectedRandomQuality, Content.Evaluator);
 
         var view = MainFormManager.MainForm.ShowContent(assignment);
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentView.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentView.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Views/3.3/GQAPAssignmentView.cs	(revision 7970)
@@ -315,5 +315,5 @@
     private void recalculateButton_Click(object sender, EventArgs e) {
       double fdq, iq, oc;
-      GQAPEvaluator.Evaluate(Content.Assignment, Content.Weights,
+      Content.Evaluator.Evaluate(Content.Assignment, Content.Weights,
         Content.Distances, Content.InstallationCosts, Content.Demands,
         Content.Capacities, out fdq, out iq, out oc);
@@ -322,6 +322,6 @@
       Content.OverbookedCapacity = new DoubleValue(oc);
       Content.Quality = new DoubleValue(
-        GQAPEvaluator.GetCombinedQuality(fdq, iq, oc,
-        Content.TransportationCosts.Value, Content.OverbookedCapacityPenalty.Value));
+        Content.Evaluator.GetFitness(fdq, iq, oc,
+        Content.TransportationCosts.Value, Content.ExpectedRandomQuality.Value));
     }
   }
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/BestGQAPSolutionAnalyzer.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/BestGQAPSolutionAnalyzer.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/BestGQAPSolutionAnalyzer.cs	(revision 7970)
@@ -29,5 +29,4 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
@@ -40,6 +39,7 @@
     IQualitiesAwareGQAPOperator, IDistancesAwareGQAPOperator, IWeightsAwareGQAPOperator, IInstallationCostsAwareGQAPOperator,
     IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator, ITransportationCostsAwareGQAPOperator,
-    IOverbookedCapacityPenaltyAwareGQAPOperator, IEquipmentNamesAwareGQAPOperator, ILocationNamesAwareGQAPOperator,
-    IBestKnownQualityAwareGQAPOperator, IBestKnownSolutionAwareGQAPOperator, IAnalyzer {
+    IExpectedRandomQualityAwareGQAPOperator, IEquipmentNamesAwareGQAPOperator, ILocationNamesAwareGQAPOperator,
+    IBestKnownQualityAwareGQAPOperator, IBestKnownSolutionAwareGQAPOperator,
+    IEvaluatorAwareGQAPOperator, IAnalyzer {
 
     public bool EnabledByDefault {
@@ -84,6 +84,6 @@
       get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
-    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
-      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    public IValueLookupParameter<DoubleValue> ExpectedRandomQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["ExpectedRandomQuality"]; }
     }
     public ILookupParameter<StringArray> EquipmentNamesParameter {
@@ -104,4 +104,7 @@
     public IValueLookupParameter<ResultCollection> ResultsParameter {
       get { return (IValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IGQAPEvaluator>)Parameters["Evaluator"]; }
     }
     #endregion
@@ -122,5 +125,5 @@
       Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ExpectedRandomQuality", GeneralizedQuadraticAssignmentProblem.ExpectedRandomQualityDescription));
       Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription));
@@ -134,7 +137,9 @@
       Parameters.Add(new LookupParameter<GQAPAssignment>("BestSolution", "The best GQAP solution found so far."));
       Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the best GQAP solution should be stored."));
+      Parameters.Add(new ValueLookupParameter<IGQAPEvaluator>("Evaluator", "The evaluator that is used to evaluate GQAP solutions."));
     }
 
     public override IOperation Apply() {
+      var evaluator = EvaluatorParameter.ActualValue;
       var assignments = AssignmentParameter.ActualValue;
       var qualities = QualityParameter.ActualValue;
@@ -150,5 +155,5 @@
       var capacities = CapacitiesParameter.ActualValue;
       var transportationCosts = TransportationCostsParameter.ActualValue;
-      var overbookedCapacityPenalty = OverbookedCapacityPenaltyParameter.ActualValue;
+      var expectedRandomQuality = ExpectedRandomQualityParameter.ActualValue;
       var results = ResultsParameter.ActualValue;
       var maximization = MaximizationParameter.ActualValue.Value;
@@ -162,10 +167,10 @@
       if (bestKnownQuality == null || HasSolutionImproved(bestKnownQuality.Value, qualities[bestIndex].Value, maximization)) {
         BestKnownQualityParameter.ActualValue = new DoubleValue(qualities[bestIndex].Value);
-        BestKnownSolutionParameter.ActualValue = new GQAPAssignment((IntegerVector)assignments[bestIndex].Clone(), (DoubleValue)qualities[bestIndex].Clone(), flowDistanceQualities[bestIndex], installationQualities[bestIndex], overbookedCapacities[bestIndex], equipmentNames, locationNames, distances, weights, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        BestKnownSolutionParameter.ActualValue = new GQAPAssignment((IntegerVector)assignments[bestIndex].Clone(), (DoubleValue)qualities[bestIndex].Clone(), flowDistanceQualities[bestIndex], installationQualities[bestIndex], overbookedCapacities[bestIndex], equipmentNames, locationNames, distances, weights, installationCosts, demands, capacities, transportationCosts, expectedRandomQuality, evaluator);
       }
 
       var assignment = BestSolutionParameter.ActualValue;
       if (assignment == null) {
-        assignment = new GQAPAssignment((IntegerVector)assignments[bestIndex].Clone(), (DoubleValue)qualities[bestIndex].Clone(), flowDistanceQualities[bestIndex], installationQualities[bestIndex], overbookedCapacities[bestIndex], equipmentNames, locationNames, distances, weights, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        assignment = new GQAPAssignment((IntegerVector)assignments[bestIndex].Clone(), (DoubleValue)qualities[bestIndex].Clone(), flowDistanceQualities[bestIndex], installationQualities[bestIndex], overbookedCapacities[bestIndex], equipmentNames, locationNames, distances, weights, installationCosts, demands, capacities, transportationCosts, expectedRandomQuality, evaluator);
         assignment.Distances = distances;
         BestSolutionParameter.ActualValue = assignment;
@@ -185,5 +190,6 @@
           assignment.Capacities = capacities;
           assignment.TransportationCosts = transportationCosts;
-          assignment.OverbookedCapacityPenalty = overbookedCapacityPenalty;
+          assignment.ExpectedRandomQuality = expectedRandomQuality;
+          assignment.Evaluator = evaluator;
         }
       }
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/GQAPSolutionArchiveAnalyzer.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/GQAPSolutionArchiveAnalyzer.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Analyzers/GQAPSolutionArchiveAnalyzer.cs	(revision 7970)
@@ -39,6 +39,6 @@
     IQualitiesAwareGQAPOperator, IDistancesAwareGQAPOperator, IWeightsAwareGQAPOperator, IInstallationCostsAwareGQAPOperator,
     IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator, ITransportationCostsAwareGQAPOperator,
-    IOverbookedCapacityPenaltyAwareGQAPOperator, IEquipmentNamesAwareGQAPOperator, ILocationNamesAwareGQAPOperator,
-    IBestKnownSolutionsAwareGQAPOperator, IAnalyzer {
+    IExpectedRandomQualityAwareGQAPOperator, IEquipmentNamesAwareGQAPOperator, ILocationNamesAwareGQAPOperator,
+    IBestKnownSolutionsAwareGQAPOperator, IEvaluatorAwareGQAPOperator, IAnalyzer {
 
     public bool EnabledByDefault {
@@ -82,6 +82,6 @@
       get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
-    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
-      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    public IValueLookupParameter<DoubleValue> ExpectedRandomQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["ExpectedRandomQuality"]; }
     }
     public ILookupParameter<StringArray> EquipmentNamesParameter {
@@ -96,4 +96,7 @@
     public ILookupParameter<GQAPAssignmentArchive> BestKnownSolutionsParameter {
       get { return (ILookupParameter<GQAPAssignmentArchive>)Parameters["BestKnownSolutions"]; }
+    }
+    public IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IGQAPEvaluator>)Parameters["Evaluator"]; }
     }
 
@@ -113,5 +116,5 @@
       Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ExpectedRandomQuality", GeneralizedQuadraticAssignmentProblem.ExpectedRandomQualityDescription));
       Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", GQAPEvaluator.QualityDescription));
@@ -123,7 +126,9 @@
       Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the best GQAP solution should be stored."));
       Parameters.Add(new LookupParameter<GQAPAssignmentArchive>("BestKnownSolutions", GeneralizedQuadraticAssignmentProblem.BestKnownSolutionsDescription));
+      Parameters.Add(new ValueLookupParameter<IGQAPEvaluator>("Evaluator", "The evaluator that is used to evaluate GQAP solutions."));
     }
 
     public override IOperation Apply() {
+      var evaluator = EvaluatorParameter.ActualValue;
       var assignments = AssignmentParameter.ActualValue;
       var qualities = QualityParameter.ActualValue;
@@ -139,5 +144,5 @@
       var capacities = CapacitiesParameter.ActualValue;
       var transportationCosts = TransportationCostsParameter.ActualValue;
-      var overbookedCapacityPenalty = OverbookedCapacityPenaltyParameter.ActualValue;
+      var expectedRandomQuality = ExpectedRandomQualityParameter.ActualValue;
       var results = ResultsParameter.ActualValue;
       var maximization = MaximizationParameter.ActualValue.Value;
@@ -145,5 +150,5 @@
       GQAPAssignmentArchive archive = results.ContainsKey("Solution Archive") ? results["Solution Archive"].Value as GQAPAssignmentArchive : null;
       if (archive == null) {
-        archive = new GQAPAssignmentArchive(equipmentNames, locationNames, distances, weights, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+        archive = new GQAPAssignmentArchive(equipmentNames, locationNames, distances, weights, installationCosts, demands, capacities, transportationCosts, expectedRandomQuality, evaluator);
         results.Add(new Result("Solution Archive", archive));
       } else {
@@ -156,5 +161,6 @@
         archive.Capacities = capacities;
         archive.TransportationCosts = transportationCosts;
-        archive.OverbookedCapacityPenalty = overbookedCapacityPenalty;
+        archive.ExpectedRandomQuality = expectedRandomQuality;
+        archive.Evaluator = evaluator;
       }
 
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPAdditivePenaltyEvaluator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPAdditivePenaltyEvaluator.cs	(revision 7970)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPAdditivePenaltyEvaluator.cs	(revision 7970)
@@ -0,0 +1,63 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("GQAPAdditivePenaltyEvaluator", "Evaluates solutions to the generalized quadratic assignment problem using an additive penalty strategy. The overbooked capacities are multiplied by the penalty and added to the quality.")]
+  [StorableClass]
+  public class GQAPAdditivePenaltyEvaluator : GQAPEvaluator {
+    public static readonly string OverbookedCapacityPenaltyDescription = "The multiplier for the constraint violation when added to the quality.";
+
+    protected IValueParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    }
+
+    public DoubleValue OverbookedCapacity {
+      get { return OverbookedCapacityPenaltyParameter.Value; }
+      set { OverbookedCapacityPenaltyParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected GQAPAdditivePenaltyEvaluator(bool deserializing) : base(deserializing) { }
+    protected GQAPAdditivePenaltyEvaluator(GQAPAdditivePenaltyEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public GQAPAdditivePenaltyEvaluator()
+      : base() {
+      Parameters.Add(new ValueParameter<DoubleValue>("OverbookedCapacityPenalty", OverbookedCapacityPenaltyDescription, new DoubleValue(1000000), true));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GQAPAdditivePenaltyEvaluator(this, cloner);
+    }
+
+    public override double GetFitness(double flowDistanceQuality,
+      double installationQuality, double overbookedCapacity,
+      double transportationCosts, double expectedRandomQuality) {
+      return installationQuality
+        + transportationCosts * flowDistanceQuality
+        + OverbookedCapacity.Value * overbookedCapacity;
+    }
+  }
+}
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPEvaluator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPEvaluator.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPEvaluator.cs	(revision 7970)
@@ -31,9 +31,10 @@
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  [Item("GQAPEvaluator", "Evaluates solutions to the generalized quadratic assignment problem.")]
+  [Item("GQAPEvaluator", "Base class for solution evaluators for the generalized quadratic assignment problem.")]
   [StorableClass]
-  public class GQAPEvaluator : SingleSuccessorOperator, IGQAPEvaluator,
+  public abstract class GQAPEvaluator : SingleSuccessorOperator, IGQAPEvaluator,
   IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator, IInstallationCostsAwareGQAPOperator,
-  IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator, IAssignmentAwareGQAPOperator {
+  IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator, IAssignmentAwareGQAPOperator,
+  IExpectedRandomQualityAwareGQAPOperator {
 
     #region Parameter Descriptions
@@ -62,6 +63,6 @@
       get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
-    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
-      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    public IValueLookupParameter<DoubleValue> ExpectedRandomQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["ExpectedRandomQuality"]; }
     }
     public ILookupParameter<DoubleMatrix> WeightsParameter {
@@ -87,6 +88,5 @@
     protected GQAPEvaluator(bool deserializing) : base(deserializing) { }
     protected GQAPEvaluator(GQAPEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public GQAPEvaluator()
-      : base() {
+    public GQAPEvaluator() : base() {
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", QualityDescription));
@@ -95,5 +95,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("OverbookedCapacity", OverbookedCapacityDescription));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ExpectedRandomQuality", GeneralizedQuadraticAssignmentProblem.ExpectedRandomQualityDescription));
       Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", GeneralizedQuadraticAssignmentProblem.WeightsDescription));
       Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", GeneralizedQuadraticAssignmentProblem.DistancesDescription));
@@ -104,21 +104,18 @@
     }
 
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new GQAPEvaluator(this, cloner);
-    }
-
-    public static double Evaluate(IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances,
-                                  DoubleMatrix installCosts, DoubleArray demands, DoubleArray capacities,
-                                  DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty) {
+    public virtual double Evaluate(IntegerVector assignment, DoubleMatrix weights,
+      DoubleMatrix distances, DoubleMatrix installCosts, DoubleArray demands,
+      DoubleArray capacities, double transportationCosts, double expectedRandomQuality) {
       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);
+      return GetFitness(flowDistanceQuality, installationQuality, overbookedCapacity,
+        transportationCosts, expectedRandomQuality);
     }
 
-    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) {
+    public virtual 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;
@@ -135,14 +132,11 @@
     }
 
-    public static double EvaluateOverbooking(DoubleArray slack, DoubleArray capacities) {
-      return slack.Select((v, i) => new { V = v, Index = i }).Where(x => x.V < 0.0).Select(x => -x.V / capacities[x.Index]).Sum();
+    public virtual double EvaluateOverbooking(DoubleArray slack, DoubleArray capacities) {
+      return slack.Select((v, i) => new { V = v, Index = i }).Where(x => x.V < 0.0).Select(x => -100.0 * x.V / capacities[x.Index]).Sum();
     }
 
-    public static double GetCombinedQuality(double flowDistanceQuality, double installationQuality, double overbookedCapacity,
-      double transportationCosts, double overbookedCapacityPenalty) {
-      return installationQuality
-        + transportationCosts * flowDistanceQuality
-        + overbookedCapacityPenalty * overbookedCapacity;
-    }
+    public abstract double GetFitness(double flowDistanceQuality,
+      double installationQuality, double overbookedCapacity,
+      double transportationCosts, double expectedRandomQuality);
 
     public override IOperation Apply() {
@@ -154,5 +148,5 @@
       var capacities = CapacitiesParameter.ActualValue;
       var transportCosts = TransportationCostsParameter.ActualValue.Value;
-      double penalty = OverbookedCapacityPenaltyParameter.ActualValue.Value;
+      var expectedRandomQuality = ExpectedRandomQualityParameter.ActualValue.Value;
 
       if (weights.Rows != weights.Columns || distances.Rows != distances.Columns
@@ -169,5 +163,5 @@
       OverbookedCapacityParameter.ActualValue = new DoubleValue(overbookedCapacity);
 
-      QualityParameter.ActualValue = new DoubleValue(GetCombinedQuality(flowDistanceQuality, installationQuality, overbookedCapacity, transportCosts, penalty));
+      QualityParameter.ActualValue = new DoubleValue(GetFitness(flowDistanceQuality, installationQuality, overbookedCapacity, transportCosts, expectedRandomQuality));
       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 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPNMoveEvaluator.cs	(revision 7970)
@@ -20,5 +20,4 @@
 #endregion
 
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -35,6 +34,7 @@
   public class GQAPNMoveEvaluator : SingleSuccessorOperator, IGQAPNMoveEvaluator, IAssignmentAwareGQAPOperator,
   IQualityAwareGQAPOperator, ITransportationCostsAwareGQAPOperator,
-  IOverbookedCapacityPenaltyAwareGQAPOperator, IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator,
-  IInstallationCostsAwareGQAPOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator {
+  IExpectedRandomQualityAwareGQAPOperator, IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator,
+  IInstallationCostsAwareGQAPOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator,
+  IEvaluatorAwareGQAPOperator {
 
     #region Parameter Descriptions
@@ -94,6 +94,6 @@
       get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
-    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
-      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    public IValueLookupParameter<DoubleValue> ExpectedRandomQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["ExpectedRandomQuality"]; }
     }
     public ILookupParameter<DoubleMatrix> WeightsParameter {
@@ -111,4 +111,7 @@
     public ILookupParameter<DoubleArray> CapacitiesParameter {
       get { return (ILookupParameter<DoubleArray>)Parameters["Capacities"]; }
+    }
+    public IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IGQAPEvaluator>)Parameters["Evaluator"]; }
     }
     #endregion
@@ -130,5 +133,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("MoveInstallationQuality", MoveInstallationQualityDescription));
       Parameters.Add(new LookupParameter<DoubleValue>("MoveOverbookedCapacity", MoveOverbookedCapacityDescription));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ExpectedRandomQuality", GeneralizedQuadraticAssignmentProblem.ExpectedRandomQualityDescription));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
       Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", GeneralizedQuadraticAssignmentProblem.WeightsDescription));
@@ -137,4 +140,5 @@
       Parameters.Add(new LookupParameter<DoubleArray>("Demands", GeneralizedQuadraticAssignmentProblem.DemandsDescription));
       Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
+      Parameters.Add(new ValueLookupParameter<IGQAPEvaluator>("Evaluator", "The evaluator that is used to evaluate GQAP solutions."));
     }
 
@@ -144,14 +148,14 @@
 
     public static double Evaluate(NMove move, IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
-      DoubleArray demands, DoubleArray capacities, DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty) {
+      DoubleArray demands, DoubleArray capacities, double transportationCosts, double expectedRandomQuality, IGQAPEvaluator evaluator) {
       double moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity;
-      Evaluate(move, assignment, weights, distances, installationCosts, demands, capacities,
+      Evaluate(move, assignment, weights, distances, installationCosts, demands, capacities, evaluator,
         out moveFlowDistanceQuality, out moveInstallationQuality, out moveOverbookedCapacity);
-      return GQAPEvaluator.GetCombinedQuality(moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity,
-        transportationCosts.Value, overbookedCapacityPenalty.Value);
+      return evaluator.GetFitness(moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity,
+        transportationCosts, expectedRandomQuality);
     }
 
     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) {
+      DoubleArray demands, DoubleArray capacities, IGQAPEvaluator evaluator, out double moveFlowDistanceQuality, out double moveInstallationQuality, out double moveOverbookedCapacity) {
       moveFlowDistanceQuality = moveInstallationQuality = moveOverbookedCapacity = 0.0;
       int moves = move.N;
@@ -184,13 +188,13 @@
       }
 
-      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();
+      moveOverbookedCapacity = evaluator.EvaluateOverbooking(slack, capacities) - evaluator.EvaluateOverbooking(oldSlack, capacities);
     }
 
     public override IOperation Apply() {
+      var evaluator = EvaluatorParameter.ActualValue;
       double moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity;
       double quality = QualityParameter.ActualValue.Value;
       double transportationCosts = TransportationCostsParameter.ActualValue.Value;
-      double overbookedCapacityPenalty = OverbookedCapacityPenaltyParameter.ActualValue.Value;
+      double expectedRandomQuality = ExpectedRandomQualityParameter.ActualValue.Value;
 
       double flowDistanceQuality = FlowDistanceQualityParameter.ActualValue.Value;
@@ -203,4 +207,5 @@
                InstallationCostsParameter.ActualValue,
                DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
+               evaluator,
                out moveFlowDistanceQuality, out moveInstallationQuality, out moveOverbookedCapacity);
 
@@ -209,10 +214,9 @@
       MoveOverbookedCapacityParameter.ActualValue = new DoubleValue(overbookedCapacity + moveOverbookedCapacity);
 
-      MoveQualityParameter.ActualValue = new DoubleValue(GQAPEvaluator.GetCombinedQuality(
+      MoveQualityParameter.ActualValue = new DoubleValue(evaluator.GetFitness(
         flowDistanceQuality + moveFlowDistanceQuality,
         installationQuality + moveInstallationQuality,
         overbookedCapacity + moveOverbookedCapacity,
-        transportationCosts,
-        overbookedCapacityPenalty));
+        transportationCosts, expectedRandomQuality));
       return base.Apply();
     }
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPPenaltyLevelEvaluator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPPenaltyLevelEvaluator.cs	(revision 7970)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluators/GQAPPenaltyLevelEvaluator.cs	(revision 7970)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  [Item("GQAPPenaltyLevelEvaluator", "Evaluates solutions to the generalized quadratic assignment problem using a penalty level strategy. Infeasible solutions have a certain base quality to which the amount of constraint violation is added.")]
+  [StorableClass]
+  public class GQAPPenaltyLevelEvaluator : GQAPEvaluator {
+    public static readonly string PenaltyDescription = "The percentage of the expected random quality that should be used as a base level for infeasible solutions.";
+
+    protected IValueParameter<PercentValue> PenaltyParameter {
+      get { return (IValueParameter<PercentValue>)Parameters["Penalty"]; }
+    }
+
+    public PercentValue Penalty {
+      get { return PenaltyParameter.Value; }
+      set { PenaltyParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected GQAPPenaltyLevelEvaluator(bool deserializing) : base(deserializing) { }
+    protected GQAPPenaltyLevelEvaluator(GQAPPenaltyLevelEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public GQAPPenaltyLevelEvaluator()
+      : base() {
+      Parameters.Add(new ValueParameter<PercentValue>("Penalty", PenaltyDescription, new PercentValue(1), true));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GQAPPenaltyLevelEvaluator(this, cloner);
+    }
+
+    public override double GetFitness(double flowDistanceQuality,
+      double installationQuality, double overbookedCapacity,
+      double transportationCosts, double expectedRandomQuality) {
+      if (overbookedCapacity > 0) {
+        return expectedRandomQuality * Penalty.Value + overbookedCapacity;
+      } else {
+        return installationQuality
+          + transportationCosts * flowDistanceQuality;
+      }
+    }
+  }
+}
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPAssignment.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPAssignment.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPAssignment.cs	(revision 7970)
@@ -176,11 +176,22 @@
 
     [Storable]
-    private DoubleValue overbookedCapacityPenalty;
-    public DoubleValue OverbookedCapacityPenalty {
-      get { return overbookedCapacityPenalty; }
-      set {
-        bool changed = (overbookedCapacityPenalty != value);
-        overbookedCapacityPenalty = value;
-        if (changed) OnPropertyChanged("OverbookedCapacityPenalty");
+    private DoubleValue expectedRandomQuality;
+    public DoubleValue ExpectedRandomQuality {
+      get { return expectedRandomQuality; }
+      set {
+        bool changed = (expectedRandomQuality != value);
+        expectedRandomQuality = value;
+        if (changed) OnPropertyChanged("ExpectedRandomQuality");
+      }
+    }
+
+    [Storable]
+    private IGQAPEvaluator evaluator;
+    public IGQAPEvaluator Evaluator {
+      get { return evaluator; }
+      set {
+        bool changed = (evaluator != value);
+        evaluator = value;
+        if (changed) OnPropertyChanged("Evaluator");
       }
     }
@@ -203,7 +214,8 @@
       capacities = cloner.Clone(original.capacities);
       transportationCosts = cloner.Clone(original.transportationCosts);
-      overbookedCapacityPenalty = cloner.Clone(original.overbookedCapacityPenalty);
-    }
-    public GQAPAssignment(IntegerVector assignment, DoubleValue quality, DoubleValue flowDistanceQuality, DoubleValue installationQuality, DoubleValue overbookedCapacity, StringArray equipmentNames, StringArray locationNames, DoubleMatrix distances, DoubleMatrix weights, DoubleMatrix installationCosts, DoubleArray demands, DoubleArray capacities, DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty)
+      expectedRandomQuality = cloner.Clone(original.expectedRandomQuality);
+      evaluator = cloner.Clone(original.evaluator);
+    }
+    public GQAPAssignment(IntegerVector assignment, DoubleValue quality, DoubleValue flowDistanceQuality, DoubleValue installationQuality, DoubleValue overbookedCapacity, StringArray equipmentNames, StringArray locationNames, DoubleMatrix distances, DoubleMatrix weights, DoubleMatrix installationCosts, DoubleArray demands, DoubleArray capacities, DoubleValue transportationCosts, DoubleValue expectedRandomQuality, IGQAPEvaluator evaluator)
       : base() {
       this.assignment = assignment;
@@ -220,5 +232,6 @@
       this.capacities = capacities;
       this.transportationCosts = transportationCosts;
-      this.overbookedCapacityPenalty = overbookedCapacityPenalty;
+      this.expectedRandomQuality = expectedRandomQuality;
+      this.evaluator = evaluator;
     }
 
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPAssignmentArchive.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPAssignmentArchive.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPAssignmentArchive.cs	(revision 7970)
@@ -131,11 +131,22 @@
 
     [Storable]
-    private DoubleValue overbookedCapacityPenalty;
-    public DoubleValue OverbookedCapacityPenalty {
-      get { return overbookedCapacityPenalty; }
+    private DoubleValue expectedRandomQuality;
+    public DoubleValue ExpectedRandomQuality {
+      get { return expectedRandomQuality; }
       set {
-        bool changed = (overbookedCapacityPenalty != value);
-        overbookedCapacityPenalty = value;
-        if (changed) OnPropertyChanged("OverbookedCapacityPenalty");
+        bool changed = (expectedRandomQuality != value);
+        expectedRandomQuality = value;
+        if (changed) OnPropertyChanged("ExpectedRandomQuality");
+      }
+    }
+
+    [Storable]
+    private IGQAPEvaluator evaluator;
+    public IGQAPEvaluator Evaluator {
+      get { return evaluator; }
+      set {
+        bool changed = (evaluator != value);
+        evaluator = value;
+        if (changed) OnPropertyChanged("Evaluator");
       }
     }
@@ -154,5 +165,6 @@
       capacities = cloner.Clone(original.capacities);
       transportationCosts = cloner.Clone(original.transportationCosts);
-      overbookedCapacityPenalty = cloner.Clone(original.overbookedCapacityPenalty);
+      expectedRandomQuality = cloner.Clone(original.expectedRandomQuality);
+      evaluator = cloner.Clone(original.evaluator);
     }
     public GQAPAssignmentArchive()
@@ -160,5 +172,5 @@
       this.solutions = new ItemList<GQAPSolution>();
     }
-    public GQAPAssignmentArchive(StringArray equipmentNames, StringArray locationNames, DoubleMatrix distances, DoubleMatrix weights, DoubleMatrix installationCosts, DoubleArray demands, DoubleArray capacities, DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty)
+    public GQAPAssignmentArchive(StringArray equipmentNames, StringArray locationNames, DoubleMatrix distances, DoubleMatrix weights, DoubleMatrix installationCosts, DoubleArray demands, DoubleArray capacities, DoubleValue transportationCosts, DoubleValue expectedRandomQuality, IGQAPEvaluator evaluator)
       : this() {
       this.distances = distances;
@@ -168,5 +180,6 @@
       this.capacities = capacities;
       this.transportationCosts = transportationCosts;
-      this.overbookedCapacityPenalty = overbookedCapacityPenalty;
+      this.expectedRandomQuality = expectedRandomQuality;
+      this.evaluator = evaluator;
     }
 
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GeneralizedQuadraticAssignmentProblem.cs	(revision 7970)
@@ -23,4 +23,5 @@
 using System.Drawing;
 using System.Linq;
+using HeuristicLab.Analysis.QualityAnalysis;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -31,5 +32,4 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.PluginInfrastructure;
-using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common;
 using HeuristicLab.Problems.Instances;
 
@@ -59,5 +59,4 @@
     public static readonly string CapacitiesDescription = "The capacities vector describes the available space at the locations.";
     public static readonly string TransportationCostsDescription = "The transportation cost represents the flow-unit per distance-unit cost factor. This value can also be set to 1 if these costs are factored into the weights matrix already.";
-    public static readonly string OverbookedCapacityPenaltyDescription = "The multiplier for the constraint violation when added to the quality.";
     public static readonly string BestKnownQualityDescription = "The best known quality (if available).";
     public static readonly string BestKnownSolutionDescription = "The best known solution (if available).";
@@ -65,4 +64,5 @@
     public static readonly string EquipmentNamesDescription = "Optional: A list of names that describes the equipments.";
     public static readonly string LocationNamesDescription = "Optional: A list of names that describes the locations.";
+    public static readonly string ExpectedRandomQualityDescription = "The expected quality value of a random solution.";
     #endregion
 
@@ -86,6 +86,6 @@
       get { return (FixedValueParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
-    public FixedValueParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
-      get { return (FixedValueParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    public FixedValueParameter<DoubleValue> ExpectedRandomQualityParameter {
+      get { return (FixedValueParameter<DoubleValue>)Parameters["ExpectedRandomQuality"]; }
     }
     public OptionalValueParameter<GQAPAssignment> BestKnownSolutionParameter {
@@ -124,11 +124,11 @@
       set { CapacitiesParameter.Value = value; }
     }
-    public DoubleValue TransportationCosts {
-      get { return TransportationCostsParameter.Value; }
-      set { TransportationCostsParameter.Value = value; }
-    }
-    public DoubleValue OverbookedCapacityPenalty {
-      get { return TransportationCostsParameter.Value; }
-      set { TransportationCostsParameter.Value = value; }
+    public double TransportationCosts {
+      get { return TransportationCostsParameter.Value.Value; }
+      set { TransportationCostsParameter.Value.Value = value; }
+    }
+    public double ExpectedRandomQuality {
+      get { return ExpectedRandomQualityParameter.Value.Value; }
+      set { ExpectedRandomQualityParameter.Value.Value = value; }
     }
     public StringArray EquipmentNames {
@@ -164,10 +164,10 @@
     }
     public GeneralizedQuadraticAssignmentProblem()
-      : base(new GQAPEvaluator(), new RandomSolutionCreator()) {
+      : base(new GQAPAdditivePenaltyEvaluator(), new RandomSolutionCreator()) {
       Parameters.Add(new ValueParameter<DoubleMatrix>("Weights", WeightsDescription, new DoubleMatrix(), false));
       Parameters.Add(new ValueParameter<DoubleMatrix>("Distances", DistancesDescription, new DoubleMatrix(), false));
       Parameters.Add(new ValueParameter<DoubleMatrix>("InstallationCosts", InstallationCostsDescription, new DoubleMatrix(), false));
       Parameters.Add(new FixedValueParameter<DoubleValue>("TransportationCosts", TransportationCostsDescription, new DoubleValue(1)));
-      Parameters.Add(new FixedValueParameter<DoubleValue>("OverbookedCapacityPenalty", OverbookedCapacityPenaltyDescription, new DoubleValue(100000)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>("ExpectedRandomQuality", ExpectedRandomQualityDescription, new DoubleValue(0), true));
       Parameters.Add(new ValueParameter<DoubleArray>("Demands", DemandsDescription, new DoubleArray(), false));
       Parameters.Add(new ValueParameter<DoubleArray>("Capacities", CapacitiesDescription, new DoubleArray(), false));
@@ -310,5 +310,5 @@
     public void Load(DoubleArray demands, DoubleArray capacities,
       DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
-      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty = null) {
+      DoubleValue transportationCosts) {
       if (weights == null || weights.Rows == 0)
         throw new System.IO.InvalidDataException(
@@ -316,6 +316,6 @@
       if (weights.Rows != weights.Columns)
         throw new System.IO.InvalidDataException(
-@"The weights matrix of the given instance contains an unequal number of rows
-and columns.");
+@"The weights matrix of the given instance contains
+an unequal number of rows and columns.");
       Weights = weights;
 
@@ -325,6 +325,6 @@
       if (distances.Rows != distances.Columns)
         throw new System.IO.InvalidDataException(
-@"The distances matrix of the given instance contains an unequal number of rows
-and columns.");
+@"The distances matrix of the given instance contains
+an unequal number of rows and columns.");
       Distances = distances;
 
@@ -335,6 +335,7 @@
         || installationCosts.Columns != distances.Columns)
         throw new System.IO.InvalidDataException(
-@"The installation costs matrix of the given instance contains different number
-of rows than given in the weights matrix and a different number of columns than
+@"The installation costs matrix of the given instance
+contains different number of rows than given in the
+weights matrix and a different number of columns than
 given in the distances matrix.");
       InstallationCosts = installationCosts;
@@ -345,6 +346,6 @@
       if (capacities.Length != distances.Rows)
         throw new System.IO.InvalidDataException(
-@"The given instance contains a different number of capacities than rows given in
-the distances matrix.");
+@"The given instance contains a different number of
+capacities than rows given in the distances matrix.");
       Capacities = capacities;
 
@@ -354,6 +355,6 @@
       if (demands.Length != weights.Rows)
         throw new System.IO.InvalidDataException(
-@"The given instance contains a different number of demands than rows given in
-the weights matrix.");
+@"The given instance contains a different number of
+demands than rows given in the weights matrix.");
       Demands = demands;
 
@@ -361,14 +362,40 @@
         throw new System.IO.InvalidDataException(
 @"The given instance does not contain transportation costs.");
-      TransportationCosts.Value = transportationCosts.Value;
-
-      if (overbookedCapacityPenalty != null)
-        OverbookedCapacityPenalty.Value = overbookedCapacityPenalty.Value;
+      TransportationCosts = transportationCosts.Value;
 
       BestKnownQuality = null;
       BestKnownSolution = null;
       BestKnownSolutions = null;
-    }
-
+      CalculateExpectedRandomQuality();
+    }
+
+    private void CalculateExpectedRandomQuality() {
+      if (IsConfigurationValid()) {
+        double[] avgDistances = new double[Capacities.Length];
+        for (int i = 0; i < Capacities.Length; i++) {
+          for (int j = 0; j < Capacities.Length; j++)
+            avgDistances[i] += Distances[i, j];
+          avgDistances[i] /= Capacities.Length;
+        }
+        double[] avgWeight = new double[Demands.Length];
+        for (int i = 0; i < Demands.Length; i++) {
+          for (int j = 0; j < Demands.Length; j++)
+            avgWeight[i] += Weights[i, j];
+          avgWeight[i] /= Demands.Length;
+        }
+        double avgCosts = InstallationCosts.Average();
+        double quality = 0;
+        for (int i = 0; i < Demands.Length; i++) {
+          double equipmentInfluence = 0;
+          for (int j = 0; j < Capacities.Length; j++)
+            equipmentInfluence += avgWeight[i] * avgDistances[j];
+          quality += equipmentInfluence * Demands.Length / (double)Capacities.Length;
+        }
+        quality *= TransportationCosts;
+        quality += avgCosts * Demands.Length;
+
+        ExpectedRandomQuality = quality;
+      }
+    }
     private void EvaluateAndLoadAssignment(int[] vector) {
       if (vector == null || vector.Length == 0) return;
@@ -382,13 +409,13 @@
       }
       double flowDistanceQuality, installationQuality, overbookedCapacity;
-      GQAPEvaluator.Evaluate(assignment, Weights, Distances, InstallationCosts, Demands, Capacities,
+      Evaluator.Evaluate(assignment, Weights, Distances, InstallationCosts, Demands, Capacities,
         out flowDistanceQuality, out installationQuality, out overbookedCapacity);
-      double quality = GQAPEvaluator.GetCombinedQuality(flowDistanceQuality, installationQuality, overbookedCapacity, TransportationCosts.Value, OverbookedCapacityPenalty.Value);
+      double quality = Evaluator.GetFitness(flowDistanceQuality, installationQuality, overbookedCapacity, TransportationCosts, ExpectedRandomQuality);
       BestKnownSolution = new GQAPAssignment((IntegerVector)assignment.Clone(), new DoubleValue(quality),
         new DoubleValue(flowDistanceQuality), new DoubleValue(installationQuality),
         new DoubleValue(overbookedCapacity), EquipmentNames, LocationNames, Distances, Weights, InstallationCosts,
-        Demands, Capacities, TransportationCosts, OverbookedCapacityPenalty);
+        Demands, Capacities, new DoubleValue(TransportationCosts), new DoubleValue(ExpectedRandomQuality), Evaluator);
       BestKnownQuality = new DoubleValue(quality);
-      BestKnownSolutions = new GQAPAssignmentArchive(EquipmentNames, LocationNames, Distances, Weights, InstallationCosts, Demands, Capacities, TransportationCosts, OverbookedCapacityPenalty);
+      BestKnownSolutions = new GQAPAssignmentArchive(EquipmentNames, LocationNames, Distances, Weights, InstallationCosts, Demands, Capacities, new DoubleValue(TransportationCosts), new DoubleValue(ExpectedRandomQuality), Evaluator);
       BestKnownSolutions.Solutions.Add(new GQAPSolution((IntegerVector)assignment.Clone(), new DoubleValue(quality), new DoubleValue(flowDistanceQuality), new DoubleValue(installationQuality), new DoubleValue(overbookedCapacity)));
     }
@@ -403,4 +430,5 @@
       base.OnEvaluatorChanged();
       Parameterize();
+      if (BestKnownSolution != null) EvaluateAndLoadAssignment(BestKnownSolution.Assignment);
       Evaluator.QualityParameter.ActualNameChanged += new System.EventHandler(Evaluator_QualityParameter_ActualNameChanged);
     }
@@ -436,4 +464,5 @@
       Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator);
       Operators.AddRange(ApplicationManager.Manager.GetInstances<IGQAPMoveEvaluator>());
+      Operators.Add(new ScaledQualityDifferenceAnalyzer());
       Parameterize();
     }
@@ -445,38 +474,47 @@
       foreach (var op in operators.OfType<IAssignmentAwareGQAPOperator>()) {
         op.AssignmentParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
-      }
-      foreach (var op in operators.OfType<IAssignmentsAwareGQAPOperator>()) {
-        op.AssignmentParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.AssignmentParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IBestKnownQualityAwareGQAPOperator>()) {
         op.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
+        op.BestKnownQualityParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IBestKnownSolutionAwareGQAPOperator>()) {
         op.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
+        op.BestKnownSolutionParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IBestKnownSolutionsAwareGQAPOperator>()) {
         op.BestKnownSolutionsParameter.ActualName = BestKnownSolutionsParameter.Name;
+        op.BestKnownSolutionsParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<ICapacitiesAwareGQAPOperator>()) {
         op.CapacitiesParameter.ActualName = CapacitiesParameter.Name;
+        op.CapacitiesParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IDemandsAwareGQAPOperator>()) {
         op.DemandsParameter.ActualName = DemandsParameter.Name;
+        op.DemandsParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IDistancesAwareGQAPOperator>()) {
         op.DistancesParameter.ActualName = DistancesParameter.Name;
+        op.DistancesParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IEquipmentNamesAwareGQAPOperator>()) {
         op.EquipmentNamesParameter.ActualName = EquipmentNamesParameter.Name;
+        op.EquipmentNamesParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IGQAPCrossover>()) {
         op.ParentsParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.ParentsParameter.Hidden = true;
         op.ChildParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.ChildParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IInstallationCostsAwareGQAPOperator>()) {
         op.InstallationCostsParameter.ActualName = InstallationCostsParameter.Name;
+        op.InstallationCostsParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<ILocationNamesAwareGQAPOperator>()) {
         op.LocationNamesParameter.ActualName = LocationNamesParameter.Name;
+        op.LocationNamesParameter.Hidden = true;
       }
       var moveEvaluator = operators.OfType<IGQAPMoveEvaluator>().FirstOrDefault();
@@ -484,7 +522,11 @@
         if (moveEvaluator != null) {
           op.MoveQualityParameter.ActualName = moveEvaluator.MoveQualityParameter.ActualName;
+          op.MoveQualityParameter.Hidden = true;
           op.MoveFlowDistanceQualityParameter.ActualName = moveEvaluator.MoveFlowDistanceQualityParameter.ActualName;
+          op.MoveFlowDistanceQualityParameter.Hidden = true;
           op.MoveInstallationQualityParameter.ActualName = moveEvaluator.MoveInstallationQualityParameter.ActualName;
+          op.MoveInstallationQualityParameter.Hidden = true;
           op.MoveOverbookedCapacityParameter.ActualName = moveEvaluator.MoveOverbookedCapacityParameter.ActualName;
+          op.MoveOverbookedCapacityParameter.Hidden = true;
         }
       }
@@ -492,40 +534,74 @@
         if (moveEvaluator != null) {
           op.MoveQualityParameter.ActualName = moveEvaluator.MoveQualityParameter.ActualName;
+          op.MoveQualityParameter.Hidden = true;
           op.MoveFlowDistanceQualityParameter.ActualName = moveEvaluator.MoveFlowDistanceQualityParameter.ActualName;
+          op.MoveFlowDistanceQualityParameter.Hidden = true;
           op.MoveInstallationQualityParameter.ActualName = moveEvaluator.MoveInstallationQualityParameter.ActualName;
+          op.MoveInstallationQualityParameter.Hidden = true;
           op.MoveOverbookedCapacityParameter.ActualName = moveEvaluator.MoveOverbookedCapacityParameter.ActualName;
+          op.MoveOverbookedCapacityParameter.Hidden = true;
         }
         op.MaximizationParameter.ActualName = MaximizationParameter.Name;
-      }
-      foreach (var op in operators.OfType<IOverbookedCapacityPenaltyAwareGQAPOperator>()) {
-        op.OverbookedCapacityPenaltyParameter.ActualName = OverbookedCapacityPenaltyParameter.Name;
+        op.MaximizationParameter.Hidden = true;
+      }
+      foreach (var op in operators.OfType<IExpectedRandomQualityAwareGQAPOperator>()) {
+        op.ExpectedRandomQualityParameter.ActualName = ExpectedRandomQualityParameter.Name;
+        op.ExpectedRandomQualityParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IQualitiesAwareGQAPOperator>()) {
         op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+        op.QualityParameter.Hidden = true;
         op.FlowDistanceQualityParameter.ActualName = Evaluator.FlowDistanceQualityParameter.ActualName;
+        op.FlowDistanceQualityParameter.Hidden = true;
         op.InstallationQualityParameter.ActualName = Evaluator.InstallationQualityParameter.ActualName;
+        op.InstallationQualityParameter.Hidden = true;
         op.OverbookedCapacityParameter.ActualName = Evaluator.OverbookedCapacityParameter.ActualName;
+        op.OverbookedCapacityParameter.Hidden = true;
         op.MaximizationParameter.ActualName = MaximizationParameter.Name;
+        op.MaximizationParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IQualityAwareGQAPOperator>()) {
         op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+        op.QualityParameter.Hidden = true;
         op.FlowDistanceQualityParameter.ActualName = Evaluator.FlowDistanceQualityParameter.ActualName;
+        op.FlowDistanceQualityParameter.Hidden = true;
         op.InstallationQualityParameter.ActualName = Evaluator.InstallationQualityParameter.ActualName;
+        op.InstallationQualityParameter.Hidden = true;
         op.OverbookedCapacityParameter.ActualName = Evaluator.OverbookedCapacityParameter.ActualName;
+        op.OverbookedCapacityParameter.Hidden = true;
         op.MaximizationParameter.ActualName = MaximizationParameter.Name;
+        op.MaximizationParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<ITransportationCostsAwareGQAPOperator>()) {
         op.TransportationCostsParameter.ActualName = TransportationCostsParameter.Name;
+        op.TransportationCostsParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IWeightsAwareGQAPOperator>()) {
         op.WeightsParameter.ActualName = WeightsParameter.Name;
+        op.WeightsParameter.Hidden = true;
+      }
+      foreach (var op in operators.OfType<IEvaluatorAwareGQAPOperator>()) {
+        op.EvaluatorParameter.ActualName = EvaluatorParameter.Name;
+        op.EvaluatorParameter.Hidden = true;
       }
 
       foreach (var op in operators.OfType<IIntegerVectorCrossover>()) {
         op.ParentsParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.ParentsParameter.Hidden = true;
         op.ChildParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.ChildParameter.Hidden = true;
       }
       foreach (var op in operators.OfType<IIntegerVectorManipulator>()) {
         op.IntegerVectorParameter.ActualName = SolutionCreator.AssignmentParameter.ActualName;
+        op.IntegerVectorParameter.Hidden = true;
+      }
+
+      foreach (var op in operators.OfType<ScaledQualityDifferenceAnalyzer>()) {
+        op.MinimumQualityParameter.ActualName = BestKnownQualityParameter.Name;
+        op.MinimumQualityParameter.Hidden = true;
+        op.MaximumQualityParameter.ActualName = ExpectedRandomQualityParameter.Name;
+        op.MaximumQualityParameter.Hidden = true;
+        op.QualityParameter.ActualName = "BestQuality";
+        op.QualityParameter.Hidden = true;
       }
     }
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 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj	(revision 7970)
@@ -105,6 +105,9 @@
     <Compile Include="Analyzers\GQAPPopulationDiversityAnalyzer.cs" />
     <Compile Include="Analyzers\GQAPSolutionArchiveAnalyzer.cs" />
+    <Compile Include="Evaluators\GQAPPenaltyLevelEvaluator.cs" />
+    <Compile Include="Evaluators\GQAPEvaluator.cs" />
     <Compile Include="Evaluators\GQAPNMoveEvaluator.cs" />
     <Compile Include="GQAPAssignment.cs" />
+    <Compile Include="Interfaces\IEvaluatorAwareGQAPOperator.cs" />
     <Compile Include="Operators\Crossovers\CordeauCrossover.cs" />
     <Compile Include="SolutionCreators\SlackMinimizationSolutionCreator.cs" />
@@ -115,5 +118,5 @@
     <Compile Include="SolutionCreators\RandomSolutionCreator.cs" />
     <None Include="Plugin.cs.frame" />
-    <Compile Include="Evaluators\GQAPEvaluator.cs" />
+    <Compile Include="Evaluators\GQAPAdditivePenaltyEvaluator.cs" />
     <Compile Include="GeneralizedQuadraticAssignmentProblem.cs" />
     <Compile Include="GQAPAssignmentArchive.cs" />
@@ -130,5 +133,5 @@
     <Compile Include="Interfaces\IGQAPEvaluator.cs" />
     <Compile Include="Interfaces\IQualityAwareGQAPOperator.cs" />
-    <Compile Include="Interfaces\IOverbookedCapacityPenaltyAwareGQAPOperator.cs" />
+    <Compile Include="Interfaces\IExpectedRandomQualityAwareGQAPOperator.cs" />
     <Compile Include="Interfaces\ITransportationCostsAwareGQAPOperator.cs" />
     <Compile Include="Interfaces\IInstallationCostsAwareGQAPOperator.cs" />
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IEvaluatorAwareGQAPOperator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IEvaluatorAwareGQAPOperator.cs	(revision 7970)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IEvaluatorAwareGQAPOperator.cs	(revision 7970)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public interface IEvaluatorAwareGQAPOperator : IGQAPOperator {
+    IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter { get; }
+  }
+}
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IExpectedRandomQualityAwareGQAPOperator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IExpectedRandomQualityAwareGQAPOperator.cs	(revision 7970)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IExpectedRandomQualityAwareGQAPOperator.cs	(revision 7970)
@@ -0,0 +1,29 @@
+﻿#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;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
+  public interface IExpectedRandomQualityAwareGQAPOperator : IGQAPOperator {
+    IValueLookupParameter<DoubleValue> ExpectedRandomQualityParameter { get; }
+  }
+}
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluator.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IGQAPEvaluator.cs	(revision 7970)
@@ -22,4 +22,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
 using HeuristicLab.Optimization;
 
@@ -30,4 +31,19 @@
     ILookupParameter<DoubleValue> InstallationQualityParameter { get; }
     ILookupParameter<DoubleValue> OverbookedCapacityParameter { get; }
+
+    double Evaluate(IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances,
+                    DoubleMatrix installCosts, DoubleArray demands, DoubleArray capacities,
+                    double transportationCosts, double expectedRandomQuality);
+
+    void Evaluate(IntegerVector assignment, DoubleMatrix weights, DoubleMatrix distances,
+                  DoubleMatrix installCosts, DoubleArray demands, DoubleArray capacities,
+                  out double flowDistanceQuality, out double installationQuality,
+                  out double overbookedCapacity);
+
+    double EvaluateOverbooking(DoubleArray slack, DoubleArray capacities);
+
+    double GetFitness(double flowDistanceQuality, double installationQuality,
+                      double overbookedCapacity, double transportationCosts,
+                      double expectedRandomQuality);
   }
 }
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IOverbookedCapacityPenaltyAwareGQAPOperator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Interfaces/IOverbookedCapacityPenaltyAwareGQAPOperator.cs	(revision 7968)
+++ 	(revision )
@@ -1,29 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-
-namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
-  public interface IOverbookedCapacityPenaltyAwareGQAPOperator : IGQAPOperator {
-    IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter { get; }
-  }
-}
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/CordeauCrossover.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/CordeauCrossover.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/CordeauCrossover.cs	(revision 7970)
@@ -34,5 +34,5 @@
     IQualitiesAwareGQAPOperator, IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator, IInstallationCostsAwareGQAPOperator,
     IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator, ITransportationCostsAwareGQAPOperator,
-    IOverbookedCapacityPenaltyAwareGQAPOperator {
+    IExpectedRandomQualityAwareGQAPOperator {
 
     public ILookupParameter<BoolValue> MaximizationParameter {
@@ -69,6 +69,9 @@
       get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
-    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
-      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    public IValueLookupParameter<DoubleValue> ExpectedRandomQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["ExpectedRandomQuality"]; }
+    }
+    public IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IGQAPEvaluator>)Parameters["Evaluator"]; }
     }
 
@@ -91,5 +94,6 @@
       Parameters.Add(new LookupParameter<DoubleArray>("Capacities", GeneralizedQuadraticAssignmentProblem.CapacitiesDescription));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ExpectedRandomQuality", GeneralizedQuadraticAssignmentProblem.ExpectedRandomQualityDescription));
+      Parameters.Add(new ValueLookupParameter<IGQAPEvaluator>("Evaluator", "The evaluator used to evaluate solutions."));
     }
 
@@ -103,5 +107,5 @@
       DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
       DoubleArray demands, DoubleArray capacities,
-      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty) {
+      double transportationCosts, double expectedRandomQuality, IGQAPEvaluator evaluator) {
       var mediana = Inizialize(distances);
       int m = capacities.Length;
@@ -158,5 +162,5 @@
         }
         if (!nofound) {
-          double sonQual = GQAPEvaluator.Evaluate(son, weights, distances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+          double sonQual = evaluator.Evaluate(son, weights, distances, installationCosts, demands, capacities, transportationCosts, expectedRandomQuality);
           if (sonQual < fbest) {
             fbest = sonQual;
@@ -197,5 +201,5 @@
           onefound = true;
         } else {
-          double sonQual = GQAPEvaluator.Evaluate(son, weights, distances, installationCosts, demands, capacities, transportationCosts, overbookedCapacityPenalty);
+          double sonQual = evaluator.Evaluate(son, weights, distances, installationCosts, demands, capacities, transportationCosts, expectedRandomQuality);
           if (sonQual < fbest) {
             fbest = sonQual;
@@ -227,5 +231,6 @@
         WeightsParameter.ActualValue, DistancesParameter.ActualValue, InstallationCostsParameter.ActualValue,
         DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
-        TransportationCostsParameter.ActualValue, OverbookedCapacityPenaltyParameter.ActualValue);
+        TransportationCostsParameter.ActualValue.Value, ExpectedRandomQualityParameter.ActualValue.Value,
+        EvaluatorParameter.ActualValue);
     }
 
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs	(revision 7970)
@@ -37,5 +37,5 @@
   public class GQAPPathRelinking : GQAPCrossover, IQualitiesAwareGQAPOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator,
   IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator, IInstallationCostsAwareGQAPOperator, ITransportationCostsAwareGQAPOperator,
-  IOverbookedCapacityPenaltyAwareGQAPOperator {
+  IExpectedRandomQualityAwareGQAPOperator, IEvaluatorAwareGQAPOperator {
 
     public ILookupParameter<BoolValue> MaximizationParameter {
@@ -72,6 +72,9 @@
       get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
-    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
-      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    public IValueLookupParameter<DoubleValue> ExpectedRandomQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["ExpectedRandomQuality"]; }
+    }
+    public IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IGQAPEvaluator>)Parameters["Evaluator"]; }
     }
 
@@ -96,5 +99,6 @@
       Parameters.Add(new LookupParameter<DoubleMatrix>("InstallationCosts", GeneralizedQuadraticAssignmentProblem.InstallationCostsDescription));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ExpectedRandomQuality", GeneralizedQuadraticAssignmentProblem.ExpectedRandomQualityDescription));
+      Parameters.Add(new ValueLookupParameter<IGQAPEvaluator>("Evaluator", "The evaluator that is used to evaluate GQAP solutions."));
       Parameters.Add(new ValueParameter<PercentValue>("CandidateSizeFactor", "(η) Determines the size of the set of feasible moves in each path-relinking step relative to the maximum size. A value of 50% means that only half of all possible moves are considered each step.", new PercentValue(0.5)));
     }
@@ -107,5 +111,5 @@
       ItemArray<DoubleValue> flowDistanceQualities, ItemArray<DoubleValue> installationQualities, ItemArray<DoubleValue> overbookedCapacities,
       DoubleArray demands, DoubleArray capacities, DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts,
-      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty, DoubleValue candidateSizeFactor) {
+      DoubleValue transportationCosts, DoubleValue expectedRandomQuality, DoubleValue candidateSizeFactor, IGQAPEvaluator evaluator) {
       if (random == null) throw new ArgumentNullException("random", "No IRandom provider is given.");
       if (parents == null || !parents.Any()) throw new ArgumentException("No parents given for path relinking.", "parents");
@@ -145,10 +149,10 @@
 
           double currentFDQ, currentIQ, currentOC;
-          GQAPEvaluator.Evaluate(pi2, weights, distances, installationCosts, demands, capacities,
+          evaluator.Evaluate(pi2, weights, distances, installationCosts, demands, capacities,
             out currentFDQ, out currentIQ, out currentOC);
 
           if (currentOC <= 0.0) {
-            var quality = GQAPEvaluator.GetCombinedQuality(currentFDQ, currentIQ, currentOC,
-                transportationCosts.Value, overbookedCapacityPenalty.Value);
+            var quality = evaluator.GetFitness(currentFDQ, currentIQ, currentOC,
+              transportationCosts.Value, expectedRandomQuality.Value);
             var solution = new GQAPSolution(pi2, new DoubleValue(quality), new DoubleValue(currentFDQ),
               new DoubleValue(currentIQ), new DoubleValue(currentOC));
@@ -211,5 +215,6 @@
         CapacitiesParameter.ActualValue, WeightsParameter.ActualValue, DistancesParameter.ActualValue,
         InstallationCostsParameter.ActualValue, TransportationCostsParameter.ActualValue,
-        OverbookedCapacityPenaltyParameter.ActualValue, CandidateSizeFactorParameter.Value);
+        ExpectedRandomQualityParameter.ActualValue, CandidateSizeFactorParameter.Value,
+        EvaluatorParameter.ActualValue);
     }
 
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/LocalImprovers/ApproximateLocalSearch.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/LocalImprovers/ApproximateLocalSearch.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/LocalImprovers/ApproximateLocalSearch.cs	(revision 7970)
@@ -37,6 +37,7 @@
   public class ApproximateLocalSearch : SingleSuccessorOperator, IDemandsAwareGQAPOperator, ICapacitiesAwareGQAPOperator,
     IWeightsAwareGQAPOperator, IDistancesAwareGQAPOperator, IInstallationCostsAwareGQAPOperator,
-    ITransportationCostsAwareGQAPOperator, IOverbookedCapacityPenaltyAwareGQAPOperator,
-    IAssignmentAwareGQAPOperator, IQualityAwareGQAPOperator, IGQAPLocalImprovementOperator, IStochasticOperator {
+    ITransportationCostsAwareGQAPOperator, IExpectedRandomQualityAwareGQAPOperator,
+    IAssignmentAwareGQAPOperator, IQualityAwareGQAPOperator, IGQAPLocalImprovementOperator,
+    IEvaluatorAwareGQAPOperator, IStochasticOperator {
     public IProblem Problem { get; set; }
     public Type ProblemType {
@@ -62,6 +63,6 @@
       get { return (IValueLookupParameter<DoubleValue>)Parameters["TransportationCosts"]; }
     }
-    public IValueLookupParameter<DoubleValue> OverbookedCapacityPenaltyParameter {
-      get { return (IValueLookupParameter<DoubleValue>)Parameters["OverbookedCapacityPenalty"]; }
+    public IValueLookupParameter<DoubleValue> ExpectedRandomQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["ExpectedRandomQuality"]; }
     }
     public ILookupParameter<IntegerVector> AssignmentParameter {
@@ -100,4 +101,7 @@
     public ILookupParameter<ResultCollection> ResultsParameter {
       get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IGQAPEvaluator>)Parameters["Evaluator"]; }
     }
 
@@ -113,5 +117,5 @@
       Parameters.Add(new LookupParameter<DoubleMatrix>("InstallationCosts", GeneralizedQuadraticAssignmentProblem.InstallationCostsDescription));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("TransportationCosts", GeneralizedQuadraticAssignmentProblem.TransportationCostsDescription));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("OverbookedCapacityPenalty", GeneralizedQuadraticAssignmentProblem.OverbookedCapacityPenaltyDescription));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ExpectedRandomQuality", GeneralizedQuadraticAssignmentProblem.ExpectedRandomQualityDescription));
       Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", GeneralizedQuadraticAssignmentProblem.MaximizationDescription));
@@ -126,4 +130,5 @@
       Parameters.Add(new ValueLookupParameter<PercentValue>("OneMoveProbability", "The probability for performing a 1-move, which is the opposite of performing a 2-move.", new PercentValue(.5)));
       Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection that stores the results."));
+      Parameters.Add(new ValueLookupParameter<IGQAPEvaluator>("Evaluator", "The evaluator that is used to evaluate GQAP solutions."));
     }
 
@@ -157,5 +162,6 @@
       IntValue maxCLS, IntValue maximumIterations,
       DoubleMatrix weights, DoubleMatrix distances, DoubleMatrix installationCosts, DoubleArray demands, DoubleArray capacities,
-      DoubleValue transportationCosts, DoubleValue overbookedCapacityPenalty, PercentValue oneMoveProbability) {
+      DoubleValue transportationCosts, DoubleValue expectedRandomQuality, PercentValue oneMoveProbability,
+      IGQAPEvaluator evaluator) {
 
       while (true) {
@@ -171,7 +177,7 @@
           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);
+            demands, capacities, evaluator, out moveFlowDistanceQuality, out moveInstallationQuality, out moveOverbookedCapacity);
+          double moveQuality = evaluator.GetFitness(moveFlowDistanceQuality, moveInstallationQuality, moveOverbookedCapacity,
+            transportationCosts.Value, expectedRandomQuality.Value);
 
           if (moveOverbookedCapacity <= 0.0 && moveQuality < 0.0) {
@@ -216,6 +222,7 @@
         DemandsParameter.ActualValue, CapacitiesParameter.ActualValue,
         TransportationCostsParameter.ActualValue,
-        OverbookedCapacityPenaltyParameter.ActualValue,
-        OneMoveProbabilityParameter.ActualValue);
+        ExpectedRandomQualityParameter.ActualValue,
+        OneMoveProbabilityParameter.ActualValue,
+        EvaluatorParameter.ActualValue);
       return base.Apply();
     }
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GreedyRandomizedSolutionCreator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GreedyRandomizedSolutionCreator.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GreedyRandomizedSolutionCreator.cs	(revision 7970)
@@ -35,5 +35,6 @@
   [Item("GreedyRandomizedSolutionCreator", "Creates a solution according to the procedure described in Mateus, G., Resende, M., and Silva, R. 2011. GRASP with path-relinking for the generalized quadratic assignment problem. Journal of Heuristics 17, Springer Netherlands, pp. 527-565.")]
   [StorableClass]
-  public class GreedyRandomizedSolutionCreator : GQAPStochasticSolutionCreator {
+  public class GreedyRandomizedSolutionCreator : GQAPStochasticSolutionCreator,
+    IEvaluatorAwareGQAPOperator {
 
     public IValueLookupParameter<IntValue> MaximumTriesParameter {
@@ -42,4 +43,7 @@
     public IValueLookupParameter<BoolValue> CreateMostFeasibleSolutionParameter {
       get { return (IValueLookupParameter<BoolValue>)Parameters["CreateMostFeasibleSolution"]; }
+    }
+    public IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IGQAPEvaluator>)Parameters["Evaluator"]; }
     }
 
@@ -52,4 +56,5 @@
       Parameters.Add(new ValueLookupParameter<IntValue>("MaximumTries", "The maximum number of tries to create a feasible solution after which an exception is thrown. If it is set to 0 or a negative value there will be an infinite number of attempts.", new IntValue(100000)));
       Parameters.Add(new ValueLookupParameter<BoolValue>("CreateMostFeasibleSolution", "If this is set to true the operator will always succeed, and outputs the solution with the least violation instead of throwing an exception.", new BoolValue(false)));
+      Parameters.Add(new ValueLookupParameter<IGQAPEvaluator>("Evaluator", "The evaluator that is used to evaluate GQAP solutions."));
     }
 
@@ -58,5 +63,7 @@
     }
 
-    public static IntegerVector CreateSolution(IRandom random, DoubleArray demands, DoubleArray capacities, int maximumTries, bool createMostFeasibleSolution, CancellationToken cancelToken) {
+    public static IntegerVector CreateSolution(IRandom random, DoubleArray demands, DoubleArray capacities,
+      IGQAPEvaluator evaluator,
+      int maximumTries, bool createMostFeasibleSolution, CancellationToken cancelToken) {
       int tries = 0;
       var assignment = new Dictionary<int, int>(demands.Length);
@@ -118,5 +125,5 @@
             slack[l] -= demands[f];
           }
-          double violation = GQAPEvaluator.EvaluateOverbooking(slack, capacities);
+          double violation = evaluator.EvaluateOverbooking(slack, capacities);
           if (violation < minViolation) {
             bestAssignment = assignment;
@@ -134,4 +141,5 @@
     protected override IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities) {
       return CreateSolution(random, demands, capacities,
+        EvaluatorParameter.ActualValue,
         MaximumTriesParameter.ActualValue.Value,
         CreateMostFeasibleSolutionParameter.ActualValue.Value,
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/RandomButFeasibleSolutionCreator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/RandomButFeasibleSolutionCreator.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/RandomButFeasibleSolutionCreator.cs	(revision 7970)
@@ -35,5 +35,6 @@
   [Item("RandomButFeasibleSolutionCreator", "Creates a random, but feasible solution to the Generalized Quadratic Assignment Problem.")]
   [StorableClass]
-  public class RandomFeasibleSolutionCreator : GQAPStochasticSolutionCreator {
+  public class RandomFeasibleSolutionCreator : GQAPStochasticSolutionCreator,
+    IEvaluatorAwareGQAPOperator {
 
     public IValueLookupParameter<IntValue> MaximumTriesParameter {
@@ -42,4 +43,7 @@
     public IValueLookupParameter<BoolValue> CreateMostFeasibleSolutionParameter {
       get { return (IValueLookupParameter<BoolValue>)Parameters["CreateMostFeasibleSolution"]; }
+    }
+    public IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IGQAPEvaluator>)Parameters["Evaluator"]; }
     }
 
@@ -51,4 +55,5 @@
       Parameters.Add(new ValueLookupParameter<IntValue>("MaximumTries", "The maximum number of tries to create a feasible solution after which an exception is thrown. If it is set to 0 or a negative value there will be an infinite number of attempts.", new IntValue(100000)));
       Parameters.Add(new ValueLookupParameter<BoolValue>("CreateMostFeasibleSolution", "If this is set to true the operator will always succeed, and outputs the solution with the least violation instead of throwing an exception.", new BoolValue(false)));
+      Parameters.Add(new ValueLookupParameter<IGQAPEvaluator>("Evaluator", "The evaluator that is used to evaluate GQAP solutions."));
     }
 
@@ -57,5 +62,7 @@
     }
 
-    public static IntegerVector CreateSolution(IRandom random, DoubleArray demands, DoubleArray capacities, int maximumTries, bool createMostFeasibleSolution, CancellationToken cancel) {
+    public static IntegerVector CreateSolution(IRandom random, DoubleArray demands,
+      DoubleArray capacities, IGQAPEvaluator evaluator,
+      int maximumTries, bool createMostFeasibleSolution, CancellationToken cancel) {
       IntegerVector result = null;
       bool isFeasible = false;
@@ -80,5 +87,5 @@
           slack[assignment[equipment]] -= demands[equipment];
         }
-        double violation = GQAPEvaluator.EvaluateOverbooking(slack, capacities);
+        double violation = evaluator.EvaluateOverbooking(slack, capacities);
         isFeasible = violation == 0;
         if (isFeasible || violation < minViolation) {
@@ -92,4 +99,5 @@
     protected override IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities) {
       return CreateSolution(random, demands, capacities,
+        EvaluatorParameter.ActualValue,
         MaximumTriesParameter.ActualValue.Value,
         CreateMostFeasibleSolutionParameter.ActualValue.Value,
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/SlackMinimizationSolutionCreator.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/SlackMinimizationSolutionCreator.cs	(revision 7968)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/SlackMinimizationSolutionCreator.cs	(revision 7970)
@@ -35,5 +35,6 @@
   [Item("SlackMinimizationSolutionCreator", "A heuristic that creates a solution to the Generalized Quadratic Assignment Problem by minimizing the amount of slack.")]
   [StorableClass]
-  public class SlackMinimizationSolutionCreator : GQAPStochasticSolutionCreator {
+  public class SlackMinimizationSolutionCreator : GQAPStochasticSolutionCreator,
+    IEvaluatorAwareGQAPOperator {
 
     public IValueLookupParameter<IntValue> MaximumTriesParameter {
@@ -49,4 +50,7 @@
       get { return (IValueLookupParameter<IntValue>)Parameters["RandomWalkLength"]; }
     }
+    public IValueLookupParameter<IGQAPEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IGQAPEvaluator>)Parameters["Evaluator"]; }
+    }
 
     [StorableConstructor]
@@ -59,4 +63,5 @@
       Parameters.Add(new ValueLookupParameter<IntValue>("Depth", "How deep the algorithm should look forward.", new IntValue(3)));
       Parameters.Add(new ValueLookupParameter<IntValue>("RandomWalkLength", "The length of the random walk in the feasible region that is used to diversify the found assignments.", new IntValue(10)));
+      Parameters.Add(new ValueLookupParameter<IGQAPEvaluator>("Evaluator", "The evaluator that is used to evaluate GQAP solutions."));
     }
 
@@ -75,5 +80,7 @@
     }
 
-    public static IntegerVector CreateSolution(IRandom random, DoubleArray demands, DoubleArray capacities, int depth, int maximumTries, bool createMostFeasibleSolution, int randomWalkLength, CancellationToken cancel) {
+    public static IntegerVector CreateSolution(IRandom random, DoubleArray demands,
+      DoubleArray capacities, IGQAPEvaluator evaluator,
+      int depth, int maximumTries, bool createMostFeasibleSolution, int randomWalkLength, CancellationToken cancel) {
       IntegerVector result = null;
       bool isFeasible = false;
@@ -118,5 +125,5 @@
           }
         } else RandomFeasibleWalk(random, assignment, demands, slack, randomWalkLength);
-        double violation = GQAPEvaluator.EvaluateOverbooking(slack, capacities);
+        double violation = evaluator.EvaluateOverbooking(slack, capacities);
         isFeasible = violation == 0;
         if (isFeasible || violation < minViolation) {
@@ -177,4 +184,5 @@
     protected override IntegerVector CreateRandomSolution(IRandom random, DoubleArray demands, DoubleArray capacities) {
       return CreateSolution(random, demands, capacities,
+        EvaluatorParameter.ActualValue,
         DepthParameter.ActualValue.Value,
         MaximumTriesParameter.ActualValue.Value,
Index: branches/GeneralizedQAP/UnitTests/CordeauCrossoverTest.cs
===================================================================
--- branches/GeneralizedQAP/UnitTests/CordeauCrossoverTest.cs	(revision 7968)
+++ branches/GeneralizedQAP/UnitTests/CordeauCrossoverTest.cs	(revision 7970)
@@ -46,8 +46,8 @@
           CordeauCrossover.Apply(random, gqap.Maximization,
             parent1,
-            new DoubleValue(GQAPEvaluator.Evaluate(parent1, gqap.Weights, gqap.Distances, gqap.InstallationCosts, gqap.Demands, gqap.Capacities, gqap.TransportationCosts, gqap.OverbookedCapacityPenalty)),
+            new DoubleValue(gqap.Evaluator.Evaluate(parent1, gqap.Weights, gqap.Distances, gqap.InstallationCosts, gqap.Demands, gqap.Capacities, gqap.TransportationCosts, gqap.ExpectedRandomQuality)),
             parent2,
-            new DoubleValue(GQAPEvaluator.Evaluate(parent2, gqap.Weights, gqap.Distances, gqap.InstallationCosts, gqap.Demands, gqap.Capacities, gqap.TransportationCosts, gqap.OverbookedCapacityPenalty)),
-            gqap.Weights, gqap.Distances, gqap.InstallationCosts, gqap.Demands, gqap.Capacities, gqap.TransportationCosts, gqap.OverbookedCapacityPenalty);
+            new DoubleValue(gqap.Evaluator.Evaluate(parent2, gqap.Weights, gqap.Distances, gqap.InstallationCosts, gqap.Demands, gqap.Capacities, gqap.TransportationCosts, gqap.ExpectedRandomQuality)),
+            gqap.Weights, gqap.Distances, gqap.InstallationCosts, gqap.Demands, gqap.Capacities, gqap.TransportationCosts, gqap.ExpectedRandomQuality, gqap.Evaluator);
         } catch {
           Assert.Fail("Error during crossover");
Index: branches/GeneralizedQAP/UnitTests/GQAPNMoveEvaluatorTest.cs
===================================================================
--- branches/GeneralizedQAP/UnitTests/GQAPNMoveEvaluatorTest.cs	(revision 7968)
+++ branches/GeneralizedQAP/UnitTests/GQAPNMoveEvaluatorTest.cs	(revision 7970)
@@ -39,5 +39,5 @@
     private static DoubleMatrix installationCosts;
     private static DoubleArray demands, capacities;
-    private static DoubleValue transportationCosts, overbookedCapacityPenalty;
+    private static double transportationCosts, overbookedCapacityPenalty;
     private static IntegerVector assignment;
     private static MersenneTwister random;
@@ -107,6 +107,6 @@
         nonZeroDiagonalWeights[index, index] = random.Next(1, Equipments * 100);
 
-      transportationCosts = new DoubleValue(random.NextDouble() * 10);
-      overbookedCapacityPenalty = new DoubleValue(1000 * random.NextDouble() + 100);
+      transportationCosts = random.NextDouble() * 10;
+      overbookedCapacityPenalty = 1000 * random.NextDouble() + 100;
       assignment = new IntegerVector(Equipments, random, 0, Locations);
     }
@@ -119,23 +119,24 @@
     [TestMethod()]
     public void EvaluateTest() {
+      var evaluator = new GQAPAdditivePenaltyEvaluator();
       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);
+        double before = evaluator.Evaluate(prevAssignment, symmetricWeights, symmetricDistances, installationCosts, demands, capacities, transportationCosts, 0);
+        double after = evaluator.Evaluate(assignment, symmetricWeights, symmetricDistances, installationCosts, demands, capacities, transportationCosts, 0);
+        double moveDiff = GQAPNMoveEvaluator.Evaluate(currentMove, prevAssignment, symmetricWeights, symmetricDistances, installationCosts, demands, capacities, transportationCosts, 0, evaluator);
         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);
+        before = evaluator.Evaluate(prevAssignment, asymmetricWeights, asymmetricDistances, installationCosts, demands, capacities, transportationCosts, 0);
+        after = evaluator.Evaluate(assignment, asymmetricWeights, asymmetricDistances, installationCosts, demands, capacities, transportationCosts, 0);
+        moveDiff = GQAPNMoveEvaluator.Evaluate(currentMove, prevAssignment, asymmetricWeights, asymmetricDistances, installationCosts, demands, capacities, transportationCosts, 0, evaluator);
         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);
+        before = evaluator.Evaluate(prevAssignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances, installationCosts, demands, capacities, transportationCosts, 0);
+        after = evaluator.Evaluate(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances, installationCosts, demands, capacities, transportationCosts, 0);
+        moveDiff = GQAPNMoveEvaluator.Evaluate(currentMove, prevAssignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances, installationCosts, demands, capacities, transportationCosts, 0, evaluator);
         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/UnitTests.csproj
===================================================================
--- branches/GeneralizedQAP/UnitTests/UnitTests.csproj	(revision 7968)
+++ branches/GeneralizedQAP/UnitTests/UnitTests.csproj	(revision 7970)
@@ -81,10 +81,10 @@
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
       <SpecificVersion>False</SpecificVersion>
-      <Private>False</Private>
+      <Private>True</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.Instances.CordeauGQAP-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances.CordeauGQAP-3.3.dll</HintPath>
       <SpecificVersion>False</SpecificVersion>
-      <Private>False</Private>
+      <Private>True</Private>
     </Reference>
     <Reference Include="HeuristicLab.Random-3.3">
