P ^ N Combinaisons with Integers(Kernel),如何生成它们?

时间:2015-03-05 14:09:22

标签: java math complexity-theory mathematical-optimization algebra

我的问题与几个月前我问过的问题几乎相同:

2^N Combinaisons with Integers (Kernel), how to generate them?

基本上,我想在内核中使用2 ^ N个组合,但是我推广了我的版本,现在它更复杂了:

我不再需要2个元素的每个可能组合的总和(模2),但我现在需要P元素的每个可能组合的总和(模P):O。

 N : the number of elements in kernel.
 M : the length of an element in the kernel.
 P : the dimension of my result.

 int[][] Kernel: 

        ....
        i   : 0 1 2 1 0 1 0 1 0 1 1 1 2 1 1 2 0 1 2 1 0 2 1 1 2  (length = M)
        i+1 : 1 2 1 0 1 2 0 2 0 1 0 1 2 0 2 1 0 1 0 1 1 0 2 0 1  (length = M)
        ....
        N   : ....

 with P = 3 (so value inside Kernel elements equals to {0,1,2}

我的目标(就像之前的2 ^ N组合一样)是为了产生所有可能性(所有P ^ N组合),他们会像:

1 * Kernel[0]
2 * Kernel[0]
....
P * kernel[0]
......
1 * Kernel[0] + 1 * Kernel[1]
1 * Kernel[0] + 2 * Kernel[1]
......
1 * kernel[0] + (P-1) * Kernel[1]
......
1 * kernel[0] + 1 * Kernel[1] ....(P elements) + 1 * Kernel[P]

我现在使用@pbabcdefp给出的版本 它仅适用于2个元素的总和(模2)并且我不知道如何使它适用于P元素的总和(模P)

public static boolean[][] combinations(boolean kernel[][]) {
    int n = kernel.length;
    int m = kernel[0].length;
    int p = 1 << n;
    boolean[][] temp = new boolean[p][m];
    for (int i = 0; i < p; i++)
        for (int j = 0; j < n; j++)
            if (((1 << j) & i) != 0)
                for (int k = 0; k < m; k++)
                    temp[i][k] ^= kernel[j][k];
    return temp;
}

与上一版本一样,不要介意内存成本,也不要介意这类阵列的复杂性,这只是一个理论案例。

提前感谢任何有关如何推广这种组合的想法的人。

致以最诚挚的问候,


以防万一:示例

int[][] Kernel : 

      [0] : 0 1 2 0 2 1 2 0
      [1] : 1 2 2 0 1 2 2 0

so we have : N equals to 2 ; M equals to 8 and P equals to 3 (values are included inside {0,1,2}
The result should be : 

 0 0 0 0 0 0 0 0 (the null element is always inside the result)

 0 1 2 0 2 1 2 0 (1x [0] % 3)
 1 2 2 0 1 2 2 0 (1x [1] % 3)
 0 2 1 0 1 2 1 0 (2x [0] % 3)
 2 1 1 0 2 1 1 0 (2x [1] % 3)
 0 0 0 0 0 0 0 0 (3x [0] % 3)
 0 0 0 0 0 0 0 0 (3x [1] % 3)
 1 0 1 0 0 0 1 0 (1x [0] + 1x [1] % 3)
 1 1 0 0 2 1 0 0 (2x [0] + 1x [1] % 3)
 2 2 0 0 1 2 0 0 (1x [0] + 2x [1] % 3)

我们以前在内核中有2个元素, 我们知道在新内核中有P ^ 2所以3 ^ 2 = 9个元素,我们只是生成它们(除了因此计算错误:D提前抱歉,但是计算结果为:D)

1 个答案:

答案 0 :(得分:1)

在数学上,这对应于使用n - 元组mod p的所有可能系数集来查找核向量的所有线性组合。它相当于mod p系数矩阵和p^n x n核矩阵之间的矩阵乘法n x m

p^n x n矩阵只是所有基数的行列表 - p数字,最多为p^n-1

我恐怕我不太了解Java,所以这里是C的答案,这可能足以让你复制和翻译。

#include <stdio.h>
#include <math.h> 

int main() {
  int p = 3; // base
  int n = 2, m = 8;   
  int kernel[2][8] = {{0, 1, 2, 0, 2, 1, 2, 0},
                      {1, 2, 2, 0, 1, 2, 2, 0}};

  int numRows = pow(p,n);
  int coeffs[numRows][n]; 
  int result[numRows][m]; 

  //convert the row numbers from base-10 to base-p   
  int num, row, q, div, remainder;
  for(row=0; row<numRows; row++) {
    num = row;
    for(q=n-1; q>=0; q--) {
      div = (int)pow(p,q);
      remainder = num % div;
      coeffs[row][q] = (num-remainder)/div;
      num = remainder;
    }
  }

  // now do the matrix multiplication
  int i,j,k;
  for(i=0; i<numRows ; i++) {
      for(j=0; j<m ; j++) {
          result[i][j] = 0;
          for(k=0; k<n; k++) {
              result[i][j] += coeffs[i][k]*kernel[k][j];
          }
          result[i][j] %= p;  // take result mod p
          printf("%d ",result[i][j]);
      }
      printf("\n");
  }

}

我得到以下输出:

0 0 0 0 0 0 0 0 
0 1 2 0 2 1 2 0 
0 2 1 0 1 2 1 0 
1 2 2 0 1 2 2 0 
1 0 1 0 0 0 1 0 
1 1 0 0 2 1 0 0 
2 1 1 0 2 1 1 0 
2 2 0 0 1 2 0 0 
2 0 2 0 0 0 2 0