Home > front end >  Method to generate random numbers to sum to a target
Method to generate random numbers to sum to a target

Time:12-07

Let's say there are 100 people and $120. What is the formula that could divide it into random amounts to where each person gets something?

In this scenario, one person could get an arbitrary amount like $0.25, someone could get $10, someone could get $1, but everyone gets something. Any tips?

So in Javascript, an array of 100 could be generated, and these random numbers would be in them, but they would add up to 100

CodePudding user response:

To get a result with the smallest possible amount of 1 cent using simple means, you can generate 100 random values, find their sum S, then multiply every value by 120.0/Sum with rounding to integer cents, get sum again. If there is some excess (some cents), distribute it to random persons.

Example in Python for 10 persons and 12$. 1 and overall-num allow to avoid zero amounts:

import random

overall = 1200
num = 10
amounts = [random.random() for _ in range(num)]
asum = sum(amounts)
for i in range(num):
    amounts[i] = 1   int(amounts[i]*(overall-num) / asum)
asum = sum(amounts)
for i in range(overall - asum):
    amounts[random.randint(0,9)]  = 1

print(amounts, sum(amounts))

>>[163, 186, 178, 152, 89, 81, 169, 90, 17, 75] 1200

Another way (fair distribution of variants in mathematical sense), as Aki Suihkonen noticed in comments, is to use random choice from divider positions array (with shuffling) to implement (my first proposal, But I supposed too complex implementation earlier):

put 12000 one-cent coins in row
put 99 sticks (dividers) between them, in 11999 spaces between coins
give coins between k and k 1 stick to k-th person

Python implementation:

arr = [i for i in range(overall-1)]
divs = [0]   sorted(random.choices(arr, k=num-1))   [overall]
amounts = [(divs[i 1]-divs[i]) for i in range(num)]
print(amounts, sum(amounts))

>>>[17, 155, 6, 102, 27, 222, 25, 362, 50, 234] 1200

CodePudding user response:

What should be the targeted distribution?

MBo gives AFAIK Poisson distribution (with the original approach of placing 99 dividers randomly between range of 1 and 11999). Another one would be to divide the sums first evenly, then for every two members redistribute the wealth by transferring a random sum between 0 and $1.19 from one person to another.

Repeat a few times, if it's not sufficient that the maximum amount is just 2x the expectation.

  • Related