【问题标题】:Given a list of 2D points and a square grid size, return the coordinate closest to the most points给定一个二维点列表和一个正方形网格大小,返回最接近最多点的坐标
【发布时间】:2019-02-04 17:25:21
【问题描述】:

这是我接受的一次采访中总结的问题陈述:

有一个n x n 网格代表一个城市,还有一个k 列表 三元组(x, y, w),其中(x, y)是事件的坐标, w 是事件的“价值”。你也有一个半径 r,代表你能看到多远。你从看到一个事件中获得幸福h,以及h=w/d,其中d 是(1 + 到事件的欧几里得距离)(说明 0 距离)。如果d大于r,则幸福度为0。输出累积幸福度最高的坐标(x,y)

我真的不知道如何解决这个问题,除了暴力破解每个可能的坐标并计算每个点的幸福度,记录最大值。我还考虑过计算点的质心并找到最接近质心的整数坐标,但这并没有正确考虑事件的“价值”。

解决这个问题的最佳方法是什么?

【问题讨论】:

标签: algorithm language-agnostic


【解决方案1】:

(我看不到明显的最佳算法或数据结构;这可能是他们更想听听您的思考过程而不是您的解决方案的问题之一。)

两种明显的方法:

  • 遍历所有位置并测量到所有事件的距离以计算位置的价值
  • 遍历所有事件并增加它们周围圆圈中位置的价值

后者似乎是最有效的一种。您永远不会查看毫无价值的位置,并且要分配价值,您只需计算圆的一个八分圆,然后将其镜像到圆的其余部分。

您显然需要内存空间来存储位置价值的矩形网格,所以这是一个考虑因素。如果您事先不知道城市大小,则必须对输入进行一次迭代才能选择网格大小。 (相比之下,第一种方法几乎不需要内存空间)。

就时间复杂度而言,您将迭代 k 个事件,并且对于每个事件,您必须计算与 r 相关的多个位置的价值2。您可以在迭代事件时保持最大值,因此找到最大值不会增加时间复杂度。 (在第一种方法中,您显然必须计算所有相同的 w/(d+1) 值,而没有镜像一个圆的一个八分圆的优势,至少加上所有的距离额外的毫无价值的位置。)

如果与城市规模相比,事件的数量及其周围的受影响区域较小,则第二种方法的优势是显而易见的。如果有大量事件和/或 r 很大,则差异可能不显着。

可能有一些数学技巧来决定首先检查哪些事件、忽略哪些事件或何时停止,但您必须了解更多细节,例如两个事件是否可以在同一位置发生。可能有例如按价值对事件进行排序并首先查看价值最高的事件是一个优势,因为在某些时候很明显,可以忽略当前最大值附近的“热点”之外的事件。但很大程度上取决于数据的具体情况。


更新

在将事件的价值分配到它周围的位置时,您显然不必多次计算距离;例如如果 r = 3 您将使用 1/d 权重制作这个 7×7 网格:

0      0      0      0.250  0      0      0
0      0.261  0.309  0.333  0.309  0.261  0
0      0.309  0.414  0.500  0.414  0.309  0
0.250  0.333  0.500  1.000  0.500  0.333  0.250
0      0.309  0.414  0.500  0.414  0.309  0
0      0.261  0.309  0.333  0.309  0.261  0
0      0      0      0.250  0      0      0

其中仅包含八个不同的值。然后,您将使用它作为模板覆盖在事件位置的网格顶部,并将事件的价值与权重相乘,并将它们添加到每个位置的价值中。


更新

我考虑了这样一种可能性,即只有发生事件的地点才有可能是最高价值的地点,而没有限制 r 是真的。那会使问题完全不同。但是,创建反例很容易;考虑例如这些事件:

-      -      60     -      -
-      -      -      -      -
60     -      -      -      60
-      -      -      -      -
-      -      60     -      -

如果限制 r 大于 4,他们将在他们周围的位置创造这个价值:

61.92  73.28  103.3  73.28  61.92
73.28  78.54  82.08  78.54  73.28
103.3  82.08  80.00  82.08  103.3
73.28  78.54  82.08  78.54  73.28
61.92  73.28  103.3  73.28  61.92

而价值最高的103.3的地点就是事件发生的地点。但是,如果我们设置限制 r = 2,我们会得到:

40     30     60     30     40
30     49.7   30     49.7   30
60     30     80     30     60
30     49.7   30     49.7   30
40     30     60     30     40

而中间的位置,没有事件,现在是最大价值80的位置。

这意味着必须考虑没有事件的位置,至少是在一组事件周围的凸包内的位置。当然,如果发现两个事件集群彼此相距超过 2 × r,则可以将它们视为单独的区域。在这种情况下,您不必为整个城市创建一个网格,而是在每个集群周围分开较小的网格。


所以总体方法是:

  • 使用权重创建大小为 2 × r 的方形网格。
  • 将事件分成簇,它们之间的距离大于 2 × r
  • 对于每个事件集群,创建适合事件周围的最小矩形网格。
  • 对于每个事件,使用权重网格在矩形网格上分配价值。
  • 在为地点增加价值的同时,跟踪最大价值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多