算法导论5.1-2

问题:
请描述RANDOM(a,b)过程的一种实现,它只调用RANDOM(0,1),该函数以等可能返回0或者1。作为a和b的函数,你的过程的期望运行时间是多少。
解答:
假设a<b,设n=b-a,首先计算出n的二进制数位数,记为digit。
接着,调用过程RANDOM(0,1)digit次,生成有digit位的二进制数result。
若result大于n,则重新调用过程RANDOM(0,1)digit次,再次生成result,直到result小于或等于n为止。
最后返回result+a作为RANDOM(a,b)结果。
算法分析:
设X为成功生成一次result所用的总次数,设p为成功生成一次result的概率,成功即result小于或者等于n,则 p=(n+1)/2digit
又该问题生成result的次数服从参数为p的几何分布,计算其均值可得,E(X)=1/p。
每次生成result调用了digit次RANDOM(0,1),所以调用RANDOM(0,1)的总次数为digit/p,即时间复杂度为:
T(n)=O(digitp)=O(digit2digitn+1)
算法实现:
c语言实现如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>

int sum;
int summary[100];

void display_bits(unsigned number) {
    unsigned mask = 1;
    mask <<= CHAR_BIT * sizeof(unsigned) - 1;
    for (int i = 0; i < CHAR_BIT * sizeof(unsigned); ++i)
    {
        /* code */
        putchar(mask & number ? '1' : '0');
        number <<= 1;
        if (i % 8 == 0)
            putchar(' ');
    }
    putchar('\n');
}

unsigned random_0_to_1() {
    return rand() % 2;
}

unsigned random_a_to_b(unsigned a, unsigned b) {
    //make sure that b is greater than a
    if (b < a) {
        unsigned temp = a;
        a = b;
        b = temp;
    }
    unsigned n = b - a;

    //get the digit of n
    int digit = 0;
    while (n != 0) {
        n >>= 1;
        digit++;
    }
    printf("digit:%d_\n", digit);
    n = b - a;
    display_bits(n);

    unsigned result = n + 1;
    while (result > n) {
        result = 0;
        for (int i = 0; i < digit; i++) {
            result <<= 1;
            result += random_0_to_1();
        }
        //summary how many times result is repeatly generated
        sum++;
    }
    //summary the numbers of each result number
    summary[result]++;
    display_bits(result);
    return result + a;
}

int main(int argc, char const *argv[])
{
    /* code */
    srand(time(NULL));
    for (int i = 0; i < 100000; ++i)
    {
        printf("random number:%d\n", random_a_to_b(5, 10));
    }
    printf("sum:%d\n", sum);
    for (int i = 0; i < 10; ++i) {
        printf("summary%d:%d\n", i, summary[i]);
    }
    return 0;
}

sum表示总共生成result的次数,summary为生成的每个合法结果的个数。经过统计得,生成的result的平均次数确实符合上述分析结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值