Describe an implementation of the procedure RANDOM(a, b) that only makes calls to RANDOM(0, 1). What is the expected running time of your procedure, as a function of a and b?
这是算法导论中随机算法部分的一道题,看似很简单,我却花了好几天才想出一个比较流氓的答案。
后悔当初学数学的时候不好好学概率啊。
#define RAND_0_OR_1 ( rand()&1 )
int rand_t(int a, int b){
if( a > b) return rand_t( b, a );
int max = ( a - b > 0 ) ? ( a - b ) : ( b - a );
int i;
int nRes = max + 1;
while( nRes > max )
{
nRes = 0;
i = 1;
while( i < max + 1 )
{
i <<= 1;
nRes += RAND_0_OR_1;
nRes <<= 1;
}
nRes >>= 1;
}
return a + nRes;
}
基本的原理是:
先把一般的情况化为(0, b - a), 之后令max = b - a, 生成从0 到 2^k - 1的一个随机数nRes,其中
2^(k-1) - 1 <= max < 2^k - 1, 如果nRes大于max,则重新生成直到nRex <= max为止。这个循环会在非常有
限的次数内结束,因为进行10次以上的概率 < 1 / (2^10)。(具体原理请参照概率论的初步知识)
在生成的结果中,每个在0 ~ max之间的数目出现的概率为 1 / 2^k。
这里我使用了C标准库的随机数函数来取得随机的0和1。
其实这个算法算是比较流氓的。大家如果有有更好的算法,请联系并告诉我,小弟将不胜感激。