2014-12-24 19 views
5

(Mutlu Noeller btw ^^) İşte 2^N Integers ile Kombinanslar (Kernel), nasıl üretilir?

(JAVA) benim sorundur ama kesinlikle algoritmik bir sorun var ve bunu çözmek için nasıl bilmiyorum:/ Yani burada öyle, bir örnekle (sadece bilgi için, bütün calculs Binary, yani 1 + = 0)

diyelim adı değişkenleri 1: tezler şeylerle

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

Amacım, tüm olası combinaison (yani 2^N üretmek için elemanları) ve bunları oluşturmak istiyorum.

İşte
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] 

Zaten başarı ne var, ama ...

o tam değil ve herhangi N ile çalışmak amacıyla Calcul genellemek nasıl bilmiyorum: By tam olarak bu demek üretmek
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; 
} 

Düzenleme: bir örnek Hakkında

, bunu verelim:

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) 

Yani bu

sonunda dizi İstiyorum aynen ÇOK BÜYÜK :) gibi görünüyor olsa bile (daha büyük isterseniz oldukça özellikle değerler, sadece :) sormak) basit bir örnek oluştur (bellekle ilgili bir şey yapma, her şey yoluna girecek).

+1

Küçük bir örnek verebilir misiniz? – sashas

+0

Bunun ile oldukça hızlı bir şekilde bellek tükendiğinizi anlıyorsunuz. Kesinlikle N> 31'e sahip olamazsınız, ve daha büyük olan M ise, hafızanız bittiğinden daha çabuk bitecek. – RealSkeptic

+0

Evet, tamamen sana katılıyorum @RealSkeptic, ama N asla daha yüksek olmayacak 20. Yani hafıza tamam olacak;) –

cevap

3

int[][] yerine boolean[][] kullanacağım. 0, false, 1, true anlamına gelir.

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

Teşekkür ederiz! Böyle şeyler yazmayı severim. İyi Noeller. –

+0

Teşekkürler! Evet, kesinlikle acemi olmadığınızı görüyorum: D Size de iyi Noeller! –

+0

base-2 modüler aritmetiği yapmak için '<<' ve '^ =' yi kullanın. – eigenchris