以均匀随机分布生成任意斜率随机线性分布

本文的目的是利用(0,1)上的均匀分布随机数生成器生成区间为(imin,imax),斜率为slope的任意归一化线性随机数生成器。

借助(0,1)上的均匀随机数生成器,可以通过反函数法生成任意分布的随机数生成器。

对于C++,生成(imin,imax)上随机数生成器的代码为

double uniform_dist(double imin,double imax)
{
    int temp;
    while((temp=rand())==RAND_MAX){
        ;
    }
    return temp/RAND_MAX*(imax-imin)+imin);
}

其中imin为随机变量最小值,imax为随机变量最大值。

在调用时,只需

x=uniform_dist(0,1);

就可以生成$(0,1)$上的任意随机变量。

对任累积意分布函数$F$,其概率密度为$f(x)$,则有

$F(x_1)=P(x\le x_1)=\int _{-\infty} ^{x_1} f(x‘) dx$

由累积分布函数的值范围$F \in (0,1),则若$F$为$(0,1)$上的随机变量,即可通过$F(x_1)$的反函数来求得与此对应的随机变量$x_1$。

因此要生成概率密度函数为$f(x)=slope*x+b$区间为$(imin,imax)$的随机变量,分为2步

1. 通过归一化求出b的值

$ \int _{-\infty} ^{\infty} f(x)dx=\int _{imin} ^{imax} f(x)dx=1$

可以求出

$b=\frac {1-\frac {1}{2} slope (imax^2-imin^2)}{imax-imin}$

2. 由累积分布函数

$F(x_1)= \int _{imin} ^{x_1} f(x)dx=F_1(x_1)-F_1(imin)$

其中$F_1$为概率密度函数$f(x)$的原函数。由$F(x_1)$的反函数$F^{-1} (x_1)$可以求得的随机变量$x_1 \in (imin,imax)$,并且服从概率密度函数$f(x)$。

带入方程得

$\frac {1}{2}a x_1^2+\frac {1-\frac {1}{2} slope (imax^2-imin^2)}{imax-imin}x_1 \\ -\frac {1}{2}\ slope\ imin^2-\frac {1-\frac {1}{2} slope (imax^2-imin^2)}{imax-imin} imin - F(x_1)=0$

$ a=\frac {1}{2}slope$

$ b=\frac {1-\frac {1}{2}\ slope \ (imax^2-imin^2)}{imax-imin}$

$ c=-\frac {1}{2}\ slope\ imin^2-\frac {1-\frac {1}{2} slope (imax^2-imin^2)}{imax-imin} imin - F(x_1)$

解得

$ x_1=\frac {-b + \sqrt {b^2-4ac}}{2a}$

C++实现程序如下

#include<iostream>
#include<vector>
#include<time.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
//*******************************************************************//  uniform distribution//*******************************************************************

double uniform_dist(double imin,double imax)
{
    int temp;
    while((temp=rand())==RAND_MAX){
        ;
    }
    return((double) temp/RAND_MAX*(imax-imin)+imin);
}

