我正在寻找一种高性能算法,根据这个数据结构,按位置,性别和年龄匹配大量人员:
>经度(表示人员所在地)
>纬度(表示人员位置)
>性别(表示性别)
>出生日期(表示出生日期)
> LookingForGender(表示该人正在寻找的性别)
> LookingForMinAge(表示该人正在寻找的最低年龄)
> LookingForMaxAge(表示该人正在寻找的最大年龄)
> LookingForRadius(表示该人正在寻找的最大距离)
>已处理(表示此人已处理的其他人)
对于任何人P,算法应返回适用的候选人C:
> C的性别必须相等P.LookingForGender
> P的性别必须相等C.LookingForGender
> C的Birthdate必须介于P.LookingForMinAge和P.LookingForMaxAge之间
> P的Birthdate必须介于C.LookingForMinAge和C.LookingForMaxAge之间
> P和C之间的纬度/长距离必须小于或等于P.LookingForRadius
>纬度/ P和C之间的长距离必须小于或等于C.LookingForRadius
>处理P不得含有C.
该算法应按距离(纬度/长度)的顺序返回前100个候选C.该算法应针对搜索和更新进行优化,因为人们可能经常更改其位置.
我目前的想法是,对于这些需求,k-d树可能比局部敏感散列更合适,我应该朝着这个方向前进.
你对我的建议是什么?我应该寻找什么?你看到了什么风险?
谢谢!
更新:
>我是否更愿意牺牲空间复杂性以获得更好的时间复杂度?是的我更喜欢牺牲空间复杂性.但是,我更喜欢有一个O(log n)解决方案,我实际上理解并且可以维护而不是O(1)解决方案,我无法掌握:)
>数据是否适合主存储器?不,不是的.数据将分布在分布式文档数据库(Azure Cosmos DB SQL API)的不同节点上.
>您想要准确的结果还是近似的结果?近似结果可以,但应严格过滤年龄/性别.
>为算法添加了“已处理”,对不起错过了!
>人们多久改变一次位置?用户在启动应用程序时会更改其位置并查找候选人.因此,每日活跃用户将每天更改一次或多次其位置.然而,位置变化可能很小,所以只有几公里.从100个应用程序下载,15个用户将每月一次或多次使用该应用程序,3个用户将每天使用一次或多次.
最佳答案
Here是Microsoft的一些信息,如何使用它们的空间索引(‘spatial’是您要搜索的关键字).
您正在寻找的查询是k-最近邻查询(kNN搜索),其中k = 100.
如果您想自己序列化索引,请查看R+tree或R*trees,它们非常适合基于页面的序列化.这些树有很多开源示例. Here是我自己在Java中的实现,遗憾的是它不支持序列化.
关于其他索引:
>我没有使用LHS的经验,所以它不能说太多.但我知道的一件事是,因为它内部是HashMap,所以需要特别注意使其具有大量数据的可扩展性.这肯定会增加复杂性.另一个问题,我不确定LSH是否适合kNN搜索,你必须要查看它.
> KD-tree非常简单且应该适用于工作,但是对于序列化是不利的,并且除非您实现可以在每个节点中具有多个条目的版本,否则可能具有大量内存开销. KD-Trees在经常更新时也会退化,因此可能需要重新平衡.
>否则我建议使用四叉树,例如qthypercube2.它们也非常简单,内存非常快,非常适合频繁更新,特别是如果条目只移动很小的距离.