繁体   English   中英

创建具有最大值和最小值以及总和的 N 个随机数列表

[英]Create a list of N random numbers with max and min value and total sum

我正在尝试创建一个包含 0.005 到 0.045 之间的 N 个随机数的列表(称为权重),总和等于 1。N 可以是 22 到 200 之间的任何 integer。所以有以下限制:

  • 权重中的数字数量 = N
  • 对于每 n 个权重:0.005 < n < 0.045
  • 所有 n 的权重之和 = 1

我认为第一个限制很容易。 另外,我知道如何解决彼此分开的第二个和第三个限制。 但我不知道如何将它们组合成一段代码。

  • 第二个限制:0.005 < x < 0.045:
import numpy as np
import random


weights_step1 = np.random.randint(min=5, max = 45, size = N)

weights = []
for weight in weights_step1:
  weights.append(weight/1000)

  • 第三个限制

生成随机数列表,总和为 1

有谁知道如何将这两个限制纳入一段代码?

这可能会奏效。 该策略是对可用空间进行统一分区,然后对分区进行迭代,每次迭代从当前分区中随机抽取一个位并将其添加到第二个分区中。

您可能会发现需要使用decimal package 以获得更高的精度。 您可能还需要引入守卫以确保对分区数量及其最小和最大大小的约束不会不一致。

import random

partitions = 45
partition_size_min = 0.005
partition_size_max = 0.045

weights = [1.0 / partitions] * partitions
for index in range(len(weights)):
    partner_index = random.randint(0, partitions-1)

    available_to_give = weights[index] - partition_size_min
    available_to_recieve = partition_size_max - weights[partner_index]
    delta = random.uniform(0, min(available_to_give, available_to_recieve))

    weights[partner_index] += delta
    weights[index] -= delta

print(f"Sum: {sum(weights)} Min:{min(weights)} Max: {max(weights)}")
print(weights)

这应该会给你一个类似的结果:

Sum: 1.0 Min:0.0057759435106850415 Max: 0.04428043727891049

[
    0.03408561328744241,
    0.010644787590344313,
    0.01400427089495221,
    0.01484912512559225,
    ...
    0.019186499047958494,
    0.02443794812733188,
    0.03475172101526412,
    0.020782296753987052
]

我确信一个合适的统计学家会发现这种方法的错误,但它可能会让你接近你想要的。

您可能想要使用Dirichlet Rescale algorithm (DRS)Python 实现可用:

这为您提供了适当的统计保证。 引用论文摘要:

向量均匀分布在所有可能向量域的有效区域上,受约束。

尝试 50 个数字总和为 1:

$ pip install drs
...
Installing collected packages: drs
Successfully installed drs-2.0.0
$ 
$ python3
Python 3.9.9 (main, Nov 19 2021, 00:00:00) 
...
>>>
>>> from drs import drs
>>>
>>> n   = 50
>>> sum = 1.0
>>>
>>> v1 = drs(n, sum, n*[0.045], n*[0.005])
>>> sum(v1)
1.0000000000000004
>>> max(v1)
0.04278387127251347
>>> min(v1)
0.005035400173241331
>>> 
>>> v2 = drs(n, sum, n*[0.045], n*[0.005])
>>> sum(v2)
0.9999999999999994
>>> max(v2)
0.04445793844097045
>>> min(v2)
0.005294943276519565
>>> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM