给出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);
}
}
每次循环一遍都重新计算一次簇心 如果簇心不再发生变化说明聚类已经收敛 打印结果即可
最终结果为: