Paper Boy 的聚类算法

Posted

技术标签:

【中文标题】Paper Boy 的聚类算法【英文标题】:Clustering Algorithm for Paper Boys 【发布时间】:2010-10-08 10:53:38 【问题描述】:

我需要根据特定标准选择或创建聚类算法的帮助。

假设您正在管理送报员。

您有一组街道地址,每个地址都经过地理编码。 您希望对地址进行聚类,以便将每个聚类分配给一名送货员。 送货人员或集群的数量不固定。如果需要,我总是可以雇佣更多的送货员,或者解雇他们。 每个集群应该有大约相同数量的地址。但是,如果集群的地址更加分散,则集群的地址可能会更少。 (换一种说法:最小数量的簇,其中每个簇包含最大数量的地址,并且簇内的任何地址必须相隔最大距离。) 对于奖励积分,当数据集发生更改(添加或删除地址)并重新运行算法时,如果集群尽可能保持不变(即排除简单的 k-means聚类本质上是随机的)。否则快递员会发疯的。

所以...想法?

更新

Arachnid 的回答中描述的街道网络图不可用。

【问题讨论】:

那么,您是否真的试图使每个集群的交付时间(大概对应于旅行时间)均等化? 我一直在思考作业,直到“疯狂”行。这让它闻起来像“过度劳累的编码器”:) @alphadogg 哪个是疯狂的台词? @carrier:是的,最后一个。老师不会关心假设的送货人...... :) @Alphadog Dunno 关于你的老师,但我的会是(特别是作为额外的信用)......然后我的又是一个有点悲伤...... 【参考方案1】:

我用 Java 编写了一个低效但简单的算法,看看我可以多接近对一组点进行一些基本聚类,或多或少如问题中所述。

如果 (x,y) 坐标 ps 指定为 ints,则该算法适用于列表。它还需要三个其他参数:

    radius (r):给定一个点,扫描附近点的半径是多少 最大地址(maxA):每个集群的最大地址(点)数是多少? 最少地址 (minA):每个集群的最少地址

设置limitA=maxA主要迭代: 初始化空列表possibleSolutions外部迭代:对于ps 中的每个点p。 初始化空列表pclusters。 定义了点wps=copy(ps) 的工作列表。 工作点wp=p内部迭代:wps 不为空。 删除wps 中的点wp。确定wps 中与wp 距离r 的所有点wpsInRadius。根据与wp 的距离对wpsInRadius 进行升序排序。将第一个min(limitA, sizeOf(wpsInRadius)) 点保留在wpsInRadius 中。这些点形成一个新的集群(点列表)pcluster。将pcluster 添加到pclusters。从wps 中删除pcluster 中的点。如果wps 不为空,wp=wps[0] 并继续内部迭代。 结束内部迭代。 获得集群pclusters 的列表。将此添加到possibleSolutions结束外部迭代。

对于ps 中的每个p,我们都有一个pclusterspossibleSolutions 中的集群列表。然后对每个pclusters 进行加权。如果avgPCpossibleSolutions(全局)中每个簇的平均点数,avgCSize 是每个pclusters(全局)中的平均簇数,那么这个函数使用这两个变量来确定重量:

  private static WeightedPClusters weigh(List<Cluster> pclusters, double avgPC, double avgCSize)
  
    double weight = 0;
    for (Cluster cluster : pclusters)
    
      int ps = cluster.getPoints().size();
      double psAvgPC = ps - avgPC;
      weight += psAvgPC * psAvgPC / avgCSize;
      weight += cluster.getSurface() / ps;
    
    return new WeightedPClusters(pclusters, weight);
  

现在最好的解决方案是重量最轻的pclusters。只要我们能找到比limitA=max(minA,(int)avgPC) 之前最好的解决方案更好的解决方案(重量更轻),我们就会重复主迭代。 结束主要迭代。

请注意,对于相同的输入数据,此算法将始终产生相同的结果。列表用于保持顺序,并且不涉及随机

要查看此算法的行为方式,这是 32 点测试模式上的结果图像。如果maxA=minA=16,那么我们会找到 2 个 16 个地址的集群。

(来源:paperboyalgorithm at sites.google.com)

接下来,如果我们通过设置minA=12 来减少每个集群的最小地址数,我们会找到 12/12/8 个点的 3 个集群。

(来源:paperboyalgorithm at sites.google.com)

为了证明该算法远非完美,这里是maxA=7 的输出,但我们得到了 6 个集群,其中一些集群很小。所以在确定参数的时候还是要猜测太多。注意r这里只有5个。

(来源:paperboyalgorithm at sites.google.com)

