Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestAverageWorstVRPToursAnalyzer.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestAverageWorstVRPToursAnalyzer.cs	(revision 4301)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestAverageWorstVRPToursAnalyzer.cs	(revision 4301)
@@ -0,0 +1,354 @@
+#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;
+
+namespace HeuristicLab.Problems.VehicleRouting {
+  /// <summary>
+  /// An operator which analyzes the best, average and worst quality of solutions in the scope tree.
+  /// </summary>
+  [Item("BestAverageWorstVRPToursAnalyzer", "An operator which analyzes the best, average and worst properties of the VRP tours in the scope tree.")]
+  [StorableClass]
+  public sealed class BestAverageWorstVRPToursAnalyzer : AlgorithmOperator, IAnalyzer {
+    #region Parameter properties
+    public ScopeTreeLookupParameter<DoubleValue> OverloadParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Overload"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestOverloadParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestOverload"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentBestOverloadParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentBestOverload"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentAverageOverloadParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentAverageOverload"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentWorstOverloadParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentWorstOverload"]; }
+    }
+    public ValueLookupParameter<DataTable> OverloadsParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["Overloads"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> TardinessParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Tardiness"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestTardinessParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestTardiness"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentBestTardinessParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentBestTardiness"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentAverageTardinessParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentAverageTardiness"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentWorstTardinessParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentWorstTardiness"]; }
+    }
+    public ValueLookupParameter<DataTable> TardinessValuesParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["TardinessValues"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> DistanceParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Distance"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestDistanceParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestDistance"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentBestDistanceParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentBestDistance"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentAverageDistanceParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentAverageDistance"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentWorstDistanceParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentWorstDistance"]; }
+    }
+    public ValueLookupParameter<DataTable> DistancesParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["Distances"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> TravelTimeParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["TravelTime"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestTravelTimeParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestTravelTime"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentBestTravelTimeParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentBestTravelTime"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentAverageTravelTimeParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentAverageTravelTime"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentWorstTravelTimeParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentWorstTravelTime"]; }
+    }
+    public ValueLookupParameter<DataTable> TravelTimesParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["TravelTimes"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> VehiclesUtilizedParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["VehiclesUtilized"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestVehiclesUtilizedParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestVehiclesUtilized"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentBestVehiclesUtilizedParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentBestVehiclesUtilized"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentAverageVehiclesUtilizedParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentAverageVehiclesUtilized"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentWorstVehiclesUtilizedParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentWorstVehiclesUtilized"]; }
+    }
+    public ValueLookupParameter<DataTable> VehiclesUtilizedValuesParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["VehiclesUtilizedValues"]; }
+    }
+
+    public ValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    #endregion
+
+    #region Properties
+    private BestVRPToursMemorizer BestMemorizer {
+      get { return (BestVRPToursMemorizer)OperatorGraph.InitialOperator; }
+    }
+    private BestAverageWorstVRPToursCalculator BestAverageWorstCalculator {
+      get { return (BestAverageWorstVRPToursCalculator)BestMemorizer.Successor; }
+    }
+    #endregion
+
+    public BestAverageWorstVRPToursAnalyzer()
+      : base() {
+      #region Create parameters     
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Overload", "The overloads of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestOverload", "The best overload value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentBestOverload", "The current best overload value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentAverageOverload", "The current average overload value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentWorstOverload", "The current worst overload value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("Overloads", "The data table to store the current best, current average, current worst, best and best known overload value."));
+ 
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Tardiness", "The tardiness of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestTardiness", "The best tardiness value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentBestTardiness", "The current best tardiness value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentAverageTardiness", "The current average tardiness value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentWorstTardiness", "The current worst tardiness value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("TardinessValues", "The data table to store the current best, current average, current worst, best and best known tardiness value."));
+
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Distance", "The distance of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestDistance", "The best distance value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentBestDistance", "The current best distance value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentAverageDistance", "The current average distance value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentWorstDistance", "The current worst distance value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("Distances", "The data table to store the current best, current average, current worst, best and best known distance value."));
+
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("TravelTime", "The travel time of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestTravelTime", "The best travel time value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentBestTravelTime", "The current best travel time value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentAverageTravelTime", "The current average travel time value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentWorstTravelTime", "The current worst travel time value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("TravelTimes", "The data table to store the current best, current average, current worst, best and best known travel time value."));
+
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("VehiclesUtilized", "The vehicles utilized of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestVehiclesUtilized", "The best  vehicles utilized value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentBestVehiclesUtilized", "The current best  vehicles utilized value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentAverageVehiclesUtilized", "The current average  vehicles utilized value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentWorstVehiclesUtilized", "The current worst  vehicles utilized value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("VehiclesUtilizedValues", "The data table to store the current best, current average, current worst, best and best known vehicles utilized value."));
+
+      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The results collection where the analysis values should be stored."));
+      #endregion
+
+      #region Create operators
+      BestVRPToursMemorizer bestMemorizer = new BestVRPToursMemorizer();
+      BestAverageWorstVRPToursCalculator calculator = new BestAverageWorstVRPToursCalculator();
+      ResultsCollector resultsCollector = new ResultsCollector();
+
+      //overload
+      bestMemorizer.BestOverloadParameter.ActualName = BestOverloadParameter.Name;
+      bestMemorizer.OverloadParameter.ActualName = OverloadParameter.Name;
+      bestMemorizer.OverloadParameter.Depth = OverloadParameter.Depth;
+
+      calculator.OverloadParameter.ActualName = OverloadParameter.Name;
+      calculator.OverloadParameter.Depth = OverloadParameter.Depth;
+      calculator.BestOverloadParameter.ActualName = CurrentBestOverloadParameter.Name;
+      calculator.AverageOverloadParameter.ActualName = CurrentAverageOverloadParameter.Name;
+      calculator.WorstOverloadParameter.ActualName = CurrentWorstOverloadParameter.Name;
+
+      DataTableValuesCollector overloadDataTablesCollector = new DataTableValuesCollector();
+      overloadDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestOverload", null, BestOverloadParameter.Name));
+      overloadDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentBestOverload", null, CurrentBestOverloadParameter.Name));
+      overloadDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentAverageOverload", null, CurrentAverageOverloadParameter.Name));
+      overloadDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentWorstOverload", null, CurrentWorstOverloadParameter.Name));
+      overloadDataTablesCollector.DataTableParameter.ActualName = OverloadsParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(OverloadsParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestOverload", null, BestOverloadParameter.Name));
+
+      //tardiness
+      bestMemorizer.BestTardinessParameter.ActualName = BestTardinessParameter.Name;
+      bestMemorizer.TardinessParameter.ActualName = TardinessParameter.Name;
+      bestMemorizer.TardinessParameter.Depth = TardinessParameter.Depth;
+
+      calculator.TardinessParameter.ActualName = TardinessParameter.Name;
+      calculator.TardinessParameter.Depth = TardinessParameter.Depth;
+      calculator.BestTardinessParameter.ActualName = CurrentBestTardinessParameter.Name;
+      calculator.AverageTardinessParameter.ActualName = CurrentAverageTardinessParameter.Name;
+      calculator.WorstTardinessParameter.ActualName = CurrentWorstTardinessParameter.Name;
+
+      DataTableValuesCollector tardinessDataTablesCollector = new DataTableValuesCollector();
+      tardinessDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestTardiness", null, BestTardinessParameter.Name));
+      tardinessDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentBestTardiness", null, CurrentBestTardinessParameter.Name));
+      tardinessDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentAverageTardiness", null, CurrentAverageTardinessParameter.Name));
+      tardinessDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentWorstTardiness", null, CurrentWorstTardinessParameter.Name));
+      tardinessDataTablesCollector.DataTableParameter.ActualName = TardinessValuesParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(TardinessValuesParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestTardiness", null, BestTardinessParameter.Name));
+
+      //Distance
+      bestMemorizer.BestDistanceParameter.ActualName = BestDistanceParameter.Name;
+      bestMemorizer.DistanceParameter.ActualName = DistanceParameter.Name;
+      bestMemorizer.DistanceParameter.Depth = DistanceParameter.Depth;
+
+      calculator.DistanceParameter.ActualName = DistanceParameter.Name;
+      calculator.DistanceParameter.Depth = DistanceParameter.Depth;
+      calculator.BestDistanceParameter.ActualName = CurrentBestDistanceParameter.Name;
+      calculator.AverageDistanceParameter.ActualName = CurrentAverageDistanceParameter.Name;
+      calculator.WorstDistanceParameter.ActualName = CurrentWorstDistanceParameter.Name;
+
+      DataTableValuesCollector distanceDataTablesCollector = new DataTableValuesCollector();
+      distanceDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestDistance", null, BestDistanceParameter.Name));
+      distanceDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentBestDistance", null, CurrentBestDistanceParameter.Name));
+      distanceDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentAverageDistance", null, CurrentAverageDistanceParameter.Name));
+      distanceDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentWorstDistance", null, CurrentWorstDistanceParameter.Name));
+      distanceDataTablesCollector.DataTableParameter.ActualName = DistancesParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(DistancesParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestDistance", null, BestDistanceParameter.Name));
+
+      //Travel Time
+      bestMemorizer.BestTravelTimeParameter.ActualName = BestTravelTimeParameter.Name;
+      bestMemorizer.TravelTimeParameter.ActualName = TravelTimeParameter.Name;
+      bestMemorizer.TravelTimeParameter.Depth = TravelTimeParameter.Depth;
+
+      calculator.TravelTimeParameter.ActualName = TravelTimeParameter.Name;
+      calculator.TravelTimeParameter.Depth = TravelTimeParameter.Depth;
+      calculator.BestTravelTimeParameter.ActualName = CurrentBestTravelTimeParameter.Name;
+      calculator.AverageTravelTimeParameter.ActualName = CurrentAverageTravelTimeParameter.Name;
+      calculator.WorstTravelTimeParameter.ActualName = CurrentWorstTravelTimeParameter.Name;
+
+      DataTableValuesCollector travelTimeDataTablesCollector = new DataTableValuesCollector();
+      travelTimeDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestTravelTime", null, BestTravelTimeParameter.Name));
+      travelTimeDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentBestTravelTime", null, CurrentBestTravelTimeParameter.Name));
+      travelTimeDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentAverageTravelTime", null, CurrentAverageTravelTimeParameter.Name));
+      travelTimeDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentWorstTravelTime", null, CurrentWorstTravelTimeParameter.Name));
+      travelTimeDataTablesCollector.DataTableParameter.ActualName = TravelTimesParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(TravelTimesParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestTravelTime", null, BestTravelTimeParameter.Name));
+
+      //Vehicles Utlized
+      bestMemorizer.BestVehiclesUtilizedParameter.ActualName = BestVehiclesUtilizedParameter.Name;
+      bestMemorizer.VehiclesUtilizedParameter.ActualName = VehiclesUtilizedParameter.Name;
+      bestMemorizer.VehiclesUtilizedParameter.Depth = VehiclesUtilizedParameter.Depth;
+
+      calculator.VehiclesUtilizedParameter.ActualName = VehiclesUtilizedParameter.Name;
+      calculator.VehiclesUtilizedParameter.Depth = VehiclesUtilizedParameter.Depth;
+      calculator.BestVehiclesUtilizedParameter.ActualName = CurrentBestVehiclesUtilizedParameter.Name;
+      calculator.AverageVehiclesUtilizedParameter.ActualName = CurrentAverageVehiclesUtilizedParameter.Name;
+      calculator.WorstVehiclesUtilizedParameter.ActualName = CurrentWorstVehiclesUtilizedParameter.Name;
+
+      DataTableValuesCollector vehiclesUtilizedDataTablesCollector = new DataTableValuesCollector();
+      vehiclesUtilizedDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestVehiclesUtilized", null, BestVehiclesUtilizedParameter.Name));
+      vehiclesUtilizedDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentBestVehiclesUtilized", null, CurrentBestVehiclesUtilizedParameter.Name));
+      vehiclesUtilizedDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentAverageVehiclesUtilized", null, CurrentAverageVehiclesUtilizedParameter.Name));
+      vehiclesUtilizedDataTablesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentWorstVehiclesUtilized", null, CurrentWorstVehiclesUtilizedParameter.Name));
+      vehiclesUtilizedDataTablesCollector.DataTableParameter.ActualName = VehiclesUtilizedValuesParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(VehiclesUtilizedValuesParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestVehiclesUtilized", null, BestVehiclesUtilizedParameter.Name));
+      #endregion
+
+      #region Create operator graph
+      OperatorGraph.InitialOperator = bestMemorizer;
+      bestMemorizer.Successor = calculator;
+      calculator.Successor = overloadDataTablesCollector;
+      overloadDataTablesCollector.Successor = tardinessDataTablesCollector;
+      tardinessDataTablesCollector.Successor = distanceDataTablesCollector;
+      distanceDataTablesCollector.Successor = travelTimeDataTablesCollector;
+      travelTimeDataTablesCollector.Successor = vehiclesUtilizedDataTablesCollector;
+      vehiclesUtilizedDataTablesCollector.Successor = resultsCollector;
+      resultsCollector.Successor = null;
+      #endregion
+
+      Initialize();
+    }
+    [StorableConstructor]
+    private BestAverageWorstVRPToursAnalyzer(bool deserializing) : base() { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void Initialize() {
+      OverloadParameter.DepthChanged += new EventHandler(OverloadParameter_DepthChanged);
+      TardinessParameter.DepthChanged += new EventHandler(TardinessParameter_DepthChanged);
+      DistanceParameter.DepthChanged += new EventHandler(DistanceParameter_DepthChanged);
+      TravelTimeParameter.DepthChanged += new EventHandler(TravelTimeParameter_DepthChanged);
+      VehiclesUtilizedParameter.DepthChanged += new EventHandler(VehiclesUtilizedParameter_DepthChanged);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      BestAverageWorstVRPToursAnalyzer clone = (BestAverageWorstVRPToursAnalyzer)base.Clone(cloner);
+      clone.Initialize();
+      return clone;
+    }
+
+    void OverloadParameter_DepthChanged(object sender, EventArgs e) {
+      BestAverageWorstCalculator.OverloadParameter.Depth = OverloadParameter.Depth;
+    }
+
+    void TardinessParameter_DepthChanged(object sender, EventArgs e) {
+      BestAverageWorstCalculator.TardinessParameter.Depth = TardinessParameter.Depth;
+    }
+
+    void DistanceParameter_DepthChanged(object sender, EventArgs e) {
+      BestAverageWorstCalculator.DistanceParameter.Depth = DistanceParameter.Depth;
+    }
+
+    void TravelTimeParameter_DepthChanged(object sender, EventArgs e) {
+      BestAverageWorstCalculator.TravelTimeParameter.Depth = TravelTimeParameter.Depth;
+    }
+
+    void VehiclesUtilizedParameter_DepthChanged(object sender, EventArgs e) {
+      BestAverageWorstCalculator.VehiclesUtilizedParameter.Depth = VehiclesUtilizedParameter.Depth;
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestAverageWorstVRPToursCalculator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestAverageWorstVRPToursCalculator.cs	(revision 4301)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestAverageWorstVRPToursCalculator.cs	(revision 4301)
@@ -0,0 +1,245 @@
+#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;
+
+namespace HeuristicLab.Problems.VehicleRouting {
+  [Item("BestAverageWorstVRPToursCalculator", "An operator which calculates the current best, average and worst properties of VRP tours in the scope tree.")]
+  [StorableClass]
+  public sealed class BestAverageWorstVRPToursCalculator : SingleSuccessorOperator {
+    public ScopeTreeLookupParameter<DoubleValue> OverloadParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Overload"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestOverloadParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestOverload"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AverageOverloadParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AverageOverload"]; }
+    }
+    public ValueLookupParameter<DoubleValue> WorstOverloadParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["WorstOverload"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> TardinessParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Tardiness"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestTardinessParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestTardiness"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AverageTardinessParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AverageTardiness"]; }
+    }
+    public ValueLookupParameter<DoubleValue> WorstTardinessParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["WorstTardiness"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> DistanceParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Distance"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestDistanceParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestDistance"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AverageDistanceParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AverageDistance"]; }
+    }
+    public ValueLookupParameter<DoubleValue> WorstDistanceParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["WorstDistance"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> TravelTimeParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["TravelTime"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestTravelTimeParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestTravelTime"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AverageTravelTimeParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AverageTravelTime"]; }
+    }
+    public ValueLookupParameter<DoubleValue> WorstTravelTimeParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["WorstTravelTime"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> VehiclesUtilizedParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["VehiclesUtilized"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestVehiclesUtilizedParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestVehiclesUtilized"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AverageVehiclesUtilizedParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AverageVehiclesUtilized"]; }
+    }
+    public ValueLookupParameter<DoubleValue> WorstVehiclesUtilizedParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["WorstVehiclesUtilized"]; }
+    }
+
+    public BestAverageWorstVRPToursCalculator()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Distance", "The distances of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestDistance", "The best distance value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AverageDistance", "The average distance value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("WorstDistance", "The worst distance value of all solutions."));
+
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Overload", "The overloads of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestOverload", "The best overload value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AverageOverload", "The average overload value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("WorstOverload", "The worst overload value of all solutions."));
+
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Tardiness", "The tardiness of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestTardiness", "The best tardiness value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AverageTardiness", "The average tardiness value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("WorstTardiness", "The worst tardiness value of all solutions."));
+
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("TravelTime", "The travel times of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestTravelTime", "The best travel time value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AverageTravelTime", "The average travel time value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("WorstTravelTime", "The worst travel time value of all solutions."));
+
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("VehiclesUtilized", "The utilized vehicles of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestVehiclesUtilized", "The best utilized vehicles value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AverageVehiclesUtilized", "The average utilized vehicles value of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("WorstVehiclesUtilized", "The worst utilized vehicles value of all solutions."));
+    }
+
+    private void UpdateOverloads() {
+      ItemArray<DoubleValue> overloads = OverloadParameter.ActualValue;
+      if (overloads.Length > 0) {
+        double min = double.MaxValue, max = double.MinValue, sum = 0.0;
+        for (int i = 0; i < overloads.Length; i++) {
+          if (overloads[i].Value < min) min = overloads[i].Value;
+          if (overloads[i].Value > max) max = overloads[i].Value;
+          sum += overloads[i].Value;
+        }
+
+        DoubleValue best = BestOverloadParameter.ActualValue;
+        if (best == null) BestOverloadParameter.ActualValue = new DoubleValue(min);
+        else best.Value = min;
+        DoubleValue average = AverageOverloadParameter.ActualValue;
+        if (average == null) AverageOverloadParameter.ActualValue = new DoubleValue(sum / overloads.Length);
+        else average.Value = sum / overloads.Length;
+        DoubleValue worst = WorstOverloadParameter.ActualValue;
+        if (worst == null) WorstOverloadParameter.ActualValue = new DoubleValue(max);
+        else worst.Value = max;
+      }
+    }
+
+    private void UpdateTardiness() {
+      ItemArray<DoubleValue> tardiness = TardinessParameter.ActualValue;
+      if (tardiness.Length > 0) {
+        double min = double.MaxValue, max = double.MinValue, sum = 0.0;
+        for (int i = 0; i < tardiness.Length; i++) {
+          if (tardiness[i].Value < min) min = tardiness[i].Value;
+          if (tardiness[i].Value > max) max = tardiness[i].Value;
+          sum += tardiness[i].Value;
+        }
+
+        DoubleValue best = BestTardinessParameter.ActualValue;
+        if (best == null) BestTardinessParameter.ActualValue = new DoubleValue(min);
+        else best.Value = min;
+        DoubleValue average = AverageTardinessParameter.ActualValue;
+        if (average == null) AverageTardinessParameter.ActualValue = new DoubleValue(sum / tardiness.Length);
+        else average.Value = sum / tardiness.Length;
+        DoubleValue worst = WorstTardinessParameter.ActualValue;
+        if (worst == null) WorstTardinessParameter.ActualValue = new DoubleValue(max);
+        else worst.Value = max;
+      }
+    }
+
+    private void UpdateDistances() {
+      ItemArray<DoubleValue> distances = DistanceParameter.ActualValue;
+      if (distances.Length > 0) {
+        double min = double.MaxValue, max = double.MinValue, sum = 0.0;
+        for (int i = 0; i < distances.Length; i++) {
+          if (distances[i].Value < min) min = distances[i].Value;
+          if (distances[i].Value > max) max = distances[i].Value;
+          sum += distances[i].Value;
+        }
+
+        DoubleValue best = BestDistanceParameter.ActualValue;
+        if (best == null) BestDistanceParameter.ActualValue = new DoubleValue(min);
+        else best.Value = min;
+        DoubleValue average = AverageDistanceParameter.ActualValue;
+        if (average == null) AverageDistanceParameter.ActualValue = new DoubleValue(sum / distances.Length);
+        else average.Value = sum / distances.Length;
+        DoubleValue worst = WorstDistanceParameter.ActualValue;
+        if (worst == null) WorstDistanceParameter.ActualValue = new DoubleValue(max);
+        else worst.Value = max;
+      }
+    }
+
+    private void UpdateTravelTimes() {
+      ItemArray<DoubleValue> travelTimes = TravelTimeParameter.ActualValue;
+      if (travelTimes.Length > 0) {
+        double min = double.MaxValue, max = double.MinValue, sum = 0.0;
+        for (int i = 0; i < travelTimes.Length; i++) {
+          if (travelTimes[i].Value < min) min = travelTimes[i].Value;
+          if (travelTimes[i].Value > max) max = travelTimes[i].Value;
+          sum += travelTimes[i].Value;
+        }
+
+        DoubleValue best = BestTravelTimeParameter.ActualValue;
+        if (best == null) BestTravelTimeParameter.ActualValue = new DoubleValue(min);
+        else best.Value = min;
+        DoubleValue average = AverageTravelTimeParameter.ActualValue;
+        if (average == null) AverageTravelTimeParameter.ActualValue = new DoubleValue(sum / travelTimes.Length);
+        else average.Value = sum / travelTimes.Length;
+        DoubleValue worst = WorstTravelTimeParameter.ActualValue;
+        if (worst == null) WorstTravelTimeParameter.ActualValue = new DoubleValue(max);
+        else worst.Value = max;
+      }
+    }
+
+    private void UpdateVehiclesUtilized() {
+      ItemArray<DoubleValue> vehiclesUtilized = VehiclesUtilizedParameter.ActualValue;
+      if (vehiclesUtilized.Length > 0) {
+        double min = double.MaxValue, max = double.MinValue, sum = 0.0;
+        for (int i = 0; i < vehiclesUtilized.Length; i++) {
+          if (vehiclesUtilized[i].Value < min) min = vehiclesUtilized[i].Value;
+          if (vehiclesUtilized[i].Value > max) max = vehiclesUtilized[i].Value;
+          sum += vehiclesUtilized[i].Value;
+        }
+
+        DoubleValue best = BestVehiclesUtilizedParameter.ActualValue;
+        if (best == null) BestVehiclesUtilizedParameter.ActualValue = new DoubleValue(min);
+        else best.Value = min;
+        DoubleValue average = AverageVehiclesUtilizedParameter.ActualValue;
+        if (average == null) AverageVehiclesUtilizedParameter.ActualValue = new DoubleValue(sum / vehiclesUtilized.Length);
+        else average.Value = sum / vehiclesUtilized.Length;
+        DoubleValue worst = WorstVehiclesUtilizedParameter.ActualValue;
+        if (worst == null) WorstVehiclesUtilizedParameter.ActualValue = new DoubleValue(max);
+        else worst.Value = max;
+      }
+    }
+
+    public override IOperation Apply() {
+      UpdateOverloads();
+      UpdateTardiness();
+      UpdateDistances();
+      UpdateTravelTimes();
+      UpdateVehiclesUtilized();
+
+      return base.Apply();
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestVRPSolutionAnalyzer.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestVRPSolutionAnalyzer.cs	(revision 4218)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestVRPSolutionAnalyzer.cs	(revision 4301)
@@ -127,20 +127,14 @@
         BestSolutionParameter.ActualValue = solution;
         results.Add(new Result("Best VRP Solution", solution));
-
-        results.Add(new Result("Best TravelTime", new DoubleValue(travelTimes[i].Value)));
-        results.Add(new Result("Best Distance",  new DoubleValue(distances[i].Value)));
-        results.Add(new Result("Best VehicleUtilization", new DoubleValue(vehiclesUtilizations[i].Value)));
-        results.Add(new Result("Best Overload",  new DoubleValue(overloads[i].Value)));
-        results.Add(new Result("Best Tardiness",  new DoubleValue(tardinesses[i].Value)));
       } else {
-        if (solution.Quality.Value > qualities[i].Value) {
+        if (qualities[i].Value <= solution.Quality.Value) {
           solution.Coordinates = coordinates;
           solution.Solution = best.Clone() as IVRPEncoding;
           solution.Quality.Value = qualities[i].Value;
-          solution.Distance.Value = (results["Best Distance"].Value as DoubleValue).Value = distances[i].Value;
-          solution.Overload.Value = (results["Best Overload"].Value as DoubleValue).Value = overloads[i].Value;
-          solution.Tardiness.Value = (results["Best Tardiness"].Value as DoubleValue).Value = tardinesses[i].Value;
-          solution.TravelTime.Value = (results["Best TravelTime"].Value as DoubleValue).Value = travelTimes[i].Value;
-          solution.VehicleUtilization.Value = (results["Best VehicleUtilization"].Value as DoubleValue).Value = vehiclesUtilizations[i].Value;
+          solution.Distance.Value = distances[i].Value;
+          solution.Overload.Value = overloads[i].Value;
+          solution.Tardiness.Value = tardinesses[i].Value;
+          solution.TravelTime.Value = travelTimes[i].Value;
+          solution.VehicleUtilization.Value = vehiclesUtilizations[i].Value;
           solution.DistanceMatrix = DistanceMatrixParameter.ActualValue;
           solution.UseDistanceMatrix = UseDistanceMatrixParameter.ActualValue;
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestVRPToursMemorizer.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestVRPToursMemorizer.cs	(revision 4301)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Analyzers/BestVRPToursMemorizer.cs	(revision 4301)
@@ -0,0 +1,115 @@
+﻿#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;
+
+namespace HeuristicLab.Problems.VehicleRouting {
+  [Item("BestVRPToursMemorizer", "An operator that updates the best VRP tour found so far in the scope three.")]
+  [StorableClass]
+  public class BestVRPToursMemorizer : SingleSuccessorOperator {
+    public ScopeTreeLookupParameter<DoubleValue> OverloadParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Overload"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> TardinessParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Tardiness"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> DistanceParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Distance"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> TravelTimeParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["TravelTime"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> VehiclesUtilizedParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["VehiclesUtilized"]; }
+    }
+
+    public ValueLookupParameter<DoubleValue> BestOverloadParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestOverload"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestTardinessParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestTardiness"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestDistanceParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestDistance"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestTravelTimeParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestTravelTime"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestVehiclesUtilizedParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestVehiclesUtilized"]; }
+    }
+
+    public BestVRPToursMemorizer()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Distance", "The distances of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Overload", "The overloads of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Tardiness", "The tardiness of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("TravelTime", "The travel times of the VRP solutions which should be analyzed."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("VehiclesUtilized", "The utilized vehicles of the VRP solutions which should be analyzed."));
+
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestDistance", "The best distance found so far."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestOverload", "The best overload found so far."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestTardiness", "The best tardiness found so far."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestTravelTime", "The best travel time found so far."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestVehiclesUtilized", "The best vehicles utilized found so far."));
+ 
+    }
+
+    public override IOperation Apply() {
+      int i = OverloadParameter.ActualValue.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index;
+      if (BestOverloadParameter.ActualValue == null)
+        BestOverloadParameter.ActualValue = new DoubleValue(OverloadParameter.ActualValue[i].Value);
+      else if(OverloadParameter.ActualValue[i].Value <= BestOverloadParameter.ActualValue.Value)
+        BestOverloadParameter.ActualValue.Value = OverloadParameter.ActualValue[i].Value;
+
+      i = TardinessParameter.ActualValue.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index;
+      if (BestTardinessParameter.ActualValue == null)
+        BestTardinessParameter.ActualValue = new DoubleValue(TardinessParameter.ActualValue[i].Value);
+      else if (TardinessParameter.ActualValue[i].Value <= BestTardinessParameter.ActualValue.Value)
+        BestTardinessParameter.ActualValue.Value = TardinessParameter.ActualValue[i].Value;
+
+      i = DistanceParameter.ActualValue.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index;
+      if (BestDistanceParameter.ActualValue == null)
+        BestDistanceParameter.ActualValue = new DoubleValue(DistanceParameter.ActualValue[i].Value);
+      else if (DistanceParameter.ActualValue[i].Value <= BestDistanceParameter.ActualValue.Value)
+        BestDistanceParameter.ActualValue.Value = DistanceParameter.ActualValue[i].Value;
+
+      i = TravelTimeParameter.ActualValue.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index;
+      if (BestTravelTimeParameter.ActualValue == null)
+        BestTravelTimeParameter.ActualValue = new DoubleValue(TravelTimeParameter.ActualValue[i].Value);
+      else if (TravelTimeParameter.ActualValue[i].Value <= BestTravelTimeParameter.ActualValue.Value)
+        BestTravelTimeParameter.ActualValue.Value = TravelTimeParameter.ActualValue[i].Value;
+
+      i = VehiclesUtilizedParameter.ActualValue.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index;
+      if (BestVehiclesUtilizedParameter.ActualValue == null)
+        BestVehiclesUtilizedParameter.ActualValue = new DoubleValue(VehiclesUtilizedParameter.ActualValue[i].Value);
+      else if (VehiclesUtilizedParameter.ActualValue[i].Value <= BestVehiclesUtilizedParameter.ActualValue.Value)
+        BestVehiclesUtilizedParameter.ActualValue.Value = VehiclesUtilizedParameter.ActualValue[i].Value;
+
+      return base.Apply();
+    }
+  }
+}
