算法导论上的两道概率题

gaoht 2011-03-24 09:27:05
1. random(0, 1)各以1/2的概率返回0或1。基于它实现random(m, n). m,n是任意正整数,n大于m

2. random(0, 1)以概率p返回0,以概率(1-p)返回1。基于它实现random2(0,1),各以1/2的概率返回0和1.

答案是什么
...全文
334 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
疯狂的烤冰 2011-04-03
  • 打赏
  • 举报
回复
第一题用二分的方法,用random(0,1)产生0或1,若产生0,在左半边找,否则在右半边找。时间复杂度是O(lg(n-m))的。
random(m, n)
{
while(m < n)
{
if(random(0, 1))
m = (n+m)/2+1;
else
n = (n+m)/2;
}
return m;
}
第二题会用到上面的函数。将p一直乘以10直到小数点后没有值,这时假设p有x位。然后用上面的函数产生一个从0到10^x的值,若此值大于p,则返回1,否则返回0。
random(0, 1)
{
int x = 0;
while(p-(int)p > 1e-9)
{
p *= 10;
x++;
}
if(random(0, power(10, x)) > p)
return 1;
else return 0;
}
竞天问 2011-03-31
  • 打赏
  • 举报
回复
第一题二分
lx3275852 2011-03-31
  • 打赏
  • 举报
回复
第一题,三楼的解法是对的。。。。。
只能这样解,其他的没考虑线性分布,出来的结果总是靠中间的数字出现的概率最大。。

第二题,1L , 13L是正解。。。。
netbusxp 2011-03-25
  • 打赏
  • 举报
回复
恩 我想了半天也是三楼的做法对 这道题难在咋样把二进制转化为十进制~~
fire_woods 2011-03-25
  • 打赏
  • 举报
回复
額, 被插樓了, 我是說1樓的第一題借錯了, 第二題正確, 但是2樓完全反了.
fire_woods 2011-03-25
  • 打赏
  • 举报
回复
2樓第一題不正確,返回的概率不是平均分布的.
第二題正確, 樓上的完全搞反了......
moorsf 2011-03-25
  • 打赏
  • 举报
回复
我觉得第一题的解法应该是:
先求出S=m-n,然后S不停右移位,每次移位,求一次x<<1+random(0,1),x初始0。直到S为零结束,求得x。
如果m+x大于n就再来一次,否则返回m+x。因为x的值域不超过2*(m-n)所以平均最多两次就可以获得一次。
这个方法可以保证每个数概率一样。

用random(0,1)来累加值域正确,但是概率却不对。
比如(0,3)
得0的情况:(0,0,0)
得1的情况:(1,0,0)(0,1,0)(0,0,1)
的2的情况: (1,1,0)(1,0,1)(0,1,1)
得3的情况: (1,1,1)

第二题理论上来说,1楼的解法是正确的。只是如果p特别接近1或0时效率很低,现实实现可能会考虑别的方法。
icerainfc522 2011-03-25
  • 打赏
  • 举报
回复
2楼1解正确,2解错误
1、m+(n-m)个random(0,1)累加
2、取一个大数N,累加N个random(0,1),如果值大于N*(1-P),则返回1,否则返回0,N越大越接近各1/2的概率分布
dreamhunter_lan 2011-03-25
  • 打赏
  • 举报
回复
第一题:http://bbs2.chinaunix.net/thread-1192193-2-1.html
第二题:
while(true)
{
x=random(0, 1);
y=random(0, 1);
if(x != y)
return x;
}
aliezeng77 2011-03-25
  • 打赏
  • 举报
回复
晕,上面一不小心死循环了,更正如下:
1. random(0, 1)各以1/2的概率返回0或1。基于它实现random(m, n). m,n是任意正整数,n大于m

设i=log(2,n-m+1)上取整,
int random(m, n)
{
int i,j, k=0;

i=Ceil(log(2,n-m+1)); //Ceil(X)表示上取整

while(1)
{
for(k=0,j=0; j<i; j++)
{
k=k*2+random(0,1);
}
if(k<n-m+1) return m+k;
}
}
aliezeng77 2011-03-25
  • 打赏
  • 举报
回复
说详细点:

1. random(0, 1)各以1/2的概率返回0或1。基于它实现random(m, n). m,n是任意正整数,n大于m

设i=log(2,n-m+1)上取整,
int random(m, n)
{
int i,j, k=0;

i=Ceil(log(2,n-m+1)); //Ceil(X)表示上取整

while(1)
{
for(k=0,j=0; j<i; j++)
{
k=k*2+random(0,1);
}
}
if(k<n-m+1) return m+k;
}
aliezeng77 2011-03-25
  • 打赏
  • 举报
回复
1. random(0, 1)各以1/2的概率返回0或1。基于它实现random(m, n). m,n是任意正整数,n大于m

将(m,n)所有数字不足够2^X个数,然后二分查找,若查到的数字是补数,重新查找
netbusxp 2011-03-24
  • 打赏
  • 举报
回复
1
for i = 1 to n-m
count+=random(0,1)
return m+count
2.
random_get()
i=random(0,1)
j=random(0,1)
if i=0 and j=1
return 0
elseif i=1 and j=0
return 1
else
return random_get()

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