Commit 31d72a87 by Fokion Zervoudakis

### Add Von Neumann randomness extractor.

parent 9644198b
 package rand; import annotation.PseudoRandom; import java.util.HashMap; import java.util.Random; class RandExtractor { @FunctionalInterface interface Coin { int tossBiased(); } /** Implements the Von Neumann randomness extractor for producing a uniform distribution from nonuniform input.

For example, the probability of deriving heads/tails from a coin toss is {@code P(H)=p} and {@code P(T)=1-p=q}.

If a biased coin with {@code p=0.6} is tossed twice and cases {@code HH} and {@code TT} are discarded, then {@code HT} and {@code TH} will occur with equal probabilities:

• {@code P(HH)=P(H)xP(H)=0.36}
• {@code P(TT)=P(T)xP(T)=0.16}
• {@code P(HT)=P(H)xP(T)=(1-P(HH)+P(TT))/2=0.24}
• {@code P(TH)=P(T)xP(H)=(1-P(HH)+P(TT))/2=0.24}

Asymptotic analysis:

• time_worst=O(1/pq)
• space_worst=O(1)
@param C a biased coin @return a uniformly distributed pseudo random number */ @PseudoRandom static int tossUnbiased(Coin C) { while (true) { int m = C.tossBiased(), n = C.tossBiased(); if (m != n) { return m; } } } private static int rand(Random R, int min, int max) { return R.nextInt((max - min) + 1) + min; } public static void main(String[] args) { var max = 10000; var R = new Random(); Coin C = () -> rand(R, 0, 100) < 80 ? 0 : 1; var M1 = new HashMap(); var M2 = new HashMap(); for (var i = 0; i < max; i++) { int m = C.tossBiased(), n = tossUnbiased(C); M1.put(m, M1.containsKey(m) ? M1.get(m) + 1 : 1); M2.put(n, M2.containsKey(n) ? M2.get(n) + 1 : 1); } for (var E : M1.entrySet()) { M1.put(E.getKey(), E.getValue() / max); } for (var E : M2.entrySet()) { M2.put(E.getKey(), E.getValue() / max); } System.out.println(M1); System.out.println(M2); } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!