2017-07-03 24 views
1

對於GA需要兩種方法:尋找快速的方法來轉換布爾[]以格雷碼至BigInteger和反之亦然的Java

BigInteger greyToBigInteger(boolean[]){...} 

boolean[] bigIntegerToGrey(BigInteger){...} 

例如:

15 ---> {true,false,false,false} 
and 
{true,false,false,false} --> 15 

我不知道,如何讓這非常快。要轉換的最大數量是10^1125,所以對於一個數字,它的工作時間超過5分鐘,如果我這樣做的話,就像維基百科的例子。

+0

如果能結合每4個布爾在一起,你可以做一個簡短的查找表,生成一個十六進制數字爲每4布爾組合。現在只需將十六進制數字添加到字符串構建器中,並從生成的十六進制字符串中生成BigInteger。十六進制到BigInteger轉換是IME,速度非常快。 –

+0

@RudyVelthuis我找到一些方法來轉換BigInteger(灰色)<--> BigInteger(二進制)。我可以使用它們,但我需要首先轉換boolean [] <--> BigInteger,但我不確定它可以工作多快。 – Legion

+0

只收集16個布爾值,將它們轉換爲16位整數,將BigInteger(Gray)左移16,並添加16位整數。重複,直到完成。然後,您只需調用BigInteger(灰色) - > BigInteger(二進制)代碼即可!你知道如何將16個布爾變量(實際上是16位)轉換爲一個16位的整數,對嗎?或者如何將16位int轉換爲16位布爾值? –

回答

1

我寫了這段代碼,它運行得非常快,沒有任何特別的技巧 - 我的筆記本電腦上的它需要少於2毫秒將小於或等於10^1125的給定數字轉換爲灰背:

import java.math.BigInteger; 
import java.util.Random; 

public class GrayCode { 

    public static void main(String[] args) { 

     // actually 10^1125 is a number with max length of 3738 bits 
     int bitLength = new BigInteger("10").pow(1125).bitLength(); 
     System.out.println("10^1125 is a number with max bit length = " + bitLength); 
     new GrayCode().test(bitLength); 
    } 

    private void test(int bitLength) { 
     long totalTime = 0; 
     long numberOfTests = 1000; 

     for (int n = 0; n < numberOfTests; n++) { 
      // We don't include time needed for generation of a number 
      BigInteger binary = generateBigInteger(bitLength); 

      // here we start measuring execution time of single conversion 
      long start = System.currentTimeMillis(); 

      // The conversion to gray and back 
      boolean[] gray = bigIntegerToGrey(binary); 
      BigInteger back = grayToBigInteger(gray); 

      // we sum up the conversion times to totalTime per this test suite 
      totalTime += System.currentTimeMillis() - start; 
     } 
     System.out.println("We have run a "+numberOfTests+" tests, for a random numbers of "+bitLength+" bit length to convert to gray code and back to binary"); 
     System.out.println("The total execution time of this test was "+totalTime+" milliseconds, giving average convesion time of " + totalTime/1000d + " ms per single test "); 

    } 

    private BigInteger grayToBigInteger(boolean[] booleanGray) { 
     BigInteger input = booleanToBigInteger(booleanGray); 
     return grayToBinary(input); 
    } 

    private boolean[] bigIntegerToGrey(BigInteger binary) { 
     BigInteger gray = binaryToGray(binary); 
     return bigIntegerToBooleanArray(gray); 
    } 

    public boolean[] bigIntegerToBooleanArray(BigInteger number) { 
     char[] binary = number.toString(2).toCharArray(); 
     boolean[] binaryBoolean = new boolean[binary.length]; 
     for (int n = 0; n < binary.length; n++) { 
      if (binary[n] == '1') { 
       binaryBoolean[n] = true; 
      } 
     } 
     return binaryBoolean; 
    } 

    private BigInteger generateBigInteger(int numBits) { 
     Random rnd = new Random(); 
     BigInteger number = new BigInteger(numBits, rnd); 
     return number; 
    } 

    public BigInteger booleanToBigInteger(boolean[] binary) { 
     StringBuilder sb = new StringBuilder(); 
     for (boolean b : binary) { 
      sb.append(b ? '1' : '0'); 
     } 
     return new BigInteger(sb.toString(), 2); 
    } 

    public BigInteger binaryToGray(BigInteger num) { 
     return num.xor(num.shiftRight(1)); 
    } 

    public BigInteger grayToBinary(BigInteger num) { 
     BigInteger mask; 
     for (mask = num.shiftRight(1); mask.compareTo(BigInteger.ZERO) != 0; mask = mask.shiftRight(1)) { 
      num = num.xor(mask); 
     } 
     return num; 
    } 

} 

結果:

10^1125 is a number with max bit length = 3738 
We have run a 1000 tests, for a number of 3738 bit length to convert to gray code and back to binary 
The total execution time of this test was 1828 milliseconds, giving average convesion time of 1.828 ms per single test 
相關問題