Gerges
Gerges

Reputation: 6509

Generate random numbers list with limit on each element and on total

Assume I have a list of values, for example:

limits = [10, 6, 3, 5, 1]

For every item in limits, I need to generate a random number less than or equal to the item. However, the catch is that the sum of elements in the new random list must be equal to a specified total.

For example if total = 10, then one possible random list is:

random_list = [2, 1, 3, 4, 0]

where you see random_list has same length as limits, every element in random_list is less than or equal to the corresponding element in limits, and sum(random_list) = total.

How to generate such a list? I am open (and prefer) to use numpy, scipy, or pandas.

Upvotes: 0

Views: 345

Answers (1)

Gerges
Gerges

Reputation: 6509

Found what I was looking for: The hypergeometric distribution which is similar to the binomial, but without replacement.

The distribution available in numpy:

import numpy as np

gen = np.random.Generator(np.random.PCG64(seed))
random_list = gen.multivariate_hypergeometric(limits, total)

# array([4, 4, 1, 1, 0])

Also to make sure I didn't misunderstand the distribution did a sanity check with 10 million samples and check that the maximum is always within the limits

res = gen.multivariate_hypergeometric(limits, total, size=10000000) 

res.max(axis=0)

# array([10,  6,  3,  5,  1])

which is same as limits.

Upvotes: 1

Related Questions