使用两个随机函数来获得特定的随机函数

时间:2013-05-09 09:59:53

标签: algorithm math

有两个随机函数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()?

提前致谢。

6 个答案:

答案 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^nthis 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难题。

那么,最后回答你的问题,是否有可能?是,这是一种方法,可能会有很多黑客攻击,以优化这一点,这为您提供了最佳方式。