给定一个公平硬币的函数,为有偏差的硬币编写一个函数?
我在进行一些审查时遇到了这个报道的面试问题(以下引用是我发现的有关该问题的所有信息):
给定一个公平硬币的函数, 为有偏差的硬币编写一个函数 返回正面 1/n 次(n 是 参数)
乍一看我写道:
int biased_coin(n) { //0=Tails, 1=Heads
int sum = 0;
if(n==1)
return 1;
for(int i=0;i<n;i++) {
sum += unbiased(); //unbiased returns 0 50% of the time and 1 50% of the time
}
if(sum == 1)
return 1;
return 0;
}
但这显然行不通。例如,对于 n=4,它确实有效:因为 4 次抛掷得到单个正面的概率是 4/(2^4)=1/4。但对于 n=3,3/(2^3)!=1/3。
假设您不能使用随机数生成器,那么实现此类操作的正确方法是什么?
I came across this reported interview question when doing some reviewing (the following quote is all the info I found about the problem):
Given a function for a fair coin,
write a function for a biased coin
that returns heads 1/n times (n is a
param)
At first glance I wrote:
int biased_coin(n) { //0=Tails, 1=Heads
int sum = 0;
if(n==1)
return 1;
for(int i=0;i<n;i++) {
sum += unbiased(); //unbiased returns 0 50% of the time and 1 50% of the time
}
if(sum == 1)
return 1;
return 0;
}
But this obviously doesn't work. For n=4, for instance, it does work: since the probability of getting a single Head given 4 tosses is 4/(2^4)=1/4. But for say n=3, 3/(2^3)!=1/3.
What is the proper way to implement something like this assuming you can't use a random number generator?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于 N 的大多数值不是 2 的幂,因此严格来说不可能保证任意次数的硬币抛掷的概率为 1/N。相反,您必须满足于接近您所需精度的 1/N 的结果。但是,嘿,这对你来说无论如何都是抛硬币。
为自己绘制一棵决策树,其根部有 2 个分支(标记为 H 和 T),然后每个节点有 2 个分支(也标记为 H 和 T),直到达到足够的叶节点来满足您的准确性要求。用您想要的值标记叶子的右侧(为您)部分,例如,如果 N=3,则为 1,2,3。然后,每个叶子定义一条从根开始的路由,例如 HHHTTHH(或其他)。这些定义了导致“3”的投掷顺序。
我将把编码留给你。
Since most values of N are not powers of 2 it's not strictly possible to guarantee a probability of 1/N from any number of coin tosses. Instead you'll have to settle for something which approaches 1/N to your desired accuracy. But hey, that's coin tossing for you anyway.
Draw yourself a decision tree with 2 branches at the root (labelled H and T), then 2 branches at each node (also labelled H and T), until you reach enough leaf nodes to satisfy your accuracy requirements. Label the right (for you) fraction of leaves with the values you want, eg 1,2,3 if N=3. Each leaf then defines a route from the root, such as HHHTTHH (or whatever). These define the sequence of tosses which result in a '3'.
I'll leave the coding to you.
假设:
正面返回 1,反面返回 2,写入:
其中正面 (1) 将出现 1/n 的时间,这应该有效:
其中
random_number(n)
生成一个公平的随机整数 i,使得<代码> 0 <= i < n。因此,random_number(3)
为 0、1 或 2。假设均匀分布,则 1/3 的时间将出现值 0。当然,我们不能使用本机随机数生成器,但无论如何我们可以创建一个。
fairCoinToss()
随机生成 1 或 0。可以组合多次抛硬币来生成更大的数字。例如:将生成:
根据定义,它是 0 到 3 之间的随机数 (n = 4)。
如果 n 是 2 的幂就可以,但也不一定。然而,这很容易满足。假设 n = 5。我们最多可以生成一个从 0 到 7 的随机数。如果您“重新滚动”5、6 或 7,直到获得 0 到 4 范围内的数字,那么您就(非确定性地)构造了一个0到4之间均匀分布的随机数,满足要求。
代码看起来像这样:
Assuming:
returns 1 for heads and 2 for tails, writing:
where heads (1) will appear 1/n of the time this should work:
where
random_number(n)
generates a fair random integer i such that0 <= i < n
. Sorandom_number(3)
is 0, 1 or 2. Assuming even distribution, value 0 will come out 1/3 of the time.Of course we can't use a native random number generator but we can create one anyway.
fairCoinToss()
randomly generates a 1 or 0. Multiple coin tosses can be combined to generate a larger number. For example:will generate:
which by definition is a random number from 0 to 3 (n = 4).
That's fine if n is a power-of-2 but it isn't necessarily. That's easy enough to cater for however. Assume n = 5. At best we can generate a random number from 0 to 7. If you "reroll" 5, 6 or 7 until you get a number in the range of 0 to 4 then you have (non-deterministically) constructed a random number fairly distributed from 0 to 4 inclusive, satisfying the requirement.
Code for that looks something like this:
这个怎么样:
1.找出n的二进制表示
2. 翻转公平硬币logn次。每一次翻转对应一个位。
3. 如果翻转的结果大于n的值,则重新滚动。
4. 如果结果为0,则返回正面。
5. 否则,返回尾部。
How about this:
1. Find out the binary representation of n
2. Flip the fair coin logn times. Each flip corresponds to a bit.
3. If the result of the flip is greater than the value of n, reroll.
4. If the result is 0, return heads.
5. Otherwise, return tails.