指数衰减样随机分布和连续分布的离散化 [英] Exponential-decay-like-random-distribution and Discretization of continuous distributions

查看:188
本文介绍了指数衰减样随机分布和连续分布的离散化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不幸的是,我并不真正有经验在编程中使用随机数,尽管使用范围内的统一整数。

我正在寻找一种方法来选择数组元素(动态大小,但已知)根据概率分布类似于指数衰减的曲线( http://zh.wikipedia.org/wiki/Exponential_decay )。
含义:我想要选择第一个元素而不是其他元素。我想要一个单调递减函数(在许多已知的概率分布中,像在伽马分布中那样,在减少之前没有增长)。



也许几何分布我可以使用?但是,然后我需要一个答案,我的第二个问题关于这个分布到数组索引的缩放。



当然,喜欢选择最后一个元素而不是第一个元素的双重方法也是可以的。

$ b $问题2(更一般的):

在任何实现中都有一个概念,它会将任何连续随机分布扩展到给定的数组范围(包括例如:使用高斯正态分布,结果总是在一些数组中有效的索引(意思是:中间的元素是首选)。



可以这样(链接文字)是否像我想使用?



平台和库:
C ++ ,并立即使用 boost :: random 库( link text ),但我愿意使用类似 gsl库或其他质量



谢谢!

解决方案

我认为将这个问题分成两个步骤是一个好的开始的地方。首先,如果你有一个离散的概率分布,那么从这个分布绘制的问题不是那么糟糕。 Boost random具有执行此操作的方法。向下滚动此到加权骰子示例。它将从给定的概率分布返回一个整数。您可以使用此整数从数组中选择您感兴趣的元素。



问题的第二部分是如何从连续概率分布将指数转换为离散分布,如升压示例中使用的分布。有几种方法可以去这里,但因为你说你想要一个曲线喜欢指数衰减,我将尝试和解释一个快速和简单的实现,我们牺牲一些统计严格。



这里的想法是从一组离散点的连续分布中抽样,然后调整这些点(归一化),使它们之和为1。这样做的代码为指数分布如下。

  double expDist(int x,double lambda)
{
return(lambda * exp *X));
}

//从这个分布中抽取代码
int i,numElements //其中numElements有你想要绘制的数组中的元素数量。
矢量< double>输出;
double sum,temp
sum = 0;
for(i = 0; i {
temp = expDist(i,0.5); //在第二个参数中替换任何你想要的值
output.push_back(temp);
sum + = temp;
}
//在所有点上进行采样之后,我们需要将数组中的每个元素除以变量sum,使得数组中的值的总和等于1,因此有效概率(i = 0; i {
output [i] / = sum;
}

然后,您可以将输出变量馈送到boost库中的加权骰子示例并且它应该适合你的需要。这种离散采样的一般方法然后归一化向量可以用于许多不同种类的分布。


sadly I'm not really experienced in using random numbers in programming, despite the use of uniform integers in range. Therefore i have to questions regarding this topic.

Question 1 (more specific):

I'm looking for a way to chose array elements (dynamic size, but known) according to a probability distribution similar to the curve of "exponential decay" (http://en.wikipedia.org/wiki/Exponential_decay). Meaning: i want to prefer to chose the first elements rather than the others. I want an monotonic decreasing function (no growing before decreasing like in many well-known probability-distributions like the gamma-distribution).

Maybe the geometric-distribution is something which i could use? But then i need an answer to my second question regarding the scaling of this distribution to array indexes.

The dual method to prefer choosing the last elements rather than the first would be ok too, of course.

Question 2 (more general): Is there a concept in any implementation which will scale me any continuous random-distribution to a given array-range (including discretization)?

Example: Use a gaussian normal distribution and the result is always a valid index in some array (meaning: the middle elements are preferred).

Could this (link text) be something like i want to use?

Platform and Libraries: I'm programming in C++ and use the boost::random library at the moment (link text), but i'm willing to use something like the the gsl library or other quality libraries.

One more wish: I would prefer a way using some quality libraries rather than some quick-and-dirty custom_functions.

Thanks!

解决方案

I think breaking this problem into two steps is a good place to start. First, if you had a discrete probability distribution, then the problem of drawing from this distribution isn't so bad. Boost random has method for doing this. Scroll down this page to the weighted dice example. It will return an integer from the given probability distribution. You can use this integer to select the element from the array that you are interested in.

The second part of your question is how to get go from a continuous probability distribution like the exponential to a discrete distribution like what was used in the boost example. There are several ways you could go here, but because you said that you wanted a curve "like" exponential decay I will try and explain a quick and simple realizing we are sacrificing some statistical rigor.

The idea here is to sample from a continuous distribution at a set of discrete points and then adjust these points (normalize) so that they sum to one. The code for doing this for an exponential distribution is below.

double expDist(int x, double lambda)  
{
   return(lambda*exp(-lambda*x));
}

//code to sample from this distribution
int i,numElements //where numElements has the number of elements in the array you wish to draw from.
vector<double> output;
double sum,temp
sum=0;
for(i=0;i<numElements;i++)
{
   temp=expDist(i,0.5);  //substitute any value you want for lambda in the second argument
   output.push_back(temp); 
   sum+=temp;
}
//after having sampled at all the points we need to divide each element in the array by the variable sum so that the sum of the values in the array is equal to 1 and thus a valid probability distribution
for(i=0;i<numElements;i++)
{
   output[i]/=sum;
}

You can then feed the output variable into the weighted dice example in the boost library and it should fit your needs. This general method of discrete sampling and then normalizing the vector can work for many different kinds of distributions.

这篇关于指数衰减样随机分布和连续分布的离散化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