Генерация нескольких случайных чисел, равных значению в Python

Не читает ли это: «Выберите все h1 элементы, у которых есть предок, который не является элементом div ...?»

blockquote>

Он делает. Но в типичном HTML-документе каждый h1 имеет по крайней мере двух предков, которые не являются div элементами, а эти предки - не что иное, как body и html.

Это проблема с попыткой фильтрации предков с помощью :not(): он просто не работает надежно, особенно когда :not() не может быть квалифицирован каким-либо другим селектором, таким как селектор типа или селектор классов, например .foo:not(div). Вам будет намного проще использовать стили для всех элементов h1 и переопределить их с помощью div h1.

В Селекторах 4 , :not() принимать полные комплексные селекторы, содержащие комбинаторы, включая комбинатор потомков. Будет ли это реализовано в быстром профиле (и, следовательно, в CSS), еще предстоит проверить и подтвердить, но как только он будет реализован, вы сможете использовать его для исключения элементов с определенными предками. Из-за того, как работают селекторы, отрицание должно выполняться самим элементом, а не предком, чтобы надежно работать, и поэтому синтаксис будет выглядеть несколько иначе:

h1:not(div h1) { color: #900; }

Любой, кто знаком с jQuery быстро укажет, что этот селектор работает в jQuery сегодня . Это один из числа несоответствий между Selector 3's :not() и jQuery :not() , которые Selectors 4 исправляет.

29
задан Jack S. 28 August 2010 в 02: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.
11
ответ дан Laurence Gonsalves 28 August 2010 в 02:37
поделиться

Генерация 4 случайных чисел, вычисление их суммы, деление каждого на сумму и умножение на 40.

Если вы хотите получить целые числа, это потребует небольшой неслучайности.

8
ответ дан lalli 28 August 2010 в 02:37
поделиться

Вот стандартное решение. Он похож на ответ Лоуренса Гонсалвеса, но имеет два преимущества перед этим ответом.

  1. Она едина: любая комбинация из 4 положительных целых чисел, в сумме дающая 40, с одинаковой вероятностью приведет к этой схеме.

и

  1. его легко адаптировать к другим суммам (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(range(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) = (д, ж - д, ж - ж, 40 - г) в обратном направлении.

Если вам нужны неотрицательные целые числа (т.е., допуская 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
83
ответ дан pjs 28 August 2010 в 02:37
поделиться
from numpy.random import multinomial
multinomial(40, [1/4.] * 4)
5
ответ дан Ruggero Turra 28 August 2010 в 02:37
поделиться

Если вы хотите, чтобы они были равномерно распределены, и если вы не хотите повторов

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 28 August 2010 в 02:37
поделиться

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

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

4
ответ дан Jim Lewis 28 August 2010 в 02:37
поделиться
Другие вопросы по тегам:

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