核心思路是按题面把 Bi-K-means 原样模拟出来,而不是求某种最优划分。外层从单个簇 C0 出发,每次在当前簇集合里选一个簇做 K=2 的 K-means,直到簇数达到 N。被选中的簇用「x 最小点 / x 最大点」当初始质心,禁止随机初始化。选簇的关键字是:SSE_Grad 最大,其次设备数最多,再次生成时间最早。SSE_Grad 定义为父簇 SSE 减去两个子簇 SSE 之和,SSE 是簇内各点到质心的欧氏距离平方和。
实现方法:用数组保存每个簇的点集和出生序号。每一轮对每个仍可分裂(至少两点)的簇试跑一遍 2-means,记下子簇划分和下降量,再按上述三关键字选出要真分裂的那个。2-means 迭代里,点到两质心距离相等时归入 x 较小的初始质心一侧;用欧氏距离衡量质心偏移,偏移小于 1e−6 或全体归属不再变化时停止。每次分裂后把原子簇换成两个子簇(先左后右),并按簇规模降序输出一行。第 0 行是尚未分裂时的 L。
设路由器数为 L,目标簇数为 N。每一轮要对当前所有簇试分裂,单次 2-means 最多扫描 O(L) 个点并迭代常数到较少次数,外层最多 N−1 次分裂,因此时间复杂度为 O(NL⋅I),其中 I 为 2-means 迭代次数(本题 L≤100,N≤20,远小于时限)。空间复杂度 O(L)。
某省骨干网中部署了多台核心路由器。为提升运维效率,要把这些地理位置分散的设备在逻辑上划成 N 个管理域,并尽量让同一域内的设备彼此靠近,便于统一调度。
划分采用 Bi-K-means(二分 K-means):一开始把全部设备看成一个簇 C0,之后反复分裂当前最适合的簇,直到簇的个数等于 N。
SSE(误差平方和)定义为
SSE(C)=p∈C∑∥p−μ∥2,其中 μ 是簇 C 的质心(各点坐标的算术平均)。将一个父簇裂成两个子簇时,SSE 下降量为
SSE_Grad=SSE(Cparent)−(SSE(Cchild1)+SSE(Cchild2)).每一次从当前簇集合里选出一个簇,对其做 K=2 的 K-means 分裂,规则如下:
第一行一个整数 N,表示期望得到的管理域(簇)个数,满足 1≤N≤20。
第二行一个整数 L,表示核心路由器台数,满足 1≤L≤100。
随后 L 行,每行两个整数 x y,表示一台路由器的二维坐标(经度、纬度)。坐标均为整数,满足 0≤x,y≤1000,且不同路由器的 x 坐标互不相同。
输出 Bi-K-means 每一轮分裂后,当前各簇设备数的降序序列。初始簇 C0 的设备数作为第 0 次的结果。共输出 N 行,第 i 行对应已经得到 i+1 个簇时的规模列表(同一行内以空格分隔)。
输入
3
4
0 0
1 0
8 0
9 1
输出
4
2 2
2 1 1
说明
4 个点要划成 3 个管理域。
第 0 次:尚未分裂,只有 C0,设备数为 4。
第 1 次:对 C0 做 2-means,初始质心取 x 最小的 (0,0) 与 x 最大的 (9,1)。归属稳定后得到两个规模为 2 的簇:{(0,0),(1,0)} 与 {(8,0),(9,1)},降序为 2 2。
第 2 次:左簇质心为 (0.5,0),SSE=0.5,裂成两个单点后 SSE_Grad=0.5;右簇质心为 (8.5,0.5),SSE=1,裂成两个单点后 SSE_Grad=1。应分裂右簇,规模变为 2,1,1,降序为 2 1 1。
输入
1
3
4 2
7 9
11 3
输出
3
说明
N=1,不需要分裂,直接输出初始簇的设备数 3。
Scan the QR code below with WeChat to sign in
First-time scan will create your account automatically
请使用微信扫描下方二维码完成注册