我不太清楚如何解决这个问题。
我需要生成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 ......}
答案 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。