Java 算法——如何高效地找到距离一百万个坐标最近的POI

Java 算法——如何高效地找到距离一百万个坐标最近的POI,java,algorithm,geocoding,Java,Algorithm,Geocoding,这是面试后我被要求实施的-- 因此,我得到了一份以欧几里德坐标表示的餐厅POI列表(大约2000个) 然后给我一个用户坐标列表(100万个) 我的任务是返回在单个POI的某个半径(10,15)内有多少用户,其次是75%的用户在POI距离内所需的半径 距离是我可以计算出来的,但暴力迫使它意味着用100万个坐标检查1000个坐标,这需要很长时间 哪种方法更有效 最好使用一个框架,该框架允许您对坐标进行空间索引并运行高效的空间操作符。Mapinfo、空间感知数据库(Oracle Spatial—生产使

这是面试后我被要求实施的--

因此,我得到了一份以欧几里德坐标表示的餐厅POI列表(大约2000个)

然后给我一个用户坐标列表(100万个)

我的任务是返回在单个POI的某个半径(10,15)内有多少用户,其次是75%的用户在POI距离内所需的半径

距离是我可以计算出来的,但暴力迫使它意味着用100万个坐标检查1000个坐标,这需要很长时间


哪种方法更有效

最好使用一个框架,该框架允许您对坐标进行空间索引并运行高效的空间操作符。Mapinfo、空间感知数据库(Oracle Spatial—生产使用可能需要额外的许可)、ESRI、开源等

通常的行动是

  • 在空间索引容器(具有空间索引的表)中加载POI
  • 在空间索引容器中加载用户
  • 将POI延伸为具有所需距离半径的圆形对象
  • POI圈内用户的空间连接/组合
  • 这些空间连接/组合器有不同风格的空间操作符

    如果您只想在练习中生成结果,而不能使用任何框架,我建议您采取一些简单的方法

    1百万用户实际上并不是超级大——这是可以管理的——问题是这些点要根据2000个POI进行评估。我相信最好的办法是

  • 首先使用2 x半径作为边围绕POI生成边界正方形
  • 这将允许您相当快速地评估每个POI感兴趣的点。原则上只将大于、小于用作运算符
  • 对于每个POI都有一组用户,您可以通过进行实际距离计算来进一步缩小其范围
  • 你可以利用各种各样的智能索引和排序来加快速度。如果您有时间实施,则注释中建议的R树似乎非常适合。这将在上面的第二步中帮助您


    一种更简单的方法——根据坐标的布局(你的世界看起来如何),是将你的世界划分成更大的正方形,并首先为每个用户和每个POI确定它们属于哪个正方形。您可以快速确定POI同一方格内的所有用户,或感兴趣的任何相邻方格内的所有用户。提出一个智能的索引/编号方案,也可以帮助您识别邻居。通过Hashmaps将用户列表索引到他们的方块。

    使用空间查找数据结构或数据库,并进行适当的查询


    要使半径包含75%的用户,您始终可以使用已知的用户总数和最外层坐标对半径进行二进制搜索。

    有很多方法,但基本上您应该将空间划分为“值得搜索”的部分和“不值得搜索”的部分。您可能需要搜索“空间数据结构”,尤其是R-树。对于第一个问题:Map Reduce可能是另一种(占用资源的)方法。对于第二个问题:对点进行聚类,然后计算最接近用户的POI。然后增加半径以覆盖75%的用户点距离。对于额外的限制,我不允许使用已经创建的外部框架