【问题标题】:How can I do better than brute force in finding closest location?在找到最近的位置时,我怎样才能比蛮力做得更好?
【发布时间】:2016-08-21 14:05:58
【问题描述】:

我有以下代码:

public static Location findClosest(Location myPosition, ArrayList<Location> spots) {  
  double min = Double.MAX_VALUE;  
  Location closer = null;  
  for(MyPosition aPosition:spots) {  
     float dist = Math.abs(aPosition.distanceTo(myPosition));  
     if(dist < min) {  
         min = dist;  
         closer = aPosition;  
     }  
  }  
  return closer;  
}  

这是一种蛮力 O(N^2) 方法,因为它是从以下函数调用的:

public static Location findClosest(Location myPosition, ArrayList<Places> places) {   
   Location closer = null;  
   double min = Double.MAX_VALUE;    
   for(Places place:places) {  
      Location currentMin = findClosest(myPosition, places.getSpots());  
      float dist = Math.abs(currentMin.distanceTo(myPosition));  
      if(dist < min) {  
         min = dist;  
         closer = currentMin;  
      }  
   }  
   return closer;  
}  

考虑到斑点的大小不是那么大~200 max.
我可以做些什么来改进我的方法?
除了 geohashing,我还有什么其他算法可以提高性能吗?
是否有一些坐标属性可以用来跳过循环的某些部分?

【问题讨论】:

  • 你可以使用优先级队列而不是列表,此时你会得到 O(1),我在这里也看到 O(n),除非我错过了什么......
  • 我看不到 O(N^2) - 但只能看到线性。无论如何,如果您能够“以某种方式”预处理点,您可以将它们存储在一些空间数据结构中,例如 R-tree、QuadTree、KD-Tree 等......以加快搜索速度。正确的数据结构取决于您使用的维度数量等。例如,请参阅 en.wikipedia.org/wiki/R-treeen.wikipedia.org/wiki/Quadtree
  • @Palcente:如何使用优先队列?我不明白
  • @convexHull:你是对的。它不是 O(N),因为我从另一个我省略提及的循环中调用了这个函数。我会更新OP。我不知道预处理可能是什么
  • 在插入过程中保持优先级队列中的顺序。因此,您的findClosest() 方法只需要从spots 中提取第一项,就可以保证它是最近的位置。

标签: java android algorithm geolocation coordinates


【解决方案1】:

因为你说 O(N^2),但这是一个 O(N) 函数,我假设你在循环中调用它来确定每个点的最近点。在那种情况下,我不知道什么会更快。

但是,为了省去每次要存储最近点时都必须运行此函数的麻烦,请将所有点添加到最近的点的 HashMap 中,并检查该点是否已添加。如果添加了新点,只需检查它和所有原始点。

希望这会有所帮助,哪怕只是一点点。

【讨论】:

    【解决方案2】:

    如果您的问题是从任何位置的所有“地点”中找到最近的“地点”,并且您的函数将被多次调用(使用相同的“地点”和“地点”),也许您应该考虑创建某种空间数据结构(这就是我所说的预处理)。 例如四叉树 (https://en.wikipedia.org/wiki/Quadtree)。四叉树的构建可能需要一些时间,但您的搜索效率会很高。 - 元素插入需要 O(log N) (对于 N 个点来说完全是 (N * logN) (你的情况可能是 N = M*M)) - 搜索只需要 O(log N) 与笛卡尔坐标完美搭配。如果您使用的是地理坐标,则应先对其进行转换。

    【讨论】:

    • 我的问题是给出 1 X 位置和其他位置列表,从列表中找到离 X 最近的位置
    • 1) 我有列表,但目标位置未知。我可以创建这样一个树结构来适应这个吗? 2)我有地理坐标。转换它们的最佳方法是什么?
    • 如果您只搜索最近的 ONCE - 这些类型的数据结构可能会产生开销,而您的解决方案已经足够好了。但是如果您搜索最近的 MULTIPLE 时间(或者如果有可能多次询问),您可以为您的点列表构建(例如)四叉树。然后,您可以轻松地询问任何未知的位置。转换为笛卡尔坐标不是那么容易,但它是可能的。参见例如movable-type.co.uk/scripts/latlong.html
    猜你喜欢
    • 1970-01-01
    • 2015-08-06
    • 2011-04-02
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多