如何快速找到空间区域的点数

时间:2014-10-15 08:43:34

标签: algorithm math

考虑由至少两个穿过原点的平面划分的5维空间。如果有n个平面,那么只要它们处于“一般位置”,这个创建的不同金字塔区域的数量就是n^4/24-n^3/4+(23 n^2)/24-(3 n)/4+1,这个术语我在下面具体说明。

通过原点的超平面可以由从与平面正交的原点开始的单个矢量定义。如果没有三个定义超平面的向量是共面的,则超平面处于一般位置。

  

如何在5维空间中有效地找到每个金字塔区域的一个点?那是   在5d空间中返回k个点,   每个都在不同的金字塔形区域。值k将成为输入的一部分。

到目前为止,我的天真尝试只是在超球面上随机选取点(使用Python)

def points_on_sphere(dim, N, norm=numpy.random.normal):
    """
    http://en.wikipedia.org/wiki/N-sphere#Generating_random_points
    """
    normal_deviates = norm(size=(N, dim))
    radius = numpy.sqrt((normal_deviates ** 2).sum(axis=0))
    points = normal_deviates / radius
    return points

然后选择一个子集,使每个子集位于不同的区域。我可以使用以下代码验证这些点是否真的都在不同的金字塔区域。

def all_in_distinct_pyramidal_regions(testpoints, hyperplanes):
    signs = numpy.sign(numpy.inner(testpoints, hyperplanes))
    return (len(set(map(tuple,signs)))==len(signs))

下面是一幅4幅飞机在3d中有14个点的图片,每个区域有一个(因为5d难以绘制),每个金字塔区域都有一个由飞机创建。

enter image description here

  

是否存在可在5维空间中工作的算法,以查找k个点,每个点都在不同的金字塔形中   区域并采取类似O(nk)时间的任何东西?

我注意到金字塔形区域是凸起的。凸起空间在附加处被关闭,特别是如果你知道形成区域边界的超平面,你可以通过平均超平面上的点来找到区域内的一个点。但是,我不确定如何将这种观察转化为完全有效的算法。

2 个答案:

答案 0 :(得分:1)

如果您愿意为线性编程挖掘Python库,那么这是一种易于实现且合理有效的方法(时间O(poly(n) k))。它与Gene提出的类似。

v1, ..., vm in R^5 \ 0成为某些平面的法向量。要在正半空间的交点中找到一个点,求解线性程序

maximize z
subject to
v1 . x - z >= 0
...
vm . x - z >= 0
x in [-1, 1]^5
z in R,
变量x, z中的

,其中.表示点积。如果在最佳解决方案中z > 0,则点x位于正半空间的交叉点。

要在每个区域中找到一个点,请递归枚举包含条目n的所有长度为±1的向量,并进行以下修剪。我们将向量的条目解释为选择每个法向量的正半空间或负半空间。如果具有对应于当前前缀的约束子集的LP是不可行的,则修剪递归。在Pythonish伪代码中:

def find_points(normals, prefix=()):
    "solve the LP with normals [sign * normals[i] for i, sign in enumerate(prefix)]"
    if "the LP is infeasible": pass
    elif len(normals) == len(prefix): yield x
    else:
        for point in find_points(normals, prefix + (1,)):  # or yield from
            yield point
        for point in find_points(normals, prefix + (-1,)):
            yield point

由于修剪,递归树的内部节点数最多是区域数的n倍,因此根本不是指数

这种方法的瓶颈几乎可以肯定地解决线性程序。由于我们一次添加一个约束,如果您的LP解算器支持它,请指定双重单纯形算法并重复使用先前的双解决方案作为起始基础。

答案 1 :(得分:0)

你可以尝试一个四核。将点转换为二进制并将其连接起来。然后对点进行排序。您可以使用最重要的位验证上限。您可以从Microsoft Bing地图中找到源代码:http://msdn.microsoft.com/en-us/library/bb259689.aspx