Убедитесь, что все 2 ** N комбинаций сгенерированы в M случайных выходах N булевых - PullRequest
0 голосов
/ 30 апреля 2020

В этом примере ниже M = 10 и N = 2, а поскольку M значительно больше, чем 2 ** N, вероятность состоит в том, что каждая возможная комбинация из N логических значений (True, True), (True False), ( False, True), (False, False) в этом примере будут сгенерированы среди выходов M как минимум один раз, как это произошло ниже.

for _ in range(10):
...     choice1 = np.random.choice((True, False))
...     choice2 = np.random.choice((True, False))
...     print(choice1, choice2)
...     
False False
False False
True False
True False
True True
False True
True True
True True
True False
False False

Но это не гарантировано. Существует низкая вероятность получения 10 X (False, False) или, альтернативно, 10 X (True, True) или, возможно, микса, в котором одна конкретная пара, скажем (False, True), никогда не появляется.

In «в реальной жизни» отпечаток заменяется инструкцией о доходности, а choice1 и choice2 сопровождаются несколькими другими случайно сгенерированными числовыми переменными c.

Как можно легко изменить генерацию choice1 и choice2, чтобы убедиться, что они всегда охватывают все 4 возможности, сохраняя при этом (в основном) случайность, без добавления 4 дополнительных неслучайных случаев, чтобы заставить их произойти?

Я чувствую как если можно использовать выбор без замены, но я не могу думать, как включить это.

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Этот ответ делает именно то, что я хочу. У него нет недостатка от R Liab, хотя это было полезно - спасибо - при выводе этого.

import numpy as np
from itertools import product

N = 2
M = 10
possibles = product((True, False), repeat=N)

selection_pool = list(possibles)
not_yet_used = set(selection_pool)
m2go = M

while m2go > 0:
    if m2go <= len(not_yet_used):
        selection_pool = list(not_yet_used)
    used = selection_pool[np.random.choice(len(selection_pool))]
    not_yet_used.discard(used)
    print(*used)
    m2go -= 1
1 голос
/ 30 апреля 2020

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

Недостатком является то, что вы не можете получить один и тот же элемент дважды до того, как все элементы будут извлечены.

Кажется, что следующий код выполняет свою работу:

import random
import copy
from itertools import product 
M = 10
N = 2

#fist generate all the possible combinations:
all_combinations_ref = product([True,False],repeat =N)
all_combinations = list(copy.copy(all_combinations_ref))
#now randomly pop one element:
for i in range(M):
    if len(all_combinations) == 0:
        all_combinations = list(copy.copy(all_combinations_ref))
    print(all_combinations.pop(random.randint(0,len(all_combinations)-1)))

Надеюсь, это поможет вам.

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