Index: branches/2457_ExpertSystem/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAP.cs
===================================================================
--- branches/1614_GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAP.cs	(revision 16728)
+++ branches/2457_ExpertSystem/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAP.cs	(revision 17175)
@@ -34,5 +34,4 @@
 using HeuristicLab.PluginInfrastructure;
 using HeuristicLab.Problems.Instances;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
@@ -96,7 +95,7 @@
     public GQAP() : base() {
       Encoding = new IntegerVectorEncoding("Assignment");
-      Parameters.Add(new OptionalValueParameter<GQAPAssignment>("BestKnownSolution", BestKnownSolutionDescription, null, false));
-      Parameters.Add(new OptionalValueParameter<GQAPAssignmentArchive>("BestKnownSolutions", BestKnownSolutionsDescription, null, false));
-      Parameters.Add(new ValueParameter<GQAPInstance>("ProblemInstance", "The problem instance that is to be solved.", new GQAPInstance(), false));
+      Parameters.Add(new OptionalValueParameter<GQAPAssignment>("BestKnownSolution", BestKnownSolutionDescription, null) { GetsCollected = false });
+      Parameters.Add(new OptionalValueParameter<GQAPAssignmentArchive>("BestKnownSolutions", BestKnownSolutionsDescription, null) { GetsCollected = false });
+      Parameters.Add(new ValueParameter<GQAPInstance>("ProblemInstance", "The problem instance that is to be solved.", new GQAPInstance()) { GetsCollected = false });
 
       InitializeOperators();
Index: branches/2457_ExpertSystem/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPInstance.cs
===================================================================
--- branches/1614_GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPInstance.cs	(revision 16728)
+++ branches/2457_ExpertSystem/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPInstance.cs	(revision 17175)
@@ -27,5 +27,4 @@
 using HeuristicLab.Encodings.IntegerVectorEncoding;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment {
@@ -146,13 +145,13 @@
     }
     public GQAPInstance() {
-      Parameters.Add(weightsParam = new ValueParameter<DoubleMatrix>("Weights", WeightsDescription, new DoubleMatrix(), false));
-      Parameters.Add(distancesParam = new ValueParameter<DoubleMatrix>("Distances", DistancesDescription, new DoubleMatrix(), false));
-      Parameters.Add(installCostsParam = new ValueParameter<DoubleMatrix>("InstallationCosts", InstallationCostsDescription, new DoubleMatrix(), false));
+      Parameters.Add(weightsParam = new ValueParameter<DoubleMatrix>("Weights", WeightsDescription, new DoubleMatrix()) { GetsCollected = false });
+      Parameters.Add(distancesParam = new ValueParameter<DoubleMatrix>("Distances", DistancesDescription, new DoubleMatrix()) { GetsCollected = false });
+      Parameters.Add(installCostsParam = new ValueParameter<DoubleMatrix>("InstallationCosts", InstallationCostsDescription, new DoubleMatrix()) { GetsCollected = false });
       Parameters.Add(transportationCostsParam = new FixedValueParameter<DoubleValue>("TransportationCosts", TransportationCostsDescription, new DoubleValue(1)));
-      Parameters.Add(penaltyLevelParam = new FixedValueParameter<DoubleValue>("PenaltyLevel", PenaltyLevelDescription, new DoubleValue(0), true));
-      Parameters.Add(demandsParam = new ValueParameter<DoubleArray>("Demands", DemandsDescription, new DoubleArray(), false));
-      Parameters.Add(capacitiesParam = new ValueParameter<DoubleArray>("Capacities", CapacitiesDescription, new DoubleArray(), false));
-      Parameters.Add(equipmentNamesParam = new OptionalValueParameter<StringArray>("EquipmentNames", EquipmentNamesDescription, null, false));
-      Parameters.Add(locationNamesParam = new OptionalValueParameter<StringArray>("LocationNames", LocationNamesDescription, null, false));
+      Parameters.Add(penaltyLevelParam = new FixedValueParameter<DoubleValue>("PenaltyLevel", PenaltyLevelDescription, new DoubleValue(0)));
+      Parameters.Add(demandsParam = new ValueParameter<DoubleArray>("Demands", DemandsDescription, new DoubleArray()) { GetsCollected = false });
+      Parameters.Add(capacitiesParam = new ValueParameter<DoubleArray>("Capacities", CapacitiesDescription, new DoubleArray()) { GetsCollected = false });
+      Parameters.Add(equipmentNamesParam = new OptionalValueParameter<StringArray>("EquipmentNames", EquipmentNamesDescription, null) { GetsCollected = false });
+      Parameters.Add(locationNamesParam = new OptionalValueParameter<StringArray>("LocationNames", LocationNamesDescription, null) { GetsCollected = false });
 
       weightsParam.ReactOnValueToStringChangedAndValueItemImageChanged = false;
Index: branches/2457_ExpertSystem/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj
===================================================================
--- branches/1614_GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj	(revision 16728)
+++ branches/2457_ExpertSystem/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj	(revision 17175)
@@ -117,4 +117,5 @@
     <Compile Include="Moves\ExhaustiveOneMoveGenerator.cs" />
     <Compile Include="Operators\Crossovers\CordeauCrossover.cs" />
+    <Compile Include="Operators\GQAPQualitySimilarityReducer.cs" />
     <Compile Include="Operators\LocalImprovers\OneOptLocalSearch.cs" />
     <Compile Include="SolutionCreators\SlackMinimizationSolutionCreator.cs" />
Index: branches/2457_ExpertSystem/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPQualitySimilarityReducer.cs
===================================================================
--- branches/2457_ExpertSystem/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPQualitySimilarityReducer.cs	(revision 17175)
+++ branches/2457_ExpertSystem/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/GQAPQualitySimilarityReducer.cs	(revision 17175)
@@ -0,0 +1,124 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Operators {
+  [Item("GQAPQualitySimilarityReducer", "Reduces two populations two one by using quality and similarity information to obtain a population of high quality, but also diverse solutions.")]
+  [StorableType("3E9B9095-C0FE-4B16-B2FD-9EC349A37CD2")]
+  public class GQAPQualitySimilarityReducer : SingleSuccessorOperator, IQualityAwareGQAPOperator, IAssignmentAwareGQAPOperator, IReducer {
+    public ILookupParameter<IntegerVector> AssignmentParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<Evaluation> EvaluationParameter {
+      get { return (ILookupParameter<Evaluation>)Parameters["Evaluation"]; }
+    }
+    public ILookupParameter<IntValue> MinimumPopulationSizeParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["MinimumPopulationSize"]; }
+    }
+    public ILookupParameter<IntValue> MaximumPopulationSizeParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["MaximumPopulationSize"]; }
+    }
+
+    [StorableConstructor]
+    protected GQAPQualitySimilarityReducer(StorableConstructorFlag _) : base(_) { }
+    protected GQAPQualitySimilarityReducer(GQAPQualitySimilarityReducer original, Cloner cloner) : base(original, cloner) { }
+    public GQAPQualitySimilarityReducer()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("Assignment", GQAPSolutionCreator.AssignmentDescription));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", ""));
+      Parameters.Add(new LookupParameter<Evaluation>("Evaluation", GQAP.EvaluationDescription));
+      Parameters.Add(new LookupParameter<IntValue>("MinimumPopulationSize", "The size of the population that should not be undershot."));
+      Parameters.Add(new LookupParameter<IntValue>("MaximumPopulationSize", "The size of the population that should not be surpassed."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GQAPQualitySimilarityReducer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      string vectorName = AssignmentParameter.TranslatedName;
+      string qualityName = QualityParameter.TranslatedName;
+      int populationSize = MaximumPopulationSizeParameter.ActualValue.Value;
+
+      IScope remaining = ExecutionContext.Scope.SubScopes[0];
+      IScope selected = ExecutionContext.Scope.SubScopes[1];
+
+      List<Individual> population =
+        remaining.SubScopes.Select(x => new Individual((IntegerVector)x.Variables[vectorName].Value,
+                                                      ((DoubleValue)x.Variables[qualityName].Value).Value,
+                                                      x)).ToList();
+      HashSet<Individual> candidates = new HashSet<Individual>(
+        selected.SubScopes.Select(x => new Individual((IntegerVector)x.Variables[vectorName].Value,
+                                                     ((DoubleValue)x.Variables[qualityName].Value).Value,
+                                                     x)));
+
+      foreach (var candidate in candidates) {
+        double[] similarities = population.Select(x => HammingSimilarityCalculator.CalculateSimilarity(x.Solution, candidate.Solution)).ToArray();
+        if (!similarities.Any()) {
+          population.Add(candidate);
+          break;
+        }
+        if (similarities.Max() == 1.0) break;
+        if (population.Count < populationSize) {
+          population.Add(candidate);
+        } else {
+          var replacement = population.Select((v, i) => new { V = v, Index = i })
+                                      .Where(x => x.V.Quality > candidate.Quality);
+          if (replacement.Any()) {
+            replacement.OrderBy(x => similarities[x.Index]).ToArray();
+            population.Remove(replacement.Last().V);
+            population.Add(candidate);
+          }
+        }
+      }
+
+      ExecutionContext.Scope.SubScopes.Clear();
+      ExecutionContext.Scope.SubScopes.AddRange(population.Select(x => x.Scope));
+
+      return base.Apply();
+    }
+
+    private class Individual {
+      internal IntegerVector Solution { get; set; }
+      internal double Quality { get; set; }
+      internal IScope Scope { get; set; }
+
+      internal Individual(IntegerVector vector, double quality, IScope scope) {
+        Solution = vector;
+        Quality = quality;
+        Scope = scope;
+      }
+    }
+  }
+}
