Select random element from a set, faster than linear time (Haskell)

前端 未结 8 1663
清酒与你
清酒与你 2021-01-17 11:38

I\'d like to create this function, which selects a random element from a Set:

randElem :: (RandomGen g) => Set a -> g -> (a, g)

Si

8条回答
  •  长发绾君心
    2021-01-17 12:06

    This problem can be finessed a bit if you don't mind completely consuming your RandomGen. With splittable generators, this is an A-OK thing to do. The basic idea is to make a lookup table for the set:

    randomElems :: Set a -> RandomGen -> [a]
    randomElems set = map (table !) . randomRs bounds where
        bounds = (1, size set)
        table  = listArray bounds (toList set)
    

    This will have very good performance: it will cost you O(n+m) time, where n is the size of the set and m is the number of elements of the resulting list you evaluate. (Plus the time it takes to randomly choose m numbers in bounds, of course.)

提交回复
热议问题