Выбор n чисел с фиксированной суммой

В каком-то коде я хочу выбрать n случайные числа в [0,1) какая сумма 1,

Я делаю это, выбирая номера независимо в [0,1) и нормализуя их путем деления каждого на общую сумму:

numbers = [random() for i in range(n)]
numbers = [n/sum(numbers) for n in numbers]

Моя "проблема" в том, что дистрибутив, который я получаю, довольно искажен. Выбирая миллион номеров, ни один не перебирает 1/2, Некоторым усилием я вычислил PDF, и это не хорошо.

Вот странный файл PDF, который я получаю для 5 переменных:

У вас есть идея для хорошего алгоритма выбора чисел, что приведет к более равномерному или простому распределению?

3 ответа

Решение

Вы хотите разделить расстояние от 0 до 1.

Выберите n - 1 чисел от 0 до 1, отсортируйте их и определите расстояния между ними.

Это разделит пространство от 0 до 1, что должно дать случайный большой результат, который вы не получаете.

Тем не менее, при больших значениях n вы обычно можете ожидать, что ваше максимальное значение также уменьшится, но не так быстро, как ваш метод.

Возможно, вас заинтересует распределение Дирихле, которое используется для генерации величин, равных 1, если вы ищете вероятности. Здесь также есть раздел о том, как сгенерировать их, используя гамма-распределения.

Еще один способ получить n случайные числа до 1:

import random


def create_norm_arr(n, remaining=1.0):
    random_numbers = []
    for _ in range(n - 1):
        r = random.random()  # get a random number in [0, 1)
        r = r * remaining
        remaining -= r
        random_numbers.append(r)
    random_numbers.append(remaining)
    return random_numbers

random_numbers = create_norm_arr(5)
print(random_numbers)
print(sum(random_numbers))

Это делает более высокие цифры более вероятными.

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