【问题标题】:P^N Combinaisons with Integers (Kernel), how to generate them?P^N 与整数(内核)的组合,如何生成它们?
【发布时间】:2015-03-05 14:09:21
【问题描述】:

我的问题和我几个月前问的几乎一样:

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)

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

【问题讨论】:

  • @stackoverflow.com/users/3973077/pbabcdefp 如果您对如何推广您的方法有任何想法,我召唤大师=D:D
  • 我很清楚这一点,“内核”向量由用户指定,内核向量可以是任意向量,整数元素从 0 到 P-1?
  • 好吧,老实说,内核向量是由其他函数计算的 :) 但是假设它是整数元素介于 0 和 (P-1) 之间的任意向量 :) 其他函数没有对组合有任何影响;)所以是的,可以是N个元素,它们都是0到(P-1)之间的随机元素
  • 另外,在您的示例中,您还需要提及2x [0] + 2x [1] %3 案例,对吗?无论如何,有趣的问题。
  • 是的,每个组合都带有一个系数

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


【解决方案1】:

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

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

【讨论】:

  • 这正是我想要的 :) 非常感谢@eigenchris! :) 确实 C 和 Java 基本相同,我会管理 :)
  • @ValentinMontmirail 很高兴您发现它很有用。出于好奇,这是专门用于某些事情的吗?还是只是出于数学上的好奇心?
  • 嗯 :D 这是因为一些很有趣的事情,我们和一位数学朋友发现有一种代数方法可以解决en.wikipedia.org/wiki/Lights_Out_%28game%29 的广义版本。所以不是 5*5 有 2 种颜色 :) 我们现在有 N*M 和 P 颜色 :) 并且我们的解决方案 + 内核中的一个元素可以给我们一个新的解决方案。有了所有线性组合,我们现在有了这个游戏中所有可能的解决方案,所以最优的一个(按光的数量);)
  • @ValentinMontmirail 非常有趣!我经常想知道那个游戏的数学解决方案。我从来没有想过用线性代数这样来描述它。太棒了!
  • 你明白了 ;) 这正是我们的目标 :)。有了这种表示,它允许 N*M 而不仅仅是 5*5 的情况,它允许中间有洞,我们可以选择想要不同于最后的“每个开关都关闭”的东西 :) 所以用不同的颜色创建游戏就像“你首先有一面法国国旗,有一些规则可以从一种颜色变成另一种颜色,试着把棋盘换成意大利国旗”,这样的事情:P 并且矩阵上有一些规则确定我们最终想要的是否可能,等等...... ;)
猜你喜欢
  • 2015-02-22
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 2019-06-22
  • 2017-07-10
  • 1970-01-01
相关资源
最近更新 更多