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

(顺便说一句圣诞快乐^^)

这是我的问题(在 JAVA 中),但这绝对是算法问题,我不知道如何解决:/ 所以这里有一个例子(仅供参考,我所有的计算都是二进制的,所以 1+1 = 0)

让我们命名变量:

  N : the number of elements in kernel.
  M : the length of an element in the kernel.

  int[][] Kernel: 

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

我对这些东西的目标是生成所有可能的组合(所以 2^N 个元素) 我想生成它们。 通过生成我的意思是这样的:

    Result[0]     = 0 0 0 0 0 0 0 0 0 0 0 0 0
    Result[1]     = Kernel[0]
    Result[2]     = Kernel[1]
    ....
    Result[i]     = Kernel[i-1]
    Result[N-1]   = Kernel[N-2]

    Result[N]     = Kernel[0] + Kernel[1]
    Result[N+1]   = Kernel[0] + Kernel[2]
    Result[N+i]   = Kernel[0] + Kernel[i]
    Result[2N-1]  = Kernel[0] + Kernel[N-1]
    ....
    Result[I]     = Kernel[0] + Kernel[1] + Kernel[2]
    Result[I+1]   = Kernel[0] + Kernel[1] + Kernel[i]
    Result[I+J]   = Kernel[0] + Kernel[1] + Kernel[N-1]
    ....
    Result[2^N+1] = Kernel[0] + Kernel[1] + ... + Kernel[i] + ... + Kernel[N-1]

这是我已经成功做的事情,但它并不完整,我不知道如何概括计算以便与任何 N 一起工作......

public static int[][] combinaisons(int[][] kernel) {

    /* if the kernel is empty, there is no possible combinaison */
    if(kernel.length == 0) return kernel;

    /* We allocate the good number of space... */
    int[][] result = new int[(int) (Math.pow(2, noyau.length)+1)][];

    /* Every element in result has the same length as in kernel's elements. */
    for(int i = 0; i < resultat.length; i++) {
        result[i] = new int[kernel[0].length];
    }

    /* The first element of result has to be only 0 0 0 0 0 0 0 */
    for(int j = 0; j < kernel[0].length; j++) {
        result[0][j] = 0;
    }

    /* We rewrite the element of kernel because they are a part of the solution... */
    for(int i = 0; i < kernel.length; i++) {
        for(int j = 0; j < kernel[i].length; j++) {
            result[i+1][j] = kernel[i][j];
        }
    }


    /* 
       I managed to do it when it's the sum of only 2 elements, 
       but it has to be with 3, 4 ... N-1 :/ 
    */
    for(int i = 0; i < kernel.length; i++) {
        for(int j = 0; j < kernel[i].length; j++) {
            for(int k = i+1; k < kernel.length; k++) {

                result[k*kernel.length+i][j] = (kernel[i][j]+kernel[k][j])%2;

            }
        }
    }

    return result;
}

编辑:

举个例子吧:

 N = 2 
 M = 4 
 Kernel: 
      0 1 1 0
      1 0 0 1 

In result I want: 
      0 0 0 0 
      0 1 1 0 
      1 0 0 1 
      1 1 1 1 (the sum of the 2 elements in Kernel) 

所以这是一个简单的例子(非常特别的值,如果你想要更大,请问:))

即使最后的数组看起来非常大 :) 这正是我想要生成的(不用关心内存,它肯定没问题)

【问题讨论】:

  • 你能举个小例子吗
  • 您确实意识到这样做会很快耗尽内存。你当然不能让 N > 31,而且 M 越大,内存耗尽的速度就越快。
  • 好吧,我完全同意你的观点@RealSkeptic,但 N 永远不会高于 20。所以内存会没问题 ;)
  • 这看起来像是个问题,不管你怎么做。这个是来做什么的?也许我们可以帮助您找到一种无需显式构造这个庞大数组的方法。还要考虑到您正在计算 M 位异或,如果 M 为 64 或更小,您可以省去很多麻烦。
  • 关于这个例子,让我们给出这个: N = 2 M = 4 Kernel: 0 1 1 0 ; 1 0 0 1 ;结果我想要: 0 0 0 0 ; 0 1 1 0 ; 1 0 0 1 ; 1 1 1 1 ; (内核中2个元素的总和)所以这是一个简单的例子(非常特别的值,如果你想要更大,请问:))

标签: java algorithm math for-loop


【解决方案1】:

我将使用boolean[][] 而不是int[][]0 表示false1 表示true

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;
}

【讨论】:

  • 谢谢!我喜欢写这样的东西。圣诞快乐。
  • 谢谢!是的,我知道你绝对不是初学者 :D 祝你圣诞快乐!
  • 很好地使用 &lt;&lt;^= 进行 base-2 模运算。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-16
  • 2010-12-19
  • 2013-08-17
相关资源
最近更新 更多