2015-04-20 3 views
-1

Я пишу программу python, которая играет в покер для класса, и мне нужно отсортировать список из пяти карточных рук. У меня есть функция wins(), которая берет две руки и возвращает True, если первый из них бьет второй, False, если это не так. Я написал реализацию quicksort, чтобы отсортировать список рук, и я заметил, что это занимает гораздо больше времени, чем ожидалось, поэтому я запрограммировал его для печати длины каждого сортируемого списка. Функция выглядит следующим образом:Проблема с quicksort и python

def sort(l): 
    if len(l) <= 1: 
     return l 
    print len(l) 
    pivot = choice(l) 
    l.remove(pivot) 
    left = [] 
    right = [] 
    for i in l: 
     if wins(i, pivot) == True: 
      right.append(i) 
     else: 
      left.append(i) 
    return sort(left) + [pivot] + sort(right) 

и когда у меня было это сортирует 64 руки, он напечатал: 64, 53, 39, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12, 7, 3, 2, 3, 2, 4, 3 , 2, 13, 9, 6, 2, 3 , 2, 2, 3 , 10, 8, 2, 5, 4, 3, 2. Обратите внимание на последовательную последовательность посередине? Я не могу понять, почему это так, но это приводит к тому, что quicksort ведет себя как O (n^2). Для него не имеет смысла выбирать самую сильную руку в качестве стержня на каждой итерации, но это то, что, похоже, происходит. Что я не замечаю?

+1

Почему вы пишете свой собственный вид?Не имеет ли у python собственную функцию сортировки? –

+0

Я не сортирую числа, я сортирую покерные руки. –

+4

Кажется, что нужно сделать [создать лямбда] (https://wiki.python.org/moin/HowTo/Sorting) для сортировки кортежей или именованных объектов. –

ответ

0

Edited ответ после комментариев:

Не могли бы вы попробовать следующий код и поделиться своими результатами. Он вводит класс эквивалентности для сокращения населения в группе «потерять или связывать» (или «меньше или равно»), образуя ответ через рекурсию.

# modified quicksort with equivalence class. 
def sort(l): 
    if len(l) <= 1: 
     return l 
    print len(l) 
    pivot = choice(l) 
    l.remove(pivot) 
    left = [] 
    right = [] 

    # I added an equivalence class 
    pivotEquivalence = [pivot] 

    # and an equivalence partitioning 
    # to reduce number of elements 
    # in the upcoming recursive calls 
    for i in l: 
     if wins(i, pivot) == True: 
      right.append(i) 
     elif wins(pivot,i) == True: 
      left.append(i) 
     else 
      pivotEquivalence.append(i) 
    return sort(left) + pivotEquivalence + sort(right) 

======

Вместо того чтобы выбрать стержень случайно, попытайтесь брать средний индексированный элемент. в среднем это гарантирует O (N log N).

Также для обозначения O вы должны сделать много симуляций для сбора эмпирических данных. Только один пример может быть очень обманчивым.

Попробуйте распечатать стержень, и это также индекс. Перетасуйте свой список с помощью random.shuffle (list) и повторите попытку, чтобы увидеть дистрибутив. Просто обеспечьте время посева системы.

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

С уважением, Умут

+0

Я пробовал выбирать точку опоры во всех отношениях. В среднем, я признаю, что, учитывая случайный выбор стержня, он должен быть O (n log n). Это не помогает тому, что это не так. Кроме того, почему выбор среднего элемента с индексом для стержня будет более вероятным? –

+0

Почему вы думаете, что случайный будет работать лучше, чем выбор фиксированной средней точки? Из-за вероятности выбранной перестановки несортированного списка они в значительной степени равны случаям для алгоритмической сложности. Ссылка: http://ru.m.wikipedia.org/wiki/Quicksort. Если он не очень чувствителен, пожалуйста, предоставьте свои функции и данные для тестирования, чтобы можно было проанализировать вашу проблему. –

+0

Почему, по вашему мнению, исправление средней точки будет работать лучше? Я пробовал и то и другое, и они такие же, оба они надежно работают. Я дал вам свою функцию сортировки, я сказал вам, что использует функцию wins (a, b), которая, как я знаю, работает. Если алгоритм быстрой сортировки терпит неудачу каждый раз, что он делает, и вероятность того, что это происходит случайно, - это одно из 2^64, которое оно есть, и я сделал это сотни раз, что у меня есть, что-то не так с моим алгоритмом, то, что я прошу вас помочь мне найти, чего вы не делаете. Пожалуйста, прекратите рассказывать мне, что он должен работать. –

Смежные вопросы