Index: /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/Analyzers/BestOrienteeringSolutionAnalyser.cs
===================================================================
--- /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/Analyzers/BestOrienteeringSolutionAnalyser.cs	(revision 11190)
+++ /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/Analyzers/BestOrienteeringSolutionAnalyser.cs	(revision 11190)
@@ -0,0 +1,115 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.Orienteering {
+  public class BestOrienteeringSolutionAnalyser : SingleSuccessorOperator, IAnalyzer {
+    public virtual bool EnabledByDefault {
+      get { return true; }
+    }
+
+    public IScopeTreeLookupParameter<IntegerVector> IntegerVector {
+      get { return (IScopeTreeLookupParameter<IntegerVector>)Parameters["IntegerVector"]; }
+    }
+    public LookupParameter<DoubleMatrix> CoordinatesParameter {
+      get { return (LookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    }
+    public ILookupParameter<DoubleArray> ScoresParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Scores"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public LookupParameter<OrienteeringSolution> BestSolutionParameter {
+      get { return (LookupParameter<OrienteeringSolution>)Parameters["BestSolution"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public LookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (LookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public LookupParameter<IntegerVector> BestKnownSolutionParameter {
+      get { return (LookupParameter<IntegerVector>)Parameters["BestKnownSolution"]; }
+    }
+
+    [StorableConstructor]
+    private BestOrienteeringSolutionAnalyser(bool deserializing) : base(deserializing) { }
+    private BestOrienteeringSolutionAnalyser(BestOrienteeringSolutionAnalyser original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestOrienteeringSolutionAnalyser(this, cloner);
+    }
+    public BestOrienteeringSolutionAnalyser()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("IntegerVector", "The Orienteering solutions which should be analysed."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the points."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Scores", "The scores of the points."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the Orienteering solutions which should be analyzed."));
+      Parameters.Add(new LookupParameter<OrienteeringSolution>("BestSolution", "The best Orienteering solution."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the best Orienteering solution should be stored."));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this Orienteering instance."));
+      Parameters.Add(new LookupParameter<IntegerVector>("BestKnownSolution", "The best known solution of this Orienteering instance."));
+    }
+
+    public override IOperation Apply() {
+      var solutions = IntegerVector.ActualValue;
+      var qualities = QualityParameter.ActualValue;
+      var results = ResultsParameter.ActualValue;
+      var bestKnownQuality = BestKnownQualityParameter.ActualValue;
+
+      int bestIndex = qualities.Select((quality, index) => new { index, quality.Value }).OrderByDescending(x => x.Value).First().index;
+
+      if (bestKnownQuality == null || qualities[bestIndex].Value > bestKnownQuality.Value) {
+        BestKnownQualityParameter.ActualValue = new DoubleValue(qualities[bestIndex].Value);
+        BestKnownSolutionParameter.ActualValue = (IntegerVector)solutions[bestIndex].Clone();
+      }
+
+      var solution = BestSolutionParameter.ActualValue;
+      var coordinates = CoordinatesParameter.ActualValue;
+      if (solution == null) {
+        solution = new OrienteeringSolution(
+          (IntegerVector)solutions[bestIndex].Clone(),
+          coordinates,
+          new DoubleValue(qualities[bestIndex].Value));
+        BestSolutionParameter.ActualValue = solution;
+        results.Add(new Result("Best Orienteering Solution", solution));
+      } else {
+        if (solution.Quality.Value < qualities[bestIndex].Value) {
+          solution.Coordinates = coordinates;
+          solution.IntegerVector = (IntegerVector)solutions[bestIndex].Clone();
+          solution.Quality.Value = qualities[bestIndex].Value;
+        }
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/HeuristicLab.Problems.Orienteering-3.3.csproj
===================================================================
--- /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/HeuristicLab.Problems.Orienteering-3.3.csproj	(revision 11189)
+++ /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/HeuristicLab.Problems.Orienteering-3.3.csproj	(revision 11190)
@@ -46,4 +46,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Analyzers\BestOrienteeringSolutionAnalyser.cs" />
     <Compile Include="DistanceMatrix.cs" />
     <Compile Include="Interfaces\IOrienteeringEvaluator.cs" />
@@ -51,4 +52,5 @@
     <Compile Include="OrienteeringProblem.cs" />
     <Compile Include="OrienteeringScript.cs" />
+    <Compile Include="OrienteeringSolution.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -67,4 +69,8 @@
       <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
       <Name>HeuristicLab.Collections-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0e27a536-1c4a-4624-a65e-dc4f4f23e3e1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
@@ -120,4 +126,5 @@
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/OrienteeringProblem.cs
===================================================================
--- /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/OrienteeringProblem.cs	(revision 11189)
+++ /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/OrienteeringProblem.cs	(revision 11190)
@@ -21,4 +21,6 @@
 
 using System;
+using System.Linq;
+using HeuristicLab.Analysis;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -110,4 +112,10 @@
       set { BestKnownSolutionParameter.Value = value; }
     }
+    private BestOrienteeringSolutionAnalyser BestOrienteeringSolutionAnalyser {
+      get { return Operators.OfType<BestOrienteeringSolutionAnalyser>().SingleOrDefault(); }
+    }
+    private SingleObjectivePopulationDiversityAnalyzer SingleObjectivePopulationDiversityAnalyzer {
+      get { return Operators.OfType<SingleObjectivePopulationDiversityAnalyzer>().SingleOrDefault(); }
+    }
     #endregion
 
@@ -116,15 +124,11 @@
       : base(deserializing) {
     }
-
     private OrienteeringProblem(OrienteeringProblem original, Cloner cloner)
       : base(original, cloner) {
       RegisterEventHandlers();
     }
-
     public override IDeepCloneable Clone(Cloner cloner) {
       return new OrienteeringProblem(this, cloner);
     }
-
-
     public OrienteeringProblem()
       : base(new OrienteeringEvaluator(), new UniformRandomIntegerVectorCreator()) { // TODO: Greedy route creator for solution creator
@@ -144,5 +148,5 @@
       SolutionCreator.IntegerVectorParameter.ActualName = "OrienteeringSolution";
 
-      InitializeRandomOrienteeringInstance();
+      InitializeInitialOrienteeringInstance();
 
       ParameterizeSolutionCreator();
@@ -156,5 +160,5 @@
     protected override void OnSolutionCreatorChanged() {
       base.OnSolutionCreatorChanged();
-      SolutionCreator.IntegerVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_IntegerVectorParameter_ActualNameChanged);
+      SolutionCreator.IntegerVectorParameter.ActualNameChanged += SolutionCreator_IntegerVectorParameter_ActualNameChanged;
       ParameterizeSolutionCreator();
       ParameterizeEvaluator();
@@ -171,4 +175,46 @@
       ParameterizeAnalyzer();
       ParameterizeOperators();
+    }
+    private void CoordinatesParameter_ValueChanged(object sender, EventArgs e) {
+      if (Coordinates != null) {
+        Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(CoordinatesValue_ItemChanged);
+        Coordinates.Reset += new EventHandler(CoordinatesValue_Reset);
+      }
+      ParameterizeSolutionCreator();
+      DistanceMatrix = null;
+    }
+    private void CoordinatesValue_ItemChanged(object sender, EventArgs<int, int> e) {
+      DistanceMatrix = null;
+    }
+    private void CoordinatesValue_Reset(object sender, EventArgs e) {
+      ParameterizeSolutionCreator();
+      DistanceMatrix = null;
+    }
+    private void StartingPointParameter_ValueChanged(object sender, EventArgs e) {
+      ParameterizeEvaluator();
+      ParameterizeAnalyzer();
+    }
+
+    private void TerminusPointParameter_ValueChanged(object sender, EventArgs e) {
+      ParameterizeEvaluator();
+      ParameterizeAnalyzer();
+    }
+    private void MaximumDistanceParameter_ValueChanged(object sender, EventArgs e) {
+      ParameterizeEvaluator();
+      ParameterizeAnalyzer();
+    }
+    private void ScoresParameter_ValueChanged(object sender, EventArgs e) {
+      ParameterizeEvaluator();
+      ParameterizeAnalyzer();
+      ParameterizeSolutionCreator();
+
+      ScoresParameter.Value.Reset += new EventHandler(ScoresValue_Reset);
+    }
+    private void ScoresValue_Reset(object sender, EventArgs e) {
+      ParameterizeSolutionCreator();
+    }
+    private void FixedPenaltyParameter_ValueChanged(object sender, EventArgs e) {
+      ParameterizeEvaluator();
+      ParameterizeAnalyzer();
     }
     #endregion
@@ -181,11 +227,26 @@
 
     private void RegisterEventHandlers() {
-      SolutionCreator.IntegerVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_IntegerVectorParameter_ActualNameChanged);
-      // TODO
-    }
+      SolutionCreator.IntegerVectorParameter.ActualNameChanged += SolutionCreator_IntegerVectorParameter_ActualNameChanged;
+
+      CoordinatesParameter.ValueChanged += CoordinatesParameter_ValueChanged;
+      if (CoordinatesParameter.Value != null) {
+        CoordinatesParameter.Value.ItemChanged += CoordinatesValue_ItemChanged;
+        CoordinatesParameter.Value.Reset += CoordinatesValue_Reset;
+      }
+
+      StartingPointParameter.ValueChanged += StartingPointParameter_ValueChanged;
+      TerminusPointParameter.ValueChanged += TerminusPointParameter_ValueChanged;
+      MaximumDistanceParameter.ValueChanged += MaximumDistanceParameter_ValueChanged;
+
+      ScoresParameter.ValueChanged += ScoresParameter_ValueChanged;
+      ScoresParameter.Value.Reset += ScoresValue_Reset;
+      FixedPenaltyParameter.ValueChanged += FixedPenaltyParameter_ValueChanged;
+    }
+
     private void ParameterizeSolutionCreator() {
-      if (SolutionCreator.LengthParameter.Value == null
-          || SolutionCreator.LengthParameter.Value.Value != Scores.Length) {
-        SolutionCreator.LengthParameter.Value = new IntValue(Scores.Length);
+      if (SolutionCreator is UniformRandomIntegerVectorCreator) {
+        if (SolutionCreator.LengthParameter.Value == null || SolutionCreator.LengthParameter.Value.Value != Scores.Length) {
+          SolutionCreator.LengthParameter.Value = new IntValue(Scores.Length);
+        }
       }
     }
@@ -193,5 +254,6 @@
       if (Evaluator is OrienteeringEvaluator) {
         var orienteeringEvaluator = (OrienteeringEvaluator)Evaluator;
-        // TODO
+        orienteeringEvaluator.SolutionParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName;
+        orienteeringEvaluator.ScoresParameter.ActualName = ScoresParameter.Name;
       }
     }
@@ -200,5 +262,5 @@
     }
     private void InitializeOperators() {
-      // TODO  
+      // TODO
     }
     private void ParameterizeOperators() {
@@ -207,6 +269,19 @@
     #endregion
 
-    private void InitializeRandomOrienteeringInstance() {
-      // TODO
+    private void InitializeInitialOrienteeringInstance() {
+      Coordinates = new DoubleMatrix(new double[21, 2] {
+        {  4.60,  7.10 }, {  5.70, 11.40 }, {  4.40, 12.30 }, {  2.80, 14.30 }, {  3.20, 10.30 },
+        {  3.50,  9.80 }, {  4.40,  8.40 }, {  7.80, 11.00 }, {  8.80,  9.80 }, {  7.70,  8.20 },
+        {  6.30,  7.90 }, {  5.40,  8.20 }, {  5.80,  6.80 }, {  6.70,  5.80 }, { 13.80, 13.10 },
+        { 14.10, 14.20 }, { 11.20, 13.60 }, {  9.70, 16.40 }, {  9.50, 18.80 }, {  4.70, 16.80 },
+        {  5.00,  5.60 }
+      });
+      UseDistanceMatrix.Value = false;
+
+      StartingPoint.Value = 0;
+      TerminusPoint.Value = 20;
+      MaximumDistance.Value = 30;
+
+      Scores = new DoubleArray(new double[21] { 0, 20, 20, 30, 15, 15, 10, 20, 20, 20, 15, 10, 10, 25, 40, 40, 30, 30, 50, 30, 0 });
     }
 
Index: /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/OrienteeringSolution.cs
===================================================================
--- /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/OrienteeringSolution.cs	(revision 11190)
+++ /branches/HeuristicLab.Problems.Orienteering/HeuristicLab.Problems.Orienteering/3.3/OrienteeringSolution.cs	(revision 11190)
@@ -0,0 +1,152 @@
+using System;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.Orienteering {
+  [Item("OrienteeringSolution", "Represents a Orienteering solution which can be visualized in the GUI.")]
+  [StorableClass]
+  public class OrienteeringSolution : Item {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Image; }
+    }
+
+    [Storable]
+    private IntegerVector integerVector;
+    public IntegerVector IntegerVector {
+      get { return integerVector; }
+      set {
+        if (integerVector != value) {
+          if (integerVector != null) DeregisterIntegerVectorEvents();
+          integerVector = value;
+          if (integerVector != null) RegisterIntegerVectorEvents();
+          OnIntegerVectorChanged();
+        }
+      }
+    }
+    [Storable]
+    private DoubleMatrix coordinates;
+    public DoubleMatrix Coordinates {
+      get { return coordinates; }
+      set {
+        if (coordinates != value) {
+          if (coordinates != null) DeregisterCoordinatesEvents();
+          coordinates = value;
+          if (coordinates != null) RegisterCoordinatesEvents();
+          OnCoordinatesChanged();
+        }
+      }
+    }
+    [Storable]
+    private DoubleValue quality;
+    public DoubleValue Quality {
+      get { return quality; }
+      set {
+        if (quality != value) {
+          if (quality != null) DeregisterQualityEvents();
+          quality = value;
+          if (quality != null) RegisterQualityEvents();
+          OnQualityChanged();
+        }
+      }
+    }
+
+    [StorableConstructor]
+    private OrienteeringSolution(bool deserializing) : base(deserializing) { }
+    private OrienteeringSolution(OrienteeringSolution original, Cloner cloner)
+      : base(original, cloner) {
+      this.integerVector = cloner.Clone(original.integerVector);
+      this.coordinates = cloner.Clone(original.coordinates);
+      this.quality = cloner.Clone(original.quality);
+      Initialize();
+    }
+    public OrienteeringSolution(IntegerVector integerVector, DoubleMatrix coordinates, DoubleValue quality)
+      : base() {
+      this.integerVector = integerVector;
+      this.coordinates = coordinates;
+      this.quality = quality;
+      Initialize();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OrienteeringSolution(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+
+    private void Initialize() {
+      if (integerVector != null) RegisterIntegerVectorEvents();
+      if (coordinates != null) RegisterCoordinatesEvents();
+      if (quality != null) RegisterQualityEvents();
+    }
+
+    #region Events
+    public event EventHandler IntegerVectorChanged;
+    private void OnIntegerVectorChanged() {
+      var changed = IntegerVectorChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    public event EventHandler CoordinatesChanged;
+    private void OnCoordinatesChanged() {
+      var changed = CoordinatesChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+
+    public event EventHandler QualityChanged;
+    private void OnQualityChanged() {
+      var changed = QualityChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    private void RegisterIntegerVectorEvents() {
+      IntegerVector.ItemChanged += new EventHandler<EventArgs<int>>(IntegerVector_ItemChanged);
+      IntegerVector.Reset += new EventHandler(IntegerVector_Reset);
+    }
+    private void DeregisterIntegerVectorEvents() {
+      IntegerVector.ItemChanged -= new EventHandler<EventArgs<int>>(IntegerVector_ItemChanged);
+      IntegerVector.Reset -= new EventHandler(IntegerVector_Reset);
+    }
+    private void RegisterCoordinatesEvents() {
+      Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
+      Coordinates.Reset += new EventHandler(Coordinates_Reset);
+    }
+    private void DeregisterCoordinatesEvents() {
+      Coordinates.ItemChanged -= new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
+      Coordinates.Reset -= new EventHandler(Coordinates_Reset);
+    }
+    private void RegisterQualityEvents() {
+      Quality.ValueChanged += new EventHandler(Quality_ValueChanged);
+    }
+    private void DeregisterQualityEvents() {
+      Quality.ValueChanged -= new EventHandler(Quality_ValueChanged);
+    }
+
+    private void IntegerVector_ItemChanged(object sender, EventArgs<int> e) {
+      OnIntegerVectorChanged();
+    }
+    private void IntegerVector_Reset(object sender, EventArgs e) {
+      OnIntegerVectorChanged();
+    }
+    private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) {
+      OnCoordinatesChanged();
+    }
+    private void Coordinates_Reset(object sender, EventArgs e) {
+      OnCoordinatesChanged();
+    }
+    private void Quality_ValueChanged(object sender, EventArgs e) {
+      OnQualityChanged();
+    }
+    #endregion
+  }
+}
