【问题标题】:How to generate a set of K points evenly spaced in unit cube/sphere of dimension D如何生成一组在 D 维单位立方体/球体中均匀分布的 K 点
【发布时间】:2013-05-29 23:36:09
【问题描述】:

我正在尝试生成一组均匀分布在内部固定空间的 K 点,我认为单位球体或立方体是最简单的。对于二维来说,这很容易,但不幸的是,当我们上升到任意维度 D 时,这要困难得多。

我认为这是在“准蒙特卡洛方法”中完成的,但我一直找不到公式,甚至找不到关于这是否是一个易于处理的问题的声明。任何输入将不胜感激。

【问题讨论】:

  • 到目前为止你试过什么鳕鱼?
  • 这不是一个编码问题,而是一个数学问题......即使是你通常在知道解决方案之前就开始编码?
  • @justaname:那为什么它被标记为Java?您是否打算最终实现这是 java,并希望得到相关的答案? 还是不应该将其标记为 Java,因为问题不需要特定语言?
  • @Craig 是的,我的意思是最终在 java 中实现它,我标记它以防碰巧有可用的库。
  • @justaname 在这种情况下,这是一个令人惊讶的难题。我不知道通用 (K,D) 解决方案,但 Gene 的建议是将点放在超立方体/球体表面上的常用方法。

标签: java math geometry


【解决方案1】:

要了解计算最佳情况“并非微不足道”,请参阅论文 Dense Packings of Equal Spheres in a Cube,该论文解决了 3D 立方体中点的子情况:它具有精确解和最多 28 个点的“最知名”解。

它确实提供了一种算法来找到这些最佳间隔配置,他们称之为“随机台球”过程。但是我不知道这是否可以适应球体、更高维度或更多的点。

看起来更一般情况的某些方面可能会在书 Finite Packing and Covering 中介绍 - (我没有副本,因此无法验证。)

2D 案例更容易处理,您可以在维基百科上查看the squarethe circle 的更多详细信息。

【讨论】:

  • 啊,太好了,一篇相当不错的论文,尽管我在这个领域之外的经验,但实际上可读。不是我希望的情况,但它确实回答了我的问题。
  • @justaname 这就是我提出运动方程想法的原因。这听起来很复杂,但实际上会简化为大约一百行代码。我以前用过。
【解决方案2】:

这取决于您所说的“均匀”是什么意思。一种方法是随机定位这些点,然后使用牛顿运动方程的数值积分器模拟阻尼介质中的粒子运动,其中粒子和边界相互排斥。这当然允许任何边界形状。

【讨论】:

  • 至于解决方案,我认为您提到的任意形状都需要数值近似。但如果单位球体/立方体存在封闭形式,则此过程相当复杂。
  • > 这取决于您所说的“均匀”。我之前的定义错了,这样更好:最小化封装单个点的最大超球面。
  • 我刚刚尝试用负 G 和边界斥力修改我自己的 n 体模拟。我认为要使用这种方法,它必须非常仔细调整,否则你最终还是会得到一堆粒子。
  • 对此的一个很好的修改是通过粗略地划分您的区域然后将点放在每个网格元素的中心来设置您的起始值。如果您将网格设置为具有大致正确数量的元素,并且只是随机添加或删除值以获得正确的计数,您应该会获得更好的起始分布,这将导致更好的收敛。
  • 另外,您可能不希望牛顿运动,而是需要额​​外的阻力来迫使您的系统变得稳定,否则它将永远振荡。
【解决方案3】:

我不确定我是否完全理解您的问题,但这是我的尝试。

public static List<int[]> getEvenSpacedPoints(int x0, int x1, int y0,
        int y1, int z0, int z1, int samplePerSide) {

    List<int[]> list = new ArrayList<>();
    int xSpacing = (x1 - x0) / samplePerSide;
    int ySpacing = (y1 - y0) / samplePerSide;
    int zSpacing = (z1 - z0) / samplePerSide;

    for (int i = 0; i < samplePerSide; i++) {
        for (int j = 0; j < samplePerSide; j++) {
            for (int w = 0; w < samplePerSide; w++) {
                int xPoint = xSpacing * i;
                int yPoint = ySpacing * j;
                int zPoint = zSpacing * w;
                int[] point = new int[] { xPoint, yPoint, zPoint };
                list.add(point);
            }
        }

    }
    return list;
}

