Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/HeuristicLab.Algorithms.ScatterSearch-3.3.csproj
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/HeuristicLab.Algorithms.ScatterSearch-3.3.csproj	(revision 7739)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/HeuristicLab.Algorithms.ScatterSearch-3.3.csproj	(revision 7740)
@@ -54,4 +54,5 @@
     </Reference>
     <Reference Include="HeuristicLab.Encodings.BinaryVectorEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Encodings.PermutationEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Operators-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
@@ -71,4 +72,5 @@
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Problems.Knapsack-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Problems.TravelingSalesman-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Random-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
@@ -84,4 +86,13 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Knapsack\DiversityCalculator.cs" />
+    <Compile Include="Knapsack\INBinaryVectorCrossover.cs" />
+    <Compile Include="Knapsack\NBinaryVectorCrossover.cs" />
+    <Compile Include="Knapsack\NChildCrossover.cs" />
+    <Compile Include="OffspringProcessor.cs" />
+    <Compile Include="TSPPopulationRebuildMethod.cs" />
+    <Compile Include="TSPSolutionPoolUpdateMethod.cs" />
+    <Compile Include="TSPReferenceSetUpdateMethod.cs" />
+    <Compile Include="TSPScatterSearchImprovementOperator.cs" />
     <None Include="HeuristicLab.snk" />
     <None Include="Plugin.cs.frame" />
@@ -94,5 +105,4 @@
     <Compile Include="ScatterSearchImprovementOperator.cs" />
     <Compile Include="ScatterSearchMainLoop.cs" />
-    <Compile Include="SolutionCombinationMethod.cs" />
     <Compile Include="SolutionPoolUpdateMethod.cs" />
   </ItemGroup>
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/DiversityCalculator.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/DiversityCalculator.cs	(revision 7740)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/DiversityCalculator.cs	(revision 7740)
@@ -0,0 +1,16 @@
+﻿using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+
+namespace HeuristicLab.Algorithms.ScatterSearch.Knapsack {
+  public sealed class DiversityCalculator {
+    public static int CalculateDiversity(IItem p, IItem r) {
+      BinaryVector pSol = p as BinaryVector;
+      BinaryVector rSol = r as BinaryVector;
+      int diversity = 0;
+      if (pSol != null && rSol != null)
+        for (int i = 0; i < pSol.Length; i++)
+          if (pSol[i] != rSol[i]) diversity++;
+      return diversity;
+    }
+  }
+}
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/INBinaryVectorCrossover.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/INBinaryVectorCrossover.cs	(revision 7740)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/INBinaryVectorCrossover.cs	(revision 7740)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Algorithms.ScatterSearch.Knapsack {
+  /// <summary>
+  /// An interface which represents an operator for crossing vectors of bool-valued data.
+  /// </summary>
+  public interface INBinaryVectorCrossover : IBinaryVectorOperator, ICrossover {
+    ILookupParameter<ItemArray<BinaryVector>> ParentsParameter { get; }
+  }
+}
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NBinaryVectorCrossover.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NBinaryVectorCrossover.cs	(revision 7740)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NBinaryVectorCrossover.cs	(revision 7740)
@@ -0,0 +1,83 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ScatterSearch.Knapsack {
+  /// <summary>
+  /// A base class for operators that perform a crossover of bool-valued vectors.
+  /// </summary>
+  [Item("NBinaryVectorCrossover", "A base class for operators that perform a crossover of bool-valued vectors.")]
+  [StorableClass]
+  public abstract class NBinaryVectorCrossover : SingleSuccessorOperator, INBinaryVectorCrossover, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    #region Parameter properties
+    public ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<ItemArray<BinaryVector>> ParentsParameter {
+      get { return (IScopeTreeLookupParameter<BinaryVector>)Parameters["Parents"]; }
+    }
+    #endregion
+
+    #region Properties
+    private IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected NBinaryVectorCrossover(bool deserializing) : base(deserializing) { }
+    protected NBinaryVectorCrossover(NBinaryVectorCrossover original, Cloner cloner) : base(original, cloner) { }
+    protected NBinaryVectorCrossover()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new ScopeParameter("CurrentScope"));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic crossover operators."));
+      Parameters.Add(new ScopeTreeLookupParameter<BinaryVector>("Parents", "The parent vectors which should be crossed."));
+      #endregion
+      ParentsParameter.ActualName = "BinaryVector";
+    }
+
+    public sealed override IOperation Apply() {
+      //ChildrenParameter.ActualValue = Cross(RandomParameter.ActualValue, ParentsParameter.ActualValue);
+      var offspringSolutions = Cross(RandomParameter.ActualValue, ParentsParameter.ActualValue);
+      for (int i = 0; i < offspringSolutions.Length; i++) {
+        CurrentScope.Variables.Add(new Variable(string.Format("Child {0}", i), offspringSolutions[i]));
+      }
+      return base.Apply();
+    }
+
+    protected abstract ItemArray<BinaryVector> Cross(IRandom random, ItemArray<BinaryVector> parents);
+  }
+}
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NChildCrossover.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NChildCrossover.cs	(revision 7740)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NChildCrossover.cs	(revision 7740)
@@ -0,0 +1,83 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ScatterSearch.Knapsack {
+  /// <summary>
+  /// N child crossover for binary vectors.
+  /// </summary>
+  [Item("NChildCrossover", "N child crossover for binary vectors.")]
+  [StorableClass]
+  public sealed class NChildCrossover : NBinaryVectorCrossover {
+    public IValueLookupParameter<IntValue> NParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["N"]; }
+    }
+
+    [StorableConstructor]
+    private NChildCrossover(bool deserializing) : base(deserializing) { }
+    private NChildCrossover(NChildCrossover original, Cloner cloner) : base(original, cloner) { }
+    public NChildCrossover()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("N", "Number of children.", new IntValue(2)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NChildCrossover(this, cloner);
+    }
+
+    public static ItemArray<BinaryVector> Apply(IRandom random, BinaryVector parent1, BinaryVector parent2, IntValue n) {
+      if (parent1.Length != parent2.Length)
+        throw new ArgumentException("NPointCrossover: The parents are of different length.");
+
+      if (n.Value > Math.Pow(2, parent1.Length) - 2)
+        throw new ArgumentException("NPointCrossover: There cannot be more breakpoints than the size of the parents.");
+
+      if (n.Value < 1)
+        throw new ArgumentException("NPointCrossover: N cannot be < 1.");
+
+      var solutions = new BinaryVector[n.Value];
+      for (int i = 0; i < n.Value; i++) {
+        var solution = new BinaryVector(parent1.Length);
+        for (int j = 0; j < solution.Length; j++) {
+          solution[j] = random.Next(2) % 2 == 0 ? parent1[j] : parent2[j];
+        }
+        solutions[i] = solution;
+      }
+
+      return new ItemArray<BinaryVector>(solutions);
+    }
+
+    protected override ItemArray<BinaryVector> Cross(IRandom random, ItemArray<BinaryVector> parents) {
+      if (parents.Length != 2) throw new ArgumentException("ERROR in NChildCrossover: The number of parents is not equal to 2");
+
+      if (NParameter.ActualValue == null) throw new InvalidOperationException("NChildCrossover: Parameter " + NParameter.ActualName + " could not be found.");
+
+      return Apply(random, parents[0], parents[1], NParameter.Value);
+    }
+  }
+}
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/PopulationRebuildMethod.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/PopulationRebuildMethod.cs	(revision 7739)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/PopulationRebuildMethod.cs	(revision 7740)
@@ -30,18 +30,21 @@
 namespace HeuristicLab.Algorithms.ScatterSearch {
   /// <summary>
-  /// An operator that updates a population.
+  /// An operator that updates the reference set and rebuilds the population.
   /// </summary>
-  [Item("PopulationRebuildMethod", "An operator that rebuilds the population.")]
+  [Item("PopulationRebuildMethod", "An operator that updates the reference set and rebuilds the population.")]
   [StorableClass]
   public sealed class PopulationRebuildMethod : SingleSuccessorOperator {
     #region Parameter properties
-    private ScopeParameter CurrentScopeParameter {
+    public ScopeParameter CurrentScopeParameter {
       get { return (ScopeParameter)Parameters["CurrentScope"]; }
     }
-    private ValueLookupParameter<IntValue> NumberOfHighQualitySolutionsParameter {
-      get { return (ValueLookupParameter<IntValue>)Parameters["NumberOfHighQualitySolutions"]; }
+    public IValueLookupParameter<IntValue> NumberOfHighQualitySolutionsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["NumberOfHighQualitySolutions"]; }
     }
-    private ValueLookupParameter<IntValue> ReferenceSetSizeParameter {
-      get { return (ValueLookupParameter<IntValue>)Parameters["ReferenceSetSize"]; }
+    public IValueLookupParameter<IntValue> ReferenceSetSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["ReferenceSetSize"]; }
+    }
+    public IValueLookupParameter<IItem> QualityParameter {
+      get { return (IValueLookupParameter<IItem>)Parameters["Quality"]; }
     }
     #endregion
@@ -59,4 +62,7 @@
       set { ReferenceSetSizeParameter.ActualValue = value; }
     }
