随机发生

时间:2011-08-10 19:32:26

标签: c# random probability

我不太清楚如何解决这个问题。

我需要生成14,296个具有不同概率水平的随机数。

所以例如我需要一个包含数字18,1和17的数组。每个数字都有不同的百分比发生。所以:

  

55%= 18
  (7,862.8次)

     

30%= 1
  (4,288.8次)

     

15%= 17
  (2,144.4次)

结果将类似于新的Array(){18,18,1,17,1,18 ......}

5 个答案:

答案 0 :(得分:4)

如果你总是把值作为整数百分比,我会根据概率填充100个元素的数组,所以在这种情况下你的数组会有55次出现18次,30次出现1次,并且15次出现17.然后你只需从该数组中选择14,296个随机值。 (即选择[0,100]范围内的整数并取该元素。)

对于表达概率的不同方式,当然有不同的方法。但如果你给出整数百分比,这是一个容易理解的选项。 (另一种方法是按总数来缩放所有概率,即进入[0,1]的范围,然后在该范围内取一个随机双精度。)

答案 1 :(得分:2)

将随机生成器的范围除以比例段,并判断下一个随机数落入哪个段,从您的集合中选择相应的数字。

像(简化)的东西:

const int numbers[3] = { 1, 17, 18 };
const int borders[2] = { 0.30*MAX_RANDOM, (0.30 + 0.15) *  MAX_RANDOM };

int i = random.next(), num;

if      (i < borders[0]) num = number[0];
else if (i < borders[0]) num = number[1];
else num = number[2];

当然,如果数字多于三个,最好使用循环。

注意:与Jon Skeet的解决方案不同,这个解决方案可以提供任何所需的粒度,最高可达1 /(MAX_RANDOM + 1)(在32位机器上通常高达2 ^ 32),而不是严格的1%。

答案 2 :(得分:1)

Random r = new Random();

// for each number to generate
int nextNumber;
double probability = r.NextDouble();
if (probability < 55.0 / 100.0)
    nextNumber = 18;
else if (probability < (55.0 + 30.0) / 100.0)
    nextNumber = 1;
else
    nextNumber = 17;

答案 3 :(得分:1)

这样的事情(未经测试):

struct np
{
    int n;
    int p;
}

创建List<np>并使用值/百分比对(例如n = 18, p = 55)。

然后只需执行以下操作即可选择一个数字:

List<np> npl = new List<np>();
// (fill the list here)



int r = rnd.next(total_of_all_p_values); // get random number
int res = 0; // result
for(int i = 0; i < npl.Length(); r -= npl[i++].n)
{
    if(r < npl[i].p) // remaining vlaue is smaller than current percentage
    {
        res = npl[i].n;
        break;
    }
}

答案 4 :(得分:0)

您可以使用3个数字中每个数字的相应数量填充List<T>,然后randomize the List