How to shuffle list in O(n) in OCaml?

前端 未结 2 599
轮回少年
轮回少年 2020-12-19 07:14

It is not hard to shuffle an array in O(n), with in place swapping,

How to do it for list in OCaml, with O(n)?


Requirement:<

2条回答
  •  隐瞒了意图╮
    2020-12-19 07:43

    You could mimick the riffle shuffle for cards.

    A riffle shuffle of a deck of cards means to:

    • cut the deck in two parts
    • interleave the two parts

    It is actually easier to do the reverse permutation:

    • have two auxiliary lists A and B, iter through your original list L and push each element randomly (with probability 1/2) in front of A or B.
    • L := List.rev A @ List.rev B (this can be tail recursive with a custom List.rev).
    • repeat k times.

    According to "Mathematical developments from the analysis of riffle shuffling, by Persi Diaconis, 2002", choose k = 3/2 log_2(n) + c. Indeed, the total variation distance between uniformity and the result falls exponentially fast to 0: it is approximately halved each time you increment c. You could choose c=10.

    Space O(1) (if you destroy L), time O(n log n). But there are O(n log n) calls to the random generator, while Jeffrey Scofield's solution only needs O(n) random bits, but Θ(n) space.

提交回复
热议问题