根据概率选择随机项目

发布于 2024-08-31 12:53:05 字数 274 浏览 5 评论 0原文

有一个类似的问题,我知道,但这让我很困惑,所以我认为用我的方式问更容易。

所以我有一系列值,包括正值和负值。等级越高,被选中的概率就越大。
我实际上很难弄清楚如何分配概率然后随机选择一个。我猜数组需要先进行排序,但之后我就有点迷失了。

There's a similar question, I know, but it confused me, so I thought it easier to ask in my way.

So I have an array of values, positive and negative. The higher they are, the more probability they have of being chosen.
I'm having trouble actually figuring out how to assign the probabilities and then randomly choose one. I'm guessing the array will need to be sorted first, but then I'm a bit lost after that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

安静 2024-09-07 12:53:05

“我有各种不同尺寸的咖啡。它们越大,我就越想为其收取更多费用。我实际上很难弄清楚如何定价”。

这不仅仅是一个编程问题 - 您已经指定概率随值增加,但您没有说明它如何随值增加。通常情况下,咖啡店不会按照咖啡量的多少直接收费。您不能按照值的比例分配概率,因为某些值是负数,但概率不能为负数。

听起来您需要先进一步确定问题,然后才能编写任何代码。

如果您真的不关心概率与值的关系,除了它们按值的顺序增加之外,那么一个简单的方法是:

  • 对数组进行排序,
  • 将 1 的概率分配给第一个元素,将 2 分配给第二个元素,依此类推在。
  • 现在,你的概率加起来不等于 1,这是一个问题。因此,将每个概率除以您分配的所有概率的总和:(1 + 2 + .. + n) = n(n+1)/2。这称为“标准化”。

给定概率列表(总计为 1),重复选择一个概率的最简单方法通常是计算累积概率,我将通过一个示例进行演示:

value (sorted):           -12     -3      127    1000000
assigned probability:     0.1     0.2     0.3      0.4
cumulative probability:   0.1     0.3     0.6      1.0

累积概率定义为总和到那时为止的所有概率。

现在,您需要从随机数生成器中获得一个 0 到 1 之间的随机(浮点)值。如果它位于 0 到 0.1 之间,则您选择了 -12。如果它介于 0.1 和 0.3 之间,则您选择 -3,依此类推。要确定它位于哪个范围,您可以线性遍历数组,或者可以进行二分搜索。

如果需要,您可以跳过标准化步骤和浮点的使用。分配“累积概率” (1, 3, 6, 10 ...) ,但要让人们理解实际概率是存储的整数值除以 n(n+1)/2。然后选择一个 0 到 n(n+1)/2 - 1 之间的随机整数。如果它小于 1,则您选择了第一个值,否则如果小于 3,则选择第二个值,依此类推。这可能会或可能不会使代码更清晰,并且您的 RNG 可能会或可能不会很好地从大范围中选择整数值。

请注意,您可以分配概率 (0.001, 0.002, 0.003, 0.994) 而不是 (0.1, 0.2, 0.3, 0.4),并且仍然满足您的要求“值越高,概率越高”。

"I have various different sizes of cups of coffee. The larger they are, the more I want to charge for them. I'm having trouble actually figuring out how to assign prices".

This isn't just a programming problem - you've specified that probability increases with value, but you haven't said how it increases with value. Normally, coffee shops don't charge in direct proportion to the amount of coffee. You can't assign probabilities in proportion to value, because some of your values are negative, but probabilities cannot be negative.

Sounds like you need to nail down the problem a bit more before you can write any code.

If you really don't care how probability relates to value, other than that they increase in order of value, then one easy way would be:

  • sort your array
  • assign a probability of 1 to the first element, 2 to the second, and so on.
  • now, your probabilities don't add up to 1, which is a problem. So divide each probability by the total of all the probabilities you have assigned: (1 + 2 + .. + n) = n(n+1)/2. This is called "normalization".

Given your list of probabilities, which add up to 1, the easiest way to repeatedly choose one is generally to calculate the cumulative probabilities, which I will demonstrate with an example:

value (sorted):           -12     -3      127    1000000
assigned probability:     0.1     0.2     0.3      0.4
cumulative probability:   0.1     0.3     0.6      1.0

The cumulative probability is defined as the sum of all the probabilities up to that point.

Now, from your random number generator you need a random (floating-point) value between 0 and 1. If it lies between 0 and 0.1, you've picked -12. If it lies between 0.1 and 0.3, you've picked -3, and so on. To figure out which range it lies in, you could walk linearly through your array, or you could do a binary search.

You could skip the normalization step and the use of floating-point, if you wanted. Assign "cumulative probabilities" (1, 3, 6, 10 ...) , but make it understood that the actual probability is the stored integer value divided by n(n+1)/2. Then choose a random integer from 0 to n(n+1)/2 - 1. If it's less than 1, you've selected the first value, else if less than 3 the second, and so on. This may or may not make the code clearer, and your RNG may or may not do well choosing integer values from a large range.

Note that you could have assigned probabilities (0.001, 0.002, 0.003, 0.994) instead of (0.1, 0.2, 0.3, 0.4), and still satisfied your requirement that "the higher the value, the higher the probability".

浸婚纱 2024-09-07 12:53:05

一种方法可以是

  • 使所有值均为正(将最小值的绝对值添加到所有值)
  • 将值标准化为总和为 1(将每个值除以值的总和)

要从生成的分布中随机化一个值,现在您可以

  • 选择[0,1] 上的随机数。
  • 开始对概率求和,直到总和大于或等于随机值。选择该索引作为随机值。

One way could be

  • Make all values positive (add absolute value of the minimum value to all values)
  • Normalize the values to sum to 1 (divide each value with the sum of the values)

To randomize a value from the generated distribution now you can

  • Pick random number on [0,1].
  • Start summing the probabilites until the sum is greater or equal to the random value. Choose that index as your random value.
℡寂寞咖啡 2024-09-07 12:53:05

遵循 Steve Jessop 的建议,在选择 0 到 n(n+1)/2 - 1 之间的随机整数后,您可以得到三角根: (-1 + sqrt((8*x)+1 ))/2

Following up on Steve Jessop's suggestion, after you've chosen a random integer from 0 to n(n+1)/2 - 1, you can just get the triangular root: (-1 + sqrt((8*x)+1))/2

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文