public ClustersModel GetKmeanClusters(VrpData data, int clustersCount) { var centers = new Point2DReal[clustersCount]; var perm = Permutations.GetRandomPermutation(data.N - 1); for (int i = 0; i < clustersCount; i++) { centers[i] = data.Customers[perm[i] + 1].Point; } var colors = new int[data.N]; var count = new int[clustersCount]; var changed = true; while (changed) { changed = false; count = new int[clustersCount]; for (int i = 1; i < data.N; i++) { var bestCenter = -1; var bestDist = 0D; for (int j = 0; j < clustersCount; j++) { if (bestCenter == -1 || centers[j].Dist(data.Customers[i].Point) < bestDist) { bestCenter = j; bestDist = centers[j].Dist(data.Customers[i].Point); } } if (colors[i] != bestCenter) { colors[i] = bestCenter; changed = true; } } for (int j = 0; j < clustersCount; j++) { var center = new Point2DReal(0, 0); for (int i = 1; i < data.N; i++) { if (colors[i] == j) { center = center + data.Customers[i].Point; count[j]++; } } centers[j] = center * (1D / count[j]); } } var result = new ClustersModel(); result.Color = colors; result.Count = count; result.Centers = centers; return result; }
private void DrawLine(Pen pen, Point2DReal a, Point2DReal b, Graphics g) { g.DrawLine(pen, (float) a.X, (float) a.Y, (float) b.X, (float) b.Y); }
public static void Main(string[] args) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; //var lines = args[0].Split('\n'); string text; using (var reader = File.OpenText(args[0])) { text = reader.ReadToEnd(); } var lines = text.Split('\n'); var n = int.Parse(lines[0]); var points = new Point2DReal[n]; for (int i = 0; i < n; i++) { var line = lines[i + 1].Split(); var x = double.Parse(line[0]); var y = double.Parse(line[1]); points[i] = new Point2DReal(x, y); } /*var matrix = new double[n,n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { matrix[i, j] = points[i].Dist(points[j]); } } double avgDist = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { avgDist += matrix[i, j]; } } avgDist /= (n * n); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { matrix[i, j] /= avgDist; } }*/ IMeasure measure; if (n <= 6000) { measure = new MatrixMeasureFactory().CreateMatrixMeasure(points); } else { measure = new PointsMeasure(points); } var path = new Opt3().GetPath(n, measure); var ans = points[path[0]].Dist(points[path[n - 1]]); for (int i = 0; i < n - 1; i++) { ans += points[path[i]].Dist(points[path[i + 1]]); } Console.WriteLine("{0} 0", ans); Console.WriteLine(string.Join(" ", path)); }