List<int[]> setOfSamplesFromCube = getEvenSpacedPoints(0, 10, 0, 10, 0,
            10, 5);
    for (int[] point : setOfSamplesFromCube) {
        String ret = "";
        for (int value : point) {
            ret += value + ",";
        }
        System.out.println(ret);
    }

输出:

0,0,0,
0,0,2,
0,0,4,
0,0,6,
0,0,8,
0,2,0,
0,2,2,
0,2,4,
0,2,6,
0,2,8,
0,4,0,
0,4,2,
0,4,4,
0,4,6,
0,4,8,
0,6,0,
0,6,2,
0,6,4,
0,6,6,
0,6,8,
0,8,0,
0,8,2,
0,8,4,
0,8,6,
0,8,8,
2,0,0,
2,0,2,
2,0,4,
2,0,6,
2,0,8,
2,2,0,
2,2,2,
2,2,4,
2,2,6,
2,2,8,
2,4,0,
2,4,2,
2,4,4,
2,4,6,
2,4,8,
2,6,0,
2,6,2,
2,6,4,
2,6,6,
2,6,8,
2,8,0,
2,8,2,
2,8,4,
2,8,6,
2,8,8,
4,0,0,
4,0,2,
4,0,4,
4,0,6,
4,0,8,
4,2,0,
4,2,2,
4,2,4,
4,2,6,
4,2,8,
4,4,0,
4,4,2,
4,4,4,
4,4,6,
4,4,8,
4,6,0,
4,6,2,
4,6,4,
4,6,6,
4,6,8,
4,8,0,
4,8,2,
4,8,4,
4,8,6,
4,8,8,
6,0,0,
6,0,2,
6,0,4,
6,0,6,
6,0,8,
6,2,0,
6,2,2,
6,2,4,
6,2,6,
6,2,8,
6,4,0,
6,4,2,
6,4,4,
6,4,6,
6,4,8,
6,6,0,
6,6,2,
6,6,4,
6,6,6,
6,6,8,
6,8,0,
6,8,2,
6,8,4,
6,8,6,
6,8,8,
8,0,0,
8,0,2,
8,0,4,
8,0,6,
8,0,8,
8,2,0,
8,2,2,
8,2,4,
8,2,6,
8,2,8,
8,4,0,
8,4,2,
8,4,4,
8,4,6,
8,4,8,
8,6,0,
8,6,2,
8,6,4,
8,6,6,
8,6,8,
8,8,0,
8,8,2,
8,8,4,
8,8,6,
8,8,8,

这包括起点(如果想省略,则从 1 开始循环)并且“简单”,因为我传递给它的立方体有很好的边可以被 5 整除,否则整数除法会破坏这一点,但你可以看到如何轻松更改它以返回双重列表。

我将开始尝试 D 维案例..

【讨论】:

    【解决方案4】:

    让我们考虑立方体,因为它更容易(我最初说容易,哈哈)。我认为这就是您想要的(3D 格式):

    一边的点数是n = floor(K1/D)。那么点之间的间距是 1 / (n - 1),假设角和边都包括在内。我打算为这种网格方法提供一些代码,但它非常难看,而且解决方案也不理想。

    【讨论】:

    • 这比电视直播更好!
    • 我正在尝试在立方体内部生成点,而不是在边界上。如果我明白你的意思。
    • @justaname 我已经包含了一张图片。你能确认这是你想要的吗?
    • 随着 D 变大,pow(floor(pow(K,1/D)),D) 和 K 之间的差异会成比例地变大。你怎么处理额外的积分? (例如如果 K=26, D=3, floor(pow(26,1/3)=2 那么你的网格只包含 8 个点,还有 18 个要分配)
    • 网格化方法不适用于一般的 K 和 D。即使在二维中,交错的行和列形成一个“蜂窝”,每个六角单元格中的中心点将在所有对之间有更好的间距点数比从矩形晶格中获得的点数多。
    猜你喜欢
    • 2019-01-21
    • 2019-06-29
    • 2013-03-30
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2017-09-01
    • 2018-01-25
    • 2016-07-13
    相关资源
    最近更新 更多