Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterCrossoverCombinedOperator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterCrossoverCombinedOperator.cs	(revision 9330)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterCrossoverCombinedOperator.cs	(revision 9331)
@@ -43,4 +43,7 @@
     protected WorstQualityAnalyzer wqAnalyzer;
 
+    [Storable]
+    protected SelectionPressureAnalyzer selPressureAnalyzer;
+
     public ILookupParameter<IEvaluator> EvaluatorParameter {
       get { return ((LookupParameter<IEvaluator>)Parameters["Evaluator"]); }
@@ -57,4 +60,5 @@
       varDuplicator = original.varDuplicator != null ? (VariableDuplicator)original.cxAnalyzer.Clone(cloner) : null;
       solToPopAnalyzer = original.solToPopAnalyzer != null ? (SolutionToPopulationAnalyzer)original.solToPopAnalyzer.Clone(cloner) : null;
+      selPressureAnalyzer = original.selPressureAnalyzer != null ? (SelectionPressureAnalyzer)original.selPressureAnalyzer.Clone(cloner) : null;
     }
 
@@ -83,4 +87,5 @@
       solToPopAnalyzer.ChartPostfixParameter.Value = new Data.StringValue("after Crossover");
       wqAnalyzer = new WorstQualityAnalyzer();
+      selPressureAnalyzer = new SelectionPressureAnalyzer();
 
       Operators.Add(wqAnalyzer);
@@ -89,4 +94,5 @@
       Operators.Add(varDuplicator);
       Operators.Add(solToPopAnalyzer);
+      Operators.Add(selPressureAnalyzer);
     }
   }
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterCrossoverCombinedOperator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterCrossoverCombinedOperator.cs	(revision 9330)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterCrossoverCombinedOperator.cs	(revision 9331)
@@ -65,4 +65,6 @@
 
       wqAnalyzer.ParentsQualityParameter.ActualName = "Quality";
+
+      selPressureAnalyzer.SolutionQualityName = "Quality";
     }
   }
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterCrossoverCombinedOperator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterCrossoverCombinedOperator.cs	(revision 9330)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterCrossoverCombinedOperator.cs	(revision 9331)
@@ -62,4 +62,6 @@
       wqAnalyzer.ParentsQualityParameter.ActualName = "Quality";
       //TODO: add unwanted mutation analyzer for TF
+
+      selPressureAnalyzer.SolutionQualityName = "Quality";
     }
   }
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterCrossoverCombinedOperator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterCrossoverCombinedOperator.cs	(revision 9330)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterCrossoverCombinedOperator.cs	(revision 9331)
@@ -61,4 +61,6 @@
 
       wqAnalyzer.ParentsQualityParameter.ActualName = "Quality";
+
+      selPressureAnalyzer.SolutionQualityName = "Quality";
     }
   }
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 9330)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 9331)
@@ -113,4 +113,5 @@
     <Compile Include="CombinedOperators\QAPAfterMutationCombinedOperator.cs" />
     <Compile Include="CombinedOperators\QAPAfterCrossoverCombinedOperator.cs" />
