Index: /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealing.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealing.cs	(revision 3621)
+++ /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealing.cs	(revision 3622)
@@ -33,4 +33,5 @@
 using HeuristicLab.PluginInfrastructure;
 using HeuristicLab.Random;
+using HeuristicLab.Analysis;
 
 namespace HeuristicLab.Algorithms.SimulatedAnnealing {
@@ -80,4 +81,7 @@
       get { return (ValueParameter<DoubleValue>)Parameters["EndTemperature"]; }
     }
+    private ValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
+    }
     #endregion
 
@@ -119,4 +123,8 @@
       set { EndTemperatureParameter.Value = value; }
     }
+    public MultiAnalyzer Analyzer {
+      get { return AnalyzerParameter.Value; }
+      set { AnalyzerParameter.Value = value; }
+    }
     private RandomCreator RandomCreator {
       get { return (RandomCreator)OperatorGraph.InitialOperator; }
@@ -133,6 +141,9 @@
       get { return annealingOperators; }
     }
+    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
     #endregion
 
+    [StorableConstructor]
+    private SimulatedAnnealing(bool deserializing) : base(deserializing) { }
     public SimulatedAnnealing()
       : base() {
@@ -147,5 +158,6 @@
       Parameters.Add(new ValueParameter<DoubleValue>("StartTemperature", "The initial temperature.", new DoubleValue(100)));
       Parameters.Add(new ValueParameter<DoubleValue>("EndTemperature", "The final temperature which should be reached when iterations reaches maximum iterations.", new DoubleValue(1e-6)));
-
+      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer()));
+      
       RandomCreator randomCreator = new RandomCreator();
       SolutionsCreator solutionsCreator = new SolutionsCreator();
@@ -172,9 +184,8 @@
       mainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
       mainLoop.ResultsParameter.ActualName = "Results";
+      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
 
       Initialize();
     }
-    [StorableConstructor]
-    private SimulatedAnnealing(bool deserializing) : base(deserializing) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -204,4 +215,6 @@
       ParameterizeMoveMakers();
       ParameterizeMoveGenerators();
+      ParameterizeAnalyzers();
+      UpdateAnalyzers();
       Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
       base.OnProblemChanged();
@@ -218,4 +231,5 @@
       ParameterizeMoveEvaluators();
       ParameterizeMoveMakers();
+      ParameterizeAnalyzers();
       Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
       base.Problem_EvaluatorChanged(sender, e);
@@ -231,4 +245,5 @@
       UpdateMoveGenerator();
       UpdateMoveParameters();
+      UpdateAnalyzers();
       ParameterizeMainLoop();
       ParameterizeMoveEvaluators();
@@ -241,4 +256,5 @@
       ParameterizeMoveEvaluators();
       ParameterizeMoveMakers();
+      ParameterizeAnalyzers();
     }
     private void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
@@ -260,4 +276,6 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void Initialize() {
+      InitializeAnalyzers();
+      UpdateAnalyzers();
       if (Problem != null) {
         Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
@@ -278,4 +296,8 @@
         AnnealingOperatorParameter.ValidValues.Add(op);
     }
+    private void InitializeAnalyzers() {
+      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
+      ParameterizeAnalyzers();
+    }
     private void UpdateMoveGenerator() {
       IMultiMoveGenerator oldMoveGenerator = MoveGenerator;
@@ -291,4 +313,12 @@
       if (MoveGenerator == null) {
         ClearMoveParameters();
+      }
+    }
+    private void ParameterizeAnalyzers() {
+      qualityAnalyzer.ResultsParameter.ActualName = "Results";
+      if (Problem != null) {
+        qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+        qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
       }
     }
@@ -367,4 +397,12 @@
       }
     }
+    private void UpdateAnalyzers() {
+      Analyzer.Operators.Clear();
+      Analyzer.Operators.Add(qualityAnalyzer);
+      if (Problem != null) {
+        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>().OrderBy(x => x.Name))
+          Analyzer.Operators.Add(analyzer);
+      }
+    }
     #endregion
   }
Index: /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs	(revision 3621)
+++ /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs	(revision 3622)
@@ -77,9 +77,6 @@
       get { return (ValueLookupParameter<IOperator>)Parameters["AnnealingOperator"]; }
     }
