Ответ 1
Я часто вижу ошибку, предложение о том, чтобы генерировать случайные числа с заданной суммой, просто использует единый случайный набор и просто масштабируйте их. Но является ли результат действительно равномерным случайным, если вы это сделаете?
Попробуйте этот простой тест в двух измерениях. Создайте огромную случайную выборку, затем масштабируйте ее до суммы до 1. Я буду использовать bsxfun для масштабирования.
xy = rand(10000000,2);
xy = bsxfun(@times,xy,1./sum(xy,2));
hist(xy(:,1),100)
Если бы они были действительно равномерно случайными, то координата x была бы равномерной, как и координата y. Любое значение будет в равной степени вероятным. По сути, для двух точек суммирования до 1 они должны лежать вдоль линии, соединяющей две точки (0,1), (1,0) в плоскости (x, y). Для того чтобы точки были равномерными, любая точка вдоль этой линии должна быть одинаково вероятна.
Четкая однородность не работает, когда я использую решение масштабирования. Любая точка на этой строке НЕ одинаково вероятна. Мы видим то же самое, что происходит в трехмерном пространстве. Смотрите, что на 3-м рисунке здесь точки в центре треугольной области более плотно упакованы. Это отражение неравномерности.
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
Опять же, простое решение масштабирования выходит из строя. Он просто НЕ производит действительно однородные результаты в интересующей области.
Мы можем сделать лучше? Ну да. Простым решением в 2-d является создание единственного случайного числа, которое обозначает расстояние по линии, соединяющей точки (0,1) и 1,0).
t = rand(10000000,1);
xy = t*[0 1] + (1-t)*[1 0];
hist(xy(:,1),100)
Можно показать, что теперь ЛЮБОЙ пункт вдоль линии, определяемой уравнением x + y = 1, в единичном квадрате, в равной степени вероятен. Это отражается на хорошей плоской гистограмме.
Разве трюк, предложенный Дэвидом Шварцем, работает в n-измерениях? Ясно, что это делается в 2-й, и на рисунке ниже показано, что он делает это в 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)
Также можно загрузить функцию 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