初始质心:直接取数据中的前 k 个样本。
距离:使用四维欧氏距离的平方(少一次开方,比较大小结果不变)。
更新:每轮按最近质心分配样本,再用簇内四维特征的平均值更新该簇质心。
收敛判定:若所有质心的新旧位置变化量(平方距离)最大值小于 1e-8,或已达到最多迭代次数 n,则停止。
空簇处理:若某簇本轮没有样本,保持该簇质心不变,避免除零错误。
第一行:k m n
接下来 m 行:每行 4 个浮点数,表示一个终端的四维特征
一行:k 个整数(各簇样本数),升序排列,用空格分隔
2 4 100 0.00 0.00 0.00 0.00 10.00 10.00 10.00 10.00 0.20 0.00 0.00 0.00 9.80 10.00 10.00 10.00
2 2
前两行即初始两个质心,后两点分别更接近对应质心;每簇各 2 个样本,升序输出为 2 2。
import sys import numpy as np ls = sys.stdin.readline().strip().split() k, m, n = list(map(int, ls)) eles = np.zeros((k, m, 4)) # k,m,n = 2,4,4 # eles = np.array([[ 10.,10.,10.,10.], # [9.8,10.,10.,10.], # [ 0. , 0., 0., 0. ], # [ 0.2 , 0., 0.,0. ]], dtype=np.float32) # eles = eles[None,:].repeat(2,0) for i, line in enumerate(sys.stdin): ls = sys.stdin.readline().strip().split() fls = list(map(float, ls)) try: eles[:, i] = fls except Exception: break centers = eles[None, 0, :k].transpose((1, 0, 2)).repeat(m, 1) new_centers = centers.copy() for i in range(n): dis = np.sum((eles - centers)**2, axis=-1) groups = np.argmin(dis, 0) for i in range(k): mean = eles[0, groups == i].mean(axis=0) new_centers[i, :] = mean[None, :] if np.allclose(new_centers, centers, atol=1e-8): break centers = new_centers.copy() print(centers[:, 0]) for i in range(k): print(sum(groups == i), end=' ')