+    private IItem Quality {
+      get { return QualityParameter.ActualValue; }
+    }
     #endregion
 
@@ -72,20 +78,15 @@
     private void Initialize() {
       #region Create parameters
-      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope to which the new solutions are added as sub-scopes."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("NumberOfHighQualitySolutions", "The number of high quality solutions that should be added to the reference set."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("ReferenceSetSize", "The size of the reference set."));
-      #endregion
-
-      #region Create operators
-      #endregion
-
-      #region Create operator graph
+      Parameters.Add(new ScopeParameter("CurrentScope"));
+      Parameters.Add(new ValueLookupParameter<IntValue>("NumberOfHighQualitySolutions"));
+      Parameters.Add(new ValueLookupParameter<IntValue>("ReferenceSetSize"));
+      Parameters.Add(new ValueLookupParameter<IItem>("Quality"));
       #endregion
     }
 
     public override IOperation Apply() {
-      IScope population = CurrentScope.SubScopes[0];
-      IScope refSet = CurrentScope.SubScopes[1];
-      refSet.SubScopes.Replace(refSet.SubScopes.OrderByDescending(r => r.Variables["Quality"].Value)
+      var population = CurrentScope.SubScopes[0];
+      var refSet = CurrentScope.SubScopes[1];
+      refSet.SubScopes.Replace(refSet.SubScopes.OrderByDescending(r => r.Variables[QualityParameter.ActualName].Value)
                                                .Take(NumberOfHighQualitySolutions.Value).ToList());
       population.SubScopes.Clear();
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ReferenceSetUpdateMethod.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ReferenceSetUpdateMethod.cs	(revision 7739)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ReferenceSetUpdateMethod.cs	(revision 7740)
@@ -20,8 +20,9 @@
 #endregion
 
+using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.BinaryVectorEncoding;
 using HeuristicLab.Operators;
 using HeuristicLab.Parameters;
@@ -36,26 +37,30 @@
   public sealed class ReferenceSetUpdateMethod : SingleSuccessorOperator {
     #region Parameter properties
-    private ScopeParameter CurrentScopeParameter {
+    public ScopeParameter CurrentScopeParameter {
       get { return (ScopeParameter)Parameters["CurrentScope"]; }
     }
-    public ValueLookupParameter<IntValue> NumberOfHighQualitySolutionsParameter {
-      get { return (ValueLookupParameter<IntValue>)Parameters["NumberOfHighQualitySolutions"]; }
+    public IValueLookupParameter<IntValue> NumberOfHighQualitySolutionsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["NumberOfHighQualitySolutions"]; }
     }
-    public ValueLookupParameter<IntValue> ReferenceSetSizeParameter {
-      get { return (ValueLookupParameter<IntValue>)Parameters["ReferenceSetSize"]; }
+    public IValueLookupParameter<IntValue> ReferenceSetSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["ReferenceSetSize"]; }
+    }
+    public IValueLookupParameter<IItem> QualityParameter {
+      get { return (IValueLookupParameter<IItem>)Parameters["Quality"]; }
     }
     #endregion
 
     #region Properties
-    public IScope CurrentScope {
+    private IScope CurrentScope {
       get { return CurrentScopeParameter.ActualValue; }
     }
-    public IntValue NumberOfHighQualitySolutions {
+    private IntValue NumberOfHighQualitySolutions {
       get { return NumberOfHighQualitySolutionsParameter.ActualValue; }
-      set { NumberOfHighQualitySolutionsParameter.ActualValue = value; }
     }
-    public IntValue ReferenceSetSize {
+    private IntValue ReferenceSetSize {
       get { return ReferenceSetSizeParameter.ActualValue; }
-      set { ReferenceSetSizeParameter.ActualValue = value; }
+    }
+    private IItem Quality {
+      get { return QualityParameter.ActualValue; }
     }
     #endregion
@@ -72,44 +77,28 @@
     private void Initialize() {
       #region Create parameters
-      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope to which the new solutions are added as sub-scopes."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("NumberOfHighQualitySolutions", "The number of high quality solutions that should be added to the reference set."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("ReferenceSetSize", "The size of the reference set."));
-      #endregion
-
-      #region Create operators
-      #endregion
-
-      #region Create operator graph
+      Parameters.Add(new ScopeParameter("CurrentScope"));
+      Parameters.Add(new ValueLookupParameter<IntValue>("NumberOfHighQualitySolutions"));
+      Parameters.Add(new ValueLookupParameter<IntValue>("ReferenceSetSize"));
+      Parameters.Add(new ValueLookupParameter<IItem>("Quality"));
       #endregion
     }
 
     public override IOperation Apply() {
-      for (int i = 0; i < ReferenceSetSize.Value - NumberOfHighQualitySolutions.Value; i++) {
-        IScope mostDiverseSolution = null;
-        int maxDiversity = 0;
-        foreach (var p in CurrentScope.SubScopes[0].SubScopes) {
-          int diversity = 0;
-          BinaryVector pSol = p.Variables["KnapsackSolution"].Value as BinaryVector;
-          foreach (var r in CurrentScope.SubScopes[1].SubScopes) {
-            BinaryVector rSol = r.Variables["KnapsackSolution"].Value as BinaryVector;
-            if (pSol != null && rSol != null) diversity += CalculateDiversity(pSol, rSol);
-          }
-          if (mostDiverseSolution == null || diversity > maxDiversity) {
-            mostDiverseSolution = p;
-            maxDiversity = diversity;
-          }
+      var population = new Dictionary<IScope, double>();
+      foreach (var pScope in CurrentScope.SubScopes[0].SubScopes) {
+        int diversity = 0;
+        var pSol = pScope.Variables[QualityParameter.ActualName].Value;
+        foreach (var rScope in CurrentScope.SubScopes[1].SubScopes) {
+          var rSol = rScope.Variables[QualityParameter.ActualName].Value;
+          if (pSol != null && rSol != null) diversity += Knapsack.DiversityCalculator.CalculateDiversity(pSol, rSol);
         }
-        CurrentScope.SubScopes[1].SubScopes.Add(mostDiverseSolution); // Update parent?
-        CurrentScope.SubScopes[0].SubScopes.Remove(mostDiverseSolution); // Update parent?
+        population[pScope] = diversity;
+      }
+      foreach (var entry in population.OrderByDescending(x => x.Value).Take(ReferenceSetSize.Value - NumberOfHighQualitySolutions.Value)) {
+        CurrentScope.SubScopes[1].SubScopes.Add(entry.Key);
+        CurrentScope.SubScopes[0].SubScopes.Remove(entry.Key);
       }
       return base.Apply();
     }
-
-    private int CalculateDiversity(BinaryVector pSol, BinaryVector rSol) {
-      int diversity = 0;
-      for (int i = 0; i < pSol.Length; i++)
-        if (pSol[i] != rSol[i]) diversity++;
-      return diversity;
-    }
   }
 }
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearch.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearch.cs	(revision 7739)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearch.cs	(revision 7740)
@@ -21,5 +21,4 @@
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Analysis;
@@ -56,99 +55,78 @@
 
     #region Parameter Properties
-    private ValueParameter<MultiAnalyzer> AnalyzerParameter {
-      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
-    }
-    private ValueParameter<ILocalImprovementOperator> ImproverParameter {
-      get { return (ValueParameter<ILocalImprovementOperator>)Parameters["Improver"]; }
-    }
-    private ValueParameter<IntValue> MaximumIterationsParameter {
-      get { return (ValueParameter<IntValue>)Parameters["MaximumIterations"]; }
-    }
-    private ConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
-      get { return (ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
-    }
-    private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
-      get { return (ConstrainedValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
-    }
-    private ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
-      get { return (ConstrainedValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
-    }
-    private ValueParameter<IntValue> NumberOfHighQualitySolutionsParameter {
-      get { return (ValueParameter<IntValue>)Parameters["NumberOfHighQualitySolutions"]; }
-    }
-    private ValueParameter<IntValue> PopulationSizeParameter {
-      get { return (ValueParameter<IntValue>)Parameters["PopulationSize"]; }
-    }
-    private ValueParameter<IntValue> ReferenceSetSizeParameter {
-      get { return (ValueParameter<IntValue>)Parameters["ReferenceSetSize"]; }
-    }
-    private ValueParameter<IntValue> SampleSizeParameter {
-      get { return (ValueParameter<IntValue>)Parameters["SampleSize"]; }
-    }
-    private ValueParameter<IntValue> SeedParameter {
-      get { return (ValueParameter<IntValue>)Parameters["Seed"]; }
-    }
-    private ValueParameter<BoolValue> SetSeedRandomlyParameter {
-      get { return (ValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
-    }
-    private RandomCreator RandomCreator {
-      get { return (RandomCreator)OperatorGraph.InitialOperator; }
-    }
-    private SolutionsCreator SolutionsCreator {
-      get { return (SolutionsCreator)RandomCreator.Successor; }
-    }
-    private ScatterSearchMainLoop MainLoop {
-      get { return FindMainLoop(SolutionsCreator.Successor); }
+    public IValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (IValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
+    }
+    public ConstrainedValueParameter<ICrossover> CrossoverParameter {
+      get { return (ConstrainedValueParameter<ICrossover>)Parameters["Crossover"]; }
+    }
+    public IValueParameter<ILocalImprovementOperator> ImproverParameter {
+      get { return (IValueParameter<ILocalImprovementOperator>)Parameters["Improver"]; }
+    }
+    public IValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public IValueParameter<IntValue> NumberOfHighQualitySolutionsParameter {
+      get { return (IValueParameter<IntValue>)Parameters["NumberOfHighQualitySolutions"]; }
+    }
+    public IValueParameter<IntValue> PopulationSizeParameter {
+      get { return (IValueParameter<IntValue>)Parameters["PopulationSize"]; }
+    }
+    public IValueParameter<IntValue> ReferenceSetSizeParameter {
+      get { return (IValueParameter<IntValue>)Parameters["ReferenceSetSize"]; }
+    }
+    public IValueParameter<IntValue> SeedParameter {
+      get { return (IValueParameter<IntValue>)Parameters["Seed"]; }
+    }
+    public IValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (IValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
     }
     #endregion
 
     #region Properties
-    public MultiAnalyzer Analyzer {
+    private MultiAnalyzer Analyzer {
       get { return AnalyzerParameter.Value; }
       set { AnalyzerParameter.Value = value; }
     }
-    public ILocalImprovementOperator Improver {
+    private ICrossover Crossover {
+      get { return CrossoverParameter.Value; }
+      set { CrossoverParameter.Value = value; }
+    }
+    private ILocalImprovementOperator Improver {
       get { return ImproverParameter.Value; }
       set { ImproverParameter.Value = value; }
     }
-    public IntValue MaximumIterations {
+    private IntValue MaximumIterations {
       get { return MaximumIterationsParameter.Value; }
       set { MaximumIterationsParameter.Value = value; }
     }
-    public ISingleObjectiveMoveEvaluator MoveEvaluator {
-      get { return MoveEvaluatorParameter.Value; }
-      set { MoveEvaluatorParameter.Value = value; }
-    }
-    public IMoveGenerator MoveGenerator {
-      get { return MoveGeneratorParameter.Value; }
-      set { MoveGeneratorParameter.Value = value; }
-    }
-    public IMoveMaker MoveMaker {
-      get { return MoveMakerParameter.Value; }
-      set { MoveMakerParameter.Value = value; }
-    }
-    public IntValue NumberOfHighQualitySolutions {
+    private IntValue NumberOfHighQualitySolutions {
       get { return NumberOfHighQualitySolutionsParameter.Value; }
       set { NumberOfHighQualitySolutionsParameter.Value = value; }
     }
-    public IntValue PopulationSize {
+    private IntValue PopulationSize {
       get { return PopulationSizeParameter.Value; }
       set { PopulationSizeParameter.Value = value; }
     }
-    public IntValue ReferenceSetSize {
+    private IntValue ReferenceSetSize {
       get { return ReferenceSetSizeParameter.Value; }
       set { ReferenceSetSizeParameter.Value = value; }
     }
-    public IntValue SampleSize {
-      get { return SampleSizeParameter.Value; }
-      set { SampleSizeParameter.Value = value; }
-    }
-    public IntValue Seed {
+    private IntValue Seed {
       get { return SeedParameter.Value; }
       set { SeedParameter.Value = value; }
     }
-    public BoolValue SetSeedRandomly {
+    private BoolValue SetSeedRandomly {
       get { return SetSeedRandomlyParameter.Value; }
       set { SetSeedRandomlyParameter.Value = value; }
+    }
+    public RandomCreator RandomCreator {
+      get { return (RandomCreator)OperatorGraph.InitialOperator; }
+    }
+    public SolutionsCreator SolutionsCreator {
+      get { return (SolutionsCreator)RandomCreator.Successor; }
+    }
+    public ScatterSearchMainLoop MainLoop {
+      get { return FindMainLoop(SolutionsCreator.Successor); }
     }
 
@@ -175,13 +153,10 @@
       #region Create parameters
       Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solution and moves.", new MultiAnalyzer()));
+      Parameters.Add(new ConstrainedValueParameter<ICrossover>("Crossover", "The operator used to combine solutions."));
       Parameters.Add(new ValueParameter<ILocalImprovementOperator>("Improver", "The operator used to improve solutions.", new ScatterSearchImprovementOperator()));
       Parameters.Add(new ValueParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(1000)));
-      Parameters.Add(new ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>("MoveEvaluator", "The operator used to evaluate a move."));
-      Parameters.Add(new ConstrainedValueParameter<IMoveGenerator>("MoveGenerator", "The operator used to generate moves to the neighborhood of the current solution."));
-      Parameters.Add(new ConstrainedValueParameter<IMoveMaker>("MoveMaker", "The operator used to perform a move."));
       Parameters.Add(new ValueParameter<IntValue>("NumberOfHighQualitySolutions", "The number of high quality solutions that should be added to the reference set.", new IntValue(5)));
       Parameters.Add(new ValueParameter<IntValue>("PopulationSize", "The size of the population.", new IntValue(30)));
       Parameters.Add(new ValueParameter<IntValue>("ReferenceSetSize", "The size of the reference set.", new IntValue(10)));
-      Parameters.Add(new ValueParameter<IntValue>("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators.", new IntValue(100)));
       Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
       Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
@@ -239,4 +214,5 @@
       mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
       mainLoop.IterationsParameter.ActualName = "Iterations";
+      mainLoop.CrossoverParameter.ActualName = CrossoverParameter.Name;
       mainLoop.PopulationSizeParameter.ActualName = PopulationSizeParameter.Name;
       mainLoop.NumberOfHighQualitySolutionsParameter.ActualName = NumberOfHighQualitySolutionsParameter.Name;
@@ -252,6 +228,5 @@
 
     public override void Prepare() {
-      if (Problem != null && MoveGenerator != null && MoveMaker != null && MoveEvaluator != null)
-        base.Prepare();
+      base.Prepare();
     }
 
@@ -261,17 +236,9 @@
       ParameterizeStochasticOperator(Problem.Evaluator);
       foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
-      foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-        op.MoveQualityParameter.ActualNameChanged += new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
-      }
+      ParameterizeAnalyzers();
+      ParameterizeMainLoop();
       ParameterizeSolutionsCreator();
-      ParameterizeMainLoop();
-      UpdateMoveGenerator();
-      UpdateMoveParameters();
       UpdateAnalyzers();
-      ParameterizeMoveGenerators();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-      ParameterizeAnalyzers();
-      ParameterizeIterationBasedOperators();
+      UpdateCrossovers();
       Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
       base.OnProblemChanged();
@@ -286,6 +253,4 @@
       ParameterizeSolutionsCreator();
       ParameterizeMainLoop();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
       ParameterizeAnalyzers();
       Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
@@ -294,39 +259,13 @@
     protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
       foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
-      // This may seem pointless, but some operators already have the eventhandler registered, others don't
-      // FIXME: Is there another way to solve this problem?
-      foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-        op.MoveQualityParameter.ActualNameChanged -= new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
-        op.MoveQualityParameter.ActualNameChanged += new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
-      }
-      UpdateMoveGenerator();
-      UpdateMoveParameters();
       UpdateAnalyzers();
+      UpdateCrossovers();
       ParameterizeMainLoop();
-      ParameterizeMoveGenerators();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-      ParameterizeAnalyzers();
-      ParameterizeIterationBasedOperators();
+      ParameterizeAnalyzers();
       base.Problem_OperatorsChanged(sender, e);
     }
     private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
       ParameterizeMainLoop();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-    }
-    private void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
-      UpdateMoveParameters();
-    }
-    private void MoveEvaluatorParameter_ValueChanged(object sender, EventArgs e) {
-      ParameterizeMainLoop();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-      ParameterizeAnalyzers();
-    }
-    private void MoveEvaluator_MoveQualityParameter_ActualNameChanged(object sender, EventArgs e) {
-      ParameterizeMainLoop();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
+      ParameterizeAnalyzers();
     }
     #endregion
@@ -336,64 +275,4 @@
       if (Problem != null) {
         Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
-        foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-          op.MoveQualityParameter.ActualNameChanged += new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
-        }
-      }
-      MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
-      MoveEvaluatorParameter.ValueChanged += new EventHandler(MoveEvaluatorParameter_ValueChanged);
-    }
-    private void UpdateMoveGenerator() {
-      IMoveGenerator oldMoveGenerator = MoveGenerator;
-      IMoveGenerator defaultMoveGenerator = Problem.Operators.OfType<IMoveGenerator>().FirstOrDefault();
-      MoveGeneratorParameter.ValidValues.Clear();
-      if (Problem != null) {
-        foreach (IMoveGenerator generator in Problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
-          MoveGeneratorParameter.ValidValues.Add(generator);
-      }
-      if (oldMoveGenerator != null) {
-        IMoveGenerator newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
-        if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
-        else oldMoveGenerator = null;
-      }
-      if (oldMoveGenerator == null && defaultMoveGenerator != null)
-        MoveGenerator = defaultMoveGenerator;
-      if (MoveGenerator == null) {
-        ClearMoveParameters();
-      }
-    }
-    private void UpdateMoveParameters() {
-      IMoveMaker oldMoveMaker = MoveMaker;
-      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
-      ClearMoveParameters();
-      if (MoveGenerator != null) {
-        List<Type> moveTypes = MoveGenerator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
-        foreach (Type type in moveTypes.ToList()) {
-          if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
-            moveTypes.Remove(type);
-        }
-
-        var operators = Problem.Operators.Where(op => moveTypes.Any(m => m.IsInstanceOfType(op))).ToList();
-        IMoveMaker defaultMoveMaker = operators.OfType<IMoveMaker>().FirstOrDefault();
-        ISingleObjectiveMoveEvaluator defaultMoveEvaluator = operators.OfType<ISingleObjectiveMoveEvaluator>().FirstOrDefault();
-        foreach (IMoveMaker moveMaker in operators.OfType<IMoveMaker>().OrderBy(op => op.Name))
-          MoveMakerParameter.ValidValues.Add(moveMaker);
-        foreach (ISingleObjectiveMoveEvaluator moveEvaluator in operators.OfType<ISingleObjectiveMoveEvaluator>().OrderBy(op => op.Name))
-          MoveEvaluatorParameter.ValidValues.Add(moveEvaluator);
-
-        if (oldMoveMaker != null) {
-          IMoveMaker mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
-          if (mm != null) MoveMaker = mm;
-          else oldMoveMaker = null;
-        }
-        if (oldMoveMaker == null && defaultMoveMaker != null)
-          MoveMaker = defaultMoveMaker;
-
-        if (oldMoveEvaluator != null) {
-          ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
-          if (me != null) MoveEvaluator = me;
-          else oldMoveEvaluator = null;
-        }
-        if (oldMoveEvaluator == null && defaultMoveEvaluator != null)
-          MoveEvaluator = defaultMoveEvaluator;
       }
     }
@@ -409,7 +288,22 @@
       Analyzer.Operators.Add(qualityAnalyzer, qualityAnalyzer.EnabledByDefault);
     }
-    private void ClearMoveParameters() {
-      MoveMakerParameter.ValidValues.Clear();
-      MoveEvaluatorParameter.ValidValues.Clear();
+    private void UpdateCrossovers() {
+      ICrossover oldCrossover = CrossoverParameter.Value;
+      CrossoverParameter.ValidValues.Clear();
+      ICrossover defaultCrossover = Problem.Operators.OfType<ICrossover>().FirstOrDefault();
+
+      foreach (ICrossover crossover in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name))
+        CrossoverParameter.ValidValues.Add(crossover);
+
+      foreach (var crossover in CrossoverParameter.ValidValues.OfType<Knapsack.INBinaryVectorCrossover>())
+        crossover.ParentsParameter.ActualName = "KnapsackSolution"; // temporary solution for the knapsack problem
+
+      if (oldCrossover != null) {
+        ICrossover crossover = CrossoverParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldCrossover.GetType());
+        if (crossover != null) CrossoverParameter.Value = crossover;
+        else oldCrossover = null;
+      }
+      if (oldCrossover == null && defaultCrossover != null)
+        CrossoverParameter.Value = defaultCrossover;
     }
     private void ParameterizeSolutionsCreator() {
@@ -423,6 +317,4 @@
         MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
       }
-      if (MoveEvaluator != null)
-        MainLoop.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
     }
     private void ParameterizeStochasticOperator(IOperator op) {
@@ -431,30 +323,4 @@
         stOp.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
         stOp.RandomParameter.Hidden = true;
-      }
-    }
-    private void ParameterizeMoveGenerators() {
-      if (Problem != null) {
-        foreach (IMultiMoveGenerator generator in Problem.Operators.OfType<IMultiMoveGenerator>()) {
-          generator.SampleSizeParameter.ActualName = SampleSizeParameter.Name;
-          generator.SampleSizeParameter.Hidden = true;
-        }
-      }
-    }
-    private void ParameterizeMoveEvaluators() {
-      foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-        op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-        op.QualityParameter.Hidden = true;
-      }
-    }
-    private void ParameterizeMoveMakers() {
-      foreach (IMoveMaker op in Problem.Operators.OfType<IMoveMaker>()) {
-        op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-        op.QualityParameter.Hidden = true;
-        if (MoveEvaluator != null) {
-          op.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
-          op.MoveQualityParameter.Hidden = true;
-        } else {
-          op.MoveQualityParameter.Hidden = false;
-        }
       }
     }
@@ -465,7 +331,5 @@
         qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
         qualityAnalyzer.MaximizationParameter.Hidden = true;
-        if (MoveEvaluator != null) {
-          qualityAnalyzer.QualityParameter.Hidden = true;
-        } else qualityAnalyzer.QualityParameter.Hidden = false;
+        qualityAnalyzer.QualityParameter.Hidden = false;
         qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
         qualityAnalyzer.BestKnownQualityParameter.Hidden = true;
@@ -473,14 +337,4 @@
         qualityAnalyzer.MaximizationParameter.Hidden = false;
         qualityAnalyzer.BestKnownQualityParameter.Hidden = false;
-      }
-    }
-    private void ParameterizeIterationBasedOperators() {
-      if (Problem != null) {
-        foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
-          op.IterationsParameter.ActualName = "Iterations";
-          op.IterationsParameter.Hidden = true;
-          op.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
-          op.MaximumIterationsParameter.Hidden = true;
-        }
       }
     }
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearchImprovementOperator.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearchImprovementOperator.cs	(revision 7739)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearchImprovementOperator.cs	(revision 7740)
@@ -79,16 +79,16 @@
 
     #region Properties
-    public IScope CurrentScope {
+    private IScope CurrentScope {
       get { return CurrentScopeParameter.ActualValue; }
     }
-    public IntArray Values {
+    private IntArray Values {
       get { return ValuesParameter.ActualValue; }
       set { ValuesParameter.ActualValue = value; }
     }
-    public IntArray Weights {
+    private IntArray Weights {
       get { return WeightsParameter.ActualValue; }
       set { WeightsParameter.ActualValue = value; }
     }
-    public IntValue KnapsackCapacity {
+    private IntValue KnapsackCapacity {
       get { return KnapsackCapacityParameter.ActualValue; }
       set { KnapsackCapacityParameter.ActualValue = value; }
@@ -104,8 +104,10 @@
     public ScatterSearchImprovementOperator()
       : base() {
-      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope."));
-      Parameters.Add(new LookupParameter<IntArray>("Values", "The values of the items."));
-      Parameters.Add(new LookupParameter<IntArray>("Weights", "The weights of the items."));
-      Parameters.Add(new LookupParameter<IntValue>("KnapsackCapacity", "The size of the knapsack."));
+      #region Create parameters
+      Parameters.Add(new ScopeParameter("CurrentScope"));
+      Parameters.Add(new LookupParameter<IntArray>("Values"));
+      Parameters.Add(new LookupParameter<IntArray>("Weights"));
+      Parameters.Add(new LookupParameter<IntValue>("KnapsackCapacity"));
+      #endregion
     }
 
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearchMainLoop.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearchMainLoop.cs	(revision 7739)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearchMainLoop.cs	(revision 7740)
@@ -37,132 +37,118 @@
   public sealed class ScatterSearchMainLoop : AlgorithmOperator {
     #region Parameter properties
-    internal LookupParameter<IRandom> RandomParameter {
-      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
-    }
-    internal LookupParameter<IntValue> IterationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters["Iterations"]; }
-    }
-    internal LookupParameter<IntValue> MaximumIterationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters["MaximumIterations"]; }
-    }
-    internal LookupParameter<BoolValue> MaximizationParameter {
-      get { return (LookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-    internal LookupParameter<IntValue> SampleSizeParameter {
-      get { return (LookupParameter<IntValue>)Parameters["SampleSize"]; }
-    }
-    internal LookupParameter<IntValue> PopulationSizeParameter {
-      get { return (LookupParameter<IntValue>)Parameters["PopulationSize"]; }
-    }
-    internal LookupParameter<IntValue> ReferenceSetSizeParameter {
-      get { return (LookupParameter<IntValue>)Parameters["ReferenceSetSize"]; }
-    }
-    internal LookupParameter<IntValue> NumberOfHighQualitySolutionsParameter {
-      get { return (LookupParameter<IntValue>)Parameters["NumberOfHighQualitySolutions"]; }
-    }
-    internal LookupParameter<DoubleValue> QualityParameter {
-      get { return (LookupParameter<DoubleValue>)Parameters["Quality"]; }
-    }
-    internal LookupParameter<DoubleValue> BestKnownQualityParameter {
-      get { return (LookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
-    }
-    internal LookupParameter<DoubleValue> MoveQualityParameter {
-      get { return (LookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
-    }
-    internal LookupParameter<VariableCollection> ResultsParameter {
-      get { return (LookupParameter<VariableCollection>)Parameters["Results"]; }
-    }
-    internal LookupParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
-      get { return (LookupParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
-    }
-    internal LookupParameter<IMoveGenerator> MoveGeneratorParameter {
-      get { return (LookupParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
-    }
-    internal LookupParameter<IMoveMaker> MoveMakerParameter {
-      get { return (LookupParameter<IMoveMaker>)Parameters["MoveMaker"]; }
-    }
-    internal LookupParameter<IOperator> ImproverParameter {
-      get { return (LookupParameter<IOperator>)Parameters["Improver"]; }
-    }
-    internal LookupParameter<IOperator> EvaluatorParameter {
-      get { return (LookupParameter<IOperator>)Parameters["Evaluator"]; }
-    }
-    internal LookupParameter<IMultiAnalyzer> AnalyzerParameter {
-      get { return (LookupParameter<IMultiAnalyzer>)Parameters["Analyzer"]; }
+    public IValueLookupParameter<IMultiAnalyzer> AnalyzerParameter {
+      get { return (IValueLookupParameter<IMultiAnalyzer>)Parameters["Analyzer"]; }
+    }
+    public IValueLookupParameter<ICrossover> CrossoverParameter {
+      get { return (IValueLookupParameter<ICrossover>)Parameters["Crossover"]; }
+    }
+    public IValueLookupParameter<IOperator> ImproverParameter {
+      get { return (IValueLookupParameter<IOperator>)Parameters["Improver"]; }
+    }
+    public IValueLookupParameter<IntValue> NumberOfHighQualitySolutionsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["NumberOfHighQualitySolutions"]; }
+    }
+    public IValueLookupParameter<IntValue> PopulationSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["PopulationSize"]; }
+    }
+    public IValueLookupParameter<IntValue> ReferenceSetSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["ReferenceSetSize"]; }
+    }
+    public IValueLookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public IValueLookupParameter<IEvaluator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IEvaluator>)Parameters["Evaluator"]; }
+    }
+    public IValueLookupParameter<IntValue> IterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["Iterations"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public IValueLookupParameter<DoubleValue> QualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public IValueLookupParameter<IRandom> RandomParameter {
+      get { return (IValueLookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (IValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    public IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+    public IValueLookupParameter<ISolutionCreator> SolutionCreatorParameter {
+      get { return (IValueLookupParameter<ISolutionCreator>)Parameters["SolutionCreator"]; }
     }
     #endregion
 
     #region Properties
-    public IRandom Random {
+    private IMultiAnalyzer Analyzer {
+      get { return AnalyzerParameter.ActualValue; }
+      set { AnalyzerParameter.ActualValue = value; }
+    }
+    private ICrossover Crossover {
+      get { return CrossoverParameter.ActualValue; }
+      set { CrossoverParameter.ActualValue = value; }
+    }
+    private IOperator Improver {
+      get { return ImproverParameter.ActualValue; }
+      set { ImproverParameter.ActualValue = value; }
+    }
+    private IntValue NumberOfHighQualitySolutions {
+      get { return NumberOfHighQualitySolutionsParameter.ActualValue; }
+      set { NumberOfHighQualitySolutionsParameter.ActualValue = value; }
+    }
+    private IntValue PopulationSize {
+      get { return PopulationSizeParameter.ActualValue; }
+      set { PopulationSizeParameter.ActualValue = value; }
+    }
+    private IntValue ReferenceSetSize {
+      get { return ReferenceSetSizeParameter.ActualValue; }
+      set { ReferenceSetSizeParameter.ActualValue = value; }
+    }
+    private DoubleValue BestKnownQuality {
+      get { return BestKnownQualityParameter.ActualValue; }
+      set { BestKnownQualityParameter.ActualValue = value; }
+    }
+    private IEvaluator Evaluator {
+      get { return EvaluatorParameter.ActualValue; }
+      set { EvaluatorParameter.ActualValue = value; }
+    }
+    private IntValue Iterations {
+      get { return IterationsParameter.ActualValue; }
+      set { IterationsParameter.ActualValue = value; }
+    }
+    private BoolValue Maximization {
+      get { return MaximizationParameter.ActualValue; }
+      set { MaximizationParameter.ActualValue = value; }
+    }
+    private IntValue MaximumIterations {
+      get { return MaximumIterationsParameter.ActualValue; }
+      set { MaximumIterationsParameter.ActualValue = value; }
+    }
+    private DoubleValue Quality {
+      get { return QualityParameter.ActualValue; }
+      set { QualityParameter.ActualValue = value; }
+    }
+    private IRandom Random {
       get { return RandomParameter.ActualValue; }
       set { RandomParameter.ActualValue = value; }
     }
-    public IntValue Iterations {
-      get { return IterationsParameter.ActualValue; }
-      set { IterationsParameter.ActualValue = value; }
-    }
-    public IntValue MaximumIterations {
-      get { return MaximumIterationsParameter.ActualValue; }
-      set { MaximumIterationsParameter.ActualValue = value; }
-    }
-    public BoolValue Maximization {
-      get { return MaximizationParameter.ActualValue; }
-      set { MaximizationParameter.ActualValue = value; }
-    }
-    public IntValue SampleSize {
+    private VariableCollection Results {
+      get { return ResultsParameter.ActualValue; }
+      set { ResultsParameter.ActualValue = value; }
+    }
+    private IntValue SampleSize {
       get { return SampleSizeParameter.ActualValue; }
       set { SampleSizeParameter.ActualValue = value; }
     }
-    public IntValue PopulationSize {
-      get { return PopulationSizeParameter.ActualValue; }
-      set { PopulationSizeParameter.ActualValue = value; }
-    }
-    public IntValue ReferenceSetSize {
-      get { return ReferenceSetSizeParameter.ActualValue; }
-      set { ReferenceSetSizeParameter.ActualValue = value; }
-    }
-    public IntValue NumberOfHighQualitySolutions {
-      get { return NumberOfHighQualitySolutionsParameter.ActualValue; }
-      set { NumberOfHighQualitySolutionsParameter.ActualValue = value; }
-    }
-    public DoubleValue Quality {
-      get { return QualityParameter.ActualValue; }
-      set { QualityParameter.ActualValue = value; }
-    }
-    public DoubleValue BestKnownQuality {
-      get { return BestKnownQualityParameter.ActualValue; }
-      set { BestKnownQualityParameter.ActualValue = value; }
-    }
-    public DoubleValue MoveQuality {
-      get { return MoveQualityParameter.ActualValue; }
-      set { MoveQualityParameter.ActualValue = value; }
-    }
-    public VariableCollection Results {
-      get { return ResultsParameter.ActualValue; }
-      set { ResultsParameter.ActualValue = value; }
-    }
-    public ISingleObjectiveMoveEvaluator MoveEvaluator {
-      get { return MoveEvaluatorParameter.ActualValue; }
-      set { MoveEvaluatorParameter.ActualValue = value; }
-    }
-    public IMoveGenerator MoveGenerator {
-      get { return MoveGeneratorParameter.ActualValue; }
-      set { MoveGeneratorParameter.ActualValue = value; }
-    }
-    public IMoveMaker MoveMaker {
-      get { return MoveMakerParameter.ActualValue; }
-      set { MoveMakerParameter.ActualValue = value; }
-    }
-    public IOperator Improver {
-      get { return ImproverParameter.ActualValue; }
-      set { ImproverParameter.ActualValue = value; }
-    }
-    public IOperator Evaluator {
-      get { return EvaluatorParameter.ActualValue; }
-      set { EvaluatorParameter.ActualValue = value; }
-    }
-    public IMultiAnalyzer Analyzer {
-      get { return AnalyzerParameter.ActualValue; }
-      set { AnalyzerParameter.ActualValue = value; }
+    private ISolutionCreator SolutionCreator {
+      get { return SolutionCreatorParameter.ActualValue; }
+      set { SolutionCreatorParameter.ActualValue = value; }
     }
     #endregion
@@ -179,23 +165,20 @@
     private void Initialize() {
       #region Create parameters
-      Parameters.Add(new LookupParameter<IRandom>("Random", "A pseudo random number generator."));
-      Parameters.Add(new LookupParameter<IntValue>("Iterations", "The number of iterations performed."));
-      Parameters.Add(new LookupParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed."));
-      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
-      Parameters.Add(new LookupParameter<IntValue>("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators."));
-      Parameters.Add(new LookupParameter<IntValue>("PopulationSize", "The size of the population."));
-      Parameters.Add(new LookupParameter<IntValue>("ReferenceSetSize", "The size of the reference set."));
-      Parameters.Add(new LookupParameter<IntValue>("NumberOfHighQualitySolutions", "The number of high quality solutions that should be added to the reference set."));
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
-      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The problem's best known quality value found so far."));
-      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The value which represents the quality of a move."));
-      Parameters.Add(new LookupParameter<IOperator>("SolutionCreator", "The operator which is used to create new solutions."));
-      Parameters.Add(new LookupParameter<IOperator>("Evaluator", "The operator which is used to evaluate new solutions."));
-      Parameters.Add(new LookupParameter<VariableCollection>("Results", "The variable collection where results should be stored."));
-      Parameters.Add(new LookupParameter<ISingleObjectiveMoveEvaluator>("MoveEvaluator", "The operator used to evaluate a move."));
-      Parameters.Add(new LookupParameter<IMoveGenerator>("MoveGenerator", "The operator that generates the moves."));
-      Parameters.Add(new LookupParameter<IMoveMaker>("MoveMaker", "The operator that performs a move and updates the quality."));
-      Parameters.Add(new LookupParameter<IOperator>("Improver", "The operator used to improve solutions."));
-      Parameters.Add(new LookupParameter<IMultiAnalyzer>("Analyzer", "The operator used to analyze the solution and moves."));
+      Parameters.Add(new ValueLookupParameter<IMultiAnalyzer>("Analyzer", "The operator used to analyze the solution and moves."));
+      Parameters.Add(new ValueLookupParameter<ICrossover>("Crossover", "The operator used to combine solutions."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("Improver", "The operator used to improve solutions."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("NumberOfHighQualitySolutions", "The number of high quality solutions that should be added to the reference set."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("PopulationSize", "The size of the population."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("ReferenceSetSize", "The size of the reference set."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestKnownQuality", "The problem's best known quality value found so far."));
+      Parameters.Add(new ValueLookupParameter<IEvaluator>("Evaluator", "The operator which is used to evaluate new solutions."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("Iterations", "The number of iterations performed."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new ValueLookupParameter<IRandom>("Random", "A pseudo random number generator."));
+      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The variable collection where results should be stored."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators."));
+      Parameters.Add(new ValueLookupParameter<ISolutionCreator>("SolutionCreator", "The operator which is used to create new solutions."));
       #endregion
 
@@ -208,5 +191,7 @@
       ConditionalBranch terminateBranch = new ConditionalBranch();
       IntCounter interationsCounter = new IntCounter();
+      OffspringProcessor offspringProcessor = new OffspringProcessor();
       Placeholder analyzer = new Placeholder();
+      Placeholder crossover = new Placeholder();
       Placeholder solutionEvaluator1 = new Placeholder();
       Placeholder solutionEvaluator2 = new Placeholder();
@@ -216,5 +201,4 @@
       ResultsCollector resultsCollector = new ResultsCollector();
       ReferenceSetUpdateMethod referenceSetUpdateMethod = new ReferenceSetUpdateMethod();
-      SolutionCombinationMethod solutionCombinationMethod = new SolutionCombinationMethod();
       SolutionPoolUpdateMethod solutionPoolUpdateMethod = new SolutionPoolUpdateMethod();
       SolutionsCreator solutionsCreator = new SolutionsCreator();
@@ -275,6 +259,12 @@
       interationsCounter.Successor = resultsCollector;
 
+      offspringProcessor.Successor = subScopesProcessor2;
+
       analyzer.Name = "Analyzer";
       analyzer.OperatorParameter.ActualName = "Analyzer";
+
+      crossover.Name = "Crossover";
+      crossover.OperatorParameter.ActualName = "Crossover";
+      crossover.Successor = offspringProcessor;
 
       solutionImprover1.Name = "SolutionImprover";
@@ -296,6 +286,4 @@
       referenceSetUpdateMethod.Successor = assigner1;
 
-      solutionCombinationMethod.Successor = subScopesProcessor2;
-
       solutionPoolUpdateMethod.Successor = analyzer;
 
@@ -321,5 +309,5 @@
 
       uniformSubScopesProcessor1.DepthParameter.Value = new IntValue(1);
-      uniformSubScopesProcessor1.Operator = solutionCombinationMethod;
+      uniformSubScopesProcessor1.Operator = crossover;
       uniformSubScopesProcessor1.Successor = solutionPoolUpdateMethod;
 
@@ -335,6 +323,4 @@
 
     public override IOperation Apply() {
-      if (MoveGeneratorParameter.ActualValue == null || MoveEvaluatorParameter.ActualValue == null || MoveMakerParameter.ActualValue == null)
-        return null;
       return base.Apply();
     }
Index: anches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/SolutionCombinationMethod.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/SolutionCombinationMethod.cs	(revision 7739)
+++ 	(revision )
@@ -1,93 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.BinaryVectorEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Algorithms.ScatterSearch {
-  /// <summary>
-  /// An operator that combines solutions to three trial solutions.
-  /// </summary>
-  [Item("SolutionCombinationMethod", "An operator that combines solutions to three trial solutions.")]
-  [StorableClass]
-  public sealed class SolutionCombinationMethod : SingleSuccessorOperator {
-    #region Parameter properties
-    private ScopeParameter CurrentScopeParameter {
-      get { return (ScopeParameter)Parameters["CurrentScope"]; }
-    }
-    #endregion
-
-    #region Properties
-    public IScope CurrentScope {
-      get { return CurrentScopeParameter.ActualValue; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    private SolutionCombinationMethod(bool deserializing) : base(deserializing) { }
-    private SolutionCombinationMethod(SolutionCombinationMethod original, Cloner cloner) : base(original, cloner) { }
-    public SolutionCombinationMethod() : base() { Initialize(); }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SolutionCombinationMethod(this, cloner);
-    }
-
-    private void Initialize() {
-      #region Create parameters
-      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope to which the new solutions are added as sub-scopes."));
-      #endregion
-
-      #region Create operators
-      #endregion
-
-      #region Create operator graph
-      #endregion
-    }
-
-    public override IOperation Apply() {
-      IScope mother = CurrentScope.SubScopes[0];
-      IScope father = CurrentScope.SubScopes[1];
-      if (mother != null && father != null) {
-        BinaryVector motherSolution = mother.Variables["KnapsackSolution"].Value as BinaryVector;
-        BinaryVector fatherSolution = father.Variables["KnapsackSolution"].Value as BinaryVector;
-        int stepSize = motherSolution.Length / 3;
-        IVariable[] children = {
-          new Variable("KnapsackSolution", new BinaryVector(motherSolution.Take(stepSize).Concat(motherSolution.Skip(stepSize).Take(stepSize)).Concat(fatherSolution.Skip(2 * stepSize)).ToArray())),
-          new Variable("KnapsackSolution", new BinaryVector(motherSolution.Take(stepSize).Concat(fatherSolution.Skip(stepSize).Take(stepSize)).Concat(motherSolution.Skip(2 * stepSize)).ToArray())),
-          new Variable("KnapsackSolution", new BinaryVector(fatherSolution.Take(stepSize).Concat(motherSolution.Skip(stepSize).Take(stepSize)).Concat(motherSolution.Skip(2 * stepSize)).ToArray())),
-        };
-        IScope offspring = new Scope("Offspring");
-        foreach (var child in children) {
-          IScope solution = new Scope();
-          solution.Variables.Add(child);
-          offspring.SubScopes.Add(solution);
-        }
-        CurrentScope.SubScopes.Add(offspring);
-      }
-      return base.Apply();
-    }
-  }
-}
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/SolutionPoolUpdateMethod.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/SolutionPoolUpdateMethod.cs	(revision 7739)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/SolutionPoolUpdateMethod.cs	(revision 7740)
@@ -20,4 +20,6 @@
 #endregion
 
+using System;
+using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
@@ -36,12 +38,18 @@
   public sealed class SolutionPoolUpdateMethod : SingleSuccessorOperator {
     #region Parameter properties
-    private ScopeParameter CurrentScopeParameter {
+    public ScopeParameter CurrentScopeParameter {
       get { return (ScopeParameter)Parameters["CurrentScope"]; }
     }
-    private ValueLookupParameter<BoolValue> NewSolutionsParameter {
-      get { return (ValueLookupParameter<BoolValue>)Parameters["NewSolutions"]; }
+    public IValueLookupParameter<BoolValue> NewSolutionsParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["NewSolutions"]; }
     }
-    private ValueLookupParameter<IntValue> ReferenceSetSizeParameter {
-      get { return (ValueLookupParameter<IntValue>)Parameters["ReferenceSetSize"]; }
+    public IValueLookupParameter<IntValue> ReferenceSetSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["ReferenceSetSize"]; }
+    }
+    public IValueLookupParameter<IItem> QualityParameter {
+      get { return (IValueLookupParameter<IItem>)Parameters["Quality"]; }
+    }
+    public IValueLookupParameter<IItem> SolutionParameter {
+      get { return (IValueLookupParameter<IItem>)Parameters["Solution"]; }
     }
     #endregion
@@ -58,4 +66,7 @@
       set { ReferenceSetSizeParameter.ActualValue = value; }
     }
+    private IItem Quality {
+      get { return QualityParameter.ActualValue; }
+    }
     #endregion
 
@@ -71,14 +82,11 @@
     private void Initialize() {
       #region Create parameters
-      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope to which the new solutions are added as sub-scopes."));
-      Parameters.Add(new ValueLookupParameter<BoolValue>("NewSolutions", "Indicates if new solutions have been found."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("ReferenceSetSize", "The size of the reference set."));
+      Parameters.Add(new ScopeParameter("CurrentScope"));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("NewSolutions"));
+      Parameters.Add(new ValueLookupParameter<IntValue>("ReferenceSetSize"));
+      Parameters.Add(new ValueLookupParameter<IItem>("Quality"));
+      Parameters.Add(new ValueLookupParameter<IItem>("Solution"));
       #endregion
-
-      #region Create operators
-      #endregion
-
-      #region Create operator graph
-      #endregion
+      SolutionParameter.ActualName = "KnapsackSolution"; // temporary solution for the knapsack problem
     }
 
@@ -91,11 +99,28 @@
       }
       CurrentScope.SubScopes.Clear();
-      CurrentScope.SubScopes.AddRange(parents.SubScopes.OrderByDescending(o => o.Variables["Quality"].Value));
-      if ((offspring.SubScopes.OrderByDescending(o => o.Variables["Quality"].Value).First().Variables["Quality"].Value as DoubleValue).Value
-          > (parents.SubScopes.OrderByDescending(o => o.Variables["Quality"].Value).First().Variables["Quality"].Value as DoubleValue).Value) {
-        CurrentScope.SubScopes.Replace(CurrentScope.SubScopes.Union(offspring.SubScopes).OrderByDescending(o => o.Variables["Quality"].Value).Take(ReferenceSetSize.Value));
+      CurrentScope.SubScopes.AddRange(parents.SubScopes.OrderByDescending(o => o.Variables[QualityParameter.ActualName].Value));
+      if ((offspring.SubScopes.OrderByDescending(o => o.Variables[QualityParameter.ActualName].Value).First().Variables[QualityParameter.ActualName].Value as DoubleValue).Value
+          > (parents.SubScopes.OrderByDescending(o => o.Variables[QualityParameter.ActualName].Value).Last().Variables[QualityParameter.ActualName].Value as DoubleValue).Value) {
+        CurrentScope.SubScopes.Replace(parents.SubScopes.Concat(offspring.SubScopes.Distinct(new KeyEqualityComparer<IScope>(x => x.Variables[SolutionParameter.ActualName].Value.ToString()))).OrderByDescending(o => o.Variables[QualityParameter.ActualName].Value).Take(ReferenceSetSize.Value));
         NewSolutions.Value = true;
       }
+
       return base.Apply();
+    }
+
+    private class KeyEqualityComparer<T> : IEqualityComparer<T> {
+      private readonly Func<T, object> keyExtractor;
+
+      public KeyEqualityComparer(Func<T, object> keyExtractor) {
+        this.keyExtractor = keyExtractor;
+      }
+
+      public bool Equals(T x, T y) {
+        return keyExtractor(x).Equals(keyExtractor(y));
+      }
+
+      public int GetHashCode(T obj) {
+        return keyExtractor(obj).GetHashCode();
+      }
     }
   }