出于好奇,我在一组更大的随机选择的点上尝试了该算法。我在下面添加了图片。

结论?这花了我半天的时间,效率低下,代码看起来很难看,而且速度比较慢。但这表明在短时间内产生一些的结果是可能的。当然,这只是为了好玩;把它变成真正有用的东西是困难的部分。

(来源:paperboyalgorithm at sites.google.com)

(来源:paperboyalgorithm at sites.google.com)

【讨论】:

我将提交一个元请求,让我投票两次,只是为了奖励您在这里的出色工作。【参考方案2】:

您所描述的是(多)车辆路由问题(VRP)。有很多关于这个问题的不同变体的学术文献,使用了各种各样的技术(启发式、现成的求解器等)。通常,作者试图为具体实例找到好的或最佳解决方案,这也意味着站点的聚类(一辆车路线上的所有站点)。

但是,集群可能会发生重大变化,实例略有不同,这是您要避免的。不过,VRP 论文中的某些内容可能会激发您的灵感……

如果您决定坚持使用显式聚类步骤,请不要忘记将您的分布包含在所有聚类中,因为它是每条路线的一部分。

使用街道网格的图形表示来评估集群可能会比连接白色地图上的点产生更真实的结果(尽管两者都是 TSP 变体)。如果图模型不可用,您可以使用出租车度量 (|x_1 - x_2| + |y_1 - y_2|) 作为距离的近似值。

【讨论】:

【参考方案3】:

我认为您需要 hierarchical agglomeration 技术而不是 k-means。如果您的算法正确,则可以在拥有正确数量的集群时停止它。正如其他人所提到的,您可以使用以前的解决方案为后续集群播种,这可能会给您带来显着的性能提升。

您可能需要仔细查看您使用的距离函数,尤其是当您的问题具有高维度时。欧几里得距离是最容易理解的,但可能不是最好的,请查看诸如 Mahalanobis 之类的替代方法。

我假设您的真正问题与送报纸无关...

【讨论】:

【参考方案4】:

您是否考虑过使用基于经济/市场的解决方案?将设置除以任意(但为常数以避免随机性影响)分成偶数子集(由送货人员的数量决定)。

为每个点分配一个成本函数,根据它在图中增加多少,并为每个额外的点赋予经济价值。

迭代允许每个人轮流拍卖他们最差的点,并给每个人一个最大预算。

这可能与人们在现实生活中的想法相当吻合,因为人们会发现交换,或者会说“如果我不做这一两个,我的生活会容易得多。它也很漂亮灵活(例如,允许在距离任何其他点数英里的地方相当容易地获得溢价)。

【讨论】:

【参考方案5】:

我会以不同的方式处理它:将街道网络视为一个图形,每条街道的每一侧都有一条边,找到将图形划分为 n 个段,每个段不超过给定长度,这样每个报童可以从路线的起点到终点骑一条连续的路径。这样,您就可以避免为人们提供需要他们重复骑行相同路段的路线(例如,当被要求覆盖街道两侧而不覆盖所有周围街道时)。

【讨论】:

这很好,但正如问题中所述,地址是地理编码的,这就是所有可用的信息。没有街道网络图。【参考方案6】:

这是发现“集群”所在位置的一种非常快速而肮脏的方法。这是受到游戏“扫雷”的启发。

将您的整个交付空间划分为正方形网格。注意 - 需要对网格大小进行一些调整才能正常工作。我的直觉告诉我,大致相当于一个物理邻域块大小的正方形将是一个很好的起点。

遍历每个方块并存储每个街区内的送货地点(房屋)的数量。使用第二个循环(或第一次传递的一些巧妙方法)来存储每个相邻块的交付点数。

现在您可以使用与照片处理软件类似的方式在此网格上进行操作。您可以通过查找某些相邻块中没有交付点的块来检测集群的边缘。

最后,您需要一个系统,该系统结合了交付的数量以及行驶的总距离来创建和分配路线。可能有一些孤立的集群,只需要少量交付,以及一两个超级集群,其中许多房屋彼此非常靠近,需要多个送货员在同一个集群中。必须访问每个家庭,这是您的第一个限制条件。

推导出任何一名送货员单次运行的最大允许距离。接下来对每人交付的数量执行相同的操作。

路由算法的第一次运行将分配一个送货员,将他们发送到任何未完成所有送货的随机集群,让他们送货直到他们达到送货限制或他们已经送货到集群中的所有家庭.如果他们已达到交货限制,请将他们送回基地以结束路线。如果他们可以安全地前往最近的集群,然后回家,而不会达到他们的最大旅行距离,请这样做并重复上述操作。

