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;
        }
示例#2
0
 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));
        }