加到 100 的随机数:Matlab

Posted

技术标签:

【中文标题】加到 100 的随机数:Matlab【英文标题】:Random numbers that add to 100: Matlab 【发布时间】:2011-12-25 06:20:16 【问题描述】:

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

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

如果我使用;

 100*rand(9,1)

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

我想要 9 个 0 到 100 之间的随机数,加起来等于 100。

是否有一个内置命令可以执行此操作,因为我似乎找不到它。

【问题讨论】:

Non biased return a list of n random positive numbers (>=0) so that their sum == total_sum 的可能重复项 好问题,但重复:与语言无关的方面比与语言相关的部分重要得多。 这能回答你的问题吗? Getting N random numbers whose sum is M 【参考方案1】:

我经常看到这个错误,建议生成具有给定总和的随机数,只需使用统一随机集,然后对其进行缩放。但是如果你这样做,结果真的是均匀随机的吗?

试试这个简单的二维测试。生成一个巨大的随机样本,然后将它们缩放到总和为 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) 的直线上。为了使点均匀,沿该线的任何点的可能性都必须相等。

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

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

同样,简单的缩放解决方案失败了。它根本不会在感兴趣的领域产生真正统一的结果。

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

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

可以证明,沿着由方程 x+y = 1 定义的直线上的任何点,在单位正方形中,现在都同样可能被选中。漂亮、平坦的直方图反映了这一点。

David Schwartz 建议的排序技巧是否适用于 n 维?很明显,它在 2-d 中这样做,下图表明它在 3-dimension 中这样做。在没有深入思考这个问题的情况下,我相信它会在 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

【讨论】:

我知道这是一个老问题,但谁能向我解释这个答案?你如何“生成一个随机数来指定沿着连接点 (0,1) 和 1,0) 的直线的距离。可以证明,沿着由方程 x+y = 1 定义的直线上的任何点,在单位方格中,现在同样有可能被选中。”?这甚至准确吗?我的部分困惑是,他为证明而发布的 Matlab 代码只是表明随机数是统一的,但它们并没有缩放到 1……这就是重点。 @jdfinch3:正在解决的问题是“选择一对数字 x, y 使得 x+y = 1。”解决方案是:“在 [0, 1] 范围内选择 x,然后计算 y = 1 - x”。这确保了对 (x, y) 是从所有可能对的宇宙中统一选择的。直方图表明它有效。 David Schwartz 的回答提供了对两个以上维度的概括(即具有两个以上元素的元组)。 @rici - 感谢您的回复!您对解决方案的重新措辞使它为我点击。 :) 证明 3 维相当容易:设两个随机数为 p 和 q,然后如果 p q 则 (q, p) 位于该三角形内。从 1 中减去较大的数字会将三角形映射到 (0,1)-(0,0)-(1,0),这是所需区域在 xy 平面上的投影,然后 z 就是 p 之间的差和 q 根据需要。对于更高的维度,我相信您可以将 N N-D 超金字塔包装在 N-D 超立方体中,这意味着对第 N 个随机数进行排序等同于选择合适的超金字塔。【参考方案2】:

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

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 的随机数。这允许我创建没有 net 效果的随机更改。 (即,移动的游戏精灵似乎或多或少地随机移动,但永远不会离开屏幕。^^) 这仅在您被允许使用介于 0 和您的总和之间的任何随机数时才有效!例如,当随机数的范围小于所需的总和时,这将不起作用。 该方法是正确的,但这个答案可以使用另一个编辑...这是一个包含 8 个数字的列表...添加 0 和 100(并从列表中默默地删除 20 以使总共九个数字)。答案以“九个数字加起来为 100:”结束,并继续列出八个数字。总体趋势是获取 N 个数字的列表,通过插入 0 和 100 创建一个 N+2 个数字的列表,然后将它们区分为总共 N+1 个数字并对结果进行排序。 @surgical:我修复了这个例子,我认为这只是一个简单的错误。我认为对最终元组进行排序会产生误导,但我会留给原作者来决定。 python 示例:>>> a = [0] + sorted([random.random()*100 for _ in range(9-1)]) + [100] >>> b = [a[i+1] - a[i] for i in range(len(a)-1)] >>> sum(b) == 100【参考方案3】:

现在给出正确答案还为时不晚

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

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

-----------------取自here ---------------------

狄利克雷是单位尺度伽马随机变量的向量,通过它们的总和进行归一化。所以,没有错误检查,这会让你:

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);

【讨论】:

【参考方案4】:

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

【讨论】:

以上是关于加到 100 的随机数:Matlab的主要内容,如果未能解决你的问题,请参考以下文章

在图像中随机更改像素值程序——matlab

matlab随机变量为一般分布,如何搜索最优解

matlab 如何产生power law分布的随机数

怎么用matlab生成20.1到25.9之间的随机数,要求保留到小数点后一位?高手进

怎么在matlab中生成一个随机的强联通图

MATLAB如何把n个数不重复地随机分为m组