Generating shuffled range using a PRNG rather than shuffling

前端 未结 5 1987
孤城傲影
孤城傲影 2020-12-01 04:55

Is there any known algorithm that can generate a shuffled range [0..n) in linear time and constant space (when output produced iteratively), given an arbitrary seed value?

5条回答
  •  暖寄归人
    2020-12-01 05:17

    Here is a Python implementation of the Linear Congruential Generator from FryGuy's answer. Because I needed to write it anyway and thought it might be useful for others.

    import random
    import math
    
    def lcg(start, stop):
        N = stop - start
    
        # M is the next largest power of 2
        M = int(math.pow(2, math.ceil(math.log(N+1, 2))))
    
        # c is any odd number between 0 and M
        c = random.randint(0, M/2 - 1) * 2 + 1
    
        # M=2^m, so make (a-1) divisible by all prime factors and 4
        a = random.randint(0, M/4 - 1) * 4 + 1
    
        first = random.randint(0, M - 1)
        x = first
        while True:
            x = (a * x + c) % M
            if x < N:
                yield start + x
            if x == first:
                break
    
    if __name__ == "__main__":
        for x in lcg(100, 200):
            print x,
    

提交回复
热议问题