使用离散输入变量在自然域中进行多对一映射?

时间:2017-10-25 09:05:00

标签: c++ math many-to-one

我想找到一个映射f:X - > N,具有不同维度的多个离散自然变量X,其中f在0到所有维度的乘法之间产生唯一的数字。例如。假设X = {a,b,c},尺寸为| a | = 2,| b | = 3,| c | = 2. f应该产生0到12(2 * 3 * 2)。

a b c | f(X)
0 0 0 | 0
0 0 1 | 1
0 1 0 | 2
0 1 1 | 3
0 2 0 | 4
0 2 1 | 5
1 0 0 | 6
1 0 1 | 7
1 1 0 | 8
1 1 1 | 9
1 2 0 | 10
1 2 1 | 11

当所有尺寸相等时,这很容易。假设二进制例如:

f(a=1,b=0,c=1) = 1*2^2 + 0*2^1 + 1*2^0 = 5

使用这个天真的不同尺寸,我们会得到重叠的值:

 f(a=0,b=1,c=1) = 0*2^2 + 1*3^1 + 1*2^2 = 4
 f(a=1,b=0,c=0) = 1*2^2 + 0*3^1 + 0*2^2 = 4

计算速度快的函数是首选,因为我打算在C ++中使用/实现它。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:1)

好的,这里最重要的部分是数学和算法。您有大小可变的尺寸(从最少订单到最多一个)d 0 ,d 1 ,...,d n 。元组(x 0 ,x 1 ,...,x n ),其中x i < d i 将代表以下数字:x 0 + d 0 * x 1 + ... + d 0 * d 1 * ... * d n-1 * x n

在伪代码中,我会写:

result = 0
loop for i=n to 0 step -1
  result = result * d[i] + x[i]

要在C ++中实现它,我的建议是创建一个类,其中构造函数将获取维度和维度本身(或简单地包含维度的vector<int>),以及接受的方法包含值的数组或相同大小的向量。 Optionaly,您可以控制没有输入值大于其维度。

可能的C ++实现可能是:

class F {
    vector<int> dims;

public:
    F(vector<int> d) : dims(d) {}

    int to_int(vector<int> x) {
        if (x.size() != dims.size()) {
            throw std::invalid_argument("Wrong size");
        }
        int result = 0;
        for (int i = dims.size() - 1; i >= 0; i--) {
            if (x[i] >= dims[i]) {
                throw std::invalid_argument("Value >= dimension");
            }
            result = result * dims[i] + x[i];
        }
        return result;
    }
};