英文:
Split an amount into 2 random groups by Gauss bell
问题
假设我有100个物品,需要将它们分成两组。
选项可以是:
-
将它们分成两半,所以我得到确切的50和50。
-
选择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:
-
Divide by 2, so I get exactly 50 and 50
-
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 < 0.5 is 1/2
# iterate through each of the values from the array created above
for value in values:
if random.random() < 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), " : ", 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() < 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论