Index: /branches/FitnessLandscapeAnalysis/HeuristicLab.Analysis.FitnessLandscape.sln
===================================================================
--- /branches/FitnessLandscapeAnalysis/HeuristicLab.Analysis.FitnessLandscape.sln	(revision 7230)
+++ /branches/FitnessLandscapeAnalysis/HeuristicLab.Analysis.FitnessLandscape.sln	(revision 7231)
@@ -11,4 +11,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Analysis.FitnessLandscape.VRP", "HeuristicLab.Analysis.FitnessLandscape.VRP\HeuristicLab.Analysis.FitnessLandscape.VRP.csproj", "{67CDB1E2-B0EE-4986-92AD-F320EBAF9088}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VRPProblemAnalyzer", "VRPProblemAnalyzer\VRPProblemAnalyzer.csproj", "{683C29F1-9A43-4998-B58A-C477B86B7A64}"
 EndProject
 Global
@@ -82,4 +84,12 @@
 		{67CDB1E2-B0EE-4986-92AD-F320EBAF9088}.Release|x86.ActiveCfg = Release|x86
 		{67CDB1E2-B0EE-4986-92AD-F320EBAF9088}.Release|x86.Build.0 = Release|x86
+		{683C29F1-9A43-4998-B58A-C477B86B7A64}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{683C29F1-9A43-4998-B58A-C477B86B7A64}.Debug|x64.ActiveCfg = Debug|x86
+		{683C29F1-9A43-4998-B58A-C477B86B7A64}.Debug|x86.ActiveCfg = Debug|x86
+		{683C29F1-9A43-4998-B58A-C477B86B7A64}.Debug|x86.Build.0 = Debug|x86
+		{683C29F1-9A43-4998-B58A-C477B86B7A64}.Release|Any CPU.ActiveCfg = Release|x86
+		{683C29F1-9A43-4998-B58A-C477B86B7A64}.Release|x64.ActiveCfg = Release|x86
+		{683C29F1-9A43-4998-B58A-C477B86B7A64}.Release|x86.ActiveCfg = Release|x86
+		{683C29F1-9A43-4998-B58A-C477B86B7A64}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/KMeansClustering.cs
===================================================================
--- /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/KMeansClustering.cs	(revision 7231)
+++ /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/KMeansClustering.cs	(revision 7231)
@@ -0,0 +1,71 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Diagnostics;
+
+namespace VRPProblemAnalyzer {
+  class Cluster {
+    public List<double[]> Items { get; set; }
+    public double[] Center { get; set; }    
+
+    public Cluster() {
+      Items = new List<double[]>();
+      Center = new double[2];
+    }
+  }
+
+  class KMeansClustering {
+    public static List<Cluster> Cluster(double[,] vertices, int k, int restarts) {
+      while (true) {
+        int info = 0;
+        double[,] centers = null;
+        int[] xyc = null;
+        bool aborted = false;
+
+
+        Thread t = new Thread(delegate() {
+          alglib.kmeansgenerate(vertices, vertices.Length / 2, 2, k, restarts + 1, out info, out centers, out xyc);
+        });
+
+        t.Start();
+        Stopwatch sw = new Stopwatch();
+        sw.Start();
+        while (t.ThreadState == System.Threading.ThreadState.Running && sw.ElapsedMilliseconds < 1000) {
+          Thread.Sleep(10);
+        }
+        sw.Stop();
+
+        if (t.ThreadState == System.Threading.ThreadState.Running) {
+          aborted = true;
+          t.Abort();
+        } 
+
+        if (info == -3)
+          return new List<Cluster>();
+        else if (info == 1 && !aborted) {
+          List<Cluster> result = new List<Cluster>();
+          int count = centers.Length / 2;
+          for (int i = 0; i < count; i++) {
+            result.Add(new Cluster());
+            result[i].Center[0] = centers[0, i];
+            result[i].Center[1] = centers[1, i];
+          }
+
+          for (int i = 0; i < xyc.Length; i++) {
+            double[] coords = new double[2];
+            coords[0] = vertices[i, 0];
+            coords[1] = vertices[i, 1];
+
+            result[xyc[i]].Items.Add(coords);
+          }
+
+          result.RemoveAll(c => c.Items.Count == 0);
+
+          return result;
+        }
+      } 
+    }
+  }
+}
Index: /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/Program.cs
===================================================================
--- /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/Program.cs	(revision 7231)
+++ /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/Program.cs	(revision 7231)
@@ -0,0 +1,256 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+
+namespace VRPProblemAnalyzer {
+  public static class Maths {
+    public static double StandardDeviation(this IEnumerable<double> data) {
+      double average = data.Average();
+      var individualDeviations = data.Select(num => Math.Pow(num - average, 2.0));
+      return Math.Sqrt(individualDeviations.Average());
+    }
+  }
+  
+  class Program {
+    private static string InstancePath = @"C:\Users\svonolfen\Desktop\Instances\Augerat";
+
+    private static double GetDistance(double[,] vertices, int source, int target) {
+      return Math.Sqrt(
+        Math.Pow((vertices[source, 0] - vertices[target, 0]), 2) + 
+        Math.Pow((vertices[source, 1] - vertices[target, 1]), 2));
+    }
+
+    private static double[] GetDistances(double[,] vertices) {
+      List<double> result = new List<double>();
+
+      int cities = vertices.Length / 2;
+      for (int i = 0; i < cities; i++) {
+        for (int j = 0; j < cities; j++) {
+          if (i != j) {
+            result.Add(GetDistance(vertices, i, j));
+          }
+        }
+      }
+
+      return result.ToArray();
+    }
+
+    private static double[] GetAverageDistances(double[,] vertices) {
+      int cities = vertices.Length / 2;
+      double[] result = new double[cities];
+      
+      for (int i = 0; i < cities; i++) {
+        double distance = 0;
+        for (int j = 0; j < cities; j++) {
+          if (i != j) {
+            distance += GetDistance(vertices, i, j);
+          }
+        }
+        result[i] = distance / (cities - 1);
+      }
+
+      return result;
+    }
+
+    private static double GetAverageDistance(TSPLIBParser instance) {
+      double result = 0;
+
+      double[] distances = GetDistances(instance.Vertices);
+      result = distances.Average();
+
+      return result;
+    }
+
+    private static double GetDistanceHeterogenity(TSPLIBParser instance) {
+      double result = 0;
+
+      result = GetAverageDistances(instance.Vertices).StandardDeviation();
+
+      return result;
+    }
+
+    private static double GetDistance(double[] cust1, double[] cust2) {
+      return Math.Sqrt(
+                 Math.Pow((cust1[0] - cust2[0]), 2) +
+                 Math.Pow((cust1[1] - cust2[1]), 2));
+    }
+
+    private static double GetDistance(Cluster cluster1, Cluster cluster2) {
+      List<double> distances = new List<double>();
+      foreach (double[] cust1 in cluster1.Items) {
+        foreach (double[] cust2 in cluster2.Items) {
+          distances.Add(GetDistance(cust1, cust2));
+        }
+      }
+
+      return distances.Min();
+
+      //return GetDistance(cluster1.Center, cluster2.Center);
+    }
+
+    private static double GetDistance(List<Cluster> clusters, Cluster cluster) {
+      List<double> distances = new List<double>();
+      foreach (Cluster other in clusters) {
+        if (other != cluster) {
+          distances.Add(GetDistance(cluster, other));
+        }
+      }
+
+      if (distances.Count > 0)
+        return distances.Min();
+      else
+        return 0;
+    }
+
+    private static double GetCohesion(Cluster cluster) {
+      double cohesion = 0;
+
+      List<double> distances = new List<double>();
+      foreach (double[] cust1 in cluster.Items) {
+        //option 1
+        foreach (double[] cust2 in cluster.Items) {
+          if (cust1 != cust2) {
+            distances.Add(GetDistance(cust1, cust2));            
+          }
+        }
+
+        //option2
+        //distances.Add(GetDistance(cluster.Center, cust1));
+      }
+
+      if (distances.Count > 0)
+        cohesion = distances.Average();
+
+      return cohesion;
+    }
+
+    private static double GetClustering(TSPLIBParser instance) {
+      double result = 0;
+
+      int cities = instance.Vertices.Length / 2 - 1;
+      double[,] coordinates = new double[cities, 2];
+      for (int i = 1; i <= cities; i++) {
+        coordinates[i - 1, 0] = instance.Vertices[i, 0];
+        coordinates[i - 1, 1] = instance.Vertices[i, 1];
+      }
+
+      double clusterFactor = 0;
+      double couplingFactor = 1;
+      double cohesionFactor = 1;
+
+      double maxQuality = double.MinValue;
+
+      int clusters = -1;
+      for (int i = 1; i <= cities; i++) {
+        List<Cluster> collection = KMeansClustering.Cluster(coordinates, i, 9);
+
+        if (collection.Count > 0) {
+          List<double> distances = new List<double>();
+          List<double> cohesions = new List<double>();
+          foreach (Cluster cluster in collection) {
+            distances.Add(GetDistance(collection, cluster));
+            cohesions.Add(GetCohesion(cluster));
+          }
+
+          double distance = distances.Average();
+          double cohesion = cohesions.Average();
+
+          double quality = clusterFactor * (distances.Count / (double)cities) + couplingFactor * distance - cohesionFactor * cohesion;
+          if (quality > maxQuality) {
+            maxQuality = quality;
+            clusters = distances.Count;
+          }
+        }
+      }
+
+      if (clusters != 0)
+        result = (cities / (double)clusters) / cities;
+
+      return result;
+    }
+
+    private static double GetDemandSize(TSPLIBParser instance) {
+      double result = 0;
+
+      result = instance.Demands.Average();
+
+      return result;
+    }
+
+    private static double GetDemandHeterogenity(TSPLIBParser instance) {
+      double result = 0;
+
+      result = instance.Demands.StandardDeviation();
+
+      return result;
+    }
+
+    private static void Normalize(TSPLIBParser instance) {
+      //normalize demands
+      for (int i = 0; i < instance.Demands.Length; i++) {
+          instance.Demands[i] = instance.Demands[i] / instance.Capacity;
+      }
+
+      //normalize coordinates
+      //-find bounds
+      double maxX = double.MinValue;
+      double maxY = double.MinValue;
+
+      int cities = instance.Vertices.Length / 2;
+      for (int i = 0; i < cities; i++) {
+        if (instance.Vertices[i, 0] > maxX)
+          maxX = instance.Vertices[i, 0];
+
+        if (instance.Vertices[i, 1] > maxY)
+          maxY = instance.Vertices[i, 1];
+      }
+
+      //-normalize
+      double factorX = 1;
+      double factorY = 1;
+      if (maxX > maxY) {
+        factorX = 1 / maxX;
+        factorY = (maxY / maxX) / maxY;
+      } else {
+        factorX = (maxX / maxY) / maxX;
+        factorY = 1 / maxY;
+      }
+
+      for (int i = 0; i < cities; i++) {
+        instance.Vertices[i, 0] *= factorX;
+        instance.Vertices[i, 1] *= factorY;
+      }
+    }
+
+    static void Main(string[] args) {
+      using (StreamWriter sw = new StreamWriter(InstancePath + Path.DirectorySeparatorChar + "analysis.csv")) {
+        sw.WriteLine("Instance;Customers;Clustering;DistanceAvg;DistanceStdev;DemandAvg;DemandStdev");
+        
+        string[] instances = Directory.GetFiles(InstancePath, "*.vrp", SearchOption.AllDirectories);
+        foreach (string instance in instances) {
+          TSPLIBParser parser = new TSPLIBParser(instance);
+          parser.Parse();
+          Normalize(parser);
+
+          sw.Write(Path.GetFileNameWithoutExtension(instance));
+          sw.Write(';');
+          sw.Write(parser.Vertices.Length / 2 - 1);
+          sw.Write(';');
+          sw.Write(GetClustering(parser));
+          sw.Write(';');
+          sw.Write(GetAverageDistance(parser));
+          sw.Write(';');
+          sw.Write(GetDistanceHeterogenity(parser));
+          sw.Write(';');
+          sw.Write(GetDemandSize(parser));
+          sw.Write(';');
+          sw.Write(GetDemandHeterogenity(parser));
+          sw.Write(';');
+          sw.WriteLine();
+        }
+      }
+    }
+  }
+}
Index: /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/Properties/AssemblyInfo.cs
===================================================================
--- /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/Properties/AssemblyInfo.cs	(revision 7231)
+++ /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/Properties/AssemblyInfo.cs	(revision 7231)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("VRPProblemAnalyzer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("VRPProblemAnalyzer")]
+[assembly: AssemblyCopyright("Copyright ©  2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("faa91e21-554d-437a-8d46-45837d27d884")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/TSPLIBParser.cs
===================================================================
--- /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/TSPLIBParser.cs	(revision 7231)
+++ /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/TSPLIBParser.cs	(revision 7231)
@@ -0,0 +1,402 @@
+#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 System.Globalization;
+using System.IO;
+
+namespace VRPProblemAnalyzer {
+  /// <summary>
+  /// Parses a *.vrp file in TSPLIB format and extracts its information about a VRP.
+  /// </summary>
+  public class TSPLIBParser {
+    #region Inner Enum TSPLIBEdgeWeightType
+    public enum TSPLIBEdgeWeightType {
+      UNDEFINED,
+      EUC_2D,
+      GEO
+    }
+    #endregion
+
+    private const int EOF = 0;
+    private const int NAME = 1;
+    private const int TYPE = 2;
+    private const int COMMENT = 3;
+    private const int DIM = 4;
+    private const int WEIGHTTYPE = 5;
+    private const int WEIGHTFORMAT = 11;
+    private const int NODETYPE = 6;
+    private const int NODESECTION = 7;
+    private const int CAPACITY = 8;
+    private const int DISTANCE = 12;
+    private const int VEHICLES = 13;
+    private const int DEPOTSECTION = 9;
+    private const int DEMANDSECTION = 10;
+
+    private StreamReader source;
+    private bool alternateFormat;
+    CultureInfo culture = new CultureInfo("en-US");
+
+    private string name;
+    /// <summary>
+    /// Gets the name of the parsed VRP.
+    /// </summary>
+    public string Name {
+      get { return name; }
+    }
+    private string comment;
+    /// <summary>
+    /// Gets the comment of the parsed VRP.
+    /// </summary>
+    public string Comment {
+      get { return comment; }
+    }
+    private double[,] vertices;
+    /// <summary>
+    /// Gets the vertices of the parsed VRP.
+    /// </summary>
+    public double[,] Vertices {
+      get { return vertices; }
+    }
+    private TSPLIBEdgeWeightType weightType;
+    /// <summary>
+    /// Gets the weight format of the parsed VRP.
+    /// </summary>
+    public TSPLIBEdgeWeightType WeightType {
+      get { return weightType; }
+    }
+
+    private double capacity;
+    public double Capacity {
+      get {
+        return capacity;
+      }
+    }
+
+    private double distance;
+    public double Distance {
+      get {
+        return distance;
+      }
+    }
+
+    private int vehicles;
+    public int Vehicles {
+      get {
+        return vehicles;
+      }
+    }
+
+    private int depot;
+    public int Depot {
+      get {
+        return depot;
+      }
+    }
+
+    private double[] demands;
+    public double[] Demands {
+      get {
+        return demands;
+      }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="TSPLIBParser"/> with the given <paramref name="path"/>.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown if the input file is not a TSPLIB TSP file (*.vrp)
+    /// </exception>
+    /// <param name="path">The path where the VRP is stored.</param>
+    public TSPLIBParser(String path) {
+      if (!path.EndsWith(".vrp"))
+        throw new ArgumentException("Input file has to be a TSPLIB CVRP file (*.vrp, *.txt).");
+
+      source = null;
+      name = path;
+      comment = string.Empty;
+      vertices = null;
+      weightType = TSPLIBEdgeWeightType.UNDEFINED;
+      capacity = -1;
+      distance = -1;
+      vehicles = -1;
+      depot = -1;
+      demands = null;
+      alternateFormat = false;
+    }
+
+    /// <summary>
+    /// Reads the TSPLIB VRP file and parses the elements.
+    /// </summary>
+    /// <exception cref="InvalidDataException">Thrown if the file has an invalid format or contains invalid data.</exception>
+    public void Parse() {
+      using (source = new StreamReader(name)) {
+        int section = -1;
+        string str = null;
+        bool typeIsChecked = false;
+        bool weightTypeIsChecked = false;
+        bool weightFormatIsChecked = false;
+
+        do {
+          str = source.ReadLine();
+          section = GetSection(str);
+
+          if (section != -1) {
+            switch (section) {
+              case NAME:
+                ReadName(str);
+                break;
+              case TYPE:
+                CheckType(str);
+                typeIsChecked = true;
+                break;
+              case COMMENT:
+                ReadComment(str);
+                break;
+              case DIM:
+                InitArrays(str);
+                break;
+              case WEIGHTTYPE:
+                ReadWeightType(str);
+                weightTypeIsChecked = true;
+                break;
+              case WEIGHTFORMAT:
+                ReadWeightFormat(str);
+                weightFormatIsChecked = true;
+                break;
+              case NODETYPE:
+                CheckNodeType(str);
+                break;
+              case NODESECTION:
+                ReadVertices();
+                break;
+              case CAPACITY:
+                ReadCapacity(str);
+                break;
+              case DISTANCE:
+                ReadDistance(str);
+                break;
+              case VEHICLES:
+                ReadVehicles(str);
+                break;
+              case DEPOTSECTION:
+                ReadDepot();
+                break;
+              case DEMANDSECTION:
+                ReadDemands();
+                break;
+            }
+          }
+        } while (!((section == EOF) || (str == null)));
+
+        if (!typeIsChecked || !weightTypeIsChecked || 
+          (alternateFormat && !weightFormatIsChecked) || 
+          weightType == TSPLIBEdgeWeightType.UNDEFINED)
+          throw new InvalidDataException("Input file does not contain format or edge weight format information.");
+      }
+      source = null;
+    }
+
+    private int GetSection(string str) {
+      if (str == null)
+        return EOF;
+
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      if (tokens.Length == 0)
+        return -1;
+
+      string token = tokens[0].Trim();
+      if (token.Equals("eof", StringComparison.OrdinalIgnoreCase))
+        return EOF;
+      if (token.Equals("name", StringComparison.OrdinalIgnoreCase))
+        return NAME;
+      if (token.Equals("type", StringComparison.OrdinalIgnoreCase))
+        return TYPE;
+      if (token.Equals("comment", StringComparison.OrdinalIgnoreCase))
+        return COMMENT;
+      if (token.Equals("dimension", StringComparison.OrdinalIgnoreCase))
+        return DIM;
+      if (token.Equals("edge_weight_type", StringComparison.OrdinalIgnoreCase))
+        return WEIGHTTYPE;
+      if (token.Equals("edge_weight_format", StringComparison.OrdinalIgnoreCase))
+        return WEIGHTFORMAT;
+      if (token.Equals("node_coord_type", StringComparison.OrdinalIgnoreCase))
+        return NODETYPE;
+      if (token.Equals("node_coord_section", StringComparison.OrdinalIgnoreCase))
+        return NODESECTION;
+      if (token.Equals("capacity", StringComparison.OrdinalIgnoreCase))
+        return CAPACITY;
+      if (token.Equals("distance", StringComparison.OrdinalIgnoreCase))
+        return DISTANCE;
+      if (token.Equals("vehicles", StringComparison.OrdinalIgnoreCase))
+        return VEHICLES;
+      if (token.Equals("depot_section", StringComparison.OrdinalIgnoreCase))
+        return DEPOTSECTION;
+      if (token.Equals("demand_section", StringComparison.OrdinalIgnoreCase))
+        return DEMANDSECTION;
+
+      return -1;
+    }
+
+    private void ReadName(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      name = tokens[tokens.Length - 1].Trim();
+    }
+
+    private void CheckType(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+
+      string type = tokens[tokens.Length - 1].Trim();
+      if (!type.Equals("cvrp", StringComparison.OrdinalIgnoreCase))
+        throw new InvalidDataException("Input file format is not \"CVRP\"");
+    }
+
+    private void ReadComment(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      comment = tokens[tokens.Length - 1].Trim();
+    }
+
+    private void InitArrays(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      string dimension = tokens[tokens.Length - 1].Trim();
+
+      int dim = Int32.Parse(dimension);
+      vertices = new double[dim, 2];
+      demands = new double[dim];
+    }
+
+    private void ReadWeightType(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      string type = tokens[tokens.Length - 1].Trim();
+
+      if (type.Equals("euc_2d", StringComparison.OrdinalIgnoreCase))
+        weightType = TSPLIBEdgeWeightType.EUC_2D;
+      else if (type.Equals("geo", StringComparison.OrdinalIgnoreCase))
+        weightType = TSPLIBEdgeWeightType.GEO;
+      else if (type.Equals("function", StringComparison.OrdinalIgnoreCase)) {
+        weightType = TSPLIBEdgeWeightType.UNDEFINED;
+        alternateFormat = true;
+      } else
+        throw new InvalidDataException("Input file contains an unsupported edge weight format (only \"EUC_2D\" and \"GEO\" are supported).");
+    }
+
+    private void ReadWeightFormat(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      string format = tokens[tokens.Length - 1].Trim();
+
+      if (alternateFormat && format.Equals("euc_2d", StringComparison.OrdinalIgnoreCase))
+        weightType = TSPLIBEdgeWeightType.EUC_2D;
+      else if (format.Equals("geo", StringComparison.OrdinalIgnoreCase))
+        weightType = TSPLIBEdgeWeightType.GEO;
+      else
+        throw new InvalidDataException("Input file contains an unsupported edge weight format.");
+    }
+
+    private void CheckNodeType(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      string type = tokens[tokens.Length - 1].Trim();
+
+      if (!type.Equals("twod_coords", StringComparison.OrdinalIgnoreCase))
+        throw new InvalidDataException("Input file contains an unsupported node coordinates format (only \"TWOD_COORDS\" is supported).");
+    }
+
+    private void ReadVertices() {
+      if (vertices == null)
+        throw new InvalidDataException("Input file does not contain dimension information.");
+
+      for (int i = 0; i < (vertices.Length / 2); i++) {
+        if (!(alternateFormat && i == 0)) {
+          string str = source.ReadLine();
+          string[] tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
+
+          if (tokens.Length != 3)
+            throw new InvalidDataException("Input file contains invalid node coordinates.");
+
+          vertices[i, 0] = double.Parse(tokens[1], culture.NumberFormat);
+          vertices[i, 1] = double.Parse(tokens[2], culture.NumberFormat);
+        }
+      }
+    }
+
+    private void ReadCapacity(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      capacity = double.Parse(tokens[tokens.Length - 1].Trim(), culture.NumberFormat);
+    }
+
+    private void ReadDistance(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      distance = double.Parse(tokens[tokens.Length - 1].Trim(), culture.NumberFormat);
+    }
+
+    private void ReadVehicles(string str) {
+      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
+      vehicles = int.Parse(tokens[tokens.Length - 1].Trim());
+    }
+
+    private void ReadDepot() {
+      if (alternateFormat) {
+        string[] tokens;
+        do { 
+          string str = source.ReadLine();
+          tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
+
+          if (tokens.Length == 2) {
+            vertices[0, 0] = double.Parse(tokens[0], culture.NumberFormat);
+            vertices[0, 1] = double.Parse(tokens[1], culture.NumberFormat);
+            depot = 1;
+          }
+        } while(tokens.Length == 2);
+      } else {
+        int read;
+        do {
+          string str = source.ReadLine();
+          read = int.Parse(str);
+          if (read != -1)
+            depot = read;
+        } while (read != -1);
+      }
+    }
+
+    private void ReadDemands() {
+      if (demands == null)
+        throw new InvalidDataException("Input file does not contain dimension information.");
+
+      for (int i = 0; i < demands.Length; i++) {
+        if (!(alternateFormat && i == 0)) {
+          string str = source.ReadLine();
+          string[] tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
+
+          if (tokens.Length != 2)
+            throw new InvalidDataException("Input file contains invalid demands.");
+
+          int index = int.Parse(tokens[0]);
+          double value = double.Parse(tokens[1]);
+
+          if (alternateFormat)
+            demands[index] = value;
+          else
+            demands[index - 1] = value;
+        } else {
+          demands[0] = 0;
+        }
+      }
+    }
+  }
+}
Index: /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/VRPProblemAnalyzer.csproj
===================================================================
--- /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/VRPProblemAnalyzer.csproj	(revision 7231)
+++ /branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/VRPProblemAnalyzer.csproj	(revision 7231)
@@ -0,0 +1,62 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{683C29F1-9A43-4998-B58A-C477B86B7A64}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>VRPProblemAnalyzer</RootNamespace>
+    <AssemblyName>VRPProblemAnalyzer</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.1.0">
+      <HintPath>..\..\..\trunk\sources\bin\ALGLIB-3.1.0.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="KMeansClustering.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TSPLIBParser.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