+    <Compile Include="SelectionPressureAnalyzer.cs" />
     <Compile Include="WorstQualityAnalyzer.cs" />
     <Compile Include="InitializableOperator.cs" />
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SelectionPressureAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SelectionPressureAnalyzer.cs	(revision 9331)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SelectionPressureAnalyzer.cs	(revision 9331)
@@ -0,0 +1,183 @@
+﻿#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 System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers {
+  [Item("SelectionPressureAnalyzer", "An operator that analyzes the current selection pressure.")]
+  [StorableClass]
+  public class SelectionPressureAnalyzer : InitializableOperator, IStatefulItem {
+    private const string ResultsParameterName = "Results";
+    private const string GenerationsParameterName = "Generations";
+    [Storable]
+    public string SolutionQualityName { get; set; }
+
+    #region Parameter properties
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> WorstKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["WorstKnownQuality"]; }
+    }
+    public ILookupParameter<ItemArray<DoubleValue>> ParentsQualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["ParentsQuality"]; }
+    }
+    #endregion
+
+    #region Properties
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    [Storable]
+    private ScatterPlotHelper selPressurePlot;
+    [Storable]
+    private int cnt = 0;
+    [Storable]
+    private int lastGeneration = 0;
+    #endregion
+
+    [StorableConstructor]
+    private SelectionPressureAnalyzer(bool deserializing) : base(deserializing) { }
+    private SelectionPressureAnalyzer(SelectionPressureAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+      cnt = original.cnt;
+      lastGeneration = original.lastGeneration;
+      selPressurePlot = (ScatterPlotHelper)original.selPressurePlot.Clone(cloner);
+      SolutionQualityName = original.SolutionQualityName;
+    }
+
+    public SelectionPressureAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "Nr of generations."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("WorstKnownQuality", "The quality of the worst known solution of this problem."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("ParentsQuality", "The quality of the parent solutions."));
+      SolutionQualityName = "TSPTourLength";
+
+      selPressurePlot = new ScatterPlotHelper(false, true, true, false);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SelectionPressureAnalyzer(this, cloner);
+    }
+
+    protected override void InitializeAction() {
+      selPressurePlot.InitializePlot(Results, "Selection Pressure", "Solution Index", "Quality Difference");
+      ParentsQualityParameter.ActualName = SolutionQualityName;
+
+      Reset();
+    }
+
+    public override IOperation Apply() {
+      Initialize();
+
+      string curGenStr = GenerationsParameter.ActualValue.Value.ToString();
+
+      IScope oldPop = ReverseScopeTreeLookup("Remaining");
+      if (oldPop == null)
+        throw new Exception("Couldn't find the remaining scope");
+
+      if (GenerationsParameter.ActualValue.Value != 0) {
+        if (GenerationsParameter.ActualValue.Value > lastGeneration) {
+          Reset();
+        }
+
+        double oldPopQuality = 0.0;
+        int popSize = 0;
+        foreach (IScope oldSolScope in oldPop.SubScopes) {
+          double curQuality = ((DoubleValue)oldSolScope.Variables[SolutionQualityName].Value).Value;
+          oldPopQuality += curQuality;
+          popSize++;
+        }
+
+        double quality = ParentsQualityParameter.ActualValue.Average(x => x.Value);
+
+        if (GenerationsParameter.ActualValue.Value == 1) {
+          double bkQuality = BestKnownQualityParameter.ActualValue.Value;
+          double wkQuality = WorstKnownQualityParameter.ActualValue.Value;
+
+          if (MaximizationParameter.ActualValue.Value) {
+            if (selPressurePlot.Max == double.MinValue) {
+              selPressurePlot.Max = bkQuality - wkQuality;
+              selPressurePlot.Min = 0;
+            }
+          } else {
+            if (selPressurePlot.Min == double.MaxValue) {
+              selPressurePlot.Max = wkQuality - bkQuality;
+              selPressurePlot.Min = 0;
+            }
+          }
+        }
+
+        Point2D<double> popQualityPoint;
+        if (MaximizationParameter.ActualValue.Value) {
+          popQualityPoint = new Point2D<double>(cnt, quality - (oldPopQuality / popSize));
+        } else {
+          popQualityPoint = new Point2D<double>(cnt, (oldPopQuality / popSize) - quality);
+        }
+
+        selPressurePlot.AddPoint(curGenStr, popQualityPoint);
+      }
+
+      return base.Apply();
+    }
+
+    private void Reset() {
+      cnt = 0;
+      lastGeneration = GenerationsParameter.ActualValue.Value;
+    }
+
+    public override void ClearState() {
+      selPressurePlot.CleanUp();
+    }
+
+    private IScope ReverseScopeTreeLookup(string scopeName) {
+      var currentScope = ExecutionContext.Scope;
+      while (currentScope != null) {
+        var scopes = currentScope.SubScopes.Where(x => x.Name == scopeName);
+        if (scopes.Count() > 0)
+          return scopes.First();
+
+        currentScope = currentScope.Parent;
+      }
+      return null;
+    }
+  }
+}