为当前送货员完成路线后,检查是否有房屋尚未送货。如果是,请指定另一个送货员,并重复上述算法。

这将生成初始路线。我会存储所有信息——每个广场的位置和尺寸、一个广场内的房屋数量及其所有直接邻居、每个广场所属的集群、送货人及其路线——我会存储所有这些在数据库中。

我将把重新计算过程留给您 - 但是将所有当前路线、集群等保存在数据库中将使您能够保留所有历史路线,并尝试各种方案以了解如何最好地适应变化对现有路线进行尽可能少的更改。

【讨论】:

【参考方案7】:

这是一个值得optimized solution 而不是试图解决“最佳”问题的经典示例。它在某些方面类似于“Travelling Salesman Problem”,但您还需要在优化过程中对位置进行分段。

我使用了三种不同的优化算法来解决这样的问题:

    Simulated Annealing Great Deluge Algorithm Genetic Algoritms

使用优化算法,我认为您已经描述了以下“目标”:

    每篇论文的地理区域 男孩应该被最小化。 服务的订阅者数量 每个都应该大致相等。 每个人走过的距离 应该差不多。 (还有一个您没有说明,但可能 问题)路线应该在哪里结束 它开始了。

希望这能让你开始!

* 编辑 *

如果您不关心路线本身,则可以消除上述目标 3 和 4,并可能使问题更适合您的奖金要求。

如果您考虑人口统计信息(例如人口密度、订阅采用率和订阅取消率),您可能可以使用上述优化技术来完全消除在订阅者采用或放弃您的服务时重新运行算法的需要。一旦优化了集群,它们就会保持平衡,因为单个集群的每个集群的速率与其他集群的速率相匹配。

您唯一需要重新运行该算法的时间是外部因素(例如经济衰退/萧条)导致人口统计群体的行为发生变化。

【讨论】:

在我的例子中,“路线应该在它开始的地方结束。”不适用。事实上,我不关心分配路线,只关心地址集。他们可以自己处理路由。 路线与实际走的方式无关,只是路线1是A->B-C,路线2是E->D>-G +1 表示问题是 OR (en.wikipedia.org/wiki/Operations_research) @carrier ... 如果集群被主要州际公路一分为二怎么办?只是在任何地方删除一个集群并不能保证一个可路由的解决方案......根据缺乏这些标准查看我的编辑 @steve moyer ...我没有人口统计信息,例如人口密度、订阅采用/取消率...我所拥有的就是我在问题中所说的【参考方案8】:

我认为您确实需要 Set Covering location 模型的一些变体,而不是聚类模型,并附加一个约束来覆盖每个设施所覆盖的地址数量。我在网上真的找不到很好的解释。您可以查看this page,但他们正在使用面积单位解决它,您可能希望在欧几里得或网络空间中解决它。如果您愿意挖掘死树格式的内容,请查看 Daskin 的 Network and Discrete Location 的第 4 章。

【讨论】:

【参考方案9】:

对简单聚类算法的良好调查。还有更多: http://home.dei.polimi.it/matteucc/Clustering/tutorial_html/index.html

【讨论】:

【参考方案10】:

可能是客户的最小生成树,根据报童所在的位置分解为集合。 Prims 或 Kruskal 获取 MST 以及房屋之间的距离作为重量。

【讨论】:

【参考方案11】:

我知道一种非常新颖的方法来解决这个问题,我已经看到它应用于生物信息学,尽管它适用于任何类型的聚类问题。这当然不是最简单的解决方案,但我认为它非常有趣。基本前提是聚类涉及多个目标。对于想要最小化集群数量的人来说,简单的解决方案是一个包含所有数据的集群。第二个标准目标是最小化集群内的方差量,简单的解决方案是许多集群,每个集群只有一个数据点。当您尝试同时包含这两个目标并优化权衡时,就会出现有趣的解决方案。

建议方法的核心是 memetic algorithm,有点像 steve 提到的遗传算法,但它不仅可以很好地探索解决方案空间,而且还能够专注于有趣的区域,即解决方案。至少我建议阅读一些关于这个主题的论文,因为模因算法是一种不寻常的方法,尽管有一点警告;它可能会导致您阅读 The Selfish Gene,但我仍然没有决定这是否是一件好事......如果您对算法不感兴趣,那么也许您可以尝试按照格式要求表达您的问题并使用源代码提供的代码。相关论文和代码可以在这里找到:Multi Objective Clustering

【讨论】:

【参考方案12】:

这与问题没有直接关系,但我听说过,如果这确实是您遇到的路线规划问题,应该考虑一下。这将影响分配给每个驱动程序的集合中地址的顺序。

