Случайные числа, которые добавляют к 100: Matlab

[Я разбиваю номер популяции на разные матрицы и хочу проверить мой код с использованием случайных чисел на данный момент.]

Быстрый вопрос ребятам и спасибо за вашу помощь заранее -

Если я использую;

 100*rand(9,1)

Каков наилучший способ добавить эти 9 чисел в 100?

Мне бы хотелось 9 случайных чисел от 0 до 100, которые добавляют до 100.

Есть ли встроенная команда, которая делает это, потому что я не могу найти ее.

Ответы

Ответ 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). Для того чтобы точки были равномерными, любая точка вдоль этой линии должна быть одинаково вероятна.

xy histogram

Четкая однородность не работает, когда я использую решение масштабирования. Любая точка на этой строке НЕ одинаково вероятна. Мы видим то же самое, что происходит в трехмерном пространстве. Смотрите, что на 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

Опять же, простое решение масштабирования выходит из строя. Он просто НЕ производит действительно однородные результаты в интересующей области.

Мы можем сделать лучше? Ну да. Простым решением в 2-d является создание единственного случайного числа, которое обозначает расстояние по линии, соединяющей точки (0,1) и 1,0).

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

Uniform x+y = 1

Можно показать, что теперь ЛЮБОЙ пункт вдоль линии, определяемой уравнением 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

Также можно загрузить функцию 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

Ответ 2

Один простой способ - выбрать 8 случайных чисел от 0 до 100. Добавьте 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. Это я получил нуль, а один был просто странным удачей.

Ответ 3

Еще не поздно дать правильный ответ

Расскажите о выборке X1... XN в диапазоне [0... 1], чтобы Sum (X1,..., XN) равнялся 1. Тогда вы можете перемасштабировать его до 100

Это называется дистрибутив Дирихле, а ниже - код для его выборки. Самый простой случай - когда все параметры равны 1, тогда все предельные распределения для X1,..., XN будут U (0,1). В общем случае с параметрами, отличными от 1s, маргинальные распределения могут иметь пики.

----------------- взято из здесь ------- --------------

Дирихле - вектор гамма-случайных величин единичного масштаба, нормированный их суммой. Таким образом, без проверки ошибок вы получите следующее:

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, создайте список номеров N + 1, вставив 0 и 100, отсортируйте список и разделите их на N номеров.