容量k-means聚类?

时间:2013-08-01 10:59:01

标签: python algorithm optimization cluster-analysis k-means

我是算法和优化的新手 我正在尝试实施获得能力的k-means ,但到目前为止尚未解决且结果不佳。
这用作CVRP模拟(容量车辆路径问题)的一部分 我很好奇,如果我解释引用的算法错误。

参考:"Improved K-Means Algorithm for Capacitated Clustering Problem" (Geetha, Poonthalir, Vanathi)

模拟CVRP有15个客户,1个仓库 每个客户都有欧几里德坐标(x,y)和需求 有3辆车,每辆车的容量为90.

因此,有能力的k-means正在尝试将15个客户集中到3个车辆中,每个集群的总需求量不得超过车辆容量。

更新

在引用的算法中,我无法捕获有关代码在“下一个最接近的质心”用完时必须执行的操作的任何信息。
也就是说,当检查了所有“最近的质心”时,在下面的步骤14.b 中,customers[1]仍然未分配。

这导致索引为1的客户未分配 注意:customer[1]是需求最大的客户(30) 问:满足此条件时,代码应该执行什么操作?

<小时/> 以下是我对引用算法的解释,请更正我的代码,谢谢。

  1. 给定n个请求者(客户),n = customerCount和一个软件仓库
  2. n要求,
  3. n坐标(x,y)

  4. 计算群集数量,k =(所有需求总和)/ vehicleCapacity

  5. 选择初始质心,
    5.A.根据{{​​1}}按降序排序客户= demand
    5.b中从d_customers选择k第一批​​客户作为初始质心= d_customers

  6. 创建二进制矩阵centroids[0 .. k-1],维度= bin_matrix
    6.A中使用全零填充(customerCount) x (k)

  7. 启动WHILE循环,condition = WHILE bin_matrix
    7.A. not converged

  8. 启动FOR循环,条件= FOR converged = False
    8.A.客户指数= i

  9. 计算从each customers到所有customers[i] =&gt;的欧几里德距离centroids
    9.A.按升序排序edist
    9.B.选择最近距离= edist

  10. 的第一个centroid
  11. 启动WHILE循环,条件= closest_centroid未分配给任何群集。

  12. 将所有其他未分配的客户分组= while customers[i]
    11.A.将G视为closest_centroid的质心。

  13. G的每个Pi计算优先级customers
    12.a.优先级G
    12.b.选择优先级最高的客户Pi = (distance from customers[i] to closest_cent) / demand[i]
    12.c.优先级最高的客户的索引= Pi
    12.D。问:如果无法找到最优先的客户,我们该怎么办?

  14. 如果可能,
  15. hpc分配给customers[hpc]
    13.a.要求centroids[closest_centroid] = customers[hpc]
    13.b.质心成员的所有要求总和= d1
    13.c. dtot ..
    13.d.将IF (d1 + dtot) <= vehicleCapacity, THEN分配给customers[hpc]
    13.e.更新centroids[closest_centroid],行索引= bin_matrix,列索引= hpc,设置为closest_centroid

  16. 如果1(仍然)customers[i]到任何群集,那么..
    14.A.选择not assigned,距离next nearest centroid的距离最近。
    14.b。问:如果没有下一个最接近的质心,那我们该怎么做?

  17. 通过比较先前的矩阵和更新的矩阵bin_matrix来计算收敛。
    15.a.如果edist没有变化,则设置bin_matrix

  18. 否则,从更新的群集中计算converged = True
    16.A.根据每个群集的成员计算新的new centroids
    16.b. centroids' coordinates =群集sum_x的所有x-coordinate的总和,
    16.c. members =群集中所有num_c的编号,
    16.d.群集的新质心customers (members) = x-coordinate
    16.e.使用相同的公式,计算群集的新质心sum_x / num_c = y-coordinate

  19. 迭代主WHILE循环。

  20. 我的代码始终以步骤14.b 中的未分配客户结束。
    也就是说,当sum_y / num_c仍未分配给任何质心时,它已经用完了“下一个最接近的质心”。

    结果集群很差。输出图:

    Image

    - 图中,星是质心,方是仓库。
    在pic中,标记为“1”的客户,需求= 30始终以没有分配的集群结束。

    计划的输出,

    customers[i]

    第一和第三个集群的计算效果不佳。
    索引为“k_cluster 3 idx [ 1 -1 1 0 2 0 1 1 2 2 2 0 0 2 0] centroids [(22.6, 29.2), (34.25, 60.25), (39.4, 33.4)] members [[3, 14, 12, 5, 11], [0, 2, 6, 7], [9, 8, 4, 13, 10]] demands [86, 65, 77] ”的idx未分配(1

    问:我的解释和实施有什么问题?
    任何更正,建议,帮助,将非常感谢,谢谢你提前。

    这是我的完整代码:

    -1

3 个答案:

答案 0 :(得分:1)

当总需求接近总容量时,此问题开始涉及bin packing的各个方面。正如您所发现的,这种特殊算法的贪婪方法并不总是成功的。我不知道作者是否承认这一点,但如果不这样做,审稿人应该抓住它。

如果你想继续这样的算法,我会尝试使用integer programming将请求者分配给质心。

答案 1 :(得分:0)

没有详细介绍所有细节,你引用的论文

 if ri is not assigned then
     choose the next nearest centroid
 end if

在第5节末尾的算法中。

必须有一个下一个最接近的质心 - 如果两个是等距的,我认为你选择哪个并不重要。

答案 2 :(得分:0)

固定大小聚类的一个常见问题是您通常可以在输出中识别“交换”,其中在聚类之间交换 2 个点可以创建更好的解决方案。

我们可以改进参考论文中的约束 k-means 算法,方法是将“找到将点分配给的集群”作为一个分配问题,而不是贪婪地选择最近的一个未满。

解决这个问题的常用方法是使用最小成本流算法。这样做的结果保证没有任何“交换”可以改善结果。

幸运的是,有人已经实现了它并为其创建了一个包:https://github.com/joshlk/k-means-constrained

查看Bradley, P. S., Bennett, K. P., & Demiriz, A. (2000). Constrained k-means clustering.

一方面,需求量很大的客户可能仍然无法分配到单个仓库,因此可能需要增加 k 的值,直到有一个可行的解决方案,或者需要允许在多个仓库之间“拆分”客户的需求。