UPS 的软件可为他们的送货人员生成最佳路线。该软件试图最大限度地增加路线中右转的次数。这为他们节省了大量的交货时间。

对于不住在美国的人来说,这样做的原因可能不是很明显。在美国,人们在马路右侧开车,所以在右转时,如果绿灯,您不必等待迎面而来的车辆。此外,在美国,当红灯右转时,您(通常)不必等到绿灯才可以走。如果您总是在右转,那么您永远不必等待灯光。

这里有一篇关于它的文章: http://abcnews.go.com/wnt/story?id=3005890

【讨论】:

【参考方案13】:

您可以通过使用前一个聚类作为聚类特征,使 K 均值或预期最大化保持尽可能不变。让每个集群拥有相同数量的项目似乎有点棘手。我可以考虑如何将其作为一个后聚类步骤,方法是执行 k 均值,然后改组一些点直到事情平衡,但这似乎不是很有效。

【讨论】:

【参考方案14】:

没有获得任何奖励积分的琐碎答案:

每个地址一个送货员。

【讨论】:

又名去买你自己的该死的纸! :P【参考方案15】:
你有一套街 地址,每个地址都经过地理编码。 您希望对地址进行集群,以便每个集群都 分配给送货人员。 送货人员或集群的数量不固定。如果需要的话, 我总是可以雇用更多的送货员 人,或解雇他们。 每个集群应该有大约相同数量的地址。然而, 如果一个集群可能有更少的地址 集群的地址更分散 出去。 (换一种说法:最低 每个集群的集群数 包含最大数量 地址,以及内的任何地址 群集必须由最大分隔 距离。) 对于奖励积分,当数据集更改时(添加地址或 删除),并重新运行算法, 如果集群就好了 尽可能保持不变(即。 这排除了简单的 k 均值 聚类本质上是随机的)。 否则快递员会走 疯了。

如前所述,车辆路线问题可能更适合...虽然严格设计时并未考虑到集群,但它会根据最近的地址进行优化分配。因此,您的集群实际上将是推荐的路线。

如果您提供最大数量的交付者并尝试达到最佳解决方案,这应该会告诉您所需的最小值。这涉及第 2 点。

可以通过对要访问的地址数量进行限制来获得相同数量的地址,基本上是分配一个库存值(现在它是一个按容量分配的车辆路线问题)。

如果地址更加分散(现在是时间窗口的人满为患的车辆路线问题),则添加送货人员工作的时间窗口或小时有助于减少负载。

如果您使用最近邻算法,那么您每次都可以获得相同的结果,删除单个地址应该不会对您的最终结果产生太大影响,因此应该处理最后一点。

我实际上正在开发一个 C# 类库来实现这样的目标,并认为这可能是最好的方法,尽管它并不容易实现。

【讨论】:

【参考方案16】:

我承认这不一定会提供大小大致相等的集群:

目前数据聚类中最好的技术之一是证据积累。 (弗雷德和耆那教,2005) 你要做的是:

给定一个具有 n 个模式的数据集。

    在 k 的范围内使用类似 k-means 的算法。或者使用一组不同的算法,目标是生成一个分区集合。

    创建一个大小为 n x n 的联合关联矩阵 C。

    对于集合中的每个分区 p: 3.1 更新协关联矩阵:对于p中属于同一簇的每个模式对(i, j),设置C(i, j) = C(i, j) + 1/N。

    使用聚类算法(如 Single Link)并应用矩阵 C 作为邻近度度量。 Single Link 给出了一个树状图作为我们选择生命周期最长的聚类的结果。

如果您有兴趣,我会提供 SL 和 k-means 的描述。

【讨论】:

【参考方案17】:

我将使用基本算法根据他们的居住地和订阅者的当前位置创建第一组报童路线,然后:

当报童是:

补充说:他们从一个或多个在新人居住的一般区域工作的报童那里获取位置。 已移除:他的位置将提供给其他报童,使用最接近他们路线的位置。

当位置是:

添加:同样的,该位置被添加到最近的路线。 已移除:刚刚从那个男孩的路线中移除。

每季度一次,您可以重新计算整个事情并更改所有路线。

【讨论】:

他从未提及任何关于报童的家位置,这并没有解决他的问题(生成集群)的任何关键挑战。

以上是关于Paper Boy 的聚类算法的主要内容,如果未能解决你的问题,请参考以下文章

基于密度的聚类方法

基于网格的聚类算法CLIQUE

用于获得相等大小的聚类的聚类算法

简单易学的机器学习算法——基于密度的聚类算法DBSCAN

第一节:基于划分的聚类算法概述

DBSCAN 算法