匹配数百万人:k-d树还是对位置敏感的哈希?

时间:2018-07-11 08:16:57

标签: algorithm azure-cosmosdb nearest-neighbor kdtree locality-sensitive-hash

我正在寻找一种高性能的算法,根据此数据结构,按位置性别年龄匹配大量人员:

  • 经度(表示人员所在的位置)
  • 纬度(表示人员所在的位置)
  • 性别(代表人们的性别)
  • 生日(表示此人的生日)
  • LookingForGender(表示此人正在寻找的性别)
  • LookingForMinAge(表示此人正在寻找的最低年龄)
  • LookingForMaxAge(表示此人正在寻找的最大年龄)
  • LookingForRadius(表示此人正在寻找的最大距离)
  • 已处理(表示此人已经处理过的其他人)

对于任何人P,算法应返回适用的候选C:

  • C的性别必须等于P.LookingForGender
  • P的性别必须等于C.LookingForGender
  • C的生日必须在P.LookingForMinAge和P.LookingForMaxAge之间
  • P的生日必须在C.LookingForMinAge和C.LookingForMaxAge之间
  • P和C之间的纬度/长距必须小于或等于P.LookingForRadius
  • P和C之间的纬度/经度距离必须小于或等于C.LookingForRadius
  • 已处理的P不能包含C

算法应按距离顺序(纬度/经度)返回前100个候选C。该算法应同时针对搜索和更新进行优化,因为人们可能会经常更改其位置。

我目前的想法是,与这些需求相比, k-d树可能比 locality-sensitive-hashing 更合适,我应该朝这个方向发展。

您对我有什么建议?我应该找什么?您看到什么风险?

谢谢!

更新

  • 我是否愿意牺牲空间复杂度来提高时间复杂度?是的,我更愿意牺牲空间复杂度。但是我更喜欢有一个我真正理解并可以维护的O(log n)解决方案,而不是一个我无法掌握的O(1)解决方案:)
  • 数据是否适合主存储器?否。数据将分布在分布式文档数据库(Azure Cosmos DB SQL API)的不同节点上。
  • 您想要确切的结果还是近似的结果?近似的结果还可以,但是年龄/性别应该正确过滤。
  • 在算法中添加了“已处理”,很抱歉错过了!
  • 人们多久更改一次位置?用户每次启动应用程序并寻找候选人时都会更改其位置。因此,每日活跃用户每天将更改其位置一次或多次。但是,位置更改可能很小,因此只有几公里。从100次应用下载中,有15位用户每月将使用一次或多次该应用,而3位用户每天将使用一次或多次。

1 个答案:

答案 0 :(得分:1)

Here是Microsoft提供的一些有关如何使用其空间索引的信息(“ spatial”是您要搜索的关键字)。

您要查找的查询是k = 100的k最近邻查询(kNN搜索)。

如果您想自己序列化索引,请查看R+treeR*trees,它们对于基于页面的序列化非常有用。这些树有很多开源示例。 Here是我自己的Java实现,很遗憾,它不支持序列化。

关于其他索引:

  • 我没有LHS的经验,因此不能多说。不过我知道一件事,因为它在内部是HashMap,所以您需要格外小心,以使其可扩展以容纳大量数据。这无疑增加了复杂性。另一个问题,我不确定LSH是否适合kNN搜索,您必须进行查找。
  • KD树非常简单,应该适合工作,但是对序列化不利,并且除非您实现的版本在每个节点中可以有多个条目,否则它会占用大量内存。 KD树在经常更新时也会退化,因此它们可能需要重新平衡。
  • 否则,我会建议使用四叉树,例如qthypercube2。它们也非常简单,存储速度非常快,非常适合频繁更新,尤其是在条目仅移动很小距离的情况下。