2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,10 +1,13 @@
|
|||
Given a weighted one bit generator of random numbers where the probability of a one occuring, <math>P_1</math>, is not the same as <math>P_0</math>, the probability of a zero occuring, the probability of the occurrence of a one followed by a zero is <math>P_1</math> × <math>P_0</math>. This is the same as the probability of a zero followed by a one: <math>P_0</math> × <math>P_1</math>.
|
||||
|
||||
'''Task Details'''
|
||||
|
||||
;Task details:
|
||||
* Use your language's random number generator to create a function/method/subroutine/... '''randN''' that returns a one or a zero, but with one occurring, on average, 1 out of N times, where N is an integer from the range 3 to 6 inclusive.
|
||||
* Create a function '''unbiased''' that uses only randN as its source of randomness to become an unbiased generator of random ones and zeroes.
|
||||
* For N over its range, generate and show counts of the outputs of randN and unbiased(randN).
|
||||
|
||||
<br>
|
||||
The actual unbiasing should be done by generating two numbers at a time from randN and only returning a 1 or 0 if they are different. As long as you always return the first number or always return the second number, the probabilities discussed above should take over the biased probability of randN.
|
||||
|
||||
This task is an implementation of [http://en.wikipedia.org/wiki/Randomness_extractor#Von_Neumann_extractor Von Neumann debiasing], first described in a 1951 paper.
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
defmodule Random do
|
||||
def init() do
|
||||
:random.seed(:erlang.now)
|
||||
end
|
||||
def randN(n) do
|
||||
if :random.uniform(n) == 1, do: 1, else: 0
|
||||
if :rand.uniform(n) == 1, do: 1, else: 0
|
||||
end
|
||||
def unbiased(n) do
|
||||
{x, y} = {randN(n), randN(n)}
|
||||
|
|
@ -12,9 +9,9 @@ defmodule Random do
|
|||
end
|
||||
|
||||
IO.puts "N biased unbiased"
|
||||
Random.init
|
||||
m = 10000
|
||||
for n <- 3..6 do
|
||||
xs = for _ <- 1..10000, do: Random.randN(n)
|
||||
ys = for _ <- 1..10000, do: Random.unbiased(n)
|
||||
IO.puts "#{n} #{Enum.sum(xs) / Enum.count(xs)} #{Enum.sum(ys) / Enum.count(ys)}"
|
||||
xs = for _ <- 1..m, do: Random.randN(n)
|
||||
ys = for _ <- 1..m, do: Random.unbiased(n)
|
||||
IO.puts "#{n} #{Enum.sum(xs) / m} #{Enum.sum(ys) / m}"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
import Control.Monad.Random
|
||||
import Control.Monad
|
||||
import Text.Printf
|
||||
|
||||
randN :: MonadRandom m => Int -> m Int
|
||||
randN n = fromList [(0, fromIntegral n-1), (1, 1)]
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
unbiased :: (MonadRandom m, Eq x) => m x -> m x
|
||||
unbiased g = do x <- g
|
||||
y <- g
|
||||
if x /= y then return y else unbiased g
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
main = forM_ [3..6] showCounts
|
||||
where
|
||||
showCounts b = do
|
||||
r1 <- counts (randN b)
|
||||
r2 <- counts (unbiased (randN b))
|
||||
printf "n = %d biased: %d%% unbiased: %d%%\n" b r1 r2
|
||||
|
||||
counts g = (`div` 100) . length . filter (== 1) <$> replicateM 10000 g
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import Control.Monad
|
||||
import Random
|
||||
import Data.IORef
|
||||
import Text.Printf
|
||||
|
||||
randN :: Integer -> IO Bool
|
||||
randN n = randomRIO (1,n) >>= return . (== 1)
|
||||
|
||||
unbiased :: Integer -> IO Bool
|
||||
unbiased n = do
|
||||
a <- randN n
|
||||
b <- randN n
|
||||
if a /= b then return a else unbiased n
|
||||
|
||||
main :: IO ()
|
||||
main = forM_ [3..6] $ \n -> do
|
||||
cb <- newIORef 0
|
||||
cu <- newIORef 0
|
||||
replicateM_ trials $ do
|
||||
b <- randN n
|
||||
u <- unbiased n
|
||||
when b $ modifyIORef cb (+ 1)
|
||||
when u $ modifyIORef cu (+ 1)
|
||||
tb <- readIORef cb
|
||||
tu <- readIORef cu
|
||||
printf "%d: %5.2f%% %5.2f%%\n" n
|
||||
(100 * fromIntegral tb / fromIntegral trials :: Double)
|
||||
(100 * fromIntegral tu / fromIntegral trials :: Double)
|
||||
where trials = 50000
|
||||
|
|
@ -16,5 +16,5 @@ for 3 .. 6 -> $n {
|
|||
@fixed[ unbiased($n) ]++;
|
||||
}
|
||||
printf "N=%d randN: %s, %4.1f%% unbiased: %s, %4.1f%%\n",
|
||||
$n, map { .perl, .[1] * 100 / $iterations }, $(@raw), $(@fixed);
|
||||
$n, map { .perl, .[1] * 100 / $iterations }, @raw, @fixed;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
function randN ( [int]$N )
|
||||
{
|
||||
[int]( ( Get-Random -Maximum $N ) -eq 0 )
|
||||
}
|
||||
|
||||
function unbiased ( [int]$N )
|
||||
{
|
||||
do {
|
||||
$X = randN $N
|
||||
$Y = randN $N
|
||||
}
|
||||
While ( $X -eq $Y )
|
||||
|
||||
return $X
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
$Tests = 1000
|
||||
ForEach ( $N in 3..6 )
|
||||
{
|
||||
$Biased = 0
|
||||
$Unbiased = 0
|
||||
|
||||
ForEach ( $Test in 1..$Tests )
|
||||
{
|
||||
$Biased += randN $N
|
||||
$Unbiased += unbiased $N
|
||||
}
|
||||
[pscustomobject]@{ N = $N
|
||||
"Biased Ones out of $Test" = $Biased
|
||||
"Unbiased Ones out of $Test" = $Unbiased }
|
||||
}
|
||||
|
|
@ -1,21 +1,20 @@
|
|||
/*REXX program generates unbiased random numbers and displays the results. */
|
||||
parse arg # R seed . /*get optional parameters from the CL. */
|
||||
if #=='' | #==',' then #=1000 /*# the number of SAMPLES to be used.*/
|
||||
if R=='' | R==',' then R=6 /*R the high number for the range. */
|
||||
if seed\=='' then call random ,,seed /*Not specified? Use for RANDOM seed. */
|
||||
w=12; pad=left('',5) /*width of columnar output; indentation*/
|
||||
dash='─'; @b='biased'; @ub='un'@b /*literals for the SAY column headers. */
|
||||
say pad c('N',5) c(@b) c(@b'%') c(@ub) c(@ub"%") c('samples') /*6 col header.*/
|
||||
/*REXX program generates unbiased random numbers and displays the results to terminal.*/
|
||||
parse arg # R seed . /*get optional parameters from the CL. */
|
||||
if #=='' | #=="," then #=1000 /*# the number of SAMPLES to be used.*/
|
||||
if R=='' | R=="," then R=6 /*R the high number for the range. */
|
||||
if datatype(seed, 'W') then call random ,,seed /*Not specified? Use for RANDOM seed. */
|
||||
w=12; pad=left('',5) /*width of columnar output; indentation*/
|
||||
dash='─'; @b="biased"; @ub='un'@b /*literals for the SAY column headers. */
|
||||
say pad c('N',5) c(@b) c(@b'%') c(@ub) c(@ub"%") c('samples') /*six column header.*/
|
||||
dash=
|
||||
do N=3 to R; b=0; u=0; do j=1 for #
|
||||
b=b+randN(N)
|
||||
u=u+unbiased()
|
||||
end /*j*/
|
||||
do N=3 to R; b=0; u=0; do j=1 for #; b=b+randN(N)
|
||||
u=u+unbiased()
|
||||
end /*j*/
|
||||
say pad c(N,5) c(b) pct(b) c(u) pct(u) c(#)
|
||||
end /*N*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*───────────────────────────────────one─liner subroutines────────────────────*/
|
||||
c: return center(arg(1), word(arg(2) w,1), left(dash,1))
|
||||
pct: return c(format(arg(1)/#*100,,2)'%') /*2 decimal digs.*/
|
||||
randN: parse arg z; return random(1,z)==z
|
||||
unbiased: do until x\==randN(N); x=randN(N); end; return x
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
c: return center( arg(1), word(arg(2) w, 1), left(dash, 1) )
|
||||
pct: return c( format(arg(1) / # * 100, , 2)'%' ) /*two decimal digits.*/
|
||||
randN: parse arg z; return random(1, z)==z
|
||||
unbiased: do until x\==randN(N); x=randN(N); end /*until*/; return x
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue