抽奖应该都不陌生,常见的双色球、摇号等。本文以简单的根据指定的概率选择奖项为例,简单介绍一下。
首先,看一下大家常见的简单的抽奖。
比如,有两项:中奖和不中奖,中奖概率0.3,不中奖概率0.7。一般都是这样实现的。
public int PrabalityRandom()
{
Random random = new Random();
if (random.Next(1000) > 700)
{
return 1;//表示中奖
}
else
{
return 0;//表示不中奖
}
}
以此为基础,那么当有N个奖项,每项都有指定的中奖概率。如下实现,
有五项,
奖项1,概率:0.01;
奖项2,概率:0.04;
奖项3,概率:0.02;
奖项4,概率:0.03;
不中奖5,概率:0.9;
实现方法:
按概率从小打到排序,然后使用累计概率-当前概率+前一项累计概率。
奖项1,概率:0.01;累积概率:0.01
奖项3,概率:0.02;累积概率:0.03
奖项4,概率:0.03;累积概率:0.06
奖项2,概率:0.04;累积概率:0.1
不中奖5,概率:0.9;累积概率:1.0。
程序:
class Program
{
static void Main(string[] args)
{
List<KeyValuePair<long, double>> elements = new List<KeyValuePair<long, double>>();
elements.Add(new KeyValuePair<long, double>(1, 0.01));
elements.Add(new KeyValuePair<long, double>(2, 0.04));
elements.Add(new KeyValuePair<long, double>(3, 0.02));
elements.Add(new KeyValuePair<long, double>(4, 0.03));
elements.Add(new KeyValuePair<long, double>(5, 0.9));
//概率计算
double allRate = 0;
foreach (var item in elements)
{
allRate += item.Value;
}
if (allRate != 1)
{
Console.WriteLine("奖品概率设置错误!");
Console.WriteLine(allRate);
Console.ReadLine();
return;
}
Random random = new Random();
long selectedElement = 0;
while (true)
{
//连抽20次已查看中奖分布情况,5为不中奖
for (int n = 0; n < 20; n++)
{
double diceRoll = random.NextDouble();
double cumulative = 0.0;
for (int i = 0; i < elements.Count; i++)
{
cumulative += elements[i].Value;
if (diceRoll <= cumulative)
{
selectedElement = elements[i].Key;
break;
}
}
Console.WriteLine(selectedElement);
}
string read = Console.ReadLine();
if (read=="e")
{
break;
}
}
Console.WriteLine(selectedElement);
Console.ReadLine();
}
}
看一组数据:
其实这样的算法,是达不到真正中奖的要求的,原因在与随机数的生成,他的概率是不知道的。这样算出的结果不是原本设定的概率。当然这需要结合概率的相关知识才能实现真正的根据概率得出的中奖结果。待续...
代码:http://download.youkuaiyun.com/detail/yysyangyangyangshan/6321281