I have written the following code to generate a random list. I want the list to have elements between 0 and 500, but the summation of all elements does not exceed 1300. I dont know how to continue my code to do that. I have written other codes; for example, to create a list of random vectors and then pick among those that satisfy the condition. But here I want to create such a list in one try.
nv = 5
bounds = [(0, 500), (0, 500), (0, 500), (0, 500), (0, 500)]
var =[]
for j in range(nv):
var.append(random.uniform(bounds[j][0], bounds[j][1]))
summ = sum(var)
if summ > 1300:
????
CodePudding user response:
Don't append
until after you've validated the value.
Use while len() < maxLen
so that you can handle repeat attempts.
You don't really need nv
since len(bounds)
dictates the final value of len(var)
.
len(var)
is also the next index of the var
list that is unused so you can use that to keep track of where you are in bounds
.
A running sum is more efficient than using sum()
on every check. (Though on small lists, it's not going to make a noticeable difference.)
The *
in the .uniform()
call splits a list into individual arguments. (Asterisks in Python: what they are and how to use them seems like a good tutorial on the subject.)
import random
bounds = [(0, 500), (0, 500), (0, 500), (0, 500), (0, 500)]
var = []
runningSum = 0
while len(var) < len(bounds):
sample = random.uniform(*bounds[len(var)])
if runningSum sample < 1300:
runningSum = sample
var.append(sample)
print(repr(var))
CodePudding user response:
Per the comments, you're able to use a third-party library, so you can do this with Numpy. This question is where I got some of this code, because I'm not very familiar with Numpy.
import numpy as np
import random
limits = [500, 500, 500, 500, 500]
total = 1300
gen = np.random.Generator(np.random.PCG64(random.randrange(1, 100)))
random_list = gen.multivariate_hypergeometric(limits, total)
print(list(random_list))
CodePudding user response:
Without the aid of numpy you could do this:
from random import uniform
def func1():
LIMIT = 1_300
bounds = [(0, 500), (0, 500), (0, 500), (0, 500), (0, 500)]
while sum(result := [uniform(lo, hi) for lo, hi in bounds]) > LIMIT:
pass
return result