想象一下,你给出了3个维度中n个点的集合S.任意2点之间的距离是简单的欧几里德距离.您希望从该集合中选择k个点的子集Q,使得它们彼此相距最远.换句话说,不存在k个点的其他子集Q’,使得Q中的所有成对距离的min小于Q’中的min.
如果n约为1600万,k约为300,我们如何有效地做到这一点?
我猜这个NP难,所以我们可能只想关注近似.我能想到的一个想法是使用多维缩放对一行中的这些点进行排序,然后使用二进制搜索的版本来获得该行上最远的点.
最佳答案
我也很确定问题是NP-Hard,我发现最类似的问题是k-Center Problem.如果运行时比正确性更重要,贪心算法可能是你的最佳选择:
Q ={}
while |Q| < k
Q += p from S where mindist(p,Q) is maximal
附注:在类似的问题中,例如,set-cover problem可以证明来自贪婪算法的解决方案至少是最佳解决方案的63%.
为了加快速度,我看到了3种可能性:
>首先在R-Tree中索引数据集,然后执行贪婪搜索. R-Tree的构造是O(n log n),但是虽然是为最近邻搜索而开发的,但它也可以帮助您找到O(log n)中一组点的最远点.这可能比天真的O(k * n)算法更快.
>从1600万个点中抽取一个子集,并对子集执行贪婪算法.无论如何,你都是近似的,所以你可能会更加准确.您还可以将其与1.算法结合使用.
>使用迭代方法,当您没有时间时停止.这里的想法是从S中随机选择k个点(让我们称之为Q’).然后在每一步中,将点p_从具有最小距离的Q’切换到Q’中的另一个距离,从S开始随机点.如果得到的集Q”更好,则继续Q”,否则重复Q’ .为了不被卡住,你可能想要选择Q’中的另一个点而不是p_如果你找不到足够的替代品来进行几次迭代.