【发布时间】:2020-05-19 06:56:36
【问题描述】:
我需要找到体积最大的长方体,包含在 2D 高度图中。
高度图是一个大小为w*d 的数组,其中w 是宽度,h 是高度,d 是深度。
在 C 中,这看起来是这样的:
unsigned heightmap[w][d]; // all values are <= h
我已经知道有一个简单的算法可以用O(w*d*h) 复杂度解决这个问题。
但是,我怀疑那里有更优化的方法。
它的工作原理如下,在 pythonic 伪代码中:
resultRectangle = None
resultHeight = None
resultVolume = -1
# iterate over all heights
for loopHeight in range(0, h):
# create a 2D bitmap from our heightmap where a 1 represents a height >= loopHeight
bool bitmap[w][d]
for x in range(0, w):
for y in range(0, d):
bitmap[x][y] = heightmap[x][y] >= loopHeight
# obtain the greatest-volume cuboid at this particular height
maxRectangle = maxRectangleInBitmap(bitmap)
volume = maxRectangle.area() * loopHeight
# compare it to our current maximum and replace it if we found a greater cuboid
if volume > resultVolume:
resultHeight = loopHeight
resultVolume = volume
resultRectangle = maxRectangle
resultCuboid = resultRectangle.withHeight(resultHeight)
在矩形中找到所有1 的最大面积是一个已知问题,O(1) 每像素复杂度或在我们的例子中为O(w*d)。
因此,朴素方法的总复杂度为O(w*h*d)。
正如我已经说过的,我想知道我们是否可以克服这种复杂性。
也许我们可以通过更智能地搜索高度而不是“暴力破解”所有高度来将其归结为O(w*d * log(h))。
Evgeny Kluev 对这个问题Find largest cuboid containing only 1's in an NxNxN binary array 的回答似乎采取了类似的方法,但它错误地(?)假设我们在这些高度处找到的体积形成单峰函数。 如果是这种情况,我们可以使用黄金分割搜索来更智能地选择高度,但我认为我们不能。
【问题讨论】:
-
如果高度真的很高,您可以在
sqrt(h)上进行迭代,这将为您提供 (i) 解决方案的下限和上限以及 (ii) 高度部分的子集(每个大小sqrt(h)) 来检查“天真”。在最坏的情况下,复杂性保持不变,但在实践中,运行速度肯定会稍微快一些。 -
@m.raynal 我不完全确定你的意思。你的意思是省略
sqrt(h)上面的数据吗?这可能不会导致最佳解决方案。最好的解决方案可以在任何给定的高度找到,除非它遵循我还不知道的模式。高度图可能是完全平坦的并且高度为 1,这使得位于h=1的平面成为最佳解决方案。但它也可能是 1x1 列,使最大体积成为最大高度。因此,如果有一种方法可以省略高度,那不能只是随意跳过高度。 -
我的意思是在两个高度
h1 < h2之间找到的最大长方体肯定小于w1*d1*h2,其中w1*d1代表1在高度h1处的最大面积,并且肯定至少与w1*d1*h1一样大。这使您可以限制最佳解决方案并丢弃一些潜在的高度(即使在最坏的情况下您最终会迭代所有可能的高度)。我的意思是,您可以按如下方式迭代h,而不是迭代所有可能的值:for h=0; h<=H; h += sqrt(H) -
@m.raynal 你对上限是正确的,这将允许你在从上到下迭代时提前取消。但是,下限不是
w1*d1*h1,因为位图是由高度为>= loopHeight的所有列构成的。更少的柱子满足更高的要求,因此在高度上升时可以找到更小的体积。考虑一个具有非常宽的底部和从其延伸的 1x1 柱的形状。当增加高度时,可能没有一个底座满足要求,最大的长方体只是这个柱子的一部分,因此体积很小。 -
我不关注。您能否帮助我理解为什么不只遍历
O(n^2)中高度图中给出的实际高度(即遍历w*d)并检查w*d*map[w][d]是否大于全局最大值?跨度>
标签: algorithm multidimensional-array 3d voxel heightmap