Алгоритм перетасовки колоды не достаточно "человеческий" - PullRequest
1 голос
/ 28 января 2020

Ради забавы я сделал эту функцию перетасовки колоды, чтобы имитировать c, как люди несовершенно перетасовывают колоду. Они разрезают его почти пополам и используют метод «ряби», чтобы переплести левую и правую колоды вместе, а затем повторяют процесс любое количество раз. Колода никогда идеально не сплетается вместе. Вы можете перетасовать их, как L1, L2, R1, L3, R2, L4, R3 и т. Д. c. или R1, L1, R2, R3, L2 и др. c. , Проблема в моем коде состоит в том, что последовательные перестановки никогда не переключают первую и последнюю карты колоды. Если в первом перетасовке смещение говорит, что ставим L1 на верх колоды, то у каждого перестановки также будет L1 наверху. Я переместил bias = random.random() в while l oop, поэтому он должен каждый раз сбрасываться и, следовательно, иногда менять порядок. Является ли это каким-то странным экземпляром псевдослучайного и рекурсивного кода, который плохо воспроизводится вместе?

def shuffle_human(cards,reshuffle):
    split = random.randint(-1*int(len(cards)/20),int(len(cards)/20)) #creates a bias to imperfectly split deck +- 5% of the deck size
    L = cards[:int(len(cards)/2)+split] # creates left deck
    R = cards[int(len(cards)/2)+split:] # creates right deck
    D =[]                               # empty new deck
    while len(D)< len(cards):           
        bias = random.random()          # creates a bias to "incorrectly" choose 
          if L and bias <=.5:           #     which deck the next card will come from**strong text**
            l = L.pop(0)                # pops the card from the deck and appends it in. 
            print(l)                    # formatted this way so i can see whats going on 
            D.append(l)     
        if R and bias >.5:           # same thing for right deck
            r = R.pop(0)
            print(r)
            D.append(r)
    print(D)
    if reshuffle>0:                     # see if there are any reshuffles attempts needed 
        shuffle_perfect(D,reshuffle-1)  # recursive call to reshuffle the deck. 

shuffle_human(deck,3)

Проблематично c output

 [0, 5, 6, 7, 8, 1, 9, 10, 2, 3, 4]   # initial shuffle
 [0, 1, 5, 9, 6, 10, 7, 2, 8, 3, 4]   # reshuffle 1
 [0, 10, 1, 7, 5, 2, 9, 8, 6, 3, 4]   # 2
 [0, 2, 10, 9, 1, 8, 7, 6, 5, 3, 4]   # 3

Как вы можете видеть, он всегда имеет L1 и Ln- 1 или R1 и Rn-1 в качестве первой и последней цифры выходной деки, в зависимости от результата первого тасования. Независимо от того, сколько перестановок я делаю. Что я делаю неправильно?

Ответы [ 2 ]

0 голосов
/ 29 января 2020

Сначала я изменил и добавил к вашему коду, чтобы рекурсия работала:

from random import random, randint


def shuffle_human(cards, reshuffles=0):
    # creates a bias to imperfectly split deck +- 5% of the deck size
    split = randint(-1*int(len(cards)/20), int(len(cards)/20))
    L = cards[:int(len(cards)/2)+split]  # creates left deck
    R = cards[int(len(cards)/2)+split:]  # creates right deck
    D = []                               # empty new deck
    while len(D) < len(cards):
        bias = random()          # creates a bias to "incorrectly" choose
        if L and bias <= .5:  # which deck the next card will come from
            # pops the card from the deck and appends it in.
            l = L.pop(0)
            # formatted this way so i can see whats going on
            D.append(l)
        if R and bias > .5:           # same thing for right deck
            r = R.pop(0)
            D.append(r)
    # print(D)
    if reshuffles > 0:  # see if there are any reshuffles attempts needed
        # recursive call to reshuffle the deck.
        return shuffle_human(D, reshuffles-1)
    return D


if __name__ == '__main__':
    yes = 0
    no = 0
    deck = list(range(10))
    for i in range(100000):
        res = shuffle_human(deck, 3)
        print(f'shuffle_human({deck}, 3):', res)
        if res[0] == deck[0] and res[-1] == deck[-1]:
            yes += 1
        else:
            no += 1

    total = yes + no
    print('\nunmixed:')
    print(f'yes: {yes/total*100:.2f}%')
    print(f'no: {no/total*100:.2f}%')

Запустив это, он повторяет случайное перемешивание несколько раз и выполняет подсчет, похоже, показывает, что ваша функция работает нормально. Возможно, проблема вызвана вашей shuffle_perfect функцией, и в этом случае мы не можем вам помочь, потому что вы не поделились ею.

К вашему сведению: первый и последний элементы, кажется, сохраняют около 2% время при использовании перестановок 3

0 голосов
/ 29 января 2020

Я не смог правильно запустить ваш код, потому что вы использовали функцию с именем 'shuffle_perfect', но ваш код, кажется, работает нормально. первый и последний элемент переключаются время от времени. но для лучшего исследования посмотрите гистограмму каждого элемента списка в 1000 итераций и посмотрите на стандартную гистограмму, например. В этой ситуации вы можете сделать более четкое суждение о проблеме.

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