number generator

Steven D'Aprano steve at REMOVEME.cybersource.com.au
Wed Mar 14 02:29:48 CET 2007


On Tue, 13 Mar 2007 08:20:49 +0200, Hendrik van Rooyen wrote:

> Is it possible to devise a test that can distinguish between sets
> of:
> 
> - five random numbers that add to 50, and
> - four random numbers and a fudge number that add to 50?
> 
> My stats are way too small and rusty to attempt to answer 
> the question, but it seems intuitively a very difficult thing.

Easy-peasey. Just collate the individual numbers from the lists, and graph
their frequencies. You will get quite different distributions. Both are
"random", but in different ways.

Here is some code to do it.

import random

def method1(total, count):
    """SLOW way of generating random lists."""
    L = []
    while sum(L) != total:
        L = [random.randint(1, total) for i in range(count)]
    assert sum(L) == total
    assert len(L) == count
    return L

def method2(total, count):
    if total <= 0 or count <= 0:
        return []
    elif count == 1:
        return [total]
    else:
        n = random.randint(1, total-count)
        L = [n] + method2(total-n, count-1)
    assert sum(L) == total
    assert len(L) == count
    return L


def collate_numbers(method, count):
    bins = {}
    for i in xrange(count):
        L = method(50, 5)
        for n in L:
            bins[n] = bins.get(n, 0) + 1
    return bins


I'll leave graphing the results as a exercise for the reader, but here's a
sample I prepared earlier:


>>> d1  # bins from method1()
{1: 208, 2: 207, 3: 158, 4: 167, 5: 162, 6: 146, 7: 142, 8: 115, 
9: 114, 10: 113, 11: 94, 12: 98, 13: 92, 14: 68, 15: 60, 16: 70, 
17: 58, 18: 56, 19: 57, 20: 44, 21: 25, 22: 36, 23: 27, 24: 34, 
25: 23, 26: 18, 27: 18, 28: 13, 29: 13, 30: 8, 31: 13, 32: 17, 
33: 7, 34: 1, 35: 5, 36: 4, 37: 3, 38: 2, 39: 1, 40: 2, 44: 1}

>>> d2  # bins from method2()
{1: 370, 2: 387, 3: 222, 4: 190, 5: 129, 6: 106, 7: 95, 8: 84, 
9: 64, 10: 61, 11: 47, 12: 56, 13: 45, 14: 35, 15: 39, 16: 26, 
17: 34, 18: 25, 19: 36, 20: 34, 21: 30, 22: 25, 23: 20, 24: 23, 
25: 18, 26: 19, 27: 24, 28: 15, 29: 17, 30: 21, 31: 14, 32: 12, 
33: 16, 34: 16, 35: 14, 36: 14, 37: 15, 38: 11, 39: 19, 40: 13, 
41: 14, 42: 16, 43: 8, 44: 11, 45: 10}


Even from the raw numbers, the differences are obvious. A bar graph makes
it even clearer.


-- 
Steven D'Aprano 




More information about the Python-list mailing list