有两个随机函数f1(),f2()。
f1()以概率p1返回1,以0概率1-p1返回。
f2()以概率p2返回1,以0概率1-p2返回。
我想实现一个新函数f3(),它以概率p3( 给定概率 )返回1,并以概率1-p3返回0。在函数f3()的实现中,我们可以使用函数f1()和f2(),但是你不能使用任何其他随机函数。
如果p3 = 0.5,则是一个实施例子:
int f3()
{
do
{
int a = f1();
int b = f1();
if (a==b) continue;
// when reachs here
// a==1 with probability p1(1-p1)
// b==1 with probability (1-p1)p1
if (a==1) return 1;//now returns 1 with probability 0.5
if (b==1) return 0;
}while(1)
}
f3()的这个实现将给出一个概率为0.5的随机函数返回1,以及概率为0.5的0。但是如何用p3 = 0.4实现f3()?我不知道。
我想知道,这项任务可能吗?以及如何实现f3()?
提前致谢。
答案 0 :(得分:3)
如果p3是有理数,这可以解决。
我们应该使用条件概率。
例如,如果要为p3 = 0.4进行此操作,则方法如下:
计算p3的分数形式。在我们的例子中,它是p3 = 0.4 = 2/5。
现在从同一个分布生成尽可能多的随机变量(假设,从f1开始,我们不会再使用f2)作为分母,称它们为X1,X2,X3,X4,X5。 我们应该重新生成所有这些随机X变量,直到它们的总和等于p3的分数形式的分子。
一旦达到这个目的,我们只返回X1(或任何其他Xn,其中n的选择独立于X变量的值)。由于5个X变量中有2个1(因为它们的和等于分子),X1为1的概率恰好是p3。
对于不合理的p3,仅使用f1无法解决问题。我现在不确定,但我想,它可以用p1 * q + p2 *(1-q)形式的p3求解,其中q是类似方法的合理,产生适当数量的Xs,分布为f1和分布为f2的Ys,直到它们具有特定的预定义和,并返回其中一个。这仍然需要详细说明。
答案 1 :(得分:3)
p1 = 0.77 -- arbitrary value between 0 and 1
function f1()
if math.random() < p1 then
return 1
else
return 0
end
end
-- f1() is enough. We don't need f2()
p3 = 0.4 -- arbitrary value between 0 and 1
--------------------------
function f3()
left = 0
rigth = 1
repeat
middle = left + (right - left) * p1
if f1() == 1 then
right = middle
else
left = middle
end
if right < p3 then -- completely below
return 1
elseif left >= p3 then -- completely above
return 0
end
until false -- loop forever
end
答案 2 :(得分:2)
首先要说的是,调整一个人的大脑是一个很好的问题。我设法解决了p3 = 0.4
的问题,因为你刚才要求的!我认为,这种问题的概括并非如此微不足道。 :d
以下是p3 = 0.4
:
直觉来自你的榜样。如果我们在迭代中生成f1()
五次的数字,( 请参阅下面的代码 ),我们可以使用 32 类型结果如下:
1: 00000
2: 00001
3: 00010
4: 00011
.....
.....
32: 11111
其中有 10 这样的结果,其中只有两个1
!在确定之后,问题变得简单。只需返回1
即可获得4个组合中的任何一个,并为其他6个组合返回0
! (概率0.4表示获得1
,10次中有4次)。你可以像下面这样做:
int f3()
{
do{
int a[5];
int numberOfOneInA = 0;
for(int i = 0; i < 5; i++){
a[i] = f1();
if(a[i] == 1){
numberOfOneInA++;
}
}
if (numberOfOneInA != 2) continue;
else return a[0]; //out of 10 times, 4 times a[0] is 1!
}while(1)
}
等待查看一般化解决方案。 干杯!
答案 3 :(得分:1)
当p3
的格式为a/2^n
(分母为2的幂的有理数)时,这是一个有用的想法。
生成n
随机数,概率分布为0.5
:
x1,x2,...,xn
将其解释为0...2^n-1
范围内的二进制数;该范围内的每个数字具有相等的概率。如果此数字小于a
,则返回1,否则返回0.
现在,由于这个问题是在计算机科学的背景下,因此假设p3
采用a/2^n
(this a common representation of numbers in computers)的形式似乎是合理的。
答案 4 :(得分:1)
我实施了anatolyg和Egor的想法:
inline double random(void)
{
return static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
}
const double p1 = 0.8;
int rand_P1(void)
{
return random() < p1;
}
int rand_P2(void)//return 0 with 0.5
{
int x, y; while (1)
{
mystep++;
x = rand_P1(); y = rand_P1();
if (x ^ y) return x;
}
}
double p3 = random();
int rand_P3(void)//anatolyg's idea
{
double tp = p3; int bit, x;
while (1)
{
if (tp * 2 >= 1) {bit = 1; tp = tp * 2 - 1;}
else {bit = 0; tp = tp * 2;}
x = rand_P2();
if (bit ^ x) return bit;
}
}
int rand2_P3(void)//Egor's idea
{
double left = 0, right = 1, mid;
while (1)
{
dashenstep++;
mid = left + (right - left) * p1;
int x = rand_P1();
if (x) right = mid; else left = mid;
if (right < p3) return 1;
if (left > p3) return 0;
}
}
通过大量的数学计算,我得到,假设P3在[0,1)中均匀分布,那么Egor的期望是(1-p1 ^ 2-(1-p1)^ 2)^( - 1)。 anatolyg是2(1-p1 ^ 2-(1-p1)^ 2)^( - 1)。
答案 5 :(得分:0)
在算法上说,是的,可以完成任务。
甚至以编程方式,这是可能的,但这是一个复杂的问题。
让我们举个例子。
让 F1(1)= .5表示F1(0)= .5 F2(2)= .8,这意味着F1(0)= .2
假设你需要一个F3,这样F3(1)= .128
让我们尝试分解它。
.128
= (2^7)*(10^-3) // decompose this into know values
= (8/10)*(8/10)*(2/10)
= F2(1)&F2(1)*(20/100) // as no Fi(1)==2/10
= F2(1)&F2(1)*(5/10)*(4/10)
= F2(1)&F2(1)&F1(1)*(40/100)
= F2(1)&F2(1)&F1(1)*(8/10)*(5/10)
= F2(1)&F2(1)&F1(1)&F2(1)&F1(1)
所以F3(1)=。128如果我们定义F3()= F2()&amp; F2()&amp; F2()&amp; F1()&amp; F1()
同样如果你想要F4(1)=。9,
你给它为F4(0)= F1(0)| F2(0)= F1(0) F2(0)=。5 .2 = .1,表示F4(1)= 1-0.1 = 0.9
这意味着只有当两者都为零时F4才为零。
所以使用这个(&amp;,|,而不是(!),xor(^),如果你想)使用f1,f2的组合使用操作肯定会给你F3,它纯粹是出于f1, F2,
找到可以提供确切概率的组合可能是NP难题。
那么,最后回答你的问题,是否有可能?是是,这是一种方法,可能会有很多黑客攻击,以优化这一点,这为您提供了最佳方式。