samedi 5 décembre 2015

Randomized algorithm not behaving as expected

I am implementing an approximate counting algorithm where we:

Maintains a counter đť‘‹ using log log đť‘› bits

• Initialize đť‘‹ to 0

• When an item arrives, increase X by 1 with probability (1/2)^đť‘‹

• When the stream is over, output 2^(X) - 1 so that 𝔼[2^đť‘‹] = đť‘› + 1

My implementation is as follows:

import System.Random

Type Prob   = Double
Type Tosses = Int

-- * for sake of simplicity we assume 0 <= p <= 1
tos :: Prob -> StdGen -> (Bool,StdGen)
tos p s = (q <= 100*p, s')
  where (q,s') = randomR (1,100) s

toses :: Prob -> Tosses -> StdGen -> [(Bool,StdGen)]
toses _ 0 _ = []
toses p n s = let t@(b,s') = tos p s in t : toses p (pred n) s'

toses' :: Prob -> Tosses -> StdGen -> [Bool]
toses' p n = fmap fst . toses p n

morris :: StdGen -> [a] -> Int
morris s xs = go s xs 0 where
  go _ []     n = n
  go s (_:xs) n = go s' xs n' where
    (h,s') = tos (0.5^n) s 
    n'     = if h then succ n else n

main :: IO Int
main = do
  s <- newStdGen
  return $ morris s [1..10000]

The problem is that my X is always incorrect for any |stream| > 2, and it seems like for all StdGen and |stream| > 1000, $X = 7$.

I tested the same algorithm in Matlab and it works there, so I assume it's an issue with my random number generator, what gives?




Aucun commentaire:

Enregistrer un commentaire