随机概率选择

时间:2011-08-04 22:12:24

标签: c# random probability

说我有10个奖品给100个人。每个人一次射击一次。因此,如果第一个人未能赢得奖品,则概率会上升,99分中为10分,所以一个......所有10个奖项必须去。

最好的方法是以最终的方式写这个,如果还剩下奖品,那么这个人将有一个机会获得奖品......

我的想法是这样的:

int playersLeft = 100
int winners = 0

while (winners < 10)
    winners += (random.Next(playersLeft--)<(10-winners)) ? 1 : 0;

我想知道是否有更好或更直接的方式来做到这一点。我知道这似乎很简单,但这个简单的任务是应用程序非常重要的一部分,它必须是正确的。

要澄清:为什么我要这样做:

实际上有无限数量的玩家,每个玩家都有一个X的Y概率获胜,比如说10/100 = 10%。但是,如果我把它留给随机数生成器,那么在100个玩家中,只有9个会赢,或者最差,11个。在我的应用程序中,我必须保证每100个玩家不会再多于10个玩家取胜。

4 个答案:

答案 0 :(得分:3)

每个人都有平等的获胜机会吗?在这种情况下,为什么不只是随机选择10个不同的数字1-100然后假装按顺序执行呢?

var winners = new HashSet<int>();
while(winners.Count < 10)
{
  var number = random.Next(100);
  if(!winners.Contains(number)) winners.Add(number);
}

for(i = 0; i < 100; i++)
{
  if(winners.Contains(i)) Console.WriteLine("{0} won!!!", i);
  else Console.WriteLine("{0} didn't win, sorry...", i);
}

答案 1 :(得分:2)

我已经考虑过这个问题了,并提出了以下建议。我们可以让第一个人获得公平的胜利,然后如果剩下的奖励在其他人中公平分配(无论他是赢还是输),那么整个事情都是公平的。当然,这远非正式证据,所以请随意纠正我。以下应该给出一个公平的系统:

int prizes = 10;
for(int i = 100; i >= 1; i++)
{
  var result = random.Next(people);
  if(result < prizes)
  {
     Console.WriteLine("{0} won", i);
     prizes--;
  }
}

编辑:证明这有效:

  1. 第一个人通常有 n / k 获胜机会( n 是奖品数量, k 是人数。
  2. 我们假设我们在剩下的人中公平分配剩余的奖品。在这种情况下,他们将在概率 n / k n-1 之间分配概率(kn)/ k ,<强> n 奖品。这相当于(n *(n-1))/ k +(n *(kn))/ k = n *(k-1)/ k ,这是它们的公平份额奖品。
  3. 我们使用相同的方法在 k-1 人群中分发 n-1 n 奖品。 Q.E.D。

答案 2 :(得分:1)

这将为您提供强制获胜者的概率随着人数减少而变为1.0的行为。然而,正如@obrok指出的那样,获奖者的概率取决于他们在100人名单中的排名。

这实际上与用于“N选择K”子集选择的算法相同。 http://mcherm.com/permalinks/1/a-random-selection-algorithm

int prizes = 10;
int people = 100;

while ( prizes > 0 ) {
   double probOfWin = (double) prizes / people; 
   if ( random.NextDouble() <= probOfWin ) {
      prizes--;
   }
   people--;
}

答案 3 :(得分:0)

完美公平的方法是生成一个从1到(100!/(90!* 10!))的随机数(因为这是获奖者可能组合的数量)并用它来奖励奖品。

然而,使用该数字的某些倍数更容易,例如获奖者的排列数,即(100!/ 90!)。这样做的一种方法是填充100个整数的数组,但每次从数组中删除获胜的整数(用最后一个非获胜整数交换它是实现此目的的最简单方法)。

您的算法有效地需要100的随机性!所以效率低得多,虽然我认为它仍然完全公平。