C 对于我使用过程Rand(0,1)创建过程Rand(A,b)的方法,一个更好的解决方案

C 对于我使用过程Rand(0,1)创建过程Rand(A,b)的方法,一个更好的解决方案,c,algorithm,random,big-o,clrs,C,Algorithm,Random,Big O,Clrs,我一直在读CLR,在编写过程Rand(a,b)时遇到了一个问题,该过程随机均匀地生成a到b之间的随机数,使用过程Rand(0,1),该过程以50%的概率生成0或1 我想到了以下解决方案,即O(b): int Rand_a_b(int a,int b) { int i,k=0; 对于(i=0;i,这里有一个算法:计算a和b之间的差值:k=abs(a-b),然后开始进行二进制搜索,如下所示: 保留一个数字n=0。抛硬币-Rand(0,1),如果结果是1,则在你的n中添加k/2,否则不添加任何内容。然

我一直在读CLR,在编写过程Rand(a,b)时遇到了一个问题,该过程随机均匀地生成a到b之间的随机数,使用过程Rand(0,1),该过程以50%的概率生成0或1

我想到了以下解决方案,即O(b):

int Rand_a_b(int a,int b)
{
int i,k=0;

对于(i=0;i,这里有一个算法:计算a和b之间的差值:
k=abs(a-b)
,然后开始进行二进制搜索,如下所示:


保留一个数字
n=0
。抛硬币-
Rand(0,1)
,如果结果是1,则在你的
n
中添加
k/2
,否则不添加任何内容。然后再次抛硬币
k/4
,重复抛硬币,直到
k/i
为0。这里有一个算法:计算a和b之间的差值:
k=abs(a-b)
然后开始进行二进制搜索,如下所示:


保留一个数字
n=0
。掷硬币-
Rand(0,1)
,如果结果是1,则在你的
n中添加
k/2
,否则不添加任何内容。然后再掷一次
k/4
,然后重复,直到
k/i
为0。

这里应该在日志(n)中添加
k/2
(我没有检查边界,它没有经过测试!) 你不能让它更快——如果你一次只发射一个比特,你至少需要一个间隔的对数(b-a)轮

function Rand_a_b(int a, int b) {
   if (a == b) return a;
   int middle = (b-a)/2;
   if (Rand(0,1)) {
      return Rand_a_b(middle + 1, b);
   } else {
      return Rand_a_b(a, middle);
   }
}

这里应该在日志(n)中。(我没有检查边界,它没有经过测试!) 你不能让它更快——如果你一次只发射一个比特,你至少需要一个间隔的对数(b-a)轮

function Rand_a_b(int a, int b) {
   if (a == b) return a;
   int middle = (b-a)/2;
   if (Rand(0,1)) {
      return Rand_a_b(middle + 1, b);
   } else {
      return Rand_a_b(a, middle);
   }
}

如果范围内不同数字的数量不是2的幂,则必须小心,因为任何始终使用N个数字的过程只能看到2^N个不同的可能性,如果范围内没有两个不同可能性的幂,则不可能在一个范围内均匀分布2^N个不同的可能性


在a..b之间生成数字时,一种方法是使用k个随机数作为k位数字中的单个位来生成a..a+2^k-1范围内的数字,其中选择k使a+2^k-1>=b。如果结果表明您生成的随机数超出范围,请重新开始。这通过使用变量来避免上述问题随机位数,取决于您是否生成超出范围的内容,以及您必须重新开始的频率。

如果范围内的不同数字的数量不是2的幂,您必须小心,因为任何始终使用N个数字的过程只会看到2^N种不同的可能性,因此无法分发如果一个范围内没有两种不同可能性的幂,则在该范围内均匀分配2^N种不同的可能性


在a..b之间生成数字时,一种方法是使用k个随机数作为k位数字中的单个位来生成a..a+2^k-1范围内的数字,其中选择k使a+2^k-1>=b。如果结果表明您生成的随机数超出范围,请重新开始。这通过使用变量来避免上述问题不可编辑的随机位数,这取决于您是否生成超出范围的内容并必须重新开始。您的函数没有生成统一的分布,而且它假定
b
不安全地大于
a
。您使用的是哪种语言?为什么不给出统一的分布?请详细说明。让我们来看看比如说
a==0
b==2
。概率
1/4
得到
0
2
概率
1/4
1
概率
1/2
。更一般地说,你的函数不生成均匀分布,加上它假设
b
大于
a
不安全。你用的是哪种语言?为什么它不能给出一个统一的分布?请详细说明。比如说
a==0
b==2
。你用概率
1/4
得到
0
,用概率
1/4
得到
2
得到概率
1/2
。更一般地说:啊,是的d发射位是一种方法!如果
(b-a+1),它将起作用
2
的幂。如果
a==0
b==2
,那么
2
是以概率选择的
1/2
0
1
是以概率选择的
1/4
。啊,是的,确实发射比特是一种方法!如果
(b-a+1)它会起作用
2
的幂。如果
a==0
b==2
2
以概率
1/2
选择;
0
1
以概率
1/4
选择。如果
b-a+1
不是二的幂,分布将不均匀。@AlexD-这是一般的伪码。如何处理不均匀数等问题显然不包括在本文中。如果
b-a+1
不是二的幂,分布将不均匀。@AlexD-这是一般的伪代码。如何处理不均匀数等问题显然不包括在本文中。