Index: /branches/ScatterSearch (trunk integration)/HeuristicLab.Algorithms.ScatterSearch/3.3/ReferenceSetUpdateMethod.cs
===================================================================
--- /branches/ScatterSearch (trunk integration)/HeuristicLab.Algorithms.ScatterSearch/3.3/ReferenceSetUpdateMethod.cs	(revision 8303)
+++ /branches/ScatterSearch (trunk integration)/HeuristicLab.Algorithms.ScatterSearch/3.3/ReferenceSetUpdateMethod.cs	(revision 8304)
@@ -80,5 +80,5 @@
         double similarity = 0;
         foreach (var rScope in CurrentScope.SubScopes[1].SubScopes) {
-          similarity += SimilarityCalculator.ExecuteCalculation(pScope, rScope);
+          similarity += SimilarityCalculator.CalculateIndividualSimilarity(pScope, rScope);
         }
         population[pScope] = similarity;
Index: /branches/ScatterSearch (trunk integration)/HeuristicLab.Algorithms.ScatterSearch/3.3/SolutionPoolUpdateMethod.cs
===================================================================
--- /branches/ScatterSearch (trunk integration)/HeuristicLab.Algorithms.ScatterSearch/3.3/SolutionPoolUpdateMethod.cs	(revision 8303)
+++ /branches/ScatterSearch (trunk integration)/HeuristicLab.Algorithms.ScatterSearch/3.3/SolutionPoolUpdateMethod.cs	(revision 8304)
@@ -130,5 +130,5 @@
       if (orderedOffspring.Any(hasBetterQuality)) {
         // produce the set union
-        var union = orderedParents.Union(orderedOffspring.Where(hasBetterQuality), new SolutionEqualityComparer<IScope>(SimilarityCalculator.ExecuteCalculation));
+        var union = orderedParents.Union(orderedOffspring.Where(hasBetterQuality), new SolutionEqualityComparer<IScope>(SimilarityCalculator.CalculateIndividualSimilarity));
         if (union.Count() > orderedParents.Count()) {
           var orderedUnion = Maximization.Value ? union.OrderByDescending(x => x.Variables[QualityParameter.ActualName].Value) :
Index: /branches/ScatterSearch (trunk integration)/HeuristicLab.Optimization.Operators/3.3/SimilarityCalculator.cs
===================================================================
--- /branches/ScatterSearch (trunk integration)/HeuristicLab.Optimization.Operators/3.3/SimilarityCalculator.cs	(revision 8303)
+++ /branches/ScatterSearch (trunk integration)/HeuristicLab.Optimization.Operators/3.3/SimilarityCalculator.cs	(revision 8304)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -50,13 +51,26 @@
     protected SimilarityCalculator() : base() { }
 
-    public double ExecuteCalculation(IScope left, IScope right) {
-      if (left == null || right == null)
-        throw new ArgumentException("Cannot calculate diversity because one or both of the provided scopes is null.");
+    public double[][] CalculateCrowdSimilarity(IScope leftCrowd, IScope rightCrowd) {
+      if (leftCrowd == null || rightCrowd == null)
+        throw new ArgumentException("Cannot calculate similarity because one of the provided crowds or both are null.");
 
-      if (left == right) return 1.0;
-      else return CalculateSimilarity(left, right);
+      var leftIndividuals = leftCrowd.SubScopes;
+      var rightIndividuals = rightCrowd.SubScopes;
+
+      if (!leftIndividuals.Any() || !rightIndividuals.Any())
+        throw new ArgumentException("Cannot calculate similarity because one of the provided crowds or both are empty.");
+
+      var similarityMatrix = new double[leftIndividuals.Count][];
+      for (int i = 0; i < leftIndividuals.Count; i++) {
+        similarityMatrix[i] = new double[rightIndividuals.Count];
+        for (int j = 0; j < rightIndividuals.Count; j++) {
+          similarityMatrix[i][j] = CalculateIndividualSimilarity(leftIndividuals[i], rightIndividuals[j]);
+        }
+      }
+
+      return similarityMatrix;
     }
 
-    protected abstract double CalculateSimilarity(IScope left, IScope right);
+    public abstract double CalculateIndividualSimilarity(IScope leftIndividual, IScope rightIndividual);
   }
 }
Index: /branches/ScatterSearch (trunk integration)/HeuristicLab.Optimization/3.3/Interfaces/ISimilarityCalculator.cs
===================================================================
--- /branches/ScatterSearch (trunk integration)/HeuristicLab.Optimization/3.3/Interfaces/ISimilarityCalculator.cs	(revision 8303)
+++ /branches/ScatterSearch (trunk integration)/HeuristicLab.Optimization/3.3/Interfaces/ISimilarityCalculator.cs	(revision 8304)
@@ -29,5 +29,6 @@
     string Target { get; set; }
 
-    double ExecuteCalculation(IScope left, IScope right);
+    double CalculateIndividualSimilarity(IScope leftIndividual, IScope rightIndividual);
+    double[][] CalculateCrowdSimilarity(IScope leftCrowd, IScope rightCrowd);
   }
 }
