Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestAverageWorstTours/PickupAndDelivery/BestAverageWorstPickupAndDeliveryVRPToursAnalyzer.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestAverageWorstTours/PickupAndDelivery/BestAverageWorstPickupAndDeliveryVRPToursAnalyzer.cs	(revision 6710)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestAverageWorstTours/PickupAndDelivery/BestAverageWorstPickupAndDeliveryVRPToursAnalyzer.cs	(revision 6710)
@@ -0,0 +1,152 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Analysis;
+using HeuristicLab.Problems.VehicleRouting.Variants;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+
+namespace HeuristicLab.Problems.VehicleRouting {
+  /// <summary>
+  /// An operator which analyzes the best, average and worst quality of solutions in the scope tree.
+  /// </summary>
+  [Item("BestAverageWorstPickupAndDeliveryVRPToursAnalyzer", "An operator which analyzes the best, average and worst properties of the VRP tours in the scope tree.")]
+  [StorableClass]
+  public sealed class BestAverageWorstPickupAndDeliveryVRPToursAnalyzer : AlgorithmOperator, IAnalyzer, IPickupAndDeliveryOperator {
+    #region Parameter properties
+    public ILookupParameter<IVRPProblemInstance> ProblemInstanceParameter {
+      get { return (ILookupParameter<IVRPProblemInstance>)Parameters["ProblemInstance"]; }
+    }
+    public ScopeTreeLookupParameter<IntValue> PickupViolationsParameter {
+      get { return (ScopeTreeLookupParameter<IntValue>)Parameters["PickupViolations"]; }
+    }
+    public ValueLookupParameter<IntValue> BestPickupViolationsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["BestPickupViolations"]; }
+    }
+    public ValueLookupParameter<IntValue> CurrentBestPickupViolationsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["CurrentBestPickupViolations"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentAveragePickupViolationsParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentAveragePickupViolations"]; }
+    }
+    public ValueLookupParameter<IntValue> CurrentWorstPickupViolationsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["CurrentWorstPickupViolations"]; }
+    }
+    public ValueLookupParameter<DataTable> PickupViolationsValuesParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["PickupViolationsValues"]; }
+    }
+
+    public ValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    #endregion
+
+    #region Properties
+    private BestPickupAndDeliveryVRPToursMemorizer BestMemorizer {
+      get { return (BestPickupAndDeliveryVRPToursMemorizer)OperatorGraph.InitialOperator; }
+    }
+    private BestAverageWorstPickupAndDeliveryVRPToursCalculator BestAverageWorstCalculator {
+      get { return (BestAverageWorstPickupAndDeliveryVRPToursCalculator)BestMemorizer.Successor; }
+    }
+    #endregion
+
+    public BestAverageWorstPickupAndDeliveryVRPToursAnalyzer()
+      : base() {
+      #region Create parameters 
+      Parameters.Add(new LookupParameter<IVRPProblemInstance>("ProblemInstance", "The problem instance."));
+
+      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("PickupViolations", "The pickup violations of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("BestPickupViolations", "The best pickup violations value."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("CurrentBestPickupViolations", "The current best pickup violations value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentAveragePickupViolations", "The current average pickup violations value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("CurrentWorstPickupViolations", "The current worst pickup violations value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("PickupViolationsValues", "The data table to store the current best, current average, current worst, best and best known pickup violations value."));
+ 
+      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The results collection where the analysis values should be stored."));
+      #endregion
+
+      #region Create operators
+      BestPickupAndDeliveryVRPToursMemorizer bestMemorizer = new BestPickupAndDeliveryVRPToursMemorizer();
+      BestAverageWorstPickupAndDeliveryVRPToursCalculator calculator = new BestAverageWorstPickupAndDeliveryVRPToursCalculator();
+      ResultsCollector resultsCollector = new ResultsCollector();
+
+      //pickup violations
+      bestMemorizer.BestPickupViolationsParameter.ActualName = BestPickupViolationsParameter.Name;
+      bestMemorizer.PickupViolationsParameter.ActualName = PickupViolationsParameter.Name;
+      bestMemorizer.PickupViolationsParameter.Depth = PickupViolationsParameter.Depth;
+
+      calculator.PickupViolationsParameter.ActualName = PickupViolationsParameter.Name;
+      calculator.PickupViolationsParameter.Depth = PickupViolationsParameter.Depth;
+      calculator.BestPickupViolationsParameter.ActualName = CurrentBestPickupViolationsParameter.Name;
+      calculator.AveragePickupViolationsParameter.ActualName = CurrentAveragePickupViolationsParameter.Name;
+      calculator.WorstPickupViolationsParameter.ActualName = CurrentWorstPickupViolationsParameter.Name;
+
+      DataTableValuesCollector pickupViolationsDataTablesCollector = new DataTableValuesCollector();
+      pickupViolationsDataTablesCollector.CollectedValues.Add(new LookupParameter<IntValue>("BestPickupViolations", null, BestPickupViolationsParameter.Name));
+      pickupViolationsDataTablesCollector.CollectedValues.Add(new LookupParameter<IntValue>("CurrentBestPickupViolations", null, CurrentBestPickupViolationsParameter.Name));
+      pickupViolationsDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentAveragePickupViolations", null, CurrentAveragePickupViolationsParameter.Name));
+      pickupViolationsDataTablesCollector.CollectedValues.Add(new LookupParameter<IntValue>("CurrentWorstPickupViolations", null, CurrentWorstPickupViolationsParameter.Name));
+      pickupViolationsDataTablesCollector.DataTableParameter.ActualName = PickupViolationsValuesParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(PickupViolationsValuesParameter.Name));
+      #endregion
+
+      #region Create operator graph
+      OperatorGraph.InitialOperator = bestMemorizer;
+      bestMemorizer.Successor = calculator;
+      calculator.Successor = pickupViolationsDataTablesCollector;
+      pickupViolationsDataTablesCollector.Successor = resultsCollector;
+      resultsCollector.Successor = null;
+      #endregion
+
+      Initialize();
+    }
+    [StorableConstructor]
+    private BestAverageWorstPickupAndDeliveryVRPToursAnalyzer(bool deserializing) : base() { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void Initialize() {
+      PickupViolationsParameter.DepthChanged += new EventHandler(PickupViolationsParameter_DepthChanged);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestAverageWorstPickupAndDeliveryVRPToursAnalyzer(this, cloner);
+    }
+
+    private BestAverageWorstPickupAndDeliveryVRPToursAnalyzer(BestAverageWorstPickupAndDeliveryVRPToursAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+        this.Initialize();
+    }
+
+    void PickupViolationsParameter_DepthChanged(object sender, EventArgs e) {
+      BestAverageWorstCalculator.PickupViolationsParameter.Depth = PickupViolationsParameter.Depth;
+      BestMemorizer.PickupViolationsParameter.Depth = PickupViolationsParameter.Depth;
+    } 
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestAverageWorstTours/PickupAndDelivery/BestAverageWorstPickupAndDeliveryVRPToursCalculator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestAverageWorstTours/PickupAndDelivery/BestAverageWorstPickupAndDeliveryVRPToursCalculator.cs	(revision 6710)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestAverageWorstTours/PickupAndDelivery/BestAverageWorstPickupAndDeliveryVRPToursCalculator.cs	(revision 6710)
@@ -0,0 +1,93 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.VehicleRouting {
+  [Item("BestAverageWorstPickupAndDeliveryVRPToursCalculator", "An operator which calculates the current best, average and worst properties of VRP tours in the scope tree.")]
+  [StorableClass]
+  public sealed class BestAverageWorstPickupAndDeliveryVRPToursCalculator : SingleSuccessorOperator {
+    public ScopeTreeLookupParameter<IntValue> PickupViolationsParameter {
+      get { return (ScopeTreeLookupParameter<IntValue>)Parameters["PickupViolations"]; }
+    }
+    public ValueLookupParameter<IntValue> BestPickupViolationsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["BestPickupViolations"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AveragePickupViolationsParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AveragePickupViolations"]; }
+    }
+    public ValueLookupParameter<IntValue> WorstPickupViolationsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["WorstPickupViolations"]; }
+    }
+
+    public BestAverageWorstPickupAndDeliveryVRPToursCalculator()
+      : base() {
+        Parameters.Add(new ScopeTreeLookupParameter<IntValue>("PickupViolations", "The pickup violations of the VRP solutions which should be analyzed."));
+        Parameters.Add(new ValueLookupParameter<IntValue>("BestPickupViolations", "The best pickup violations value."));
+        Parameters.Add(new ValueLookupParameter<DoubleValue>("AveragePickupViolations", "The average pickup violations value of all solutions."));
+        Parameters.Add(new ValueLookupParameter<IntValue>("WorstPickupViolations", "The worst pickup violations value of all solutions."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestAverageWorstPickupAndDeliveryVRPToursCalculator(this, cloner);
+    }
+
+    private BestAverageWorstPickupAndDeliveryVRPToursCalculator(BestAverageWorstPickupAndDeliveryVRPToursCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    private BestAverageWorstPickupAndDeliveryVRPToursCalculator(bool deserializing) : base(deserializing) { }
+
+    private void UpdatePickupViolations() {
+      ItemArray<IntValue> pickupViolations = PickupViolationsParameter.ActualValue;
+      if (pickupViolations.Length > 0) {
+        int min = int.MaxValue, max = int.MinValue, sum = 0;
+        for (int i = 0; i < pickupViolations.Length; i++) {
+          if (pickupViolations[i].Value < min) min = pickupViolations[i].Value;
+          if (pickupViolations[i].Value > max) max = pickupViolations[i].Value;
+          sum += pickupViolations[i].Value;
+        }
+
+        IntValue best = BestPickupViolationsParameter.ActualValue;
+        if (best == null) BestPickupViolationsParameter.ActualValue = new IntValue(min);
+        else best.Value = min;
+        DoubleValue average = AveragePickupViolationsParameter.ActualValue;
+        if (average == null) AveragePickupViolationsParameter.ActualValue = new DoubleValue(sum / pickupViolations.Length);
+        else average.Value = sum / pickupViolations.Length;
+        IntValue worst = WorstPickupViolationsParameter.ActualValue;
+        if (worst == null) WorstPickupViolationsParameter.ActualValue = new IntValue(max);
+        else worst.Value = max;
+      }
+    }
+  
+    public override IOperation Apply() {
+      UpdatePickupViolations();
+     
+      return base.Apply();
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestAverageWorstTours/PickupAndDelivery/BestPickupAndDeliveryVRPToursMemorizer.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestAverageWorstTours/PickupAndDelivery/BestPickupAndDeliveryVRPToursMemorizer.cs	(revision 6710)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestAverageWorstTours/PickupAndDelivery/BestPickupAndDeliveryVRPToursMemorizer.cs	(revision 6710)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.VehicleRouting {
+  [Item("BestPickupAndDeliveryVRPToursMemorizer", "An operator that updates the best VRP tour found so far in the scope three.")]
+  [StorableClass]
+  public class BestPickupAndDeliveryVRPToursMemorizer : SingleSuccessorOperator {
+    public ScopeTreeLookupParameter<IntValue> PickupViolationsParameter {
+      get { return (ScopeTreeLookupParameter<IntValue>)Parameters["PickupViolations"]; }
+    }
+
+    public ValueLookupParameter<IntValue> BestPickupViolationsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["BestPickupViolations"]; }
+    }
+
+    public BestPickupAndDeliveryVRPToursMemorizer()
+      : base() {
+        Parameters.Add(new ScopeTreeLookupParameter<IntValue>("PickupViolations", "The pickup violations of the VRP solutions which should be analyzed."));
+
+        Parameters.Add(new ValueLookupParameter<IntValue>("BestPickupViolations", "The best pickup violations found so far."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestPickupAndDeliveryVRPToursMemorizer(this, cloner);
+    }
+
+    protected BestPickupAndDeliveryVRPToursMemorizer(BestPickupAndDeliveryVRPToursMemorizer original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    protected BestPickupAndDeliveryVRPToursMemorizer(bool deserializing) : base(deserializing) { }
+
+    public override IOperation Apply() {
+      int i = PickupViolationsParameter.ActualValue.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index;
+      if (BestPickupViolationsParameter.ActualValue == null)
+        BestPickupViolationsParameter.ActualValue = new IntValue(PickupViolationsParameter.ActualValue[i].Value);
+      else if (PickupViolationsParameter.ActualValue[i].Value <= BestPickupViolationsParameter.ActualValue.Value)
+        BestPickupViolationsParameter.ActualValue.Value = PickupViolationsParameter.ActualValue[i].Value;
+
+      return base.Apply();
+    }
+  }
+}
