网络拓扑距离的高效KNN查询(结项报告)

来源:互联网 发布:unity3d 卡通场景下载 编辑:程序博客网 时间:2024/05/17 04:59

网络拓扑距离的高效KNN查询(结项报告) 

下面,对最近两个月的工作做个完整的总结。

 

首先,介绍下项目内容以及我们最终实现的结果。项目内容是完成对用户IP-Geo-ISP等信息的索引,以腾讯提供的更详细IP库的部分数据,千万级别用户,在上面进行KNN查找的效率不低于单机100QPS。我们最终使用自适应格子算法完成了对用户信息的编码,并分别使用随机数据和真实数据对算法效率进行了测试。对于生成的千万级别的随机数据,查询效率为4000QPS;对于通过百度地图API查询到的25万真实数据,查询效率为1000QPS。效率远远超过项目所预期达到的效率。



图一

 

接下来,对自适应格子算法进行详细的介绍。如上图一所示,假设我们的编码长度为3,第三层中格子的总数就是4^3=64。对于每个点,根据它的经纬度,都可以编码成一个长度为3的字符串。上图Level3是第三层中每个块对应的编码。一共64个块,我们在编程时就需要建立64vector分别保存对应块中的点。同时,建立一个深度为三的字典树,这个字典树记录各个Level中,每个格子中点的总数。在查询时,输入一个IP,我们根据这个IP的经纬度可以编码出它所属于的格子,比如属于000这个格子。通过字典树以及要查询的K的大小,我们可以知道该使用哪个level大小的格子合适,这样就可以控制中间结果集中点的数量了。

通过测试,我们发现使用真实数据的效率是不如随机数据的。产生这个现象的原因是真实数据的重合点太多。这样,不管使用什么级别的格子,格子中的点数量都是那么多。针对这种现象,我们在搜索中间结果集时,可以记录下与要查询点重合的点的数量,如果这个数量是大于K的,我们可以随机的从中输出K个重合点即可。

至于经纬度编码成字符串的方法,我们是使用geohash的编码方式。

 

最后,说说项目未来可能优化的余地。

查询时,对于当前格子,我们需要找到周围的8个格子,我们目前找格子的方法是根据编码规律使用递归的方法进行查找的。查找的结果,是可以保存在字典树中的,这样下次再查找这个格子周围8个格子时,就可以直接从字典树中输出结果了。(目前的程序没有进行这步优化。假设编码长度为10,查找周围8个格子运算次数大概为百次;如果使用字典树对结果进行保存的话,运算次数大概为十次。不过,在时间复杂度较低、空间复杂度高的情况下,是否有必要再进行空间换时间呢?)。

0 0
原创粉丝点击