Index: /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.Knapsack/3.3/SimilarityCalculators/KnapsackSimilarityCalculator.cs
===================================================================
--- /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.Knapsack/3.3/SimilarityCalculators/KnapsackSimilarityCalculator.cs	(revision 8303)
+++ /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.Knapsack/3.3/SimilarityCalculators/KnapsackSimilarityCalculator.cs	(revision 8304)
@@ -42,5 +42,6 @@
     public static double CalculateSimilarity(BinaryVector left, BinaryVector right) {
       if (left == null || right == null)
-        throw new ArgumentException("Cannot calculate similarity because one of the provided solutions or both are null.");
+        throw new ArgumentException("Cannot calculate diversity because one or both of the provided scopes is null.");
+      if (left == right) return 1.0;
 
       double similarity = 0.0;
@@ -50,7 +51,7 @@
     }
 
-    protected override double CalculateSimilarity(IScope left, IScope right) {
-      BinaryVector sol1 = left.Variables[Target].Value as BinaryVector;
-      BinaryVector sol2 = right.Variables[Target].Value as BinaryVector;
+    public override double CalculateIndividualSimilarity(IScope left, IScope right) {
+      var sol1 = left.Variables[Target].Value as BinaryVector;
+      var sol2 = right.Variables[Target].Value as BinaryVector;
 
       return CalculateSimilarity(sol1, sol2);
Index: /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.TestFunctions/3.3/SimilarityCalculators/SingleObjectiveTestFunctionSimilarityCalculator.cs
===================================================================
--- /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.TestFunctions/3.3/SimilarityCalculators/SingleObjectiveTestFunctionSimilarityCalculator.cs	(revision 8303)
+++ /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.TestFunctions/3.3/SimilarityCalculators/SingleObjectiveTestFunctionSimilarityCalculator.cs	(revision 8304)
@@ -57,4 +57,5 @@
       if (bounds == null)
         throw new ArgumentException("Cannot calculate similarity because no bounds were provided.");
+      if (left == right) return 1.0;
 
       double maxSum = 0.0;
@@ -71,7 +72,7 @@
     }
 
-    protected override double CalculateSimilarity(IScope left, IScope right) {
-      RealVector sol1 = left.Variables[Target].Value as RealVector;
-      RealVector sol2 = right.Variables[Target].Value as RealVector;
+    public override double CalculateIndividualSimilarity(IScope left, IScope right) {
+      var sol1 = left.Variables[Target].Value as RealVector;
+      var sol2 = right.Variables[Target].Value as RealVector;
 
       return CalculateSimilarity(sol1, sol2, Bounds);
Index: /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.TravelingSalesman/3.3/SimilarityCalculators/TSPSimilarityCalculator.cs
===================================================================
--- /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.TravelingSalesman/3.3/SimilarityCalculators/TSPSimilarityCalculator.cs	(revision 8303)
+++ /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.TravelingSalesman/3.3/SimilarityCalculators/TSPSimilarityCalculator.cs	(revision 8304)
@@ -43,4 +43,5 @@
       if (left == null || right == null)
         throw new ArgumentException("Cannot calculate similarity because one of the provided solutions or both are null.");
+      if (left == right) return 1.0;
 
       int[,] edges = new int[right.Length, 2];
@@ -60,7 +61,7 @@
     }
 
-    protected override double CalculateSimilarity(IScope left, IScope right) {
-      Permutation sol1 = left.Variables[Target].Value as Permutation;
-      Permutation sol2 = right.Variables[Target].Value as Permutation;
+    public override double CalculateIndividualSimilarity(IScope left, IScope right) {
+      var sol1 = left.Variables[Target].Value as Permutation;
+      var sol2 = right.Variables[Target].Value as Permutation;
 
       return CalculateSimilarity(sol1, sol2);
Index: /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.VehicleRouting/3.3/SimilarityCalculators/VRPSimilarityCalculator.cs
===================================================================
--- /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.VehicleRouting/3.3/SimilarityCalculators/VRPSimilarityCalculator.cs	(revision 8303)
+++ /branches/ScatterSearch (trunk integration)/HeuristicLab.Problems.VehicleRouting/3.3/SimilarityCalculators/VRPSimilarityCalculator.cs	(revision 8304)
@@ -46,4 +46,5 @@
       if (left == null || right == null)
         throw new ArgumentException("Cannot calculate similarity because one of the provided solutions or both are null.");
+      if (left == right) return 1.0;
 
       // extract edges from first solution
@@ -77,7 +78,7 @@
     }
 
-    protected override double CalculateSimilarity(IScope left, IScope right) {
-      PotvinEncoding sol1 = left.Variables[Target].Value as PotvinEncoding;
-      PotvinEncoding sol2 = right.Variables[Target].Value as PotvinEncoding;
+    public override double CalculateIndividualSimilarity(IScope left, IScope right) {
+      var sol1 = left.Variables[Target].Value as PotvinEncoding;
+      var sol2 = right.Variables[Target].Value as PotvinEncoding;
 
       return CalculateSimilarity(sol1, sol2);
