Java 在没有存储所有可能坐标的情况下,通过三维空间中的所有点移动

Java 在没有存储所有可能坐标的情况下,通过三维空间中的所有点移动,java,algorithm,math,multidimensional-array,shuffle,Java,Algorithm,Math,Multidimensional Array,Shuffle,我正在编程一个三维细胞自动机。我现在在每一代中迭代的方式是: 创建三维空间中所有可能坐标的列表 洗牌名单 遍历列表,直到访问了所有坐标 转到2 代码如下: 我有一个简单的3整数结构 public class Coordinate { public int x; public int y; public int z; public Coordinate(int x, int y, int z) {this.x = x; this.y = y; this.z = z

我正在编程一个三维细胞自动机。我现在在每一代中迭代的方式是:

  • 创建三维空间中所有可能坐标的列表
  • 洗牌名单
  • 遍历列表,直到访问了所有坐标
  • 转到2
  • 代码如下:

    我有一个简单的3整数结构

    public class Coordinate
    {
        public int x;
        public int y;
        public int z;
    
        public Coordinate(int x, int y, int z) {this.x = x; this.y = y; this.z = z;}
    }
    
    然后在某个时候我会这样做:

    List<Coordinate> all_coordinates = new ArrayList<>();
    [...]
    for(int z=0 ; z<length ; z++)
    {
        for(int x=0 ; x<diameter ; x++)
        {
            for(int y=0 ; y<diameter ; y++)
            {
                all_coordinates.add(new Coordinate(x,y,z));
            }
        }
    }
    
    private void next_generation() 
    { 
        Collections.shuffle(all_coordinates);
        for (int i=0 ; i < all_coordinates.size() ; i++) 
        {
            [...]
        }
    }
    
    列出所有坐标=新的ArrayList();
    [...]
    
    对于(int z=0;z一种方法是首先将三维坐标映射到一个一维。假设三维尺寸为X、Y和z。因此,X坐标从0到X-1,以此类推。整个空间的大小为
    X*Y*z
    。我们称之为
    s

    要将3-空间中的任何坐标映射到1-空间,请使用公式
    (x*x)+(Y*Y)+z

    当然,一旦生成数字,就必须转换回3-空间。这是一个简单的问题,可以反转上面的转换。假设
    coord
    是1-空间坐标:

    x = coord/X
    coord = coord % X
    y = coord/Y
    z = coord % Y
    
    现在,通过使用单个维度,您已经将问题简化为以伪随机顺序生成从0到S的所有数字,而无需重复

    我知道至少有三种方法可以做到这一点。最简单的方法是使用a,如我在这里所示:

    生成所有数字后,通过为乘法逆计算选择不同的
    x
    m
    值来“重新洗牌”列表

    在特定范围内创建非重复伪随机序列的另一种方法是使用。我没有现成的示例,但我已经使用了它们。要更改顺序(即重新洗牌),请使用不同的参数重新初始化生成器

    您可能还对以下问题的答案感兴趣:。该用户只查找了1000个数字,因此他可以使用一个表,而接受的答案反映了这一点。其他答案包括LFSR,以及设计有特定句点的

    我提到的所有方法都不需要维护很多状态。无论您的范围是20还是20000000,您需要维护的状态量都是恒定的


    请注意,我上面提到的所有方法都提供伪随机序列。它们不是真正的随机序列,但它们可能足够接近随机序列以满足您的需要。

    洗牌必须有多好?例如,您可以使用随机素数迭代它们-例如,用x=(x+p)替换x++%diameter.@cpp初学者它应该尽可能统一。这个方法叫什么名字?它有名字吗?这样我可以进一步研究吗?除了模运算之外,我不认为它有一个特定的名字。@cpp初学者很酷,认为它可能有一个像Fisher–Yates shuffling3这样的特定名字。为什么需要随机洗牌?(怎么可能或完成它呢?回顾过去,3D到1D的映射看起来如此明显,这很可能是最可行的方式。感谢Jim和@Kovalainen的全面回答,你不能也使用相同的整数映射函数(在回答中称为“伪随机序列”)每个x、y和z维都是单独的,而不是先将它们转换成一个空间?当然可以,但是你要维护三个独立的伪随机数生成器。这不一定是件坏事,但我更喜欢转换成一维,只使用一个。不过,你确实提出了一个有趣的观点。我要讲一个对我的答案进行补充。@Kovalainen:请参阅我的“附加信息”,它提供了另一个选项。@•㪞דרקן(和@jim mischel)这是一个有趣的想法,但如果我没有正确理解它,它仍然会以某种顺序遍历3D空间,对吗?例如,在您的示例代码中,它将遍历整个“切片”(如中所示,给定Z坐标中的每个X,Y对)然后移动到下一个。