1. 程式人生 > >c++構建正態分佈的隨機數

c++構建正態分佈的隨機數

最近程式設計的時候遇到一個問題,需要用c++來產生一個滿足正態分佈的的隨機數,用c++產生一個均勻分佈的隨機數很容易,但是滿足正態分佈還是有點懵逼的。然後就在網上搜一些資料,發現有三種方法可以產生正態分佈的隨機數。但是看別人從理論上的推導,感覺還是沒有說清楚,我想寫寫關於我自己對於這三種方法的理解!!

方法一:利用分佈函式的反函式來求取

在講這個方法前,我要先證明一個定理:就是任何分佈函式的概率都服從隨機分佈!! 假設y=f(x),f(x)是x的分佈函式,假設f(x)是連續函式,而且單調遞增,則存在反函式x=f(-1)(y),有: 這裡我們對於反函式,就考慮0<y<1的時候,簡單一點分析:
由上式可知,,說明y是一個均勻分佈函式。 之後證明一下為什麼可以分佈函式的反函式可以求取正態分佈的隨機數?? 假設x=f(-1)(y),由上面可知,y是一個均勻分佈的函式,x是它的反函式,我們要求的就是x的值。 上面式子可能你會有點看不懂,你可以從另外一個角度來理解,y=f(x),f(x)是分佈函式的值,則有x=f(-1)(y),x是服從正態分佈的,所以可以求分佈函式的反函式來得到x。 但是很不幸的是,一般正態分佈的反函式都很難求,但是並不是這種思想沒有用,下面介紹的box-muller方法就是基於反函式方法的改進。

方法2:利用中心極限定理

首先介紹一下中心極限定理的基本原理,設X1,X2,......Xn,是獨立同分布的隨機變數列,且有
均存在,這隨機變數滿足:

可以看出,當資料量很大時,隨機變數近似的服從正態分佈,由此,隨機變數近似的滿足分佈 通過中心極限定理可以很快的寫出相應的程式碼,很簡單,但是運算量會很大,佔用很大的時間複雜度。

方法3 box-muller方法

這個方法是反函式的方法的變形,需要推導了,比較麻煩,但是運算量小,是我們常用的產生正態分佈隨機數的方法。 首先我們先來求服從正態分佈的隨機數,該正態分佈的密度函式為 設(X,Y)是一對相對獨立服從上述正態分佈的隨機數,則其概率密度函式為: 我們設,則對於r的分佈函式有 下面我們來對其進行化簡: 則對於r的分佈函式求反函式,可得: 可以令(1-Z)為均勻分佈的隨機數,這裡因為Z為r的分佈密度,所以Z為均勻分佈,1-Z也為均勻分佈。均勻分佈的反函式即滿足該分佈的隨機數。
U1,U2都滿足在(0,1)區間內的均勻分佈。 通過上面的公式就可以得到滿足的隨機數,我們如果要求得到滿足的隨機數,只需要在 向左或向右平移u個單位即可。 這樣,通過上述的公式就可以得到滿足的隨機數了。 下面貼上用box-muller方法產生隨機數的c程式碼:
#include
#include  
#include  
#include
#include
#define pi 3.1415926
using namespace std;
double rand_back(double i,double j)
{
	
	double u1=double(rand()%1000)/1000,u2=double(rand()%1000)/1000,r;
	static unsigned int seed=0;
	r=i+sqrt(j)*sqrt(-2.0*(log(u1)/log(exp(1.0))))*cos(2*pi*u2);
	return r;
}
int main()
{
	srand( (unsigned)time( NULL ) );
	cout<<rand_back(10.0,1.0)<<endl;       
}

相關推薦

c++構建分佈隨機數

最近程式設計的時候遇到一個問題,需要用c++來產生一個滿足正態分佈的的隨機數,用c++產生一個均勻分佈的隨機數很容易,但是滿足正態分佈還是有點懵逼的。然後就在網上搜一些資料,發現有三種方法可以產生正態

C產生分佈隨機數寫入檔案並讀出後用快速排序法排序

基於快速排序法的正態隨機數排序 使用中心極限定理產生正態分佈隨機數 使用快速排序法進行排序 讀寫資料到記事本 程式計時 #include <stdio.h> #include <stdlib.h> #include <mat

C#產生分佈、泊松分佈、指數分佈、負指數分佈隨機數(原創)

http://blog.sina.com.cn/s/blog_76c31b8e0100qskf.html 在程式設計過程中,由於資料模擬模擬的需要,我們經常需要產生一些隨機數,在C#中,產生一般隨機數用Random即可,但是,若要產生服從特定分佈的隨機數,就需要一定的演

np.random.rand均勻分佈隨機數和np.random.randn分佈隨機數函式使用方法

np.random.rand用法 覺得有用的話,歡迎一起討論相互學習~Follow Me 生成特定形狀下[0,1)下的均勻分佈隨機數 np.random.rand(a1,a2,a3…)生成形狀為(a1,a2,a3…),[0,1)之間的 均勻分佈 隨機數 np

分佈隨機數的產生

最近平凡聽到關於正態分佈取樣相關的內容,突然想到一個問題: 到底如何利用正態分佈取樣? 正好近期模式識別課程上也有一個相關的內容,整理了一下查到的資料。 一。柱狀圖估計分佈 假設樣本 x N(u,θ) x~N(u, \theta), 其pdf圖如下:

