Python 脚本生成一组带有约束的随机数

Python script to generate set of random numbers with a constraint

提问人:Alfonzo 提问时间:11/8/2023 更新时间:11/8/2023 访问量:67

问:

我希望脚本输出 159 个介于“0.04”和“4.5”之间的随机数,这些随机数的总数与目标总数匹配。这是我到目前为止所拥有的,但这只生成 142 个数字。如何强制创建 159 个号码?

import random

target_total = 298.51
total_numbers = 159
min_value = 0.04
max_value = 4.50

random_numbers = []

for i in range(total_numbers - 1):
    # Generate a random number within the specified range
    num = round(random.uniform(min_value, max_value), 2)  # Limit to 2 decimal places
    
    # Append the number to the list
    random_numbers.append(num)
    
    # Calculate the current sum of numbers
    current_sum = round(sum(random_numbers), 2)
    
    # If the current sum exceeds the target total, remove the last number
    while current_sum > target_total:
        excess = current_sum - target_total
        random_numbers.remove(random_numbers[-1])
        current_sum = round(current_sum - excess, 2)

# The last number is adjusted to reach the target total
last_num = round(target_total - sum(random_numbers), 2)
random_numbers.append(last_num)

# Print each generated number with row numbers on a new line
for i, num in enumerate(random_numbers, start=1):
    print(f"Row {i}: {num}")

print("Total sum:", round(sum(random_numbers), 2))


python-3.x 操作数据 生成

评论

0赞 Mark Ransom 11/8/2023
你要求的是不可能的,至少最终的数字不会是随机的。
0赞 Alfonzo 11/8/2023
@MarkRansom - 我很想知道为什么?从表面上看,这似乎是一个非常简单的挑战,但我开始看到它的问题。任何进一步的见解将不胜感激。
1赞 Mark Ransom 11/8/2023
选择 158 个号码后会发生什么?你认为第 159 次会有多随机?
0赞 Alfonzo 11/8/2023
我现在明白你的意思了,你这么说。感谢您的回复。

答:

0赞 Suramuthu R 11/8/2023 #1

问题在于:虽然max_value是 4.50,但如果创建的更多随机数接近最大值,则要达到目标总数,则将以较少的总数达到目标。此外,如果我们使用此方法,循环将继续到无穷无尽的数字。因此,我们必须自己决定max_value。在这里,我给出了一个更好的方法。里面给出了解释:

import random as rd
target_total = 298.51
total_numbers = 159
each_number = target_total/total_numbers

#calculate the sum of adjacent two numbers
adj_sum = each_number*2

min_value = 0.04
random_numbers = []

#create a loop for 1 number less than the total numbers i.e 158. 
# We will find out the last number afterwards
for i in range(total_numbers-1):
    #generate random number only for even index
    if i%2==0:
        #generate random_number between min_value and the adj_sum
        
        number = rd.uniform(min_value, adj_sum)
    #if i is odd the random number should be the difference between adj_sum and previous number
    else:
        number = adj_sum - number
    
    #round_off to 2 decimals and append
    random_numbers.append(round(number,2))

#find the last number

sum = round(sum(random_numbers), 2)
last_number = round((target_total - sum),2)

#append the last number
random_numbers.append(last_number)

sum = sum + last_number

for i, num in enumerate(random_numbers, start=1):
    print(f"Row {i}: {num}")

print("Total sum:", round(sum, 2))

如果您希望每个随机数不惜一切代价都是唯一的,您可以在第 18 行后添加一个 while 循环。即我已经包含了您应该在该行之后插入以下代码的行

#generate random_number between min_value and the adj_sum(line 17)
    number = rd.uniform(min_value, adj_sum) #line 18
    j = 0
    while j>=0:
        if number not in random_numbers:
            break
        else:
            j += 1