-    public ValueLookupParameter<IOperator> VisualizerParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["Visualizer"]; }
-    }
-    public LookupParameter<IItem> VisualizationParameter {
-      get { return (LookupParameter<IItem>)Parameters["Visualization"]; }
+    public ValueLookupParameter<IOperator> AnalyzerParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["Analyzer"]; }
     }
     public ValueLookupParameter<VariableCollection> ResultsParameter {
@@ -112,6 +109,5 @@
       Parameters.Add(new ValueLookupParameter<IOperator>("AnnealingOperator", "The operator that modifies the temperature."));
 
-      Parameters.Add(new ValueLookupParameter<IOperator>("Visualizer", "The operator used to visualize solutions."));
-      Parameters.Add(new LookupParameter<IItem>("Visualization", "The item which represents the visualization of solutions."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("Analyzer", "The operator used to analyze each generation."));
       Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The variable collection where results should be stored."));
       #endregion
@@ -119,13 +115,10 @@
       #region Create operators
       VariableCreator variableCreator = new VariableCreator();
-      BestQualityMemorizer bestQualityMemorizer1 = new BestQualityMemorizer();
-      BestQualityMemorizer bestQualityMemorizer2 = new BestQualityMemorizer();
-      QualityDifferenceCalculator qualityDifferenceCalculator1 = new QualityDifferenceCalculator();
-      Placeholder visualizer1 = new Placeholder();
+      ResultsCollector resultsCollector1 = new ResultsCollector();
+      Placeholder analyzer1 = new Placeholder();
       SubScopesProcessor sssp = new SubScopesProcessor();
       ResultsCollector resultsCollector = new ResultsCollector();
       Placeholder annealingOperator = new Placeholder();
       UniformSubScopesProcessor mainProcessor = new UniformSubScopesProcessor();
-      DataTableValuesCollector valuesCollector = new DataTableValuesCollector();
       Placeholder moveGenerator = new Placeholder();
       UniformSubScopesProcessor moveEvaluationProcessor = new UniformSubScopesProcessor();
@@ -137,47 +130,20 @@
       IntCounter iterationsCounter = new IntCounter();
       Comparator iterationsComparator = new Comparator();
-      BestQualityMemorizer bestQualityMemorizer3 = new BestQualityMemorizer();
-      BestQualityMemorizer bestQualityMemorizer4 = new BestQualityMemorizer();
-      QualityDifferenceCalculator qualityDifferenceCalculator2 = new QualityDifferenceCalculator();
-      Placeholder visualizer2 = new Placeholder();
+      ResultsCollector resultsCollector2 = new ResultsCollector();
+      Placeholder analyzer2 = new Placeholder();
       ConditionalBranch iterationsTermination = new ConditionalBranch();
       
       variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
-      variableCreator.CollectedValues.Add(new ValueParameter<DataTable>("Qualities", new DataTable("Qualities")));
       variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("Temperature", new DoubleValue(double.MaxValue)));
 
-      bestQualityMemorizer1.BestQualityParameter.ActualName = "BestQuality";
-      bestQualityMemorizer1.MaximizationParameter.ActualName = MaximizationParameter.Name;
-      bestQualityMemorizer1.QualityParameter.ActualName = QualityParameter.Name;
-
-      bestQualityMemorizer2.BestQualityParameter.ActualName = BestKnownQualityParameter.Name;
-      bestQualityMemorizer2.MaximizationParameter.ActualName = MaximizationParameter.Name;
-      bestQualityMemorizer2.QualityParameter.ActualName = QualityParameter.Name;
-
-      qualityDifferenceCalculator1.AbsoluteDifferenceParameter.ActualName = "AbsoluteDifferenceBestKnownToBest";
-      qualityDifferenceCalculator1.FirstQualityParameter.ActualName = BestKnownQualityParameter.Name;
-      qualityDifferenceCalculator1.RelativeDifferenceParameter.ActualName = "RelativeDifferenceBestKnownToBest";
-      qualityDifferenceCalculator1.SecondQualityParameter.ActualName = "BestQuality";
-
-      visualizer1.Name = "Visualizer (placeholder)";
-      visualizer1.OperatorParameter.ActualName = VisualizerParameter.Name;
-
-      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Iterations"));
-      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>(QualityParameter.Name));
-      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Best Quality") { ActualName = "BestQuality" });
-      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Best Known Quality", null, BestKnownQualityParameter.Name));
-      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>("Qualities"));
-      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Temperature"));
-      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Absolute Difference of Best Known Quality to Best Quality", null, "AbsoluteDifferenceBestKnownToBest"));
-      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Relative Difference of Best Known Quality to Best Quality", null, "RelativeDifferenceBestKnownToBest"));
-      resultsCollector.CollectedValues.Add(new LookupParameter<IItem>("Solution Visualization", null, VisualizationParameter.Name));
-      
+      resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>("Iterations"));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Temperature"));
+      resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
+
+      analyzer1.Name = "Analyzer (placeholder)";
+      analyzer1.OperatorParameter.ActualName = AnalyzerParameter.Name;
+
       annealingOperator.Name = "Annealing operator (placeholder)";
       annealingOperator.OperatorParameter.ActualName = AnnealingOperatorParameter.Name;
