我有一个 3d网格,其中网格上的每个点(x,y,z) 都与 相关联成本价值。任何点(x,y,z)的成本事先不知道。要知道成本,我们需要进行一个非常昂贵的复杂查询。我们对这个目标了解的一件事是,所有3个维度的成本单调不减少。
现在给定成本C,我需要找到表面上具有成本C 的点(x,y,z)。这必须通过仅花费最低成本来完成。如何解决我的问题?
当我在网上搜索时,我正在获得与轮廓识别相关的技术,但所有这些技术都假设所有点的成本都是预先知道的,比如Marching cubes方法等。在我的情况下,主要指标是计算成本的点数应该是最小。
如果有人能够提出一种获取近似位置的方法,至少如果不准确的话会很有帮助。
答案 0 :(得分:2)
您应该查看本文,其中讨论了二维案例,并让您深入了解不同的方法:
http://leetcode.com/2010/10/searching-2d-sorted-matrix.html
在我看来,逐步线性搜索(在那里的第二部分)对你来说是一个很好的第一步,因为它很容易应用于三维情况,它真的不需要很多经验来理解。
因为这是非常简单且仍然非常有效,我会继续使用它,看看它是否符合您在3-d中使用的数据类型的需求。
但是,如果您的唯一目标是性能,则应将二进制分区应用于3-d。这有点复杂,因为他所说的“二进制分区”基本上变成了“二进制平面分区”
因此,您没有将矩阵划分为2个可能较小的矩阵的线
相反,你有一个平面将你的立方体分成两个可能的较小的立方体
要使该平面(或矩阵)中的搜索有效,您首先必须实现他的一种方法:)。
然后用较小的立方体重复一切
请记住,以非常有效的方式实现这一点(即记住内存访问)并非易事。
答案 1 :(得分:2)
我会给出这个答案,以尽量减少计算的费用数量。 Matt Ko链接到一个很好的解决方案,但它假设一个廉价的成本函数和基于矩阵的数据,你似乎没有。我给出的方法要求更接近成本函数O(log N + k)
调用,其中k
是具有所需成本的点数。请注意,这种具有一些性能优化的算法可以在3D矩阵上成为O(N)
,几乎没有机会调用性能成本函数,尽管它有点复杂。
psudeocode基于quickselect中使用的技术,如下所示:
While there are still points under considerations:
Find the ideal pivot point and calculate it's cost
Remove the pivot from the point set
If the cost is the desired cost then:
Add the pivot to the solution set
Else:
Separate the points into 3 groups:
G1. Those that are in in the pivot's octant `VII`
G2. Those have the same x, y, or z of the pivot
G3. Those that are not in the pivot's octant `VII`
# Note this can be done in O(N)
If all points are in group 2:
Use 1D binary searches in each dimension to find points with the desired cost
Else:
Compute the cost of the pivot
Keep all points in group 2
If the pivot cost is greater than desired:
Keep only the points in group 1
Else:
Keep only the points in group 3
根据该行octant VII
内外的点选择枢轴。如果需要,可以在稍后处理形成八分圆的3条线中的任何一条点(G2)。
理想的枢轴点是组1(G1)和组3(G3)中的点数尽可能接近相等。以数学方式看待它将沿两条中较小的一条最大化两者中的较大者,或maximize(max(|G1|,|G3|) / min(|G1|,|G3|) )
。即使是一个寻找理想枢轴点的相当天真的算法也可以在O(N^2)
(可能存在O(N log N)
算法)中找到它,但是需要O(N^3)
来计算理想枢轴的成本。找到。
在找到理想的枢轴并计算成本之后,每次迭代应该平均看到丢弃的剩余点的大约一半,这再次导致仅对成本函数进行O(log N + k)
次调用。
最后注意事项:
回想起来,我不确定第2组的特殊考虑是否真的需要,因为它可能在第3组,但我不是100%肯定。但是,将它分离似乎并没有改变Big O,所以我没有看到需要改变它,尽管这样做会略微简化算法。