计算随机放在桌子上的卡所覆盖的区域

时间:2012-03-28 15:09:47

标签: algorithm math data-structures computational-geometry

这是一个面试问题,面试已经完成。

考虑到一副长方形牌,将它们随机放在一张矩形桌子上,这张桌子的大小远远大于卡片的总和。尺寸。有些卡片可能会随机重叠。设计一种算法,可以计算所有卡覆盖的表面积,并分析算法的时间复杂度。所有卡的每个顶点的所有坐标都是已知的。卡可以任何模式重叠。

我的想法:

按垂直坐标降序对卡片进行排序。

在到达卡片的边缘或顶点后,从上到下垂直扫描卡片,继续使用另一条扫描线扫描,直至到达另一条边缘,然后找到位于两条线条之间的区域。最后,对位于两条线之间的所有区域求和并得到结果。

但是,如果区域不规则,如何计算位于两条线之间的区域是一个问题。

感谢任何帮助。谢谢!

5 个答案:

答案 0 :(得分:8)

这可以使用union-intersection formula (A联盟B联盟的大小C = A + B + C - AB - AC - BC + ABC等)轻松完成,但是会导致O(n!)算法。另一种更复杂的方式导致O(n^2 (log n)^2)


将每张卡片作为多边形+其区域存储在列表中。将列表中的每个多边形与每个其他多边形进行比较如果它们相交,则从列表中删除它们,并将它们的并集添加到列表中。继续,直到没有多边形相交。求它们的面积来找出总面积。

多边形可以是凹的并且有孔,因此计算它们的交点并不容易。但是,有algorithms (以及libraries可用于在O(k log k)中计算它,其中k是顶点数。由于顶点的数量可以是n的量级,这意味着计算交点为O(n log n)

将每个多边形与每个其他多边形进行比较是O(n^2)。但是,我们可以使用O(n log n) sweeping algorithm来查找最近的多边形,从而制作整体算法O((n log n)^2) = O(n^2 (log n)^2)

答案 1 :(得分:6)

这几乎肯定不是你的采访者所寻求的,但我们只是想看看他们回答的内容:

我假设所有卡都是相同的尺寸,并且严格是矩形而没有孔,但它们是随机放置在X,Y意义上的,并且也是在θ意义上随机定向的。因此,每张卡的特点是三重(x,y,theta),当然你也有四角的位置。有了这些信息,我们可以相当简单地进行蒙特卡罗分析。

只需在表面上随机生成多个点,并使用列表确定每个点是否都被任何卡覆盖。如果是,请保留;如果没有,扔掉它。按保持点数与总点数之比计算卡片面积。

显然,你可以测试O(n)中的每个点,其中n是卡的数量。然而,我认为这里有一种灵巧的小技术,我认为会加快速度。您可以使用适当的网格尺寸(与卡的大小相关)将桌面网格化,并对卡片进行预处理,以确定它们可能位于哪些网格中。(您可以通过预处理卡片来高估)好像它们是圆形磁盘,直径在相对的角之间。)现在建立一个哈希表,其中键作为网格位置,每个键的内容都是可能与该网格重叠的卡。 (卡片将出现在多个网格中。)

现在,每当您需要包含或排除某个点时,您无需检查每张卡,只需检查可能位于您网点位置的预处理卡。

这种方法有很多话要说:

  • 您可以非常轻松地将其更改为使用非矩形卡,特别是如果它们是凸起的
  • 你可以改变它来使用不同尺寸或形状的卡片,如果必须的话(在这种情况下,几何结构真的很烦人)
  • 如果你在一个从事科学或工程工作的地方进行面试,他们会喜欢它
  • 它很好地并行化
  • 太酷!!

另一方面:

  • 这是一种近似技术(但你可以运行任何你想要的精度!)
  • 你处于预期运行时间,而不是确定性运行时
  • 有人可能会问你关于蒙特卡洛的详细问题
  • 如果他们不熟悉蒙特卡洛,他们可能会认为你正在制作东西

我希望我能相信这个想法,但唉,我是从纸上根据蛋白质中原子的位置和大小计算蛋白质的表面积来选择的。 (同样基本的想法,除了现在我们在3空间中有一个3D网格,卡片确实是磁盘。我们将通过并为每个原子在其表面上生成一堆点,看看它们是否存在任何其他原子的内部。)

编辑:我发现原始问题规定总桌面面积远大于卡片总面积。在这种情况下,适当的网格大小意味着大多数网格必须未被占用。一旦构建了哈希表,您还可以预处理网格位置,并完全消除这些位置,仅在可能占用的网格位置内生成点。 (基本上,对每个可能被遮挡的网格位置执行单独的MC估计。)

答案 2 :(得分:2)

这是一个不完美但实际上有用的想法。您设计的算法取决于精度度量epsilon(eps)。想象一下,你将空间分成大小为eps x eps的正方形。现在你要计算卡内的方格数。让卡的数量为n,让卡的两边为h和w。

这是一种天真的方式:

S = {} // Hashset
for every card:
   for x in [min x value of card, max x value of card] step eps:
       for y in [min y value of card, max y value of card] step eps:
           if (x, y) is in the card:
               S.add((x, y))
return size(S) * eps * eps

算法在O(n *(S / eps)^ 2)中运行,误差受(2 * S * n * eps)的强烈限制,因此相对误差最多(2 * eps * n / S)。

因此,例如,为了保证误差小于1%,您必须选择小于S /(200 n)的eps,并且算法以大约200 ^ 2 * n ^ 3步进行。

答案 3 :(得分:1)

假设有n张单位面积的牌。设T为表格的面积。对于离散问题,所涵盖的预期面积将为

$ T(1 - ({{T-1} \ over {T}})^ n)$

答案 4 :(得分:0)

T =表格的总面积。

C =卡片可以覆盖的总面积(一张卡片的面积乘以卡片的数量)。

V =重叠卡片的总面积(V = oVerlap)

要计算的面积= T - (C - V)

应该(有些是危险词)以某种方式有效地分析卡所占用的空间,以便轻松识别重叠与非重叠的情况。确定这些因素,将所有重叠区域分解出来,然后就完成了。

时间的复杂性在于逐个考虑每张卡片,并将每张卡片与每张剩余的卡片进行比较(卡片2已经针对卡片1进行了检查),这使得它成为n!,不是很好......但是这个是“应该”进来的地方。必须有一些有效的方法来删除所有不考虑重叠的卡片,如果它们不可能与其他/之前的卡片重叠,并且可能用于识别或分组,则可以使卡片显而易见可能重叠的卡片。

有趣的问题。