回复内容:给定一个累积分布函数( cumulative distribution function, cdf),只要能求出其反函数,就能把均匀分布的随机数映射至。这称为 inverse transform sampling。random sampling (numpy.random)
numpy.random 已经实现了从定义好的分布中抽样的函数,
比如beta(a, b[, size]) draw samples from a beta distribution.binomial(n, p[, size]) draw samples from a binomial distribution.chisquare(df[, size]) draw samples from a chi-square distribution.dirichlet(alpha[, size]) draw samples from the dirichlet distribution.exponential([scale, size]) draw samples from an exponential distribution.f(dfnum, dfden[, size]) draw samples from an f distribution.gamma(shape[, scale, size]) draw samples from a gamma distribution.geometric(p[, size]) draw samples from the geometric distribution.gumbel([loc, scale, size]) draw samples from a gumbel distribution.
假设楼主取的是1-100的整数,100的概率比99大一倍,99比98大一倍,
那么按1 为基准,
总和sum= 1+2+ 4 + 2^99 =2^100-1
那么 随机取rand(1,sum), 如果在2^30-1到2^31范围之间,那么就是取到30。简单的公式是log(rand(1,sum))/log2献一下丑,有错误劳烦指出!
恰好做毕设碰到了这个问题,与大家分享下。
假设我们获得了每个值的概率,然后对每个值的概率进行累加,将每次累加结果统一放在一个数轴上表示。我们取10个值来说明问题,如下图:
[i]表示第i个值,横坐标轴(0-0.1)就代表 [1]的概率;(0.5-0.75)代表第 [7]的概率;(0-0.75)代表 [1]到 [7]的概率累加和。
接下来,比如说在matlab里,使用rand()函数,产生一个范围为0-1均匀分布的随机数,假如图中产生的数为0.65,它落在(0.5-0.75)这个区间,而这个区间代表着 [7]的概率。于是,我们判定将 [7]拿出来作为本次按概率筛选的结果。
附matlab的代码
%其中max_column值的个数,prob代表每个
%值的概率,prob_array代表概率累加和
%largest_cumulative_prob代表概率累加最大值
for j=1:max_column -1
prob_array(j+1) = prob_array(j)+prob(j);
end
largest_cumulative_prob=prob_array(max_column);
%largest_cumulative_prob和prob_array需要做
%归一化,代码里没有做
choice = rand() * largest_cumulative_prob;
low = 1;
high = max_column;
while (high>(low+1))
middle = (high+low)/2;
middle = floor(middle);
if (choice > prob_array(middle))
low = middle;
else high = middle;
end
end
%最后取出low作为本次筛选结果
%这里就不解释了,其思想和上面图中一样的
这个方法适用于离散的数,对于连续的数我还不清楚怎么处理,个人猜想可能会用到概率密度?望大神解答!舍选法。
不用特别担心计算次数:不用特别担心计算次数:
看过一点ndndsim的源码。里面生成zipf分布的方法很有趣。希望能给题主参考。给定累积分布函数和范围比如是1-50。算出累计分布函数在1到50函数值存在数组里。然后用一个均匀分布 生成一个随机数。然后依次和五十个分布函数值比较。返回下标。当然返回下标这一点可以随要求变化。100/rand(1,100)rand(1,rand(1,rand(1,100)))这样你看行不行
