2014-12-24 21 views
5

(Merry Christmas btw ^^)2^N Combinaisons với số nguyên (hạt nhân), làm thế nào để tạo ra chúng?

Đây là vấn đề của tôi (trong JAVA) nhưng chắc chắn là một vấn đề về thuật toán và tôi không biết cách giải quyết nó:/ Vì vậy, đây là một ví dụ cung cấp thông tin, tất cả calculs của tôi là trong nhị phân, vì vậy 1 + 1 = 0)

let của tên biến:

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 : .... 

mục tiêu của tôi với đề tài điều, là để tạo ra tất cả các combinaison thể (để 2^N các yếu tố) và tôi muốn tạo chúng. Bằng cách tạo ra tôi muốn nói chính xác này:

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] 

Dưới đây là những gì tôi đã thành công để làm, nhưng nó không hoàn thành và tôi không biết làm thế nào để khái quát các calcul để làm việc với bất kỳ 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; 
} 

Edit:

Về một ví dụ, chúng ta hãy cung cấp cho này:

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) 

Vì vậy, đây là một ví dụ đơn giản (khá đặc biệt là giá trị, nếu bạn muốn lớn hơn, chỉ cần hỏi :))

Thậm chí nếu các mảng cuối cùng có vẻ là :) rất lớn đó là chính xác những gì tôi muốn tạo ra (không quan tâm đến bộ nhớ, nó chắc chắn sẽ không sao)

+1

bạn có thể đưa ra một ví dụ nhỏ – sashas

+0

Bạn nhận ra rằng bạn sẽ hết bộ nhớ khá nhanh chóng với điều này. Bạn chắc chắn không thể có N> 31, và M lớn hơn, nhanh hơn bạn sẽ hết bộ nhớ. – RealSkeptic

+0

Tôi hoàn toàn đồng ý với bạn @RealSkeptic, nhưng N sẽ không bao giờ cao hơn 20. Vì vậy, bộ nhớ sẽ không sao;) –

Trả lời

3

Tôi sẽ sử dụng boolean[][] thay vì int[][]. 0 có nghĩa là false, 1 có nghĩa là 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; 
} 
+0

Cảm ơn bạn! Tôi thích viết những thứ như thế. Chuc Giang Sinh vui vẻ. –

+0

Cảm ơn! Vâng, tôi có thể thấy rằng bạn chắc chắn không phải là người mới bắt đầu: D Chúc mừng giáng sinh cho bạn! –

+0

Sử dụng tốt '<<' và '^ =' để làm số học mô-đun cơ sở 2. – eigenchris

Các vấn đề liên quan