Pseudorandom experiments

本文通过实验探讨了伪随机函数生成的数字分布情况,利用不同的参数设置,对伪随机数生成器进行了测试,以评估其均匀分布特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Question:

Run some experiments to determine the distribution of numbers returned by the new pseudorandom functions from the previous project. Recall that this function returns a double number in the range [0, 1). Divide this range into 10 intervals, and call the function one million times, producing a table such as this:

RangeNumber of Occurrences
[0.0, 0.1)99889
[0.1, 0.2)100309
[0.2, 0.3)100070
[0.3, 0.4)99940
[0.4, 0.5)99584
[0.5, 0.6)100028
[0.6, 0.7)99669
[0.7, 0.8)100100
[0.8, 0.9)100107
[0.9, 1.0)100304

Run your experiment for different values of the multiplier, increment, and modulus. With good choices of the constants, you will end up with about 10%10\%10% of the numbers in each interval. A pseudorandom number generator with this equal-interval behavior is called uniformly distributed.

My answer:

修改main.cpp

#include "random.h"
#include <iostream>
#include <iomanip>
#include <cassert>

using namespace std;

const int NUM = 10;

enum Range{
    R1, R2, R3, R4, R5, R6, R7, R8, R9, R10
};

unsigned int range[NUM] = {0};

void update_list(double r);
void print_list();

int main(){
    pseudorandom_generator a(40, 725, 729, 1);
    cout << "Test 1: multiplier = 40, increment = 725, modulus = 729, seed = 1" << endl;
    int i = 0;
    while(i < 1000000){
        // a.generate_number();
        double r = a.generate_double_number();
        update_list(r);
        i++;
    }
    print_list();
    pseudorandom_generator b(35, 899, 938, 37);
    cout << "Test 2: multiplier = 35, increment = 899, modulus = 1038, seed = 1" << endl;
    i = 0;
    for(int j = R1; j <= R10; j++){
        range[j] = 0;// reinitialize
    }
    while(i < 1000000){
        // a.generate_number();
        double r = b.generate_double_number();
        update_list(r);
        i++;
    }
    print_list();
    return 0;
}

void update_list(double r){
    if(r >= 0 && r < 0.1){
        range[R1] += 1;
    } else if(r >= 0.1 && r < 0.2){
        range[R2] += 1;
    } else if(r >= 0.2 && r < 0.3){
        range[R3] += 1;
    } else if(r >= 0.3 && r < 0.4){
        range[R4] += 1;
    } else if(r >= 0.4 && r < 0.5){
        range[R5] += 1;
    } else if(r >= 0.5 && r < 0.6){
        range[R6] += 1;
    } else if(r >= 0.6 && r < 0.7){
        range[R7] += 1;
    } else if(r >= 0.7 && r < 0.8){
        range[R8] += 1;
    } else if(r >= 0.8 && r < 0.9){
        range[R9] += 1;
    } else if(r >= 0.9 && r < 1.0){
        range[R10] += 1;
    }
}

void print_list(){
    cout << "------------------------------------" << endl;
    cout << setiosflags(ios::left) << setw(14) << "Range" << resetiosflags(ios::left)
         << setiosflags(ios::right) << setw(9) << "Number of Occurrences" << resetiosflags(ios::right) << endl;
    cout << "------------------------------------" << endl;
    for(int i = R1; i <= R10; i++){
        switch(i){
            case R1:
                cout << setiosflags(ios::left) << setw(14) << "[0.0, 0.1)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R1] << resetiosflags(ios::right) << endl;
                break;
            case R2:
                cout << setiosflags(ios::left) << setw(14) << "[0.1, 0.2)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R2] << resetiosflags(ios::right) << endl;
                break;
            case R3:
                cout << setiosflags(ios::left) << setw(14) << "[0.2, 0.3)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R3] << resetiosflags(ios::right) << endl;
                break;
            case R4:
                cout << setiosflags(ios在这里插入代码片::left) << setw(14) << "[0.3, 0.4)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R4] << resetiosflags(ios::right) << endl;
                break;
            case R5:
                cout << setiosflags(ios::left) << setw(14) << "[0.4, 0.5)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R5] << resetiosflags(ios::right) << endl;
                break;
            case R6:
                cout << setiosflags(ios::left) << setw(14) << "[0.5, 0.6)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R6] << resetiosflags(ios::right) << endl;
                break;
            case R7:
                cout << setiosflags(ios::left) << setw(14) << "[0.6, 0.7)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R7] << resetiosflags(ios::right) << endl;
                break;
            case R8:
                cout << setiosflags(ios::left) << setw(14) << "[0.7, 0.8)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R8] << resetiosflags(ios::right) << endl;
                break;
            case R9:
                cout << setiosflags(ios::left) << setw(14) << "[0.8, 0.9)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R9] << resetiosflags(ios::right) << endl;
                break;
            case R10:
                cout << setiosflags(ios::left) << setw(14) << "[0.9, 1.0)" << resetiosflags(ios::left)
                     << setiosflags(ios::right) << setw(9) << range[R10] << resetiosflags(ios::right) << endl;
                break;
        }
    }
}

结果:

Test 1: multiplier = 40, increment = 725, modulus = 729, seed = 1
------------------------------------
Range         Number of Occurrences
------------------------------------
[0.0, 0.1)       100137
[0.1, 0.2)       100145
[0.2, 0.3)       100136
[0.3, 0.4)       100138
[0.4, 0.5)       100138
[0.5, 0.6)       100138
[0.6, 0.7)       100137
[0.7, 0.8)       100129
[0.8, 0.9)       100138
[0.9, 1.0)        98764
Test 2: multiplier = 35, increment = 899, modulus = 1038, seed = 1
------------------------------------
Range         Number of Occurrences
------------------------------------
[0.0, 0.1)        75757
[0.1, 0.2)       121213
[0.2, 0.3)       121211
[0.3, 0.4)        90907
[0.4, 0.5)        90908
[0.5, 0.6)        75758
[0.6, 0.7)       121211
[0.7, 0.8)       121213
[0.8, 0.9)        90912
[0.9, 1.0)        90910

第二个例子似乎和均匀分布相去甚远,是参数选取的问题吗?

Reference:

整理自 Data Structures and Other Objects Using C++ ( Fourth Edition ) Michael Main, Walter Savitch. p124

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Memories off

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值