C# K-Means

首先不知道怎么理解K-means的同学先看一下这篇文章

接下来直接上代码:

    public class Model
    {
        public List<Point> CenterPoints { get; set; }
        public Dictionary<int, List<Point>> Result { get; set; }
    }
    public class Program
    {
        static void Main(string[] args)
        {
            var pList = new List<Point>();
            pList.Add(new Point() { X = 3, Y = 10 });
            pList.Add(new Point() { X = 2, Y = 2 });
            pList.Add(new Point() { X = 3, Y = 8 });
            pList.Add(new Point() { X = 7, Y = 9 });
            pList.Add(new Point() { X = 10, Y = 2 });
            pList.Add(new Point() { X = 7, Y = 3 });
            pList.Add(new Point() { X = 4, Y = 4 });
            pList.Add(new Point() { X = 1, Y = 10 });
            pList.Add(new Point() { X = 2, Y = 7 });
            pList.Add(new Point() { X = 5, Y = 5 });
            pList.Add(new Point() { X = 5, Y = 7 });
            pList.Add(new Point() { X = 9, Y = 3 });
            pList.Add(new Point() { X = 8, Y = 5 });

            var result = KMeans(pList, 4);

            for (int i = 0; i < result.CenterPoints.Count; i++)
            {
                Console.WriteLine($"中心点 ({result.CenterPoints[i].X},{result.CenterPoints[i].Y}) :");
                result.Result[i].ForEach(p => Console.Write($"{p.X},{p.Y}  "));
                Console.WriteLine();
            }

            Console.ReadLine();
        }

        static Model KMeans(List<Point> pList, int NumberOfCenter)
        {
            if (pList.Count <= NumberOfCenter) throw new Exception("点的超过数据量");

            var pCenters = pList.Take(NumberOfCenter).ToList(); // 随机选择K个数据点 作为中心点

            while (true)
            {
                var model = CalcAndGetNewCenters(pList, pCenters);

                if (ComparisonPoints(model.CenterPoints, pCenters)) return model;
                pCenters = model.CenterPoints;
            }

        }

        static bool ComparisonPoints(List<Point> p1, List<Point> p2)
        {
            var temp1 = p1.Select(x => $"{x.X},{x.Y}");
            var temp2 = p2.Select(x => $"{x.X},{x.Y}");
            return temp1.All(temp2.Contains) && temp1.Count() == temp2.Count();
        }

        static Model CalcAndGetNewCenters(List<Point> pList, List<Point> pCenters)
        {
            var NumberOfCenter = pCenters.Count;
            // 数据归类
            var result = new Dictionary<int, List<Point>>();
            for (int i = 0; i < pList.Count; i++)
            {
                var distences = new List<double>();
                // 计算数据点 到 每个中心点的距离
                for (int j = 0; j < NumberOfCenter; j++)
                {
                    distences.Add(CalcDistence(pCenters[j], pList[i]));
                }

                // 将数据点 归入 最近的中心点下
                var minIndex = distences.IndexOf(distences.Min());
                if (!result.ContainsKey(minIndex))
                    result[minIndex] = new List<Point>();
                result[minIndex].Add(pList[i]);
            }

            // 计算新的中心点
            var newPCenters = new List<Point>();
            foreach (var tempList in result)
            {
                if (tempList.Value == null || tempList.Value.Count <= 0) continue;

                newPCenters.Add(new Point(
                    tempList.Value.Sum(x => x.X) / tempList.Value.Count,
                    tempList.Value.Sum(x => x.Y) / tempList.Value.Count));
            }

            return new Model { CenterPoints = newPCenters, Result = result };
        }


        static double CalcDistence(Point p1, Point p2)
        {
            return Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y));
        }
    }

 

完美,收工

不懂的留言。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值