将一个值随机分配给一个固定大小的值列表

huangapple go评论65阅读模式
英文:

distribute randomly a value to a fixed size list of values

问题

以下是已经翻译好的内容:

我有一个值(总和)(在实现中是 n)我想要“随机”分配它,使其成为一个包含12个元素的列表,总和为该值(总和),我编写了以下方法来实现这一目标:

def create_list_summing_up_to(n): 
    values = []
    for i in range(1, 13):
        value = random.randint(0, int(n / i))
        values.append(value)
        n -= value
        if n <= 0 and i < 12:
            values.extend(np.zeros(12 - i).tolist())
            break
    if n > 0:
        for idx, el in enumerate(values):
            values[idx] = values[idx] + int(n / 12)
    return values

我的问题是:即使对于很大的总和(数百万级别),这个方法是否高效?如何使它更高效?

英文:

I have a value (a sum) (in the implementation it is n) that I want to distribute "randomly" to become a list of 12 elements summing up to that value (sum), I wrote the following method to achieve that:

def create_list_summing_up_to(n): 
    values = []
    for i in range(1,13):
        value = random.randint(0, int(n / i))
        values.append(value)
        n -= value
        if n&lt;=0 and i&lt;12:
            values.extend(np.zeros(12-i).tolist())
            break
    if n&gt;0:
        for idx,el in enumerate(values):
            values[idx] = values[idx]+int (n/12)
    return values

My question is: is the method efficient even for large sums (of the order of millions)?
How could it be more efficient?

答案1

得分: 1

尝试这段代码

import random

def create_list_summing_up_to(n):
    # 生成一个包含12个0到1之间随机值的列表
    values = [random.random() for _ in range(12)]
    
    # 计算随机值的总和
    total = sum(values)
    
    # 按比例调整这些值,以确保它们总和为n
    values = [int(value / total * n) for value in values]
    
    # 调整最后一个元素,以确保总和精确等于n
    values[-1] += n - sum(values)
    
    return values

print(create_list_summing_up_to(150000000))

更多方法可以参考这里

英文:

Try this code

import random

def create_list_summing_up_to(n):
    # Generate a list of random values between 0 and 1
    values = [random.random() for _ in range(12)]
    
    # Calculate the sum of the random values
    total = sum(values)
    
    # Scale the values proportionally to ensure they sum up to n
    values = [int(value / total * n) for value in values]
    
    # Adjust the last element to ensure the sum is exact
    values[-1] += n - sum(values)
    
    return values

print(create_list_summing_up_to(150000000))

For more ways you can check this

答案2

得分: 0

你可以使用 numpy.random.multinomial

多项式分布是二项式分布的多变量推广。考虑一个具有 p 种可能结果的实验。一个这样的实验示例是掷骰子,其中结果可以是1到6。从该分布中抽取的每个样本代表了 n 次这样的实验。它的值,X_i = [X_0, X_1, ..., X_p],表示结果为 i 的次数。

import numpy as np
np.random.multinomial(20, [1/12.]*12, size=1)

array([[1, 1, 2, 3, 1, 1, 0, 3, 0, 3, 2, 3]])  # 随机
import numpy as np
np.random.multinomial(30, [1/12.]*12, size=1)

array([[4, 1, 2, 2, 3, 4, 2, 2, 1, 3, 2, 4]])  # 随机

类似地对于 n

import numpy as np
np.random.multinomial(n, [1/12.]*12, size=1)
英文:

You can use numpy.random.multinomial:

>The multinomial distribution is a multivariate generalization of the binomial distribution. Take an experiment with one of p possible outcomes. An example of such an experiment is throwing a dice, where the outcome can be 1 through 6. Each sample drawn from the distribution represents n such experiments. Its values, X_i = [X_0, X_1, ..., X_p], represent the number of times the outcome was i.

import numpy as np
np.random.multinomial(20, [1/12.]*12, size=1)

array([[1, 1, 2, 3, 1, 1, 0, 3, 0, 3, 2, 3]])  # random

import numpy as np
np.random.multinomial(30, [1/12.]*12, size=1)

array([[4, 1, 2, 2, 3, 4, 2, 2, 1, 3, 2, 4]])  # random

Similarly for n:

import numpy as np
np.random.multinomial(n, [1/12.]*12, size=1)

答案3

得分: 0

你的问题表达不够清晰。你不是在“随机选择一个数字”,而是从给定的分布中选择一个随机数字。这样的分布可以是在0和1之间均匀分布的,也可以是高斯分布或泊松分布。

你要求我们选择12个随机数字,然后确保它们的总和达到特定值。这实际上是不可能的。(总和正确的概率为0。)你能期望的最好情况是选择12个随机数字,然后以某种方式对它们进行缩放以达到你的总和。再次强调,从线性缩放到更复杂的缩放方式,有很多可能性。而且,取决于你的原始分布和缩放方法,最终的12个数字是否仍然属于原始分布也是不确定的。

所以,你认为很简单的问题实际上并不简单。


从你的回答中可以看出,你没有理解我所说的要点:根本不存在所谓的“随机选择一个数字”。

假设我让你选择一个随机整数。无论你选择什么数字,它都将是不可能的小。绝大多数整数都是难以置信地大,而你能够在脑海中思考它的事实意味着你已经将自己限制住了。我可以让你“从1到100中选择一个数字”。无论如何,我都必须明确或隐含地为每个整数分配一个概率,而这些概率必须相加为1。我甚至可以说:以1/2的概率选择0,以1/2的概率选择1,以1/4的概率选择2,......这是合法的。

同样,对于选择一个浮点数也是如此。我必须为你提供一个非负的曲线f,并且曲线下的面积必须总和为1。你选择一个在x的“邻域”内的数字的概率等于f(x)的值乘以邻域的宽度。(是的,这涉及到微积分。)

根本不存在所谓的“只是一个随机数字”。

英文:

Your question is not well formed. You do not "pick a random number". You pick a random number from a given distribution. Such a distribution might be uniform between 0 and 1, or Gaussian, or Poisson distribution.

You're asking us to pick 12 random numbers, and then ensure that they have a specific total. That is not really possible. (The probability is 0 that the total is correct.) The best you can hope for is to pick 12 random numbers and then scale them in some way to reach your total. Again, there are many possibilities from linear scaling to more exotic scalings. And it depends on your original distribution and scaling method whether the resulting 12 numbers are still members of the original distribution.

So what you think is an easy question really isn't.


From your response, it is clear you didn't get the point I was making: there is no such thing as "pick a random number".

Suppose I asked you to pick a random integer. Whatever number you pick is going to be impossibly small. The vast majority of integers are unbelievably large, and the fact you can even think it in your head means you've limited yourself. I can ask you "pick a number between 1 and 100". No matter what, I have to explicitly or implicitly give you a probability for each integer, and those probabilities have to add up to 1. I might even say: pick 0 with probability 1/2, pick 1 with probability 1/2, pick 2 with probability 1/4, .... that's legal.

Likewise for picking a floating point number. I have to give you a non-negative curve, f and the area under the curve has to total 1. The probability of your picking a number in the "neighborhood" of x is the value of f(x) times the width of the neighborhood. (Yeah, calculus.)

There is no such thing as "just a random number".

huangapple
  • 本文由 发表于 2023年7月3日 23:25:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76606159.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定