Limit to values of a Linear congruential generator

350 Views Asked by At

I'm doing a bit of a project with some coding (Python) regarding the LCG theory of being able to generate seemingly random numbers using a modulus, multiplier, an increment value, and a "seed" to produce the same randomly generated numbers. However, each iteration of my formula:

$Xn+1=(a*Xn+b) mod M$

Returns a number that is only smaller than the last iteration. I used the following values for my presets:

$n = 20$, $a = 1103515245$, $b = 12345$, $M = 2^{32}$, $Xo = 19680801$

After 5 iterations or so, the values plateau to a certain number, which means that it does not produce a random result.

For those interested, here is my Python code. I'm using 3.8 and there are no runtime errors.

Function:

def LCG_calc():
        
    randnum = 19680801      # Fixing random state for reproducibility
    randnum2 = []           # clearing list for next random set
    
    for x in range(0, n):
        randnum = ((a*randnum)+b) % M
        randnum = randnum /M
        randnum2.append(randnum)
        if x>n:
            break
        
    return randnum2

Called From:

for m, zlow, zhigh in [('o', -50, -25), ('^', -30, -5)]:
    xs = LCG_calc()
    ys = LCG_calc()
    zs = LCG_calc(zlow, zhigh)
    ax.scatter(xs, ys, zs, marker=m)

Is there an issue with my setup?

1

There are 1 best solutions below

0
On BEST ANSWER

This

for x in range(0, n):
    randnum = ((a*randnum)+b) % M
    randnum = randnum /M
    randnum2.append(randnum)

Should be

for x in range(0, n):
    randnum = ((a*randnum)+b) % M
    randnum2.append(randnum/M)

Otherwise you overwrite the integer seed (that you call randnum) with a floating-point number between 0 and 1. Not correct.