1. 程式人生 > >2016阿里實習線上筆試題-附加題1-隨機數生成器

2016阿里實習線上筆試題-附加題1-隨機數生成器

隨機數生成器

計算機使用的隨機數生成器往往是偽隨機的,為了達到統計意義上的真隨機數,可以需要引入系統
外的變數等作為隨機種子(如UNIX系統中熵池)。假設有一天出現了上帝的投硬幣函式: int G();
由於這裡用到的上帝硬幣可能不均勻。但可以保證是G()可以x概率返回1,1-x的概率返回0,其中x為未知常數(且x不等於0或1)。

請實現目標函式: int F(double p);
要求

    1. F函式以概率p返回1,以1-p返回0。
    1. 除了G之外,不使用的任何庫函式。 PS:定義巨集UINT_MAX=0xffffffff

基於前述類似思路,請建構函式求下述無理數近似值:

    1. double pi(); //圓周率π
    1. double e(); // 自然對數函式的底數e。

提示:作為模擬過程,可引入最高重複試驗次數,請簡述思路並完成程式碼。

思路:
1. 構造p概率隨機數生成函式

  • 由G()生成等概率隨機數生成函式,可參考演算法導論或這篇部落格
  • 由等概隨機函式進行多次數(例如10次)隨機,那麼就會產生1024種結果,而且每種結構都等概。那麼我們可以分析每種隨機結果,每種隨機結果可以用十進位制表示,
0 1 0 1 0 0 1 0 1 1

可以用十進位制331表示,所有可能的十進位制都在[0, 1024)範圍裡。所以只要生成的十進位制數小於1024*p就返回1,大於就返回0,這樣就可滿足要求。

2. pi和e生成方法
π=4(1113+1517...)
e=10!+11!+12!+...+1n!...
這種方法不知道是不是滿足出題人的意思呢?這一部分的程式碼就不貼上來了。

#include <stdlib.h>
#include <iostream>

using namespace std;

int F(double p)
{
    int sum = 0;
    int t = 10;
    int all = 1024;
    int t1 = all * p;

    for (int i = 0; i < t; ++i)
        sum += U()<<i;
    if
(sum < t1) return 1; else if (sum >= t1) return 0; } // generate the uniform random function // reference book: <<algorithm introduction>> int U() { int n1 = -1, n2 = -1; do{ n1 = G(); n2 = G(); if (n1 == 0 && n2 == 1) return 1; else if (n1 = 1 && n2 == 0) return 0; }while((n1 == 0 && n2 == 0) || (n1 == 1 && n2 == 1)) exit(-1); }