我经常看到这个错误,建议生成具有给定总和的随机数,只需使用统一随机集,然后对其进行缩放。但是如果你这样做,结果真的是均匀随机的吗?
试试这个简单的二维测试。生成一个巨大的随机样本,然后将它们缩放到总和为 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