C# 概率与随机数发生器

C# 概率与随机数发生器,c#,C#,我正在研究一个涉及概率和随机数生成器的问题,我相信我和它关系密切,但需要帮助敲定最后一件事。我有一个大理石包,我会在里面输入不同颜色的大理石数量。意思是红色10绿色5蓝色5橙色3。我必须推断出每个彩色大理石的概率,然后根据概率随机生成大理石的数量。到目前为止,我可以这样计算概率 int MarbleCnt = red + green + blue + orange; double probRed = (double)red / MarbleCnt; double probGreen

我正在研究一个涉及概率和随机数生成器的问题,我相信我和它关系密切,但需要帮助敲定最后一件事。我有一个大理石包,我会在里面输入不同颜色的大理石数量。意思是红色10绿色5蓝色5橙色3。我必须推断出每个彩色大理石的概率,然后根据概率随机生成大理石的数量。到目前为止,我可以这样计算概率

  int MarbleCnt = red + green + blue + orange;
  double probRed = (double)red / MarbleCnt;
  double probGreen = (double)green / MarbleCnt;
  double probBlue = (double)blue / MarbleCnt;
  double probOrange = (double)orange / MarbleCnt;
然后我计划使用
Random()

for (int i = 0; i < 10; i++) {
    double randNum = mRandom.NextDouble();             
    if (0 <= randNum && randNum < probRed) { probArr[i] = RED_MARBLE; }
    else if (probRed <= randNum && randNum < probGreen) { probArr[i] = GREEN_MARBLE; }
    else if (probGreen <= randNum && randNum < probBlue) { probArr[i] = BLUE_MARBLE; }
    else  { probArr[i] = ORANGE_MARBLE; }
}
for(int i=0;i<10;i++){
double randNum=mRandom.NextDouble();

如果(0个人而言,我根本不会使用
double
——我只会选择一个介于0(包括)和大理石总数(不包括)之间的随机整数。实际上,你会用一个数字“标记”每个大理石,然后根据随机整数确定拾取了哪个大理石。例如:

MarbleColor PickMarble
    (Random rng, int redCount, int greenCount, int blueCount, int orangeCount)
{
    int index = rng.Next(redCount + greenCount + blueCount + orangeCount);
    if (index < redCount)
    {
        return MarbleColor.Red;
    }
    if (index < redCount + greenCount)
    {
        return MarbleColor.Green;
    }
    if (index < redCount + greenCount + blueCount)
    {
        return MarbleColor.Blue;
    }
    return MarbleColor.Orange;
}
MarbleColor拾取大理石
(随机计数、整数红色计数、整数绿色计数、整数蓝色计数、整数橙色计数)
{
int index=rng.Next(红色计数+绿色计数+蓝色计数+橙色计数);
如果(索引<红色计数)
{
返回大理石色。红色;
}
如果(索引<红色计数+绿色计数)
{
返回大理石色。绿色;
}
如果(索引<红计数+绿计数+蓝计数)
{
返回大理石色。蓝色;
}
返回大理石色。橙色;
}

这基本上与使用双精度的方法相同,但更容易理解(IMO)。

就我个人而言,我根本不会使用
double
——我只会在0(包括)和大理石总数(不包括)之间选择一个随机整数。实际上,你是在“标记”每个大理石都有一个数字,然后根据随机整数计算出拾取的大理石。例如:

MarbleColor PickMarble
    (Random rng, int redCount, int greenCount, int blueCount, int orangeCount)
{
    int index = rng.Next(redCount + greenCount + blueCount + orangeCount);
    if (index < redCount)
    {
        return MarbleColor.Red;
    }
    if (index < redCount + greenCount)
    {
        return MarbleColor.Green;
    }
    if (index < redCount + greenCount + blueCount)
    {
        return MarbleColor.Blue;
    }
    return MarbleColor.Orange;
}
MarbleColor拾取大理石
(随机计数、整数红色计数、整数绿色计数、整数蓝色计数、整数橙色计数)
{
int index=rng.Next(红色计数+绿色计数+蓝色计数+橙色计数);
如果(索引<红色计数)
{
返回大理石色。红色;
}
如果(索引<红色计数+绿色计数)
{
返回大理石色。绿色;
}
如果(索引<红计数+绿计数+蓝计数)
{
返回大理石色。蓝色;
}
返回大理石色。橙色;
}

这基本上与使用双精度的方法相同,但更容易理解(IMO)。

就我个人而言,我根本不会使用
double
——我只会在0(包括)和大理石总数(不包括)之间选择一个随机整数。实际上,你是在“标记”每个大理石都有一个数字,然后根据随机整数计算出拾取的大理石。例如:

MarbleColor PickMarble
    (Random rng, int redCount, int greenCount, int blueCount, int orangeCount)
{
    int index = rng.Next(redCount + greenCount + blueCount + orangeCount);
    if (index < redCount)
    {
        return MarbleColor.Red;
    }
    if (index < redCount + greenCount)
    {
        return MarbleColor.Green;
    }
    if (index < redCount + greenCount + blueCount)
    {
        return MarbleColor.Blue;
    }
    return MarbleColor.Orange;
}
MarbleColor拾取大理石
(随机计数、整数红色计数、整数绿色计数、整数蓝色计数、整数橙色计数)
{
int index=rng.Next(红色计数+绿色计数+蓝色计数+橙色计数);
如果(索引<红色计数)
{
返回大理石色。红色;
}
如果(索引<红色计数+绿色计数)
{
返回大理石色。绿色;
}
如果(索引<红计数+绿计数+蓝计数)
{
返回大理石色。蓝色;
}
返回大理石色。橙色;
}

这基本上与使用双精度的方法相同,但更容易理解(IMO)。

就我个人而言,我根本不会使用
double
——我只会在0(包括)和大理石总数(不包括)之间选择一个随机整数。实际上,你是在“标记”每个大理石都有一个数字,然后根据随机整数计算出拾取的大理石。例如:

MarbleColor PickMarble
    (Random rng, int redCount, int greenCount, int blueCount, int orangeCount)
{
    int index = rng.Next(redCount + greenCount + blueCount + orangeCount);
    if (index < redCount)
    {
        return MarbleColor.Red;
    }
    if (index < redCount + greenCount)
    {
        return MarbleColor.Green;
    }
    if (index < redCount + greenCount + blueCount)
    {
        return MarbleColor.Blue;
    }
    return MarbleColor.Orange;
}
MarbleColor拾取大理石
(随机计数、整数红色计数、整数绿色计数、整数蓝色计数、整数橙色计数)
{
int index=rng.Next(红色计数+绿色计数+蓝色计数+橙色计数);
如果(索引<红色计数)
{
返回大理石色。红色;
}
如果(索引<红色计数+绿色计数)
{
返回大理石色。绿色;
}
如果(索引<红计数+绿计数+蓝计数)
{
返回大理石色。蓝色;
}
返回大理石色。橙色;
}

这与使用double的方法基本相同,但更容易理解(IMO)。

我也会避免使用
double
。虽然这看起来很自然,因为你在处理概率,但你会发现你最终编写的代码很难证明正确性和进行调试

最好尝试更离散地模拟大理石袋

我会这样做:

var red = 10;
var green = 5;
var blue = 5;
var orange = 2;

var rnd = new Random();

var bag =
    Enumerable.Repeat(RED_MARBLE, red)
        .Concat(Enumerable.Repeat(GREEN_MARBLE, green))
        .Concat(Enumerable.Repeat(BLUE_MARBLE, blue))
        .Concat(Enumerable.Repeat(ORANGE_MARBLE, orange))
        .OrderBy(m => rnd.Next())
        .ToList();
我现在有一个统一的混合弹珠袋,我可以从中挑选,以模拟从袋中移除弹珠


虽然这不如纯粹的数学方法那么有效,但它仍然非常快。我可以用这种方法在1秒内制作和分类一个装有180万颗弹珠的袋子。

我也会避免使用
双精度
。虽然这看起来很自然,因为你在处理概率,你会发现在编写代码时,很难证明正确性和进行调试

最好尝试更离散地模拟大理石袋

我会这样做:

var red = 10;
var green = 5;
var blue = 5;
var orange = 2;

var rnd = new Random();

var bag =
    Enumerable.Repeat(RED_MARBLE, red)
        .Concat(Enumerable.Repeat(GREEN_MARBLE, green))
        .Concat(Enumerable.Repeat(BLUE_MARBLE, blue))
        .Concat(Enumerable.Repeat(ORANGE_MARBLE, orange))
        .OrderBy(m => rnd.Next())
        .ToList();
我现在有一个统一的混合弹珠袋,我可以从中挑选,以模拟从袋中移除弹珠


虽然这不如纯粹的数学方法那么有效,但它仍然非常快。我可以用这种方法在1秒内制作和分类一个装有180万颗弹珠的袋子。

我也会避免使用
双精度
。虽然这看起来很自然,因为你在处理概率,你会发现在编写代码时,很难证明正确性和进行调试

最好尝试更离散地模拟大理石袋

我会这样做:

var red = 10;
var green = 5;
var blue = 5;
var orange = 2;

var rnd = new Random();

var bag =
    Enumerable.Repeat(RED_MARBLE, red)
        .Concat(Enumerable.Repeat(GREEN_MARBLE, green))
        .Concat(Enumerable.Repeat(BLUE_MARBLE, blue))
        .Concat(Enumerable.Repeat(ORANGE_MARBLE, orange))
        .OrderBy(m => rnd.Next())
        .ToList();
我现在有了一个统一洗牌的弹珠袋,我可以从中挑选