将一个金额按照高斯分布分成两个随机组。

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

Split an amount into 2 random groups by Gauss bell

问题

假设我有100个物品,需要将它们分成两组。

选项可以是:

  1. 将它们分成两半,所以我得到确切的50和50。

  2. 选择1到100之间的随机数字,然后将这个数量从剩下的物品中分开。

在选项2中,一个物品与50个物品具有相同的概率(1/100)
但实际上,我想象一个高斯钟曲线,例如,50的概率最大,49和48的概率较低,47和46的概率更低,依此类推。

问题:

如何模拟这种“带有概率的随机”选择?
在.NET 6中是否有函数可以实现这一点?

顺便说一下,我正在使用C#,但我认为我可以处理代码,所以我没有在这里编写代码,但我需要逻辑。

提前感谢。

英文:

Let's suppose I've 100 items and I need to split them into two groups.

Options can be:

  1. Divide by 2, so I get exactly 50 and 50

  2. Select a random number between 1 and 100 and then separate that amount from the rest.

In option 2, 1 item has the same probability than 50 items (1/100)
But in the reality, I imagine a Gauss bell where for e.g., 50 has the most probability, 49 and 48 the less, 47 and 46 more less, and so far.

Question:

How can simulate that "random with probability" selection?
Is there any function to do this in .NET 6?

By the way I'm working in C# but I think I can handle the lines, so that's why I don't write code here, but not the logic.

Thanks in advance

答案1

得分: 2

你可以通过迭代遍历项目集合,使用概率 p = 0.5 将每个项目分配到集合 1 或集合 2。所得的集合具有二项分布 B(n=100, p=0.5),这将给出正态分布的离散近似。实际结果会有所变化,但集合计数从 50 偏离超过 10 的概率很低,这相当于使用该参数设置的 2 个标准偏差。

我不是 C# 用户,所以不会尝试使用你首选的编程语言,但这相当简单。由于 Python 得到广泛使用并类似于伪代码,以下是用 Python 编写的算法:

import random

# 创建一个包含 1 到 100 的数字的数组
values = [i for i in range(1, 101)]

# 重复以下操作 10 次...
for replication in range(10):
    # 创建两个空数组
    set1 = []
    set2 = []

    # 注意:random.random() 会产生范围在 [0.0, 1.0) 的浮点数值,
    # 获得小于 0.5 的概率是 1/2

    # 遍历上面创建的数组中的每个值
    for value in values:
        if random.random() < 0.5:  # 概率为 1/2
            set1.append(value)     # 该值放入第一个集合
        else:
            set2.append(value)     # 否则放入第二个集合

    # 一旦所有值都已分配,计算每个集合中有多少值,并打印结果
    print(len(set1), " : ", len(set2))

这将生成 10 个类似以下的拆分:

49  :  51
48  :  52
47  :  53
59  :  41
39  :  61
50  :  50
43  :  57
54  :  46
50  :  50
60  :  40

如果你想偏好其中一个集合,可以调整分配的 p 值。通过简单地更改条件为:

if random.random() < 0.7:

你将得到如下结果:

71  :  29
76  :  24
80  :  20
67  :  33
67  :  33
72  :  28
66  :  34
67  :  33
72  :  28
68  :  32
英文:

You can achieve your option 2 by iterating through the set of items and allocating each one to set 1 or set 2 with probability p = 0.5. The resulting sets have a binomial distribution, B(n=100, p=0.5), which will give a discrete approximation to the bell-shaped normal distribution. The actual results will vary, but there's a low likelihood of the set counts varying from 50 by more than 10, which corresponds to 2 standard deviations with that parameterization.

I'm not a C# user so I won't attempt to fake it in your preferred language, but it's pretty straightforward. Since Python is widely used and is pseudocode-like, here's the algorithm in that language:

import random

# create an array with the numbers 1 to 100
values = [i for i in range(1, 101)]

# repeat the following set of operations 10 times...
for replication in range(10):
    # create two empty arrays
	set1 = []
	set2 = []

    # Note: random.random() produces float values in the range [0.0, 1.0),
    # the probability of getting a value &lt; 0.5 is 1/2

    # iterate through each of the values from the array created above
	for value in values:
		if random.random() &lt; 0.5:  # with probability 1/2
			set1.append(value)     # the value goes in the first set
		else:
			set2.append(value)     # otherwise it goes in the second set

    # once all values have been allocated, count how
    # many are in each set and print the results
	print(len(set1), &quot; : &quot;, len(set2))

which produces 10 splits such as:

49  :  51
48  :  52
47  :  53
59  :  41
39  :  61
50  :  50
43  :  57
54  :  46
50  :  50
60  :  40

If you want to favor one set or the other, adjust the p-value for the allocations. By simply changing the conditional to

if random.random() &lt; 0.7:

you'll get results such as:

71  :  29
76  :  24
80  :  20
67  :  33
67  :  33
72  :  28
66  :  34
67  :  33
72  :  28
68  :  32

huangapple
  • 本文由 发表于 2023年3月4日 06:41:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75632447.html
匿名

发表评论

匿名网友

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

确定