因为项目需要,需要产生一串随机数,此随机数非均匀分布,而是基于正态分布,同时该随机数需要在指定区间内。
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之间,即