-2

What is the easiest and quickest way to generate N (let's say 50,000) random unique sequences of length L (let's say 1000) containing 1s and 0s in java? I need this to be a pseudo random generator - Given a certain seed as input, the program should always result in generating the same sequences no matter how many times it's run.

This edit is for the downvoters of this question - random.nextInt() or random.nextDouble() gives me an integer or double value, but I need a sequence of 1s and 0s. If I need a sequence of 1s and 0s corresponding to the random integer generated from random.nextInt() I need to convert that to a binary array? And I need to do this 50,000 times? That's 50,000 * 32 ? I was wondering if there is a faster approach.And that's the purpose of this question.

David Pérez Cabrera
  • 4,960
  • 2
  • 23
  • 37
brisbeck
  • 19
  • 3
  • 1
    Possible duplicate of [Java Random Numbers Using a Seed](http://stackoverflow.com/questions/12458383/java-random-numbers-using-a-seed) – Kevin L Aug 21 '16 at 13:27
  • 1
    This is an interesant question, please post you first try! – David Pérez Cabrera Aug 21 '16 at 13:34
  • 1
    random.nextInt() or random.nextDouble() gives me an integer or double value, but I need a sequence of 1s and 0s. If I need a sequence of 1s and 0s corresponding to the random integer generated from random.nextInt() I need to convert that to a binary array? And I need to do this 50,000 times? That's 50,000 * 32 ? I was wondering if there is a faster approach. – brisbeck Aug 21 '16 at 13:34
  • 1
    `random.next(1)` or `random.nextInt(1)` will return 0 or 1 as int. However this wont be very efficient. It is much better to request byte[] b = new byte[len/8]; random.nextBytes(b);` (or only request them if needed and not store 1000 of them). – eckes Aug 21 '16 at 14:45
  • An array of integers is also an array of bits, if that's how you treat it. – harold Aug 21 '16 at 15:12

3 Answers3

1

The base algorithm can be enough:

With n = 50000 and l = 1000 the collision rate is near to zero.

public static void main(String args[]) throws Exception {
    int n = 50000;
    int l = 1000;
    long seed = 0L;
    for (BitSet bitSet : createSequeces(n, l, seed)) {
        for (int i = 0; i < l; i++) {
            System.out.print(((bitSet.get(i)) ? "0" : "1"));
        }
        System.out.println();
    }
}

public static Set<BitSet> createSequeces(int n, int length, long seed ) {
    // check 2^length < n
    Set<BitSet> set = new HashSet<>();
    Random rand = new Random(seed);
    while (set.size() < n) {
        set.add(createRandom(rand, length));
    }
    return set;
}

private static BitSet createRandom(Random rand, int length) {
    BitSet secuence = new BitSet(length);
    for (int i = 0; i < length; i++) {
        secuence.set(i, rand.nextBoolean());
    }
    return secuence;
}
David Pérez Cabrera
  • 4,960
  • 2
  • 23
  • 37
  • I would construct the BitSet from a byte[] array (requested in a single operation from Random), this cuts down invocations tremendously.`BitSet.valueOf(b)`. If the length is not a multiple of 8 bits, I would just round up. – eckes Aug 21 '16 at 14:48
  • Also, just wondering if this would be deterministic? Given a starting seed, the sequences generated should be same. – brisbeck Aug 21 '16 at 14:49
  • Yes the seeding should happen outside the createSequence() – eckes Aug 21 '16 at 14:50
1

You could generate a random string of hex digits, [0..9, A..F] and convert the string to binary at the end. 1,000 binary digits is 250 hex digits.

If you want the 1,000 bits guaranteed unique then use simple steganography hide a counter in the sequence. 50,000 is 0xC350, which is four hex digits in the 250 you will pick. Randomly pick 246 hex digits, and insert (not replace) the four hex digits of a counter [0x0001 -> 0xC350] in, say, positions 31, 96, 142 and 206.

In pseudocode:

function randomBinary(counter)

  hexString <- ""

  for i in [1..250]
    if (i = 31) hexString.append(first hex digit of counter)
    else if (i = 96) hexString.append(second hex digit of counter)
    else if (i = 142) hexString.append(third hex digit of counter)
    else if (i = 206) hexString.append(fourth hex digit of counter)
    else hexString.append(randomHexDigit())
  endfor

  return toBinary(hexString)

endfunction

The output is guaranteed unique if the counter supplied is unique. A repeated counter will probably produce unique output, but that is not guaranteed. The simple steganography is not cryptographically secure, so do not use this method if you want cryptographic security.

rossum
  • 15,344
  • 1
  • 24
  • 38
0

Initialize the random generator with the seed, then from there do something as simple as this:

String myString = "";
double toDetermine = random.nextDouble();
if(toDetermine < 0.5) {
    myString+="1" }
else { 
    myString+="0"; }
appills
  • 172
  • 1
  • 14