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

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

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

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

 100*rand(9,1)

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

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

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

4 ответа

Решение

Я часто вижу ошибку: предположение, что для генерации случайных чисел с заданной суммой нужно просто использовать равномерный случайный набор и просто масштабировать их. Но действительно ли результат действительно случайно, если вы делаете это таким образом?

Попробуйте этот простой тест в двух измерениях. Создайте огромную случайную выборку, затем масштабируйте их до суммы 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-х измерениях. Обратите внимание, что на 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-й состоит в том, чтобы сгенерировать одно случайное число, которое обозначает расстояние вдоль линии, соединяющей точки (0,1) и 1,0).

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

Равномерное х + у = 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)

Сортировать трюк

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

Один простой способ - выбрать 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. То, что я получил ноль, а одно было просто странной удачей.

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

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

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

----------------- взято отсюда ---------------------

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

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

Возьмите список из N - 1 чисел, создайте список из N + 1 чисел, вставив 0 и 100, отсортируйте список и разведите их до общего числа N чисел.

Другие вопросы по тегам