添加到100的随机数:Matlab

Tet*_*tra 40 random matlab uniform-distribution

[我正在将一个人口编号分成不同的矩阵,并希望现在使用随机数来测试我的代码.]

快速提问的人,感谢您的帮助 -

如果我使用;

 100*rand(9,1)
Run Code Online (Sandbox Code Playgroud)

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

我想要0到100之间的9个随机数,加起来为100.

是否有内置命令执行此操作,因为我似乎无法找到它.

小智 79

我经常看到这个错误,建议用一个给定的总和生成随机数,一个只使用一个统一的随机集,然后只是缩放它们.但如果你这样做,结果是否真的一致随机?

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

xy = rand(10000000,2);
xy = bsxfun(@times,xy,1./sum(xy,2));
hist(xy(:,1),100)
Run Code Online (Sandbox Code Playgroud)

如果它们是真正均匀随机的,则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
Run Code Online (Sandbox Code Playgroud)

xyzplot

同样,简单的扩展解决方案失败了.它只是不会在感兴趣的领域产生真正统一的结果.

我们可以做得更好吗?嗯,是.2-d中的简单解决方案是生成单个随机数,该随机数指定沿着连接点(0,1)和1,0的线的距离.

t = rand(10000000,1);
xy = t*[0 1] + (1-t)*[1 0];
hist(xy(:,1),100)
Run Code Online (Sandbox Code Playgroud)

均匀x + y = 1

可以证明,在单位平方中沿着由等式x + y = 1定义的线的任何点现在同样可能被选择.这可以通过漂亮,扁平的直方图反映出来.

David Schwartz提出的排序技巧是否在n维中起作用?显然它在2-d中这样做,下图显示它在3维中这样做.如果没有深入思考这个问题,我相信它会在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)
Run Code Online (Sandbox Code Playgroud)

排序技巧

人们还可以从文件交换中下载函数randfixedsum,Roger Stafford的贡献.这是一种更通用的解决方案,可以在单位超立方体中生成真正均匀的随机集,具有任何给定的固定总和.因此,为了生成位于单位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
Run Code Online (Sandbox Code Playgroud)

randfixedsum


Dav*_*rtz 62

一种简单的方法是在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和总和之间的任意随机数的情况!例如,当随机数的范围小于期望的总和时,这将不起作用. (4认同)
  • 该方法是合理的,但这个答案可以使用另一个编辑...这是一个包含 8 个数字的列表...添加 0 和 100(并默默地从列表中删除 20,使总共 9 个数字)。答案以“九个数字相加为 100:”结尾,然后列出八个数字。总体趋势是获取一个包含 N 个数字的列表,通过插入 0 和 100 创建一个包含 N+2 个数字的列表,将它们差异化为总共 N+1 个数字,然后对结果进行排序。 (3认同)
  • 真棒!我喜欢它.我已经调整了你的方法来创建一系列总和为0的随机数.这允许我创建没有*net*效果的随机变化.(即一个移动的游戏精灵似乎或多或少随机移动,但永远不会离屏.^^) (2认同)

Sev*_*eux 6

给出正确答案还为时不晚

让我们谈谈在[0 ... 1]范围内对X1 ... XN进行采样,以使Sum(X1,...,XN)等于1。然后可以将其缩放为100

这称为Dirichlet分布,下面是从中采样的代码。最简单的情况是,当所有参数都等于1时,则X1,...,XN的所有边际分布将为U(0,1)。一般情况下,如果参数不同于1s,则边际分布可能会出现峰值。

-----------------从这里取走---------------------

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);
Run Code Online (Sandbox Code Playgroud)