Free cookie consent management tool by TermsFeed Policy Generator

source: branches/FitnessLandscapeAnalysis/VRPProblemAnalyzer/Program.cs @ 7232

Last change on this file since 7232 was 7232, checked in by epitzer, 12 years ago

#1696: Updated build configuration and simplified thread handling and removed hard coded paths

File size: 7.7 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.IO;
6
7namespace VRPProblemAnalyzer {
8  public static class Maths {
9    public static double StandardDeviation(this IEnumerable<double> data) {
10      double average = data.Average();
11      var individualDeviations = data.Select(num => Math.Pow(num - average, 2.0));
12      return Math.Sqrt(individualDeviations.Average());
13    }
14  }
15 
16  class Program {
17
18    private static double GetDistance(double[,] vertices, int source, int target) {
19      return Math.Sqrt(
20        Math.Pow((vertices[source, 0] - vertices[target, 0]), 2) +
21        Math.Pow((vertices[source, 1] - vertices[target, 1]), 2));
22    }
23
24    private static double[] GetDistances(double[,] vertices) {
25      List<double> result = new List<double>();
26
27      int cities = vertices.Length / 2;
28      for (int i = 0; i < cities; i++) {
29        for (int j = 0; j < cities; j++) {
30          if (i != j) {
31            result.Add(GetDistance(vertices, i, j));
32          }
33        }
34      }
35
36      return result.ToArray();
37    }
38
39    private static double[] GetAverageDistances(double[,] vertices) {
40      int cities = vertices.Length / 2;
41      double[] result = new double[cities];
42     
43      for (int i = 0; i < cities; i++) {
44        double distance = 0;
45        for (int j = 0; j < cities; j++) {
46          if (i != j) {
47            distance += GetDistance(vertices, i, j);
48          }
49        }
50        result[i] = distance / (cities - 1);
51      }
52
53      return result;
54    }
55
56    private static double GetAverageDistance(TSPLIBParser instance) {
57      double result = 0;
58
59      double[] distances = GetDistances(instance.Vertices);
60      result = distances.Average();
61
62      return result;
63    }
64
65    private static double GetDistanceHeterogenity(TSPLIBParser instance) {
66      double result = 0;
67
68      result = GetAverageDistances(instance.Vertices).StandardDeviation();
69
70      return result;
71    }
72
73    private static double GetDistance(double[] cust1, double[] cust2) {
74      return Math.Sqrt(
75                 Math.Pow((cust1[0] - cust2[0]), 2) +
76                 Math.Pow((cust1[1] - cust2[1]), 2));
77    }
78
79    private static double GetDistance(Cluster cluster1, Cluster cluster2) {
80      List<double> distances = new List<double>();
81      foreach (double[] cust1 in cluster1.Items) {
82        foreach (double[] cust2 in cluster2.Items) {
83          distances.Add(GetDistance(cust1, cust2));
84        }
85      }
86
87      return distances.Min();
88
89      //return GetDistance(cluster1.Center, cluster2.Center);
90    }
91
92    private static double GetDistance(List<Cluster> clusters, Cluster cluster) {
93      List<double> distances = new List<double>();
94      foreach (Cluster other in clusters) {
95        if (other != cluster) {
96          distances.Add(GetDistance(cluster, other));
97        }
98      }
99
100      if (distances.Count > 0)
101        return distances.Min();
102      else
103        return 0;
104    }
105
106    private static double GetCohesion(Cluster cluster) {
107      double cohesion = 0;
108
109      List<double> distances = new List<double>();
110      foreach (double[] cust1 in cluster.Items) {
111        //option 1
112        foreach (double[] cust2 in cluster.Items) {
113          if (cust1 != cust2) {
114            distances.Add(GetDistance(cust1, cust2));           
115          }
116        }
117
118        //option2
119        //distances.Add(GetDistance(cluster.Center, cust1));
120      }
121
122      if (distances.Count > 0)
123        cohesion = distances.Average();
124
125      return cohesion;
126    }
127
128    private static double GetClustering(TSPLIBParser instance) {
129      double result = 0;
130
131      int cities = instance.Vertices.Length / 2 - 1;
132      double[,] coordinates = new double[cities, 2];
133      for (int i = 1; i <= cities; i++) {
134        coordinates[i - 1, 0] = instance.Vertices[i, 0];
135        coordinates[i - 1, 1] = instance.Vertices[i, 1];
136      }
137
138      double clusterFactor = 0;
139      double couplingFactor = 1;
140      double cohesionFactor = 1;
141
142      double maxQuality = double.MinValue;
143
144      int clusters = -1;
145      for (int i = 1; i <= cities; i++) {
146        List<Cluster> collection = KMeansClustering.Cluster(coordinates, i, 9);
147
148        if (collection.Count > 0) {
149          List<double> distances = new List<double>();
150          List<double> cohesions = new List<double>();
151          foreach (Cluster cluster in collection) {
152            distances.Add(GetDistance(collection, cluster));
153            cohesions.Add(GetCohesion(cluster));
154          }
155
156          double distance = distances.Average();
157          double cohesion = cohesions.Average();
158
159          double quality = clusterFactor * (distances.Count / (double)cities) + couplingFactor * distance - cohesionFactor * cohesion;
160          if (quality > maxQuality) {
161            maxQuality = quality;
162            clusters = distances.Count;
163          }
164        }
165      }
166
167      if (clusters != 0)
168        result = (cities / (double)clusters) / cities;
169
170      return result;
171    }
172
173    private static double GetDemandSize(TSPLIBParser instance) {
174      double result = 0;
175
176      result = instance.Demands.Average();
177
178      return result;
179    }
180
181    private static double GetDemandHeterogenity(TSPLIBParser instance) {
182      double result = 0;
183
184      result = instance.Demands.StandardDeviation();
185
186      return result;
187    }
188
189    private static void Normalize(TSPLIBParser instance) {
190      //normalize demands
191      for (int i = 0; i < instance.Demands.Length; i++) {
192          instance.Demands[i] = instance.Demands[i] / instance.Capacity;
193      }
194
195      //normalize coordinates
196      //-find bounds
197      double maxX = double.MinValue;
198      double maxY = double.MinValue;
199
200      int cities = instance.Vertices.Length / 2;
201      for (int i = 0; i < cities; i++) {
202        if (instance.Vertices[i, 0] > maxX)
203          maxX = instance.Vertices[i, 0];
204
205        if (instance.Vertices[i, 1] > maxY)
206          maxY = instance.Vertices[i, 1];
207      }
208
209      //-normalize
210      double factorX = 1;
211      double factorY = 1;
212      if (maxX > maxY) {
213        factorX = 1 / maxX;
214        factorY = (maxY / maxX) / maxY;
215      } else {
216        factorX = (maxX / maxY) / maxX;
217        factorY = 1 / maxY;
218      }
219
220      for (int i = 0; i < cities; i++) {
221        instance.Vertices[i, 0] *= factorX;
222        instance.Vertices[i, 1] *= factorY;
223      }
224    }
225
226    static void Main(string[] args) {
227      if (args.Length < 1) {
228        Console.Error.WriteLine("Not enough arguments, please specify directory with VRP instances.");
229        Environment.Exit(-1);
230      }
231      var path = args[0];
232      using (StreamWriter sw = new StreamWriter(Path.Combine(path, "analysis.csv"))) {
233        sw.WriteLine("Instance;Customers;Clustering;DistanceAvg;DistanceStdev;DemandAvg;DemandStdev");
234       
235        string[] instances = Directory.GetFiles(path, "*.vrp", SearchOption.AllDirectories);
236        foreach (string instance in instances) {
237          TSPLIBParser parser = new TSPLIBParser(instance);
238          parser.Parse();
239          Normalize(parser);
240
241          sw.Write(Path.GetFileNameWithoutExtension(instance));
242          sw.Write(';');
243          sw.Write(parser.Vertices.Length / 2 - 1);
244          sw.Write(';');
245          sw.Write(GetClustering(parser));
246          sw.Write(';');
247          sw.Write(GetAverageDistance(parser));
248          sw.Write(';');
249          sw.Write(GetDistanceHeterogenity(parser));
250          sw.Write(';');
251          sw.Write(GetDemandSize(parser));
252          sw.Write(';');
253          sw.Write(GetDemandHeterogenity(parser));
254          sw.Write(';');
255          sw.WriteLine();
256        }
257      }
258    }
259  }
260}
Note: See TracBrowser for help on using the repository browser.