-
-      valuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Quality", null, QualityParameter.Name));
-      valuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Best Quality", null, "BestQuality"));
-      valuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Best Known Quality", null, BestKnownQualityParameter.Name));
-      valuesCollector.DataTableParameter.ActualName = "Qualities";
 
       moveGenerator.Name = "Move generator (placeholder)";
@@ -209,19 +175,10 @@
       iterationsComparator.Comparison.Value = ComparisonType.GreaterOrEqual;
 
-      bestQualityMemorizer3.BestQualityParameter.ActualName = "BestQuality";
-      bestQualityMemorizer3.MaximizationParameter.ActualName = MaximizationParameter.Name;
-      bestQualityMemorizer3.QualityParameter.ActualName = QualityParameter.Name;
-
-      bestQualityMemorizer4.BestQualityParameter.ActualName = BestKnownQualityParameter.Name;
-      bestQualityMemorizer4.MaximizationParameter.ActualName = MaximizationParameter.Name;
-      bestQualityMemorizer4.QualityParameter.ActualName = QualityParameter.Name;
-
-      qualityDifferenceCalculator2.AbsoluteDifferenceParameter.ActualName = "AbsoluteDifferenceBestKnownToBest";
-      qualityDifferenceCalculator2.FirstQualityParameter.ActualName = BestKnownQualityParameter.Name;
-      qualityDifferenceCalculator2.RelativeDifferenceParameter.ActualName = "RelativeDifferenceBestKnownToBest";
-      qualityDifferenceCalculator2.SecondQualityParameter.ActualName = "BestQuality";
-
-      visualizer2.Name = "Visualizer (placeholder)";
-      visualizer2.OperatorParameter.ActualName = VisualizerParameter.Name;
+      resultsCollector2.CollectedValues.Add(new LookupParameter<IntValue>("Iterations"));
+      resultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>("Temperature"));
+      resultsCollector2.ResultsParameter.ActualName = ResultsParameter.Name;
+
+      analyzer2.Name = "Analyzer (placeholder)";
+      analyzer2.OperatorParameter.ActualName = AnalyzerParameter.Name;
 
       iterationsTermination.Name = "Iterations termination condition";
@@ -231,16 +188,13 @@
       #region Create operator graph
       OperatorGraph.InitialOperator = variableCreator;
-      variableCreator.Successor = bestQualityMemorizer1;
-      bestQualityMemorizer1.Successor = bestQualityMemorizer2;
-      bestQualityMemorizer2.Successor = qualityDifferenceCalculator1;
-      qualityDifferenceCalculator1.Successor = visualizer1;
-      visualizer1.Successor = sssp;
+      variableCreator.Successor = resultsCollector1;
+      resultsCollector1.Successor = analyzer1;
+      analyzer1.Successor = sssp;
       sssp.Operators.Add(resultsCollector);
       resultsCollector.Successor = null;
       sssp.Successor = annealingOperator;
       annealingOperator.Successor = mainProcessor;
-      mainProcessor.Operator = valuesCollector;
+      mainProcessor.Operator = moveGenerator;
       mainProcessor.Successor = iterationsCounter;
-      valuesCollector.Successor = moveGenerator;
       moveGenerator.Successor = moveEvaluationProcessor;
       moveEvaluationProcessor.Operator = moveEvaluator;
@@ -250,9 +204,7 @@
       improvesQualityBranch.TrueBranch = moveMaker;
       iterationsCounter.Successor = iterationsComparator;
-      iterationsComparator.Successor = bestQualityMemorizer3;
-      bestQualityMemorizer3.Successor = bestQualityMemorizer4;
-      bestQualityMemorizer4.Successor = qualityDifferenceCalculator2;
-      qualityDifferenceCalculator2.Successor = visualizer2;
-      visualizer2.Successor = iterationsTermination;
+      iterationsComparator.Successor = resultsCollector2;
+      resultsCollector2.Successor = analyzer2;
+      analyzer2.Successor = iterationsTermination;
       iterationsTermination.TrueBranch = null;
       iterationsTermination.FalseBranch = annealingOperator;
