Случайное распределение целых чисел с фиксированным итоговым [дубликатом]

Это означает, что ваш код использовал ссылочную переменную объекта, которая была установлена ​​в нуль (т. е. она не ссылалась на экземпляр фактического объекта).

Чтобы предотвратить ошибку, объекты, которые могут быть пустыми, должны быть протестированы для null перед тем, как использовать.

if (myvar != null)
{
    // Go ahead and use myvar
    myvar.property = ...
}
else
{
    // Whoops! myvar is null and cannot be used without first
    // assigning it to an instance reference
    // Attempting to use myvar here will result in NullReferenceException
}
24
задан Jack S. 28 August 2010 в 03:37
поделиться

6 ответов

b = random.randint(2, 38)
a = random.randint(1, b - 1)
c = random.randint(b + 1, 39)
return [a, b - a, c - b, 40 - c]

(Я предполагаю, что вам нужны целые числа, так как вы сказали «1-40», но это можно легко обобщить для поплавков.)

Вот как это работает:

  • сокращает общий диапазон в два раза, то есть b. Нечетный диапазон - это то, что они будут по крайней мере на 2 ниже середины и не менее 2 выше. (Это происходит от вашего 1 минимального значения для каждого значения).
  • разрезает каждый из этих диапазонов двумя случайными способами. Опять же, оценка должна учитывать 1 минимум.
  • возвращает размер каждого фрагмента. Они добавят до 40.
12
ответ дан Laurence Gonsalves 24 August 2018 в 04:28
поделиться

В диапазоне [1,37] (с разрешенными повторами) существует только 37 ^ 4 = 1,874,161 расположения четырех целых чисел. Перечислите их, сохраните и подсчитайте перестановки, которые составляют до 40. (Это будет намного меньшее число, N).

Нарисуйте равномерно распределенные случайные целые числа K в интервале [0, N-1] и верните K-ю перестановку. Это легко увидеть, чтобы гарантировать равномерное распределение по пространству возможных исходов, причем каждая позиция последовательности одинаково распределена. (Многие из ответов, которые я вижу, будут иметь окончательный выбор, предвзятый ниже, чем первые три!) [/ ​​G1]

3
ответ дан Jim Lewis 24 August 2018 в 04:28
поделиться

Создайте 4 случайных числа, вычислите их сумму, разделите каждую на сумму и умножьте на 40.

Если вам нужны целые числа, тогда для этого потребуется небольшая неслучайность.

6
ответ дан lalli 24 August 2018 в 04:28
поделиться

Вот стандартное решение. Это похоже на ответ Лоуренса Гонсалвеса, но имеет два преимущества перед этим ответом. (1) Это единообразно: каждая комбинация из 4 положительных целых чисел, добавляющая до 40, в равной степени может придумать эту схему, и (2) легко адаптироваться к другим итоговым значениям (7 чисел, добавляя до 100 и т. Д.):

import random

def constrained_sum_sample_pos(n, total):
    """Return a randomly chosen list of n positive integers summing to total.
    Each such list is equally likely to occur."""

    dividers = sorted(random.sample(xrange(1, total), n - 1))
    return [a - b for a, b in zip(dividers + [total], [0] + dividers)]

Выводы выборки:

>>> constrained_sum_sample_pos(4, 40)
[4, 4, 25, 7]
>>> constrained_sum_sample_pos(4, 40)
[9, 6, 5, 20]
>>> constrained_sum_sample_pos(4, 40)
[11, 2, 15, 12]
>>> constrained_sum_sample_pos(4, 40)
[24, 8, 3, 5]

Объяснение: существует взаимно однозначное соответствие между (1) 4-кортежами (a, b, c, d) положительных целых чисел, для которых a + b + c + d == 40 , и (2) тройки целых чисел (e, f, g) с 0 < e < f < g < 40, и это легко произвести последним, используя random.sample. Соответствие задается параметром (e, f, g) = (a, a + b, a + b + c) в одном направлении и (a, b, c, d) = (e, f - e, g - f, 40 - g) в обратном направлении.

Если вы хотите неотрицательные целые числа (то есть, разрешая 0) вместо положительные, то есть простое преобразование: если (a, b, c, d) - неотрицательные целые числа, суммирующие к 40, тогда (a+1, b+1, c+1, d+1) представляют собой положительные целые числа, суммирующие 44, и наоборот. Используя эту идею, мы имеем:

def constrained_sum_sample_nonneg(n, total):
    """Return a randomly chosen list of n nonnegative integers summing to total.
    Each such list is equally likely to occur."""

    return [x - 1 for x in constrained_sum_sample_pos(n, total + n)]

Графическая иллюстрация constrained_sum_sample_pos(4, 10), благодаря @FM. (Отредактировано слегка.)

0 1 2 3 4 5 6 7 8 9 10  # The universe.
|                   |   # Place fixed dividers at 0, 10.
|   |     |       | |   # Add 4 - 1 randomly chosen dividers in [1, 9]
  a    b      c    d    # Compute the 4 differences: 2 3 4 1
66
ответ дан Mark Dickinson 24 August 2018 в 04:28
поделиться

Предполагая, что вы хотите, чтобы они были равномерно распределены, и предполагая, что вы не хотите повторений

addends = []
picks = range(1, 34)
while sum(addends) != 40:
    addends = random.sample(picks, 3)
    if sum(addends) > 39:
        continue
    addends.append(40 - sum(addends))
1
ответ дан msw 24 August 2018 в 04:28
поделиться
from numpy.random import multinomial
multinomial(40, [1/4.] * 4)
3
ответ дан Ruggero Turra 24 August 2018 в 04:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: