添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

因为项目需要,需要产生一串随机数,此随机数非均匀分布,而是基于正态分布,同时该随机数需要在指定区间内。

2.结果展示

我的项目中,希望产生一个正态分布的随机数,范围在[20,240],那么正态分布的均值就是130((20+240)/2),经过不断调试结果,设置标准差为50。

上图就是产生的范围在20~240之间的符合正态分布的随机数。

假如不设置取值范围。见下图:

改变标准差到100,让其变得更“胖”。效果如下:

通过上述展示,达到了设计目的。

3.1 源码

# THIS FILE IS PART OF RANDN PROJECT # randn - The core part of the GCC # THIS PROGRAM IS UNFREE SOFTWARE, IS LICENSED UNDER Ding Zhenjin([email protected]) # YOU SHOULD HAVE RECEIVED A COPY OF RANDN LICENSE, IF NOT, PLEASE DO NOT USE. #YOU SHOULD BUY THE COPYRIGHT 2021.7.9 任意范围的正态分布随机数 环境:Ubuntu32 16.04.1 cairo库实现 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <cairo.h> #include <math.h> #include <time.h> #include "randn.h" /* 采集样本数量 */ #define N 100 背景图标是1300*600 /* 原点坐标 */ #define OriginX 650 //原点居中 #define OriginY 20 /* 坐标转换 */ #define X(n) ((n)*1.0) #define Y(n) ((600-(n))*1.0) /* 坐标系内位置 */ #define PosX(n) (X(OriginX+(n))) #define PosY(n) (Y(OriginY+(n))) #define ANGLE(ang) (ang * 3.1415926 / 180.0) #define OFFSET 600 struct POS{ int x; int y; cairo_surface_t *image_surface_create_from_png(const char *filename) cairo_status_t cst; cairo_surface_t *image_sf=cairo_image_surface_create_from_png(filename); cst = cairo_surface_status (image_sf); if (cst!=CAIRO_STATUS_SUCCESS) printf( "failed to cairo_image_surface_create_from_png cairo_status_t is:%d file: %s",cst, filename); image_sf = NULL; //if (cst == CAIRO_STATUS_NO_MEMORY) { //image_sf = cairo_image_surface_create_from_jpeg(filename); return image_sf; void draw_png2surface(cairo_t *cr, double x, double y, cairo_surface_t *surface){ if(surface != NULL){ cairo_set_source_surface(cr, surface, x, y); cairo_paint(cr); void createBackground(cairo_t *cr,char *file) cairo_surface_t *g_background; if(cr == NULL || file == NULL) return; /* 背景图 */ g_background = image_surface_create_from_png(file); draw_png2surface(cr, 0, 0, g_background); 构建坐标系 void createCoordinate(cairo_t *cr) char tempbuf[64]; if(cr == NULL) return; /* 划线 */ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);/* 设置颜色 -黑色 */ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_width (cr, 1.0); cairo_move_to (cr, X(OriginX-OFFSET), Y(OriginY));//X轴 cairo_line_to (cr, X(OriginX+OFFSET), Y(OriginY)); cairo_stroke (cr); cairo_move_to (cr, X(OriginX), Y(OriginY));//Y轴 cairo_line_to (cr, X(OriginX), Y(OriginY+550)); cairo_stroke (cr); /* 量程 */ cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 15.0); cairo_move_to (cr, X(OriginX-5), Y(OriginY-15)); cairo_show_text (cr, "0"); //负X轴 cairo_move_to (cr, X(OriginX-OFFSET-15), Y(OriginY-15)); sprintf(tempbuf,"%d",-OFFSET); cairo_show_text (cr, tempbuf); //正X轴 cairo_move_to (cr, X(OriginX+OFFSET-15), Y(OriginY-15)); sprintf(tempbuf,"%d",OFFSET); cairo_show_text (cr, tempbuf); cairo_move_to (cr, X(OriginX-10), Y(OriginY+550+5)); cairo_show_text (cr, "550"); cairo_stroke (cr); 构建坐标点 void createPoints(cairo_t *cr,int x,int y) char buf[64]; if(cr == NULL) return; cairo_set_source_rgb(cr, 0.0, 0.0, 1.0);/* 设置颜色 -蓝色 */ cairo_set_line_width(cr, 1); cairo_arc(cr, PosX(x), PosY(y), 1, ANGLE(0), ANGLE(360)); cairo_stroke (cr); /* 显示坐标 */ memset(buf,0x00,sizeof(buf)); sprintf(buf,"(%d,%d)",x,y); cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);/* 设置颜色 -黑色 */ cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 2.0); cairo_move_to(cr,PosX(x-8), PosY(y+8)); cairo_show_text (cr, buf); cairo_stroke (cr); 构建坐标系Y直线 void createLine(cairo_t *cr,int start_x,int start_y,int end_x,int end_y) if(cr == NULL) return; /* 划线 */ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);/* 设置颜色 -红色 */ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_width (cr, 1.0); cairo_move_to (cr, PosX(start_x), PosY(start_y)); cairo_line_to (cr, PosX(end_x), PosY(end_y)); cairo_stroke (cr); 创建正态分布曲线 void createNormalCurve(cairo_t *cr,int start_x,int start_y,int end_x,int end_y) 指数和对数函数测试 int mathTest(void) printf("pow(x,y) x= 10,y=2 value=%lf\n",pow(10.0,2.0)); printf("powl(x,y) log x=10,y=100 value=%lf\n",powf(100.0,2.0)); printf("exp(x) e x=1 value=%f\n",exp(1)); printf("exp(x) e x=2 value=%f\n",exp(2)); printf("loge=%f\n",log(10)); //以e为底的对数函数 printf("loge=%f\n",log(2.718282)); //以e为底的对数函数 printf("log10=%f\n",log10(100)); //以10为底的对数函数 printf("sqrt=%f\n",sqrt(16));//平方根 int main(int argc,char *argv[]) int rand_sum[OFFSET*2+1]={0}; int i,j,i_randn; double u,g,r,o,d_randn,dec; /************************ 创建cairo ****************************/ cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1300, 600); cairo_t *cr = cairo_create (surface); /*********************** 创建背景 *****************************/ createBackground(cr,"background.png"); /*********************** 构建坐标系 *****************************/ createCoordinate(cr); /**************************** 设置随机数种子 ***************************/ /* 最同一轮显示效果中,随机数种子应该保持一致!!!! */ srand(time(0)); r = rand(); //r = 5.0;// /**************************** 正态分布参数设置 ***************************/ u = 130.0;//均值 g = 100; //标准差 /**************************** 设置随机数范围 ***************************/ o = 0.0; //设置为0,表示为生成的随机数在任意范围,非0,表示产生的随机数在[u-o,u+o]之间 for(i = 0; i < 12000; i++) for(j = 0; j < 5; j++) d_randn = randn(u,g,&r); printf("%10.7lf ",d_randn); //设置随机数范围 if(o != 0.0) if(d_randn < u-o || d_randn > u+o) continue; i_randn = (int)d_randn; dec = d_randn-i_randn; if(dec > 0.5) i_randn++; if(i_randn >= -OFFSET && i_randn <= OFFSET) rand_sum[OFFSET+i_randn] = rand_sum[OFFSET+i_randn]+1; printf("\n"); /************************ 对找出的随机数进行绘点 ****************************/ for(i = 0; i < sizeof(rand_sum)/sizeof(int); i++) if(rand_sum[i] == 0) continue; createLine(cr,i-OFFSET,0,i-OFFSET,rand_sum[i]); /************************ 创建图片 ****************************/ cairo_surface_write_to_png (surface, "randn.png"); /************************ 销毁cairo ****************************/ cairo_destroy (cr); cairo_surface_destroy (surface); return 0;

3.2 cairo库

基于Linux C编程,图像显示使用cairo库。至于如何使用不在本文论述的重点。详见:

https://blog.csdn.net/dingzj2000/article/details/103719104

3.3 随机数种子

谈到随机数,必然有随机数种子,代码里用时间产生种子,是为了每一轮结果(一轮60000个点)产生不同的效果。在我的项目中,一轮是从开机到关机整个流程,在设置好初始随机数种子后,就不要在改变。

	/**************************** 设置随机数种子 ***************************/
	/* 最同一轮显示效果中,随机数种子应该保持一致!!!! */
	srand(time(0));
	r = rand();
	//r = 5.0;//

3.4 显示原理

产生的随机数是浮点型,然后强制转换为整型,这个整型对应的像素坐标就加1,在一轮显示后,显示所有像素。

因为浮点型强制转换为整型,简单做了一个四舍五入。在实际项目中可以不用。

i_randn = (int)d_randn;
dec = d_randn-i_randn;
if(dec > 0.5)
	i_randn++;
if(i_randn >= -OFFSET && i_randn  <= OFFSET)
	rand_sum[OFFSET+i_randn] = rand_sum[OFFSET+i_randn]+1;

3.5 函数参数定义

        double randn(double u,double g,double *r)

        参数比较简单:

        u是正态分布平均值;

        g是正态分布标准差;

        *r是随机数种子

/**************************** 正态分布参数设置 ***************************/
u = 130.0;//均值
g = 100;   //标准差
/**************************** 设置随机数范围 ***************************/
o = 0.0;  //设置为0,表示为生成的随机数在任意范围,非0,表示产生的随机数在[u-o,u+o]之间

3.6 输出结果打印

4.核心算法

加微信(微信号:dingzj2000),获取详细算法。

1.目的 因为项目需要,需要产生一串随机数,此随机数非均匀分布,而是基于正态分布,同时该随机数需要在指定区间内。2.结果展示 我的项目中,希望产生一个正态分布的随机数,范围在[20,240],那么正态分布的均值就是130((20+240)/2),经过不断调试结果,设置标准差为50。 上图就是产生的随机数正态分布。 假如不设置取值范围。见下图: 改变标准差到100,让其变得更“胖”。效果如下:...
产生任意分布随机数的一般定理 产生连续型随机变量样本值的方法有如下定理: 定理:设随机变量U~U(0,1),F(x)是某一随机变量的分布函数,且F(x)为严格单调增加且连续的函数,则随机变量F-1(U)具有分布函数F(x),其中F-1(x)是F(x)的反函数。 利用该定理可以生成不同分布函数的随机变量。如随机变量X具有指数分布,其分布函数为 试产生随机变量X。X可以通过以下过程得到: 设U~U(0,1),令 因为当U~U(0,1),也有1 - U~U(0,1),从而 就是所要产生的指数分布的随
      随机数在实际运用中非常之多,如游戏设计,信号处理,通常我们很容易得到平均分布的随机数。但如何根据平均分布的随机数进而产生其它分布的随机数呢?本文提出了一种基于几何直观面积的方法,以正态分布随机数产生为例讨论了任意分布的随机数产生方法。 一、平均分布随机数产生       大家都知道,随机数在各个方面都有很大的作用,在vc的环境下,为我 最近在做中小学试卷分析系统,其中数据的分析让自己很头疼,整个系统采用B/S架构。在分析试卷难度梯度的时候需要用到正态分布,自己做了一些,也查阅了一些资料,终于掌握了将一组数据分析检验,最后生成正态分布。 (1)利用随机函数rand()生成(0,1)区间的100个均匀分布随机数; (2)计算这100个均匀分布随机数均值方差, (3)将这100个均匀分布的随机...
随机数,是软件根据条件生成的一系列随机分布的数值。在一些抽奖、分配序号等对随机性要求较高的实践中,经常会运用生成随机数的方法。那么,在使用IBM SPSS Statistics软件时,怎么才能生成随机数呢? IBM SPSS Statistics可应用数学表达式的方式,生成符合特定条件的随机数。IBM SPSS Statistics的随机数函数类型很多,本文将以生成特定标准差的随机数为例,演示一下具体的操作。 一、数据准备 在运用IBM SPSS Statistics生成随机数前,我们需先在数据集中激
随机数生成时Monte Carlo模拟的中心任务。前面的章节介绍了如何使用Python和例如numpy.random等库莱生成不同分布的随机数的方法。对于我们现在的项目,最重要的是标准正态分布随机数。这样我们应当有一个专门用来生成这种随机数的方便的函数。 这个函数中使用了方差减少技术,也就是antithetic paths和moment matching,这些在前面章节中有所介绍。 应用这个函数是很直接的。这个函数是我们后续分析的重要驱动力量。 import numpy as np def sn.
[(0,1)均匀分布] X = rand(sz1,...,szN)返回由随机数组成的sz1×...×szN数组,其中sz1,...,szN指示每个维度的大小。例如:rand(3,4)返回一个 3×4 的矩阵。 [(a,b)均匀分布] X = unifrnd(a,b,m,n) 返回由随机数生成的 m x n 数组,其中X的范围在[m,n] [标准正态分布] X = randn(...
1. 公式概率密度函数: f(x)=1σ2π−−√e−(x−μ)22σ2 f(x) = \frac{1}{\sigma \sqrt {2 \pi}}e^{-\frac{(x-\mu)^2}{2\sigma^2}} E[X]=μ E[X] = \mu VAR[X]=σ2 VAR[X] = \sigma^2 2. C代码生成随机数C代码double Gauss(double m
文章目录前言一、截断正态分布是什么?1.概率密度函数:(限制了a,b的范围)二、如何截断生成想要的范围正态分布1.说明本人想要截断范围正态分布的意图2.奉上代码,并且简要的介绍补充: 对于一般的正态分布,μ=0,σ=1的分布在python中的代码: plt.hist(np.random.normal(0,1,size = 1000),bins=100) hist是画图工具 一、截断正态分布是什么? 截断分布是指,限制变量x取值范围(scope)的一种分布。例如,限制x取值在0到50之间,即