Random Number Generation

A

adrian.bartholomew

public Deck() {
reset();
try {
random = SecureRandom.getInstance(RANDOM_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
throw new NoSecureRandomException(e);
}
}

public final void reset() {
cards.clear();
cards.addAll(Card.allCards);
}

public void shuffle() {
for (int i=0; i<10; i++) {
random.setSeed(System.currentTimeMillis());
Collections.shuffle(cards, random);
}
}
......

The above code works, except that after a while i begin to see the
same patterns in hands dealt.
I can predict what the other hands would hold and can continue with
correct anticipatory play.
This should not be.
As you can see, I have even tried shuffling 10 times each time.

Any help would be appreciated.
 
Z

zerg

Matt said:
SecureRandom (and Random) are pseudo-random and will reproduce the same
sequence for the same seed. Most likely your shuffle loop is so fast that
the clock you're using for seeds does not change between iterations. Many
PC-based millisecond clocks are only accurate to about 3 or 13 milliseconds,
which is actually a very long time for fitting in calculations. Secure
random includes a good pre-randomizer based on thread scheduling so try not
setting a seed at all or set the seed once when the PRNG is created.

There's also System.nanoTime(), which is supposed to have a far higher
resolution than currentTimeMillis().
 
J

Joshua Cranmer

public void shuffle() {
for (int i=0; i<10; i++) {
random.setSeed(System.currentTimeMillis());
Collections.shuffle(cards, random);
}
}

From experience, I can tell you that you've shuffled at most twice (if
you're lucky), and probably once, assuming you have no more than 52
cards. A millisecond is an awful long time for a computer, and the
method does not in general have millisecond-scale resolution (10 and 16
are common, IIRC).

Resetting the seed so rapidly kills your entropy big time. Even if each
shuffle takes 1 ms, you'd essentially only see changes in the last 4-6
bits, throwing away several bits of good information. Don't reset the
seed, you don't need to.

Also, note that, although using the current time in milliseconds might
be fair entropy across invocations, using it multiple times in the same
invocation hurts entropy. The random number generator, without a seed,
will generate its own without any problems, and it does so in a far
smarter way.
 
U

Uwe Schmitt

    public Deck() {
        reset();
        try {
            random = SecureRandom.getInstance(RANDOM_ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new NoSecureRandomException(e);
        }
    }

    public final void reset() {
        cards.clear();
        cards.addAll(Card.allCards);
    }

    public void shuffle() {
        for (int i=0; i<10; i++) {
            random.setSeed(System.currentTimeMillis());
            Collections.shuffle(cards, random);
        }
    }

You should call setSeed only once before shuffling. You can move it
outside the for loop, or into your constructor.

Greetings, Uwe
 
A

adrian.bartholomew

From experience, I can tell you that you've shuffled at most twice (if
you're lucky), and probably once, assuming you have no more than 52
cards. A millisecond is an awful long time for a computer, and the
method does not in general have millisecond-scale resolution (10 and 16
are common, IIRC).

Resetting the seed so rapidly kills your entropy big time. Even if each
shuffle takes 1 ms, you'd essentially only see changes in the last 4-6
bits, throwing away several bits of good information. Don't reset the
seed, you don't need to.

Also, note that, although using the current time in milliseconds might
be fair entropy across invocations, using it multiple times in the same
invocation hurts entropy. The random number generator, without a seed,
will generate its own without any problems, and it does so in a far
smarter way.

Thanks guys. So you're saying that I DONT even need a seed? And that
the seed itself is what's causing my predictability?
 
J

Joshua Cranmer

Thanks guys. So you're saying that I DONT even need a seed? And that
the seed itself is what's causing my predictability?

More accurately, the problem is that you are reseeding unnecessarily and
in such a manner that you are reseeding with the same value over and
over again under the illusion that it will increase randomness.
 
R

Roedy Green

Thanks guys. So you're saying that I DONT even need a seed? And that
the seed itself is what's causing my predictability?

The only time you use a seed is if you want reproducibility. This can
be helpful in debugging or when you want others to get the exact same
results as you when they rerun.

If you want random effects, don't use a seed at all. The class will
start itself with a clever seed based on time and perhaps other random
factors.

Then there is something in between -- picking a "random" quote of the
day, which should pick the same quote any time the computation is done
that day. I talk about that too at
http://mindprod.com/jgloss/pseudorandom.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top