Как написать сортировку хуже, чем O (n!)

Я написал сортировку O (n!) для моего развлечения, которая не может быть оптимизирована тривиально, чтобы работать быстрее, не заменяя ее полностью. [И нет, я не просто рандомизировал элементы, пока они не были отсортированы].

Как я могу написать еще худший вид Big-O, не добавляя лишнего мусора, который можно вытащить, чтобы уменьшить временную сложность?

http://en.wikipedia.org/wiki/Big_O_notation имеет различные временные сложности, отсортированные в порядке возрастания.

Изменить: я нашел код, вот мой дефинитивный тип O (n!) с забавным взломом для создания списка всех комбинаций списка. У меня немного более длинная версия get_all_combinations, которая возвращает итерабельность комбинаций, но, к сожалению, я не мог сделать ее одним утверждением. [Надеюсь, я не ввел ошибок, исправляя опечатки и удаляя символы подчеркивания в приведенном ниже коде]

def mysort(somelist):
    for permutation in get_all_permutations(somelist):
        if is_sorted(permutation):
            return permutation

def is_sorted(somelist):
    # note: this could be merged into return... something like return len(foo) <= 1 or reduce(barf)
    if (len(somelist) <= 1): return True
    return 1 > reduce(lambda x,y: max(x,y),map(cmp, somelist[:-1], somelist[1:]))

def get_all_permutations(lst):
    return [[itm] + cbo for idx, itm in enumerate(lst) for cbo in get_all_permutations(lst[:idx] + lst[idx+1:])] or [lst]

Ответ 1

Существует (доказанный!) алгоритм наименьшей сортировки, называемый медленный сортировка, в котором используется парадигма "multiply and surrender" и выполняется в экспоненциальном времени.

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

Ответ 3

Всегда существует NeverSort, который является O (∞):

def never_sort(array)
  while(true)
  end
  return quicksort(array)
end

PS: Я действительно хочу видеть ваш детерминированный тип O (n!); Я не могу придумать ни одного, что есть O (n!), Но имеет конечную верхнюю границу в классическом вычислении (он же детерминирован).

PPS: Если вы беспокоитесь о том, что компилятор уничтожает этот пустой блок, вы можете заставить его не использовать переменную как внутри, так и вне блока:

def never_sort(array)
  i=0
  while(true) { i += 1 }
  puts "done with loop after #{i} iterations!"
  return quicksort(array)
end

Ответ 4

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

Ответ 5

Вот самый медленный, конечный сорт, который вы можете получить:

Свяжите каждую операцию Quicksort с функцией Busy Beaver.

К тому времени, когда вы получите > 4 операции, вам понадобится нотация со стрелкой вверх:)

Ответ 6

Один из способов, о котором я могу думать, состоял бы в том, чтобы вычислить позицию позиции каждого элемента через функцию, которая изменяется постепенно, перемещая большие элементы в конец, а маленькие - в начало. Если вы использовали функцию, основанную на триггерах, вы могли бы заставить элементы сориентироваться через список, а не идти прямо к своей конечной позиции. После того, как вы обработали каждый элемент в наборе, выполните полный обход, чтобы определить, отсортирован ли массив или нет.

Я не уверен, что это даст вам O (n!), но он все равно будет довольно медленным.

Ответ 7

Я думаю, что если вы сделаете много копий, вы сможете получить "разумный" поиск грубой силы (N!), чтобы взять N ^ 2 раза за случай, давая N! * N ^ 2

Ответ 8

Как насчет циклизации по всем массивам t из n целых чисел (n-кортежи целых чисел являются счетными, поэтому это выполнимо, хотя это, конечно, бесконечный цикл), и для каждого из них:

  • если его элементы точно соответствуют элементам входного массива (см. algo ниже!), и массив сортируется (например, линейный алгоритм, но я уверен, что мы можем сделать хуже), а затем вернем t;
  • в противном случае продолжить цикл.

Чтобы проверить, что два массива a и b длины n содержат одни и те же элементы, как насчет следующего рекурсивного алгоритма: петля над всеми парами (i, j) индексов между 0 и n-1 и для каждой такой пары

  • test, если [i] == b [j]:
  • если это так, верните TRUE тогда и только тогда, когда рекурсивный вызов в списках, полученных путем удаления [i] из a и b [j] из b, возвращает TRUE;
  • продолжить цикл по парам, и если все пары выполнены, верните FALSE.

Время будет сильно зависеть от распределения целых чисел во входном массиве.

Серьезно, однако, есть ли точка зрения на такой вопрос?

Edit:

@Jon, ваша случайная сортировка будет в среднем в O (n!) (так как есть n! перестановки, вы имеете вероятность 1/n! найти правильный). Это справедливо для массивов различных целых чисел, может быть несколько иным, если некоторые элементы имеют множественные вхождения во входном массиве и будут затем зависеть от распределения элементов входных массивов (в целых числах).