0
import random
#lets take kg(for Total) for better understanding

Total = random.randint(40, 110) #For example Total=100   kg and this is 100%

Total = (a+b+c+d+e) 
 

Each value in Total has own range (in %).

First: find random values (within ranges that is % from Total.).

I tried this (but sum() can be >or< than 100):

a=random.randint(40, 70)

b=random.randint(0, 4)

c=random.randint(0, 2)

d=random.randint(22, 44)

e=random.randint(0, 7)

Second:find exact value for a,b,c,d,e (according to the percentage from Total in First part). I tried this:

a=Total*random.randint(40, 70)/100

b=Total*random.randint(0, 4)/100

c=Total*random.randint(0, 2)/100

d=Total*random.randint(22, 44)/100

e=Total*random.randint(0, 7)/100

This code does not work. please help

Neeraj
  • 975
  • 4
  • 10
  • 1
    Does this answer your question? [Is there an efficient way to generate N random integers in a range that have a given sum or average?](https://stackoverflow.com/questions/61393463/is-there-an-efficient-way-to-generate-n-random-integers-in-a-range-that-have-a-g) – Peter O. Apr 10 '21 at 22:44

2 Answers2

0

Try this:

import random

random_ints = []
sum_randoms = 0
upper_limit = 100
while sum(random_ints) < 100 and len(random_ints) < 5:
    random_int = random.randint(0, upper_limit)
    random_ints.append(random_int)
    upper_limit = 100 - sum(random_ints)

random_ints.append(100 - sum(random_ints))

print(random_ints)
Paul
  • 813
  • 11
  • 27
  • Ok, I received 5 random int (with sum 100) but only one range can be used in this way: random_int = random.randint(0, upper_limit) But I need 5 randoms with different ranges – Kolachynskyi Nazarii Apr 10 '21 at 17:50
0

I'd start with the smallest ranges first, then pick the last one not randomly but as the difference between the sum of the other 4 and 100. Since random numbers can't be guaranteed to meet all the constraints, you may need to keep picking until you get a satisfactory answer.

def sum_to_100(range_list):
    if sum(lo for lo,hi in range_list) > 100 or sum(hi for lo,hi in range_list) < 100:
        raise ValueError('Solution is impossible within the constraints')
    ordered_ranges = sorted((lo,hi,i) for i,(lo,hi) in enumerate(range_list))
    n = len(range_list)
    solution = []
    while len(solution) != n or sum(solution) != 100:
        index = len(solution)
        lo, hi, i = ordered_ranges[index]
        if index == n - 1:
            final = 100 - sum(solution)
            if lo <= final <= hi:
                solution.append(final)
            else:  # start over
                solution = []
        else:
            solution.append(random.randint(lo, hi))
    # restore the original order
    solution = [num for i,num in sorted(enumerate(solution), key=lambda x:ordered_ranges[x[0]][2])]
    return solution

>>> sum_to_100([(40, 70), (0, 4), (0, 2), (22, 44), (0, 7)])
[59, 3, 1, 32, 5]
>>> sum_to_100([(40, 70), (0, 4), (0, 2), (22, 44), (0, 7)])
[47, 2, 0, 44, 7]
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622