Я часто вижу ошибку: предположение, что для генерации случайных чисел с заданной суммой нужно просто использовать равномерный случайный набор и просто масштабировать их.Но действительно ли результат действительно случайный, если вы делаете это таким образом?
Попробуйте этот простой тест в двух измерениях.Создайте огромную случайную выборку, затем масштабируйте их до суммы 1. Я буду использовать bsxfun для масштабирования.
xy = rand(10000000,2);
xy = bsxfun(@times,xy,1./sum(xy,2));
hist(xy(:,1),100)
Если бы они были действительно равномерно случайными, то координата x была бы равномерной, как если быкоордината у.Любая ценность будет в равной степени вероятна.Фактически, чтобы две точки суммировали с 1, они должны лежать вдоль линии, соединяющей две точки (0,1), (1,0) в плоскости (x, y).Чтобы точки были однородными, любая точка вдоль этой линии должна быть одинаково вероятной.
![xy histogram](https://i.stack.imgur.com/FeGrK.jpg)
Очевидно, что при использовании решения масштабирования не получается равномерности.Любая точка на этой линии НЕ одинаково вероятна.Мы можем видеть, что то же самое происходит в 3-х измерениях.Обратите внимание, что на 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
![xyzplot](https://i.stack.imgur.com/1Y3Sr.jpg)
Опять же, простое решение масштабирования не удается.Он просто НЕ дает действительно единообразных результатов в интересующей области.
Можем ли мы добиться большего успеха?Ну да.Простое решение в 2-й состоит в том, чтобы сгенерировать одно случайное число, которое обозначает расстояние вдоль линии, соединяющей точки (0,1) и 1,0).
t = rand(10000000,1);
xy = t*[0 1] + (1-t)*[1 0];
hist(xy(:,1),100)
![Uniform x+y = 1](https://i.stack.imgur.com/aWUPg.jpg)
Можно показать, что ЛЮБАЯ точка вдоль линии, определяемой уравнением 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)
![Sort trick](https://i.stack.imgur.com/F2hLN.jpg)
Можно также загрузить функцию 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](https://i.stack.imgur.com/pGiU3.jpg)