pseudo random distribution which guarantees all possible permutations of value sequence - C++

前端 未结 3 1923
天命终不由人
天命终不由人 2021-01-13 16:53

Random question.

I am attempting to create a program which would generate a pseudo-random distribution. I am trying to find the right pseudo-random algorithm for my

相关标签:
3条回答
  • 2021-01-13 17:38

    In your update, "appears random (to the human eye)" is the phrasing you use. The definition of "appears random" is not a well agreed upon topic. There are varying degrees of tests for "randomness."

    However, if you're just looking to make it appear random to the human eye, you can just use ring multiplication.

    • Start with the idea of generating N! values between 0 and M (N>=410, M>=29^3200)
    • Group this together into one big number. we're going to generate a single number ranging from 0 to *M^N!. If we can show that the pseudorandom number generator generates every value from 0 to M^N!, we guarantee your permutation rule.
    • Now we need to make it "appear random." To the human eye, Linear Congruent Generators are enough. Pick a LCG with a period greater than or equal to 410!*M^N satisfying the rules to ensure a complete period. Easiest way to ensure fairness is to pick a LCG in the form x' = (ax+c) mod M^N!

    That'll do the trick. Now, the hard part is proving that what you did was worth your time. Consider that the period of just a 29^3200 long sequence is outside the realm of physical reality. You'll never actually use it all. Ever. Consider that a superconductor made of Josephine junctions (10^-12kg processing 10^11bits/s) weighing the mass of the entire universe 3*10^52kg) can process roughly 10^75bits/s. A number that can count to 29^3200 is roughly 15545 bits long, so that supercomputer can process roughly 6.5x10^71 numbers/s. This means it will take roughly 10^4600s to merely count that high, or somewhere around 10^4592 years. Somewhere around 10^12 years from now, the stars are expected to wink out, permanently, so it could be a while.

    0 讨论(0)
  • 2021-01-13 17:42

    Ok, I'm not sure if there is a general answer, so I would concentrate on random number generator having, say, 64bit internal state/seed, producing 64bit output and having 2^64-1 period. In particular, I would look at linear congruential generator (aka LCG) in the form of

    next = (a * prev + c) mod m
    

    where a and m are primes to each other

    So:

    1) Check

    2) Check

    3) Check (well, for 64bit space of course)

    4) Check (again, except 0 I believe, but each and every permutation of 64bits is output of LCG starting with some seed)

    5) Check. LCG is known to be reversible, i.e. one could get

    prev = (next - c) * a_inv mod m
    

    where a_inv could be computed from a, m using Euclid's algorithm

    Well, if it looks ok to you, you could try to implement LCG in your 15546bits space

    UPDATE

    And quick search shows reversible LCG discussion/code here

    Reversible pseudo-random sequence generator

    0 讨论(0)
  • 2021-01-13 17:48

    There are M**N sequences of N numbers between 0 and M-1. You can imagine writing all of them one after the other in a (pseudorandom) sequence and placing your read pointer randomly in the resulting loop of N*(M**N) numbers between 0 and M-1...

    def output(input):
        total_length = N*(M**N)
        index = input % total_length
        permutation_index = shuffle(index / N, M**N)
        element = input % N
        return (permutation_index / (N**element)) % M
    

    Of course for every permutation of N elements between 0 and M-1 there is a sequence of N consecutive inputs that produces it (just un-shuffle the permutation index). I'd also say (just using symmetry reasoning) that given any starting input the output of next N elements is equally probable (each number and each sequence of N numbers is equally represented in the total period).

    0 讨论(0)
提交回复
热议问题