作者:裕作
(本文为原创,转贴请注明出处:http://blog.csdn.net/KyosukeNo1)
在自然界中,虽然存在着一定的客观规律,但并没有绝对的可能性和不可能性。因此,使用随机概率去描述事物的发生与消亡,最能贴切反应事物原有特征。
随机函数最一般性的运用,莫过于使用%来简单的限制随机数值的大小――相信经常使用Random函数的读者,对random() % RANDOM_RANGE的随机几率产生已经十分的熟悉了,然而,在实际的应用中,随机几率有着更复杂的应用。本文将介绍2种随机几率使用方面的小窍门,以之抛砖引玉,希望能引起读者们的一点讨论。
小窍门一:累计型随机几率的快速查找。
假设A的几率是25,B的几率是35,C的几率是20,那么怎么才能用最简单的方法去随机的、按照设定的概率去得到随机数呢?以下是以C++的实现代码:
int i; // 用做循环的变量(废话-_-b)
int nProb[] = { 25, 35, 20 }; // 设定各元素的概率
int nSum = 0; // 存储概率总数的变量
for( i=0; i<sizeof(nProb)/sizeof(int); i++ )
nSum += nProb[i]; // 计算概率的总数
int nRand = rand() % nSum; // 取一个在概率的总数范围内的随机数
for( i=0; i<sizeof(nProb)/sizeof(int); i++ ) {
if( nRand < nProb[i] ) {
break; // 第i个元素命中
} else {
nRand -= nProb[i]; // 把随机数减去之前不命中的元素的概率
}
}
这种算法的步骤很简单:
-
首先把所有概率的总数统计出来,然后以此作为随机数nRand的取值范围。
-
依次把nRand和当前元素的概率比较,如果nRand小于这个概率,则命中这个元素,退出查找。
-
如果nRand大于当前元素的概率,就用nRand减去该元素的概率,然后回到步骤2,直至所有元素查找完毕。
这种算法的优点是计算量小,而且容易在不同的编程语言中使用。
小窍门二:几率可以表示为分母为2的次方数时的快速查找。
在某些情况下,当前需要计算的随机几率可以表示为一个分母为2的此方数的分数:例如1/4,3/4,1/16,15/16等等,这时只要以以下的公式,就能快速的计算:
// 例1
// 元素A的概率是1/4
// 元素B的概率是3/4
int nRand = rand() & 0x3;
if( nRand == 0 )
{
// 命中元素A
}
else
{
// 命中元素B
}
// 例2
// 元素A的概率是1/16
// 元素B的概率是15/16
int nRand = rand() & 0xF;
if( nRand == 0 )
{
// 命中元素A
}
else
{
// 命中元素B
}