k-means 聚类 算法 Java实现

   给出8个坐标 点 题目选择A1,A4,A7为初始簇心  将这8个坐标点分为三组

 代码就是通过循环 算出每个点应该被分到的组类

package org.example;


public class T1 {
    public static void compute(double [][] n,double [][] target){
       // n:所有点的坐标     target: 簇心
        HashMap<Object, List<double[]>> res = new HashMap<>();
            while (true) {
            HashMap<Object, List<double[]>> map = new HashMap<>();
            //遍历所有坐标
                for (int i = 0; i < n.length; i++) {
                    double x = n[i][0];
                    double y = n[i][1];
                    double length = 100;
                    Map m1 = new HashMap<>();
                    //找出距离当前点最近的簇心
                    for (int j = 0; j < target.length; j++) {
                        double x1 = target[j][0];
                        double y1 = target[j][1];
                        double length1 = Math.pow(((x - x1) * (x - x1) + (y - y1) * (y - y1)), 0.5);
                        if (length1 < length) {
                            length = length1;
                            m1.put(i, j);
                        }
                    }
                    double[] r = new double[2];
                    r[0] = x;
                    r[1] = y;
                    if (map.get(m1.get(i)) == null) {
                        List<double[]> t = new ArrayList<>();
                        t.add(r);
                        map.put(m1.get(i), t);
                    } else {
                        List<double[]> t = map.get(m1.get(i));
                        t.add(r);
                        map.put(m1.get(i), t);
                    }
                }
                   boolean changed = false;
                //算出新的簇心坐标
                for (int i = 0; i < target.length; i++) {
                    List<double[]> doubles = map.get(i);
                    double newx = 0;
                    double newy = 0;

                    for (double[] aDouble : doubles) {
                        newx += aDouble[0];
                        newy += aDouble[1];
                    }
                    double newx1 = newx / doubles.size();
                    double newy1 = newy / doubles.size();
                    if (target[i][0] != newx1 || target[i][1] != newy1) {
                        target[i][0] = newx1;
                        target[i][1] = newy1;
                           changed = true;
                    }
                }
                //当簇心坐标不再变化 说明聚类已经收敛 退出循环打印结果
                     if (!changed) {
                         res=map; break;}


            }

            for (Map.Entry<Object, List<double[]>> objectListEntry : res.entrySet()) {
                Integer key = (int)objectListEntry.getKey();
                List<double[]> value = objectListEntry.getValue();
                for (double[] doubles : value) {
                    int group=key+1;
                    System.out.println("第" +group+"组" + ":" + " x :" + doubles[0] + " ,y:" + doubles[1]);
                }
            }



    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("请输入坐标点数量");
        int groupcount = sc.nextInt();
        double [][] q=new double[groupcount][2];
        for (int i = 0; i < groupcount; i++) {
            q[i][0]=sc.nextInt();
            q[i][1]=sc.nextInt();
        }
        System.out.println("请输入 簇心");
         int cx=sc.nextInt();
        double [][] t=new double[cx][2];
        for (int i = 0; i < cx; i++) {
           t[i][0]=sc.nextInt();
            t[i][1]=sc.nextInt();
        }

     compute(q,t);







    }
}

每次循环一遍都重新计算一次簇心   如果簇心不再发生变化说明聚类已经收敛 打印结果即可

最终结果为:

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值