Search code examples
pythonrandom

Generating a list of random numbers, summing to 1


  • This question is not a duplicate of Getting N random numbers whose sum is M because:
    1. Most answers there are about theory, not a specific coding solution in python to answer this question
    2. The accepted answer here is 5 years older than the one answer in the duplicate that answers this question.
    3. The duplicate accepted answer does not answer this question

How would I make a list of N (say 100) random numbers, so that their sum is 1?

I can make a list of random numbers with

r = [ran.random() for i in range(1,100)]

How would I modify this so that the list sums to 1 (this is for a probability simulation).


Solution

  • The simplest solution is indeed to take N random values and divide by the sum.

    A more generic solution is to use the Dirichlet distribution which is available in numpy.

    By changing the parameters of the distribution you can change the "randomness" of individual numbers

    >>> import numpy as np, numpy.random
    >>> print np.random.dirichlet(np.ones(10),size=1)
    [[ 0.01779975  0.14165316  0.01029262  0.168136    0.03061161  0.09046587
       0.19987289  0.13398581  0.03119906  0.17598322]]
    
    >>> print np.random.dirichlet(np.ones(10)/1000.,size=1)
    [[  2.63435230e-115   4.31961290e-209   1.41369771e-212   1.42417285e-188
        0.00000000e+000   5.79841280e-143   0.00000000e+000   9.85329725e-005
        9.99901467e-001   8.37460207e-246]]
    
    >>> print np.random.dirichlet(np.ones(10)*1000.,size=1)
    [[ 0.09967689  0.10151585  0.10077575  0.09875282  0.09935606  0.10093678
       0.09517132  0.09891358  0.10206595  0.10283501]]
    

    Depending on the main parameter the Dirichlet distribution will either give vectors where all the values are close to 1./N where N is the length of the vector, or give vectors where most of the values of the vectors will be ~0 , and there will be a single 1, or give something in between those possibilities.

    EDIT (5 years after the original answer): Another useful fact about the Dirichlet distribution is that you naturally get it, if you generate a Gamma-distributed set of random variables and then divide them by their sum.