//*******************************************************************//  linear distribution for any slope//*******************************************************************
double linear_dist(double a,double b,double imin,double imax,double slope)
{
    double c;
    c=-0.5*slope*imin*imin-b*imin-uniform_dist(0,1);
    return ((-b+sqrt(b*b-4*a*c))/(2a));
}
 int main()
{  //===========================================================  //  sequence to be sampled  //===========================================================
    const N=1000000;
    vector<
    double> x(N);
    srand((unsigned)time(NULL));

  //===========================================================  //  parameters of the linear distribution  //===========================================================
    double imin,imax,slope;
    imin=0.0;
    imax=3.0;
    slope=-0.2;

    double a,b,criterion;
    a=0.5*slope;
    b=(1-0.5*slope*(imax*imax-imin*imin))/(imax-imin);

  //*********************************************************  //  judge the reasonability of the linear distribution  //*********************************************************
    if(slope>0){
        criterion=slope*imin+b;
        if(criterion<0){
            cerr<<"The probability of the variable must be larger than 0"<<endl;
            exit(1);
        }
    }
    else if(slope<0){
        criterion=slope*imax+b;
        if(criterion<0){
            cerr<<"The probability of the variable must be larger than 0"<<endl;
            exit(1);
        }
    }
  //**********************************************************  //  sampling the random data  //**********************************************************
    for(int i=0;i!=x.size();++i){
        x[i]=linear_dist(a,b,imin,imax,slope);
    }
  //**********************************************************  //  output the data  //**********************************************************
    for(int i=0;i!=x.size();++i){
        cout<<x[i]<<"";
    }
    return 0;

注意:

对斜率的选取和随机变量区间的选取需要考虑归一化的限制,也即是需要考虑每一个随机变量的概率要大于0。

时间: 2024-08-11 07:46:35

以均匀随机分布生成任意斜率随机线性分布的相关文章

记一次随机字符串生成算法的随机概率与性能的提升

一.前言背景 前几天我部门一个和银行对接的项目中出现了业务Id重复的现象,导致了很多之前不可预见的bug.由于该项目有资金流动,涉及到金钱交易,故不敢有任何闪失.于是leader把同事写的Handler.ashx.cs发给我瞧了瞧,其中的一处流水号生成代码引起了我的注意.代码如下: string[] str1 = new string[] { "A", "B", "C", "D", "E", "F

Linux Shell 生成随机数和随机字符串

日常生活中,会经常用到随机数,使用场景非常广泛,例如买彩票.丢骰子.抽签.年会抽奖等. Shell 下如何生成随机数呢,米扑博客特意写了本文,总结 Linux Shell 产生随机数的多种方法. 本文原文转自米扑博客:Linux Shell 生成随机数和随机字符串 计算机产生的的只是"伪随机数",不会产生绝对的随机数(是一种理想随机数).实际上,伪随机数和理想随机数也是相对的概念,例如伪随机数在1万万亿亿亿年内也无法重复,算是理想随机数么? 伪随机数在大量重现时也并不一定保持唯一,但一

利用random生成6位随机验证码

使用random生成6位随机验证码 #!/usr/bin/env python # _*_ coding:utf-8 _*_ import random code = [] for i in range(6):     #可在此处改变条件表达式来调整生成数字的机率     if i == random.randint(0,5):         # 如果随机数与0-5中的随机数相等,生成数字验证码        code.append(str(random.randint(0,9)))     

咸蛋系列一●《模板模式构建随机对象生成》2 构思

随机对象生成可以说是随机数生成的一个延伸,在实际使用中,我们可能要生成的不是一个简简单单的数字,而是像数字.大小写字符.中文汉字.算数表达式等. 由于其实现相对简单,取各种随机对象的源码网上也比比皆是,因而貌似也没人做一个通用的.可扩展的随机对象生成. 博主要不是因为闲得蛋疼也是不会想到做这个东西的,好了,言归正传.分析随机对象生成,其要点无外乎三点: 1. 设置随机对象集: 2. 获取一个或多个随机对象: 3. 获取一个或多个不重复随机对象: 在这三点中,后两者算法皆固定,仅设置对象集不同,故

机器学习算法的随机数据生成

在学习机器学习算法的过程中,我们经常需要数据来验证算法,调试参数.但是找到一组十分合适某种特定算法类型的数据样本却不那么容易.还好numpy, scikit-learn都提供了随机数据生成的功能,我们可以自己生成适合某一种模型的数据,用随机数据来做清洗,归一化,转换,然后选择模型与算法做拟合和预测.下面对scikit-learn和numpy生成数据样本的方法做一个总结. 1. numpy随机数据生成API numpy比较适合用来生产一些简单的抽样数据.API都在random类中,常见的API有:

随机验证码生成代码 (转)

随机验证码生成代码 package com.zuidaima.core.util; import java.util.Random; public class RandomUtil { public static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; public static final String LETTERCHAR = "abc

【python】13位随机序列号生成工具 源码分析

By Dolphin,BeiJing,20150712 0X00  背景 最近在学习python 这门语言,刚学完for循环,对于很多语句语法都不太熟悉.就在今天,看到有某个网站的活动,需要输入一个13位的序列号来判断你是否中奖,但是这个13位序列号是需要购买他们家的产品才能获得,得耗费一定的金钱,于是我就在想,是不是能自己写一个序列号生成器来碰碰运气,所以决定运用刚学的python的初级知识进行编写. 0X01  知识点准备 这个工具主要的功能是生成随机字母做序列号,python中的rando

python生成20个随机的DNA fasta格式文件

生成20个随机的文件, 由于没有用到hash名字,文件名有可能会重复 每个文件中有30-50条序列 每条序列的长度为70-120个碱基 import os import random import string print (dir(string)) letter = string.ascii_letters os.chdir("D:\\") bases = {1:"A", 2:"T", 3:"C", 4:"G&qu

随机字符串生成

function TfrmPWGenerate.btnGenerateClick(Sender: TObject): string; {max length of generated password}const  intMAX_PW_LEN = 10;var  i: Byte;  s: string;begin  {if you want to use the 'A..Z' characters}  if cbAZ.Checked then    s := 'ABCDEFGHIJKLMNOPQ