将数字映射到N维网格/数组

时间:2010-12-23 12:03:48

标签: java math discrete-mathematics

让我们假设,例如,我有一个三维网格/数组,其中轴的运行范围是1到1000(或0到999等效)。这个数组有1000 ^ 3个元素。

我想使用Java以确定的方式将0到1000 ^ 3范围内的单个整数映射到此数组。优选地,该解决方案适用于任何尺寸N.

以下是此类函数的伪编码示例:

public Vector<int> nthElement( Vector<int> dims, int n )

因此,如果我将其称为nthElement([1000, 1000, 1000], 0),则会返回[0, 0, 0],而nthElement([1000, 1000, 1000], 1001)会返回[999, 1, 0]之类的内容。

解决方案应该是N维,而不是我的例子中的3。

4 个答案:

答案 0 :(得分:3)

这是正确的映射算法:

map([X, Y, Z, T, ...], N) = [
    N mod X, 
    N div X mod Y, 
    N div X div Y mod Z, 
    N div X div Y div Z (mod ...)?
    ...
]

或递归

map([X, Y, Z, T, ...], N) = [N mod X, map([Y, Z, T, ...], N div X)]

其中,div B为Floor(A / B)。

答案 1 :(得分:1)

你可以这样做:

a = Number % (1000 * 1000)
b = (Number / 1000) % 1000
c = Number / (1000 * 1000)

这是一个映射(唯一),你可以简单地做反向

注意2/3 = 0不是.6666

答案 2 :(得分:1)

检查这个

List<Integer> nthElement( List<Integer> dims, int n ){
    List<Integer> res = new ArrayList<Integer>(dims.size());
    for(Integer cur  : dims){
        if(n <= 0 ){
            res.add(0);
        } else {
            n -= cur;
            res.add(n >= 0 ? cur -1  : cur + n );
        }
    }
    return res;
}

UPD 用法示例

    //create list with 3 dimensions using Guava
    List<Integer> dims = ImmutableList.of(1000, 1000, 1000);
    //or with standard JDK
    //List<Integer> dims = new ArrayList<Integer>(3);dims.add(1000);dims.add(1000);dims.add(1000);

    System.out.println(nthElement(dims, 0));
    System.out.println(nthElement(dims, 1000));
    System.out.println(nthElement(dims, 1001));
    System.out.println(nthElement(dims, 2001));

将打印

    [0, 0, 0]
    [999, 0, 0]
    [999, 1, 0]
    [999, 999, 1]

答案 3 :(得分:0)

您可能正在寻找的是Cantor pairing function。它是为NxN定义的,因此您可以将其用于任意大的尺寸。如维基百科页面所述,它可以归纳为一个维数为n的数组,在你的情况下,n = 3就可以了。

上面的页面还解释了反转函数,因此您可以从给定的数字中获取数组中的坐标,这正是您想要的nthElement

当然,康托尔只定义了一种可能的方式来走过一个二维场。还有其他可能的步行,但这是最流行的方式。

编辑:我应该提一下,如果您的数组具有矩形尺寸,则Cantor配对功能将采用最大尺寸的尺寸。因此,相关的数字不再在您的数组中连续出现。 F.ex.大小为1000x2的数组将被视为1000x1000数组,与实际数组中的条目对应的数字将只是数字0..1000 * 1000的非连续列表。 但是,如果您的三个维度始终相同,则可以完全忽略这一点。

回应评论:逐行和Cantor配对只是走过矩阵空间的不同方式。 Cantor配对的一个优点是它是在自然数上定义的,因此如果您没有矩阵尺寸的精确值,或者矩阵随时间增长,也适用。