我正在尝试生成一组均匀分布在固定空间内的 K 点,我认为单位球体或立方体是最简单的。对于二维来说,这很容易,但不幸的是,当我们上升到任意维度 D 时,这要困难得多。
我认为这是在“准蒙特卡罗方法”中完成的,但我一直找不到公式,甚至找不到关于这是否是一个易于处理的问题的声明。任何输入将不胜感激。
要了解计算最佳情况“并非微不足道”,请查看论文Dense Packings of Equal Spheres in a Cube该论文解决了 3D 立方体中点的子情况:它具有精确解和“最知名”解,最多仅 28点。
它确实提出了一种用于找到这些最佳间隔配置的算法,他们称之为“随机台球”程序。但是我不知道这是否可以适应球体、更高维度或更多点。
看起来更一般的情况的某些方面可能包含在有限包装和覆盖一书中- (我没有副本,所以无法验证。)
这取决于您所说的“均匀”是什么意思。一种方法是随机定位这些点,然后使用牛顿运动方程的数值积分器模拟阻尼介质中的粒子运动,其中粒子和边界相互排斥。这当然允许任何边界形状。
我不确定我是否完全理解你的问题,但这是我的尝试。
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 维案例..
让我们考虑立方体,因为它更容易(我最初说容易,哈哈)。我认为这是您想要的(3D 格式):
边上的点数为 n = floor(K 1/D )。那么点之间的间距是 1 / (n - 1),假设角和边都包括在内。我打算为这种网格方法提供一些代码,但它非常难看,而且解决方案也不理想。