随机数加上100:Matlab

[我正在将人口数字分成不同的矩阵,现在想用随机数来测试我的代码。]

快速提问,感谢您的帮助 –

如果我使用;

100*rand(9,1) 

将这9个数字加到100的最好方法是什么?

我想要0到100之间的9个随机数,合计为100。

有没有这样的内置命令,因为我似乎无法找到它。

我经常看到这个错误,建议用一个给定的和来产生随机数,只是使用一个统一的随机集合,然后对它们进行缩放。 但是如果你这样做的话,真的是一致的随机结果吗?

尝试在两个维度这个简单的测试。 生成一个巨大的随机样本,然后将它们缩放到总和为1.我将使用bsxfun来进行缩放。

 xy = rand(10000000,2); xy = bsxfun(@times,xy,1./sum(xy,2)); hist(xy(:,1),100) 

如果它们是真正一致的随机数,那么x坐标将是一致的,y坐标也是一样的。 任何价值都可能发生。 实际上,对于总计为1的两点,它们必须位于连接(x,y)平面中两点(0,1),(1,0)的线上。 为了统一点,沿着这条线的任何点必须是相同的可能性。

xy直方图

当我使用缩放解决方案时,显然一致性失败。 这条线上的任何一点都不可能。 我们可以看到同样的事情发生在三维。 在三维图中可以看到,三角形区域中心的点更密集。 这是不一致的反映。

 xyz = rand(10000,3); xyz = bsxfun(@times,xyz,1./sum(xyz,2)); plot3(xyz(:,1),xyz(:,2),xyz(:,3),'.') view(70,35) box on grid on 

xyzplot

再次,简单的缩放解决方案失败。 它不会在感兴趣的领域产生真正一致的结果。

我们可以做得更好吗? 嗯,是。 二维简单的解决方案是生成一个单一的随机数,指定沿着连接点(0,1)和1,0)的直线距离。

 t = rand(10000000,1); xy = t*[0 1] + (1-t)*[1 0]; hist(xy(:,1),100) 

均匀x + y = 1

可以看出,单位平方的方程x + y = 1所定义的直线上的任何一点现在都可能被选择。 这反映了漂亮,平坦的直方图。

大卫·施瓦茨(David Schwartz)在n维方面提出的排序技巧? 很显然,它在二维情况下是如此,下图表明它在三维情况下是如此。 如果没有深思熟虑的话,我相信它将在这个有n个层面的基本案例中起作用。

 n = 10000; uv = [zeros(n,1),sort(rand(n,2),2),ones(n,1)]; xyz = diff(uv,[],2); plot3(xyz(:,1),xyz(:,2),xyz(:,3),'.') box on grid on view(70,35) 

排序技巧

也可以从文件交换器Roger Stafford的贡献中下载函数randfixedsum 。 这是一个更一般的解决方案,在单位超立方体中生成真正一致的随机集,并给定固定和。 因此,为了产生位于单位3立方体中的随机点集合,根据约束它们总和为1.25 …

 xyz = randfixedsum(3,10000,1.25,0,1)'; plot3(xyz(:,1),xyz(:,2),xyz(:,3),'.') view(70,35) box on grid on 

randfixedsum

一个简单的方法是从0到100之间选择8个随机数。将0和100加到列表中,给出10个数字。 排序他们。 然后输出每个连续的数字对之间的差异。 例如,这里有0到100之间的8个随机数:

96,38,95,5,13,57,13,20

所以添加0和100并排序。

0,5,13,13,20,38,57,95,96,100

现在减去:

5-0 = 5
13-5 = 8
13-13 = 0
20-13 = 7
38-20 = 18
57-38 = 19
95-57 = 38
96-95 = 1
100-96 = 4

在那里,有九个数字,总和为100:0,1,4,5,7,8,18,19,38。我得到了一个零,一个是一个奇怪的运气。

给出正确答案还为时不晚

让我们来讨论在范围[0 … 1]内取样X1 … XN,使Sum(X1,…,XN)等于1.然后你可以将它重新调整到100

这称为Dirichlet分布 ,下面是从中抽取的代码。 最简单的情况是,当所有参数都等于1时,则X1,…,XN的所有边际分布都是U(0,1)。 在一般情况下,参数不同于1,边际分布可能有峰值。

—————–从这里取出———————

Dirichlet是单位尺度的伽马随机变量的矢量,用它们的和来标准化。 所以,没有错误检查,这会让你:

 a = [1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0]; // 9 numbers to sample n = 10000; r = drchrnd(a,n) function r = drchrnd(a,n) p = length(a); r = gamrnd(repmat(a,n,1),1,n,p); r = r ./ repmat(sum(r,2),1,p); 

取一个N – 1的数字列表,通过插入0和100来创建N + 1个数字的列表,对列表进行排序,然后将它们分解为总共N个数字。

Interesting Posts