C語言實現均勻分佈隨機函數

前言

隨機函數就是產生數的函數,C語言裏使用rand(),srand()等隨機函數實現隨機數生成。算法


函數簡介

int rand( void );網絡

返回的是一個界於0~32767(0x7FFF)之間的僞隨機數,包括0和32767。dom

C預先生成一組隨機數,每次調用隨機函數時從指針所指向的位置開始取值,所以使用rand()重複運行程序產生的隨機數都是相同的,能夠經過srand()函數來改變指針位置。函數

srand()會設置供rand()使用的隨機數種子。若是在第一次使用rand()以前沒有調用srand(),那麼系統會自動調用srand()。而使用同種子相同的數調用 rand()會致使相同的隨機數序列被生成。ui


void srand( unsigned int seed );this

改變隨機數表的指針位置(用seed變量控制)。spa

使用系統定時/計數器的值做爲隨機種子。每一個種子對應一組根據算法預先生成的隨機數,因此,在相同的平臺環境下,不一樣時間產生的隨機數會是不一樣的,相應的,若將srand(unsigned)time(NULL)改成srand(TP)(TP爲任一常量),則不管什麼時候運行、運行多少次獲得的「隨機數」都會是一組固定的序列,所以srand生成的隨機數是僞隨機數。指針

通常配合time(NULL)使用,由於時間每時每刻都在改變,產生的seed值都不一樣。code


場景

使用rand函數生成的隨機數嚴格知足正態分佈。而在不少時候,咱們但願隨機數的生成不要知足正態分佈,特別是在處理網絡通訊報文的時候。orm

例如,咱們須要在交換機處理到海量報文時,可以使遠端的從設備儘量的分段同時向局端迴應報文,以減輕局部報文處理壓力。


均勻分佈隨機函數實現

開發環境

實現步驟

1)打開Qt Creater,建立GUI工程


2)在mainwindow.h中添加函數聲明

void paintEvent(QPaintEvent *);

3)在mainwindow.cpp中添加函數實現

導入頭文件

#include <QPainter>

實現void paintEvent(QPaintEvent *)函數

/*
 *Qt中函數paintEvent(QPaintEvent*)是被系統自動調用。
 *paintEvent(QPaintEvent *)函數是QWidget類中的虛函數,用於ui的繪製,會在多種狀況下被其餘函數自動調用。
*/
void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPen pen; //畫筆
    pen.setColor(QColor(255,0,0)); //設置畫筆顏色
    painter.setPen(pen); //添加畫筆

    long int r[kSum] = {0};
    int i = 0;
    int j = 0;

    do{
        r[i] = Uniform(0, 300);
        i++;
    }while(i < kSum);

    while((j + 30) < (kSum + 30)){
        painter.drawPoint(j, r[j]);
        j++;
    }
}

4)添加隨機函數實現代碼

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

#define kSum 1000
//算法一
/*
 *均勻分佈隨機函數均勻化
*/
double _uniform(double min, double max, long int *seed) {
    double t = 0;
    *seed = 2045 * (*seed) + 1;
    *seed = *seed - (*seed / 1048576) * 1048576;
    t = (*seed) / 1048576.0;
    t = min + (max - min) * t;
    return t;
}

/*
 *均勻分佈隨機函數產生隨機數
*/
long int Uniform(double min, double max) {
    long int s = 0;
    double r = 0;

    s = rand();
    r = _uniform(min, max, &s);

    return ((long int)r);
}

//算法二
double AverageRandom(double min, double max) {
    int minInteger = (int)(min * 10000);
    int maxInteger = (int)(max * 10000);
    int randInteger = rand() * rand();
    int diffInteger = maxInteger - minInteger;
    int resultInteger = randInteger % diffInteger + minInteger;

    return (resultInteger/10000.0);
}

實現效果


小結

從圖中能夠看出,使用上述函數生成的隨機數符合均勻分佈。

本案例主要使用了Qt的繪圖功能,用來直觀展現生成隨機數的效果。檢驗隨機函數生成隨機數的效果。


附錄

最後附上該算法實現的所有代碼:

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void paintEvent(QPaintEvent *);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>

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

#define kSum 1000

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

/*
 *均勻分佈隨機函數均勻化
*/
double _uniform(double min, double max, long int *seed) {
    double t = 0;
    *seed = 2045 * (*seed) + 1;
    *seed = *seed - (*seed / 1048576) * 1048576;
    t = (*seed) / 1048576.0;
    t = min + (max - min) * t;
    return t;
}

/*
 *均勻分佈隨機函數產生隨機數
*/
long int Uniform(double min, double max) {
    long int s = 0;
    double r = 0;

    //srand((unsigned int)time(NULL)); /*同一個時間種子可能會從產生相同的隨機數列*/
    s = rand();
    r = _uniform(min, max, &s);

    return ((long int)r);
}

/*
 *Qt中函數paintEvent(QPaintEvent*)是被系統自動調用。
 *paintEvent(QPaintEvent *)函數是QWidget類中的虛函數,用於ui的繪製,會在多種狀況下被其餘函數自動調用。
*/
void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPen pen; //畫筆
    pen.setColor(QColor(255,0,0)); //設置畫筆顏色
    painter.setPen(pen); //添加畫筆

    long int r[kSum] = {0};
    int i = 0;
    int j = 0;

    do{
        r[i] = Uniform(0, 300);
        i++;
    }while(i < kSum);

    while((j + 30) < (kSum + 30)){
        painter.drawPoint(j, r[j]);
        j++;
    }
}
//main.cpp
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}
相關文章
相關標籤/搜索