【问题标题】:How can you find points in regions of space quickly如何快速找到空间区域中的点
【发布时间】:2014-10-15 08:43:33
【问题描述】:

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

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

如何在 5 维空间中有效地找到每个金字塔区域的一个点?那是 返回k 5d 空间中的点, 每个都在不同的金字塔区域。值 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))

这是 3d 中 4 个平面的图片,有 14 个点,每个区域一个(因为 5d 很难绘制),每个平面创建的金字塔区域一个。

是否有一种算法可以在 5 维空间中找到k 点,每个点都在不同的金字塔中 区域并需要 O(nk) 时间?

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

【问题讨论】:

  • 你快到了。找到由 5 个平面(或 3d 示例中的 3 个)的所有组合的交点生成的点。然后添加 10 个额外的(3d 中的 6 个)平面(实际上您可以使用 6 个(3d 中的 4 个),但 10 个可以垂直于轴,这可能会简化事情)围绕这些点形成一个封闭区域。现在确定由所有平面形成的每个封闭凸区域的顶点。半空间相交算法当然是做到这一点的一种方法。可能会有更好的想法。平均这些封闭区域的顶点以获得所需的点。
  • @Gene 在我的问题中有n 超平面,所以你的意思是n 超平面的所有组合的所有交集?

标签: algorithm math


【解决方案1】:

如果您愿意为线性编程挖掘 Python 库,那么这里有一种易于实现且相当高效的方法(时间 O(poly(n) k))。跟吉恩提议的差不多。

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 求解器支持它,请指定对偶单纯形算法并重用之前的对偶解作为起始基础。

【讨论】:

  • 谢谢你。严格来说,LP 求解不太可能是多时间,无论我能找到什么库吗?
  • @user2179021 单纯形的最坏情况是指数的,但在实践中很少发生。从理论的角度来看,在恒定维度上存在用于 LP 的多时间算法(但您可能必须自己实现它们)。
  • 好的,谢谢。您是否认为 Gene(和您)的想法有一个版本不依赖于 LP 求解可以更快地工作?
  • @user2179021 似乎很棘手。仅测试半空间的交集是否为空就等同于没有目标的 LP(这有点等同于有目标的 LP,通过使用带有额外约束替换目标的二分搜索)。
  • Gene 的草图算法似乎不需要 LP 求解,对吗?还是我错过了一些实际实施所需的关键细节?
【解决方案2】:

你可以试试四键。将点转换为二进制并将其连接起来。然后对点进行排序。您可以使用最高有效位验证上限。您可以从微软必应地图找到源代码:http://msdn.microsoft.com/en-us/library/bb259689.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    相关资源
    最近更新 更多