Matlab中產生分佈隨機數的函式normrnd-----用來產生高斯隨機矩陣

   >> help normrnd NORMRND Random arrays from the normal distribution. R = NORMRND(MU,SIGMA) returns an array of random numbers chosen from a normal

【matlab】Matlab中產生分佈隨機數的函式normrnd

Date: 2018.8.5 功能:生成服從正態分佈的隨機數 語法: R=normrnd(MU,SIGMA) R=normrnd(MU,SIGMA,m) R=normrnd(MU,SIGMA,m,n) 說 明: R=normrnd(MU

分佈隨機數生成演算法

最近在學習基於蒙特卡羅的強化學習方法時遇到 生成服從正態分佈的隨機數的演算法,因此做一個回顧和總結。要程式設計得到服從均勻分佈的偽隨機數是容易的,C、Python、Java語言等都提供了相應的函式。但是要想生成服從正態分佈的隨機數就沒那麼容易了,生成服從正態分佈的隨機數的基本

產生服從分佈隨機數(轉載)

一、為什麼需要服從正態分佈的隨機函式 一般我們經常使用的隨機數函式 Math.random() 產生的是服從均勻分佈的隨機數,能夠模擬等概率出現的情況,例如 扔一個骰子,1到6點的概率應該相等,但現實生活中更多的隨機現象是符合正態分佈的,例如20歲成年人的體重分佈等。

如何用均勻分佈隨機數生成分佈隨機數

前言 在Monte Carlo模擬技術中,許多地方都需要用到符合標準正態分佈(高斯)的隨機數來設計取樣方案,因此瞭解如何用均勻分佈隨機數(實際上是均勻分佈的偽隨機數)來生成標準正態分佈的隨機數十分重要。本文將對這個最基本的問題做討論,並提供c++11程式

JAVA自定義演算法產生分佈隨機數

一、為什麼需要服從正態分佈的隨機函式 一般我們經常使用的隨機數函式 Math.random() 產生的是服從均勻分佈的隨機數,能夠模擬等概率出現的情況,例如 扔一個骰子,1到6點的概率應該相等,但現實生活中更多的隨機現象是符合正態分佈的,例如20歲成年人的體重分佈等。 假如我們在製作一個遊戲,要

分佈隨機數生成器

import math,random u=1800. q=800. reslist=[] for v in xrange(0,3600):    y=math.exp(-((v-u)/q)*((v-u)/q)/2)/(q*math.sqrt(2*3.14159265359)

一種用C++自帶的類生成服從分佈隨機數

今天寫關於深度學習的程式碼時,裡面要用服從標準正態分佈的隨機數初始化權值,就是matlab裡面那個randn函式,網上找了很多方法,最後發現C++本身就有自帶的方法生成服從正態分佈的隨機數序列。下面給出C++程式碼: C++程式碼: #include &

C++生成隨機數:高斯/分佈(gaussian/normal distribution)

常用的成熟的生成高斯分佈隨機數序列的方法由Marsaglia和Bray在1964年提出,C++版本如下: #include <stdlib.h> #include <math.h> double gaussrand() { static double V1, V2, S

分佈隨機數發生器 in C#

Box 和 Muller 在 1958 年給出了由均勻分佈的隨機變數生成正態分佈的隨機變數的演算法。設 U1, U2 是區間 (0, 1) 上均勻分佈的隨機變數,且相互獨立。令X1 = sqrt(-2*log(U1)) * cos(2*PI*U2);X2 = sqrt(-2*log(U1)) * sin(2*

C語言產生標準分佈或高斯分佈隨機數

1 #include <stdlib.h> 2 #include <stdio.h> 3 double gaussrand() 4 { 5 static double V1, V2, S; 6 static int phase = 0; 7

課堂練習--計算陣列的最大值,最小值,平均值,標準差,中位數;numpy.random模組提供了產生各種分佈隨機數的陣列;分佈;Matplotlib

#計算陣列的最大值,最小值,平均值,標準差,中位數 import numpy as np a=np.array([1, 4, 2, 5, 3, 7, 9, 0]) print(a) a1=np.max(a) #最大值 print(a1) a2=np.min(a) #最小值 print(a2) a3

[C++]Random庫--分佈

Random庫–正態分佈 背景介紹 正態分佈(Normal distribution)又名高斯分佈(Gaussian distribution),是一個在數學、物理及工程等領域都非常重要的概率分佈,在統計學的許多方面有著重大的影響力。若隨機變數X服

概率論中高斯分佈(分佈)介紹及C++11中std::normal_distribution的使用

高斯分佈:最常用的分佈是正態分佈(normal distribution),也稱為高斯分佈(Gaussian distribution):正態分佈N(x;μ,σ2)呈現經典的”鐘形曲線”的形狀,其中中心峰的x座標由μ給出,峰的寬度受σ控制。正態分佈由兩個引數控制,μ∈R和σ∈

使用rand()產生服從高斯/分佈隨機數

我們藉助於rand()去生成高斯/正態分佈。 當然,rand是偽隨機的問題在此先不考慮。 (1)用Box-Muller方法,隨機抽出兩個從均勻分佈的數字和。然後 那和都是正態分佈的。 證明可用極座標,請參考教科書中的Box-Muller方法。 C程式碼: #