代码改变世界

算法导论第5章 概率分析和随机算法(5.1)

2013-01-29 15:41  撞破南墙  阅读(2107)  评论(2编辑  收藏  举报

看看概率和你的代码和数学有什么关系,换个(概率的)角度来看看代码,也许有所收获。擅长百度、谷歌代码完成功能的码农看过来。

第5章  概率分析和随机算法

5.1  雇佣问题

wps_clip_image-30267

wps_clip_image-12375

概率分析:在问题的分析中应用概率技术。

随机算法:如果一个算法的行为,不只由输入决定,也由随机数生成器决定,那么称这个算法为随机算法。

1. 习题解答

5.1-1

wps_clip_image-28491

如果可以知道任意两个人的排名的大小,自然等价于得到了总排名。

5.1-2

wps_clip_image-27461

解:这题等价于二进制表示任意数,其中一次random相当于一位二进制,其取值为0或1.

例如a=3,b=5;共3个数:3,4,5。等价于0,1,2.只需要2个random即可。00,01,10分别表示3,4,5。

分析其期望运行时间,理论上,N位数表示的是偶数个数,所以有可能多一个数。故一次生成的概率为X=(b-a)/(b-a+1);根据引理5.2,EX=(b-a)/(b-a+1)(次);

再分析运行一次的时间复杂度。位数为w=wps_clip_image-2756([lg(high-low+1)]的向上取整),故需要循环w次依次取随机数。

综上所述:期望运行时间为EX*w=wps_clip_image-30770

附C语言下实现如下:

//统计上概率地返回在low和high之间的数

#define random(x) (rand()%x)

int t5_1_2(int low,int high)

{

    int i=0;

    int count=0;

    double j=log(high-low+1)/log(2);

    if(j-(int)j>0) {

        j++;

    }

    while(1) {

        count=0;

        for(i=0; i<j; i++) {

            count+=random(2)*pow(2,i);

        }

        if(low+count<=high) {

            break;

        }

    }

    return low+count;

}

测试代码:

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#define random(x) (rand()%x)

int main()

{

    int j=0;

    for(; j<11; j++) {

        int a1=t5_1_2(1,4);

        int a2=t5_1_2(11,14);

        printf("between %d and %d : %d\n",a1,a2,t5_1_2(a1,a2));

    }

    return 0;

}

 

PS:是不是很神奇~~~~。下一题更有趣。

5.1-3

wps_clip_image-31122

解:根据上一题的启发。一位表示一次random。

根据离散型随机变量的相关知识,我们可以猜出来:

只要找到两个等概率的取值就好了。例如(0,1)和(1,0)。他们的概率分别是p(1-p)和(1-p)p。我们如上题一样舍去(0,0)和(1,1)即可。

取值

00

01

10

11

P

(1-p)(1-p)

(1-p)p

p(1-p)

pp

为了复习一下概率,我把它当做概率题来做好了。

设X表示两位random的值。

Y=1 当X==01或10;

Y=0 当X==11 或00

取值

1

0

P

2p(1-p)

Pp+(1-p)(1-p)

计算其期望:

EX=2p(1-p).

再分析其单次运行时间为O(1);

所以其运行时间期望为EX=2p(1-p).

附C语言实现代码:

//有偏输出0或1

int biasedRandom()

{

    int i=random(3);

    if(i>=1) return 1;

    else return 0;

}

int t5_1_3( )

{

    int j1=0,j2=0;

    while (1) {

        j1 =biasedRandom();

        j2 =biasedRandom();

        if(j1+j2!=1) {

            continue;

        }

        if(j1==1) return 1;

        else return 0;

    }

}

测试代码:

    int j=0;

    int i0=0;

    int i1=0;

    for(; j<500; j++) {

        if( t5_1_3( )==0) i0++;

        else i1++;

    }

    printf("i0=%d,i1=%d",i0,i1);

    return 0;

欢迎加入QQ群181539446