减少从连续数字列表中选择数字的机会

时间:2017-07-13 14:28:15

标签: java random percentage

比方说,我得到了号码3。然后我必须选择0到3之间的随机数,但是0的选择概率大于1,1选择的概率大于2,而2选择的概率大于3。 / p>

我已经知道,通过执行以下操作可以实现从0到3选择特定数字的百分比:

double r = Math.random();
int n = 0;
if (r < 0.5) {
    n = 0;
    // 50% chance of being 0
} else if (r < 0.8) {
    n = 1;
    // 30% chance of being 1
} else if (r < 0.95) {
    n = 2;
    // 15% chance of being 2
} else {
    n = 3;
    // 5% chance of being 3
}

问题是3可以是任何东西。我怎么能这样做?

注意:数字0.5,0.8和0.95由我任意选择。我希望这些数字减少,以便所有这些数字的总和等于1,因此如果可能的话,它们都不相同。

4 个答案:

答案 0 :(得分:6)

这似乎是您希望使用通用概率分布,其域可以根据您的喜好进行缩放。您可以选择f(0) = 0f(1) = 1之类的任何功能。对于此示例,我将采用f(x) = x^2

要从此处获取随机数 - 更多值集中在0附近 - 我们可以执行以下操作:

numbers = ceil(max * f(rand()))

其中ceil是天花板函数,max是您想要的最高输出,f()是您选择的函数,rand()给出一个零之间的随机数一个。请注意,此函数的输出范围为1max,而不是0max

下面的图表可以让您了解为什么这实际上有效:

Graph of <code>ceil(f(x))</code> for <code>max == 10</code>)

请注意,当整数变大时,选择整数的可能性会减小 - 即ceil(max * f(x))等于“最长”1和“最短”10。

如果您希望所选数字与其数量之间存在直接关系,则只需选择不同的f(x)即可。然而,在这一点上,这变成了一个数学问题而不是其他任何东西。我会寻找一个合适的f(x) - 如果我理解你至少要找的东西并回复你。我猜到现在f(x)将是e^x,但我会仔细检查。

我希望这有帮助!

快速代码示例:

public int weightedRandom(int max, Random rand) {
     return Math.ceil(((double) max) * Math.pow(rand.nextDouble(), 2));
}

我还在java程序中打印了一对,并在max == 10

中得到了以下列表
2.0, 6.0, 8.0, 3.0, 2.0, 2.0, 1.0, 1.0, 1.0, 1.0, 7.0, 1.0, 4.0, 1.0, 1.0, 6.0, 8.0, 9.0, 7.0, 5.0

答案 1 :(得分:3)

我建议使用public double nextGaussian()中的java.util.Random方法 这允许在平均值

周围具有更多元素的分布

我再也不会解释它写在那里的内容Javamex nextGaussian(如果你想了解更多细节)

因此,实际上您需要0n之间的值:

该方法将给出如下值:

  • 70%,与平均值相差1次
  • 95%与平均值的偏差
  • 99%,与平均值相差3次

偏差为1,无任何

 Random r = new Random();
 int n = 10;
 int res = (int) Math.min(n, Math.abs(r.nextGaussian()) * n / 3);

所以:

  • 乘以n:偏差变为n
  • 除以4:使用这样的事实:你可以得到比偏差更大的值(在3偏差时为99%),大约99%的值将在偏差之下(你的n
  • 使用Math.abs,因为它与中间
  • 的对称关系为0
  • 如果值高于Math.min
  • ,请使用n作为最终检查

测试10 000次迭代:

Histogram

答案 2 :(得分:0)

您可以将函数应用于随机数,以减少出现数字接近1的机会。 然后乘以你的(无法到达的)最大数字:在这个例子中为4

{{1}}

答案 3 :(得分:0)

“均匀”可能意味着“每个连续数字的概率减少固定数量”或“每个连续数字减少固定百分比的概率”。例如,如果您使用50%的固定百分比随机选择4个数字:

  • 100%的50%是50%,因此第一个数字的概率为50%。
  • 50%的50%是25%,所以第二个数字的概率是25%。'
  • 25%的50%为12.5%,因此第三个数字的概率为12.5%。
  • 您需要的概率加起来为100%,因此最后一个数字(#4)的概率等于倒数第二个数字(#3)的概率 - 即12.5%。

如果你想每次减少一个随机(但递减)的百分比,你可以只生成一个小于前一概率的概率的随机数 - 即如果第一个的概率是0.5 ,第二个的概率是0.0 < p&lt; 0.5。但是,您可能希望比这更复杂一点,否则您可能会面临最后几个项目的微小百分比。例如,如果您为第二项随机选择0.1,则第三项的概率是0.0 <范围内的随机数。 p&lt; 0.1,这是非常小的,它只会从那里变得更糟。您可能希望使连续项的概率同时具有最小值和最大值(例如,第二项的概率为0.3

请注意,我使用<而非<=的事实非常非常重要。例如,您不希望0.0 <= p <= 0.5,因为这意味着第二项可能与第三项(您不想要的)具有相同的概率,并且它是所有后续项目的概率也可能等于0.0(即第一个数字的概率为100%,任何其他数字概率为0%,这根本不是你想要的)。

后一种策略的弱点在于你必须调整其中一个概率,使它们加起来为1.0。