Java 带整数的P^N组合(内核),如何生成它们?

Java 带整数的P^N组合(内核),如何生成它们?,java,math,complexity-theory,mathematical-optimization,algebra,Java,Math,Complexity Theory,Mathematical Optimization,Algebra,我的问题与我几个月前提出的问题几乎相同: 基本上,我希望在内核中有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:

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

基本上,我希望在内核中有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)

我们以前在内核中有两个元素,
我们知道在新内核中有P^2 so 3^2=9个元素,我们只是生成它们(除了计算错误:D,很抱歉,但计算是写的:D)

从数学上讲,这相当于使用所有可能的系数集,即

n
-元组
mod P
,来查找内核向量的所有线性组合。它相当于系数矩阵和核矩阵之间的矩阵乘法

p^n x n
矩阵只是一个列式列表,其中列出了截至
p^n-1
的所有基本
p
数字

恐怕我对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");
  }

}

@如果你对如何推广你的方法有任何想法,我会调用master=D:DJust,所以我很清楚,“内核”向量是由用户指定的,内核向量可以是包含从0到P-1的整数元素的任意向量?老实说,核向量由其他函数计算:)但假设它是整数元素介于0和(P-1)之间的任意向量:)其他函数对组合没有任何影响;)是的,可以是N个元素,它们都是0到(P-1)之间的随机数。在你的例子中,你还需要提到
2x[0]+2x[1]%3
的情况,对吗?无论如何,这是一个有趣的问题。是的,每一个系数小于P;)的组合这正是我想要的:)非常感谢@Igenchris!:)事实上,C和Java基本上是一样的,我会设法:)@ValentinMontmirail很高兴你发现它很有用。出于好奇,这是不是有什么特别的用途?或者这只是一个数学上的好奇?嗯:D,有件很有趣的事,我们和一个数学朋友一起发现,有一种代数方法可以解决这个问题的广义形式。因此,我们不再使用5*5和2种颜色:)而是使用N*M和P种颜色:)我们的解决方案+内核中的一个元素可以为我们提供一个新的解决方案。对于所有的线性组合,我们现在在这个游戏中有了所有可能的解决方案,所以最佳的解决方案(在按下的灯光数量上);)@瓦伦丁·蒙特米拉尔非常有趣!我经常想知道那个游戏的数学解。我从来没有想过用线性代数来描述它。令人惊叹的!你明白了;)这正是目标:)。有了这个表示,它允许N*M,而不仅仅是5×5的情况,它允许中间的洞,我们可以选择不同于“最后每个开关关闭”的东西:所以,用不同的颜色,它创建游戏。“首先,你有一面法国国旗,从一种颜色到另一种颜色有一些规则,试着把棋盘换成意大利国旗”,这类东西:P,矩阵上有一些规则,决定我们到底想要什么是可能的,等等……)
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)
#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