基于距离的大小为 2 的组
Posted
技术标签:
【中文标题】基于距离的大小为 2 的组【英文标题】:Groups of size 2 based on distance 【发布时间】:2017-01-13 06:00:59 【问题描述】:我有一个长度为 N 的数千个点的列表,每个点都有纬度和经度。
我想将这些点分成 N/2 组,每组包含 2 个点(如果 N 为奇数,则一个将有 3 个)。
此分组的目的是最小化 2 个点之间的距离。我们可以将每组的误差视为点之间的距离的平方。以及所有组的误差总和。
考虑到算法应该相对较快的约束(这将部署在 API 上并响应用户请求运行),实现这一目标的最佳算法是什么?
分组不一定需要是“最好的”,但最好是确定性的。
【问题讨论】:
这是某种最小权重(完美)匹配,但我不知道一般图的确切术语(通常匹配被认为是二分图) 【参考方案1】:计算中心。
按距中心的距离对点进行排序。
按降序,选择下一个不匹配的点并将其与最近的不匹配邻居配对。您可以使用三角不等式来保持候选者较小。
使用索引,这种 贪婪 方法是 O(n log n) 否则 O(n^2)。这可能不是最好的结果,但对于这个运行时间来说应该是相当不错的。预排序避免了真正糟糕的情况(只要中心不太不平衡)。
【讨论】:
【参考方案2】:首先,我们可以定义一个象限函数:
int quadrant(point a)
if(a.latitude > 0)
if(a.longitude > 0) return 1;
else return 2;
else
if(a.longitude < 0) return 3;
else return 4;
然后我们可以像这样对点进行排序:
bool comparison(point a, point b)
if (quadrant(a) == quadrant(b))
if(a.longitude > b.longitude) return true;
else return a.longitude > b.longitude;
else
return quadrant(a) < quadrant(b);
象限函数就像笛卡尔平面一样工作,可以帮助您将点放在一起。
基于此类比较的排序将帮助您将附近的点组合在一起,因此您可以配对 (a1,a2), (a3,a4), ..., (an-1, an) 和它将花费 O(N lg(N)) 时间。
如果你更好地处理相邻的象限或做更多的逻辑,你可以优化一点,但这是一个好的开始。
【讨论】:
以上是关于基于距离的大小为 2 的组的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Zeppelin 中基于 HadoopGroupProvider 中的组配置角色,使用 Knox 提供基于 SAML 的 SSO?
基于组 ID 子集的时间戳列的组中的最后一行 - Postgres
聚类:层次聚类基于划分的聚类(k-means)基于密度的聚类基于模型的聚类