Случайные числа, которые добавляют к 100: Matlab - PullRequest
36 голосов
/ 09 ноября 2011

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

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

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

 100*rand(9,1)

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

Я бы хотел, чтобы 9 случайных чисел находились в диапазоне от 0 до 100это добавляет до 100.

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

Ответы [ 4 ]

74 голосов
/ 09 ноября 2011

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

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

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

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

59 голосов
/ 09 ноября 2011

Один простой способ - выбрать 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 голосов
/ 27 июля 2017

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

Давайте поговорим о выборке 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);
0 голосов
/ 18 июля 2016

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...