【问题标题】:C# How to Generate Random Number Depends on ProbabilitiesC#如何生成随机数取决于概率
【发布时间】:2015-07-05 14:45:44
【问题描述】:

我有一种情况,我必须生成一个随机数,这个数必须是zeroone

所以,代码是这样的:

randomNumber = new Random().Next(0,1)

但是,业务需求表明生成的数字只有 10% 的概率为零,而生成的数字为 1 的概率只有 90%

但是,我可以在生成随机数时包含该概率吗?

我想到的是:

  1. 生成包含 10 个零和 90 个一的整数数组。
  2. 生成一个介于 1 到 100 之间的随机索引
  3. 取与该索引对应的值

但我不知道这种方式是不是正确的方式,另外,我认为C#应该已经准备好了

【问题讨论】:

  • 你不能只生成一个 1 到 10 之间的数字然后除以 10 吗? 9 次 ... x/10 将为 0。1 次 x/10 将为 1。
  • @ta.speot.is 我不知道我数学不好
  • .Next(0,1) 这将生成 0 或 0。最大值是独占的,不包括在内。另一件事:我希望你不要每次做Next() 时都做new Random()。这将是错误
  • @xanatos 说得好,谢谢

标签: c# .net math random distributed-computing


【解决方案1】:

以 10% 的概率实现:

bool result = new Random().Next(1, 11) % 10 == 0;

以 40% 的概率实现:

bool result = new Random().Next(1, 11) > 6;

【讨论】:

  • 你不能对结果做一个if 吗?如果结果 > 6,则 number = 1,否则 number = 0 ?
  • @Random 你的意思是解决 40% 和 60% 的问题吗?
  • @MarcoDinatsoli 是的,我编辑了因为它会是> 6而不是>= 6
  • 感谢您的努力,我希望我能接受多个答案,再加一个
【解决方案2】:

你可以这样实现它:

  // Do not re-create Random! Create it once only
  // The simplest implementation - not thread-save
  private static Random s_Generator = new Random();

  ...
  // you can easiliy update the margin if you want, say, 91.234%
  const double margin = 90.0 / 100.0; 

  int result = s_Generator.NextDouble() <= margin ? 1 : 0;

【讨论】:

  • 使用双精度是明智的。它可以防止 &lt;&lt;= 之间的任何混淆,因为它变得微不足道。
  • 但在这种情况下,s_Generator 可以生成介于0MaxDouble 之间的数字,对吗?在这种情况下,您是说所有大于 90 的数字都应视为一,小于 90 的数字为零
  • @Dmitry 这不是微不足道的。它几乎是微不足道的。应该是
  • @MarcoDinatsoli 不。它在 0.0 和 1.0 之间生成。见msdn.microsoft.com/en-us/library/…
  • 对不起,我不知道你在说什么,&lt;= 应该是&lt; 吗?还是还有其他问题?
【解决方案3】:

首先,您应该保存对随机实例的引用,以便获得正确的随机数字序列:

Random randGen = new Random();

要知道的第二件事是,随机的最大值是排他的,所以要正确解决你应该做的问题:

int eitherOneOrZero = randGen.Next(1, 11) % 10;

要将其推广到任何机会变化,您可以这样做:

Random randGen = new Random();
var trueChance = 60;

int x = randGen.Next(0, 100) < trueChance ? 1 : 0;

测试:

Random randGen = new Random();
var trueChance = 60;

var totalCount = 1000;
var trueCount = 0;
var falseCount = 0;

for (int i = 0; i < totalCount; i++)
{
    int x = randGen.Next(0, 100) < trueChance ? 1 : 0;

    if (x == 1)
    {
        trueCount++;
    }
    else
    {
        falseCount++;
    }
}

输出:

正确:60.30 %

错误:39.70 %

【讨论】:

  • 谢谢,但如果我将要求更改为 40% 的零和 60% 的零,您也可以给我一个解决方案吗?
  • 首先,您应该保存对随机实例的引用,以便获得正确的随机数字序列: 这是误导,因为Random 不是线程安全的。如果你在不同的线程上使用引用,你可能不会得到随机数。
  • @ta.speot.is 没错。但是我怀疑他正在使用多个线程。但很高兴知道。在多个线程的情况下,每个线程都应该保留一个引用。不过,您绝对应该每次都创建一个新的 Random 实例。
  • @YoryeNathan 比这要复杂一些。如果每个线程都有不同的Random,您必须确保它们都使用不同的种子。否则几乎同时(相同毫秒)创建的线程将使用相同的种子。
  • @xanatos 您可以通过父线程中的一个随机实例为每个线程提供一个随机种子。不过,让Random 线程安全并不是重点。我是在指出他不应该每次都重新实例化它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 2017-10-01
  • 2016-01-26
  • 1970-01-01
  • 2019-09-14
  • 1970-01-01
相关资源
最近更新 更多