Why is the average of a million random numbers not in the middle of the range?

Viewed 196

So I was writing a script that used random.randint() in python, but it doesn't really matter since I think most mainstream languages have this "problem". It's like this: I set i to a random number and then add a random number 1 million times and then divide it by two. The outputs vary wildly, sometimes it's close to 0, sometimes close to 1, but by logic the output should pretty much be 0.5. What is causing this change.

from random import randint

i = randint(0, 1)
for x in range(1000000):
    i = (i + randint(0, 1)) / 2
print(i)
3 Answers

Your approach isn't calculating the average of all million numbers. It is merely repeatedly calculating an aggregate where each step is the average of the previous value and a new number. This is going to make it so every new value added to the series is going to have a disproportionately large effect on the resulting "average" value, contrary to a true average where each value affects the result equally.

To see what I mean, consider the following code:

from random import randint

nums = [randint(0, 1) for x in range(0, 1000)]

avg = 0
for i in nums:
  avg += i
avg /= len(nums)

pseudo_avg = 0
for i in nums:
  pseudo_avg = (pseudo_avg + i) / 2

print('True Average: %s' % avg)
print('Pseudo-average: %s' % pseudo_avg)

On one run, I got the following as the result:

True Average: 0.492
Pseudo-average: 0.979068653199454

Say you witness 0, 1, 0 in that order. The average is (0 + 1 + 0)/3 = 1/3. Your code (with, of course, range(3)) would give:

i = 0
i = (0 + 1)/2
i = (0 + 1/2)/2 = 1/4

So, firstly, you're not calculating averages.

Now, suppose you are at some in the iteration and i is some value between 0 and 1. You get a value of 0 next then i = i/2, effectively halving what ever you have. If you have a sequence of say 5 0s at the end, you will get a value <= 1/2^5) at the end. Now suppose instead the value is is 1 i = (i+1)/2. This converges quickly to 1. Say i was, in the worst case 0. Then if you read a string of 1s, after only reading 2 1s you will end up at 0.75.

(Note: You can show that i is always between 0 and 1 through induction.)

I'm not sure about what you are trying, but take a look on this result :enter image description here

Maybe your way to calculate average is not suitable to your intent.

Related