Есть ли худшие алгоритмы сортировки, чем Bogosort (иначе Monkey Sort)? [закрыто]


178

Мои коллеги вернули меня во время моих университетских дней с обсуждением алгоритмов сортировки сегодня утром. Мы вспомнили о наших избранных, таких как StupidSort , и один из нас был уверен, что мы видели алгоритм сортировки, который был O(n!). Это заставило меня начать искать "худшие" алгоритмы сортировки, которые я мог найти.

Мы постулировали, что совершенно случайная сортировка была бы довольно плохой (то есть рандомизировать элементы - по порядку? Нет? Снова рандомизировать), и я оглянулся и обнаружил, что она, очевидно, называется BogoSort, или Monkey Sort, или иногда просто Random Sort ,

Сортировка обезьяны имеет худшую производительность O(∞), лучшую производительность O(n)и среднюю производительность O(n·n!).

Каков в настоящее время официально принятый алгоритм сортировки с худшей средней производительностью сортировки (и, следовательно, хуже, чем O(n·n!))?


10
Сколько богомипов на богосорт? Пытливые умы хотят знать.
зомбат

13
Чтобы уточнить, исключаете ли вы тривиальный случай, в котором наилучшим результатом является O (∞)?
Тлофлин


6
Я слышал, что сорт обезьян также известен как «вид пьяного человека», имя, которое я нахожу гораздо более запоминающимся.
Matteo Italia

6
@Matteo Italia - или это можно назвать "сортировкой малышей", как может засвидетельствовать любой, кому 2 года
Мартин Каподичи

Ответы:


442

Со страницы Эзотерических Алгоритмов Дэвида Морган-Мара : Интеллектуальный Сортировка Проекта

Введение

Интеллектуальный проект сортировки - это алгоритм сортировки, основанный на теории интеллектуального проектирования.

Описание алгоритма

Вероятность того, что исходный входной список находится в точном порядке, в котором он находится, равна 1 / (n!). Вероятность этого настолько мала, что явно абсурдно говорить, что это произошло случайно, поэтому, должно быть, это было сознательно установлено в этом порядке разумным Сортировщиком. Поэтому можно с уверенностью предположить, что это уже каким-то образом оптимально отсортировано, что выходит за пределы нашего наивного смертного понимания «восходящего порядка». Любая попытка изменить этот порядок в соответствии с нашими собственными предубеждениями фактически сделает его менее сортированным.

Анализ

Этот алгоритм постоянен во времени и сортирует список на месте, совсем не требуя дополнительной памяти. На самом деле, он даже не требует никаких подозрительных компьютерных технологий. Хвала Сортировщику!

Обратная связь

Гари Роджерс пишет:

Постоянная во времени сортировка отрицает силу Сортировщика. Сортировщик существует вне времени, таким образом, сортировка вне времени. Требование времени для проверки сортировки уменьшает роль сортировщика. Таким образом ... этот конкретный сорт имеет недостатки, и его нельзя отнести к «Сортировщику».

Ересь!


94
Также известен как «Предположительная сортировка»: предположим, список отсортирован, вернитесь!
BioGeek,

42
+100 - этот ответ сделан из 100% чистого выигрыша.
womp

11
Привет! Не забывайте «нерешительная сортировка» (также известная как «сортировка Шредингера» или «квантовая сортировка»), где список может сортироваться или не сортироваться, однако при проверке выясняется, так ли это. Вот мой пример реализации: void quantum_sort (void *b, size_t n, size_t s, int (*c)(const void *, const void*)) { if (rand () % 2) qsort (b, n, s, c); }.
Джо Д

6
Мы должны перезаписать эту Candide Sort :"This is the best of all posibble worlds because it is the world that is, and so in the best possible world the array would already be sorted!"
echochamber

2
Я, например, приветствую нашего нового повелителя сортировки. Приветствую сортировщика!
Брайсон

299

Много лет назад я изобрел (но никогда не реализовывал) MiracleSort.

Start with an array in memory.
loop:
    Check to see whether it's sorted.
    Yes? We're done.
    No? Wait a while and check again.
end loop

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

Для большей надежности скопируйте массив в экранированную папку и сравните потенциально отсортированные массивы с оригиналом.

Так как же проверить потенциально отсортированный массив по сравнению с оригиналом? Вы просто сортируете каждый массив и проверяете, совпадают ли они. MiracleSort - это очевидный алгоритм для использования на этом этапе.

РЕДАКТИРОВАТЬ: Строго говоря, это не алгоритм, так как это не гарантирует завершение. «Алгоритм» не квалифицируется как «худший алгоритм»?


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

1
Какая большая О это? O(2^N)?
Mooing Duck

12
@MooingDuck: я не думаю, что на самом деле это большой О.
Кит Томпсон

5
@MooingDuck: Строго говоря, если он не завершается, это не алгоритм, согласно тому, чему меня учили в колледже, и статье в Википедии .
Кит Томпсон

7
@ Олате: Проблема остановки говорит, что мы не можем определить для всех программ , останавливаются ли они, но есть много программ, для которых мы можем сделать это определение. Мы знаем, что Quicksort и Bubblesoft останавливаются, и мы знаем, что они являются алгоритмами.
Кит Томпсон

133

Квантовый Богосорт

Алгоритм сортировки, который предполагает правильность многомерной интерпретации квантовой механики:

  1. Проверьте, что список отсортирован. Если нет, уничтожьте вселенную.

По завершении алгоритма список будет отсортирован в единственной оставшейся вселенной. Этот алгоритм требует времени O (N) для наихудшего случая и времени O (1) для среднего случая. Фактически, среднее число выполненных сравнений равно 2: есть вероятность 50%, что вселенная будет уничтожена на втором элементе, вероятность 25%, что она будет уничтожена на третьем, и так далее.


42
Но время перестает существовать во вселенной, которую вы только что разрушили. Таким образом, наблюдатель в юниверсе, который вы еще не проверили, не сможет сказать, какая часть алгоритма была выполнена. Таким образом, этот алгоритм всегда занимает O (1) времени, так как предыдущие разрушения вселенной больше не существуют.
Барри Браун

12
Да, в единственном юниверсе, который наблюдает за отсортированным списком, выполнение заняло O (n) времени - сколько времени это заняло в других юниверсах, не имеет значения.
Ник Джонсон

19
Этот алгоритм имеет гораздо большую проблему, однако. Предположим, что один из 10 миллиардов раз вы ошибочно придете к выводу, что список отсортирован, если это не так. Есть 20! способы сортировки списка из 20 элементов. После сортировки оставшиеся юниверсы будут теми, в которых список был отсортирован правильно, и 2,4 миллиона юниверсов, в которых алгоритм ошибочно завершил список, были отсортированы правильно. Итак, здесь у вас есть алгоритм массового увеличения частоты ошибок на части оборудования.
Ник Джонсон

10
Это, очевидно, лучший алгоритм сортировки, а не худший.
Boann

11
Несоблюдение совета Жука может привести к разрушению всех вселенных.
CrashCodes

60

Я удивлен, что никто еще не упомянул о сне ... Или я этого не заметил? Тем не мение:

#!/bin/bash
function f() {
    sleep "$1"
    echo "$1"
}
while [ -n "$1" ]
do
    f "$1" &
    shift
done
wait

пример использования:

./sleepsort.sh 5 3 6 3 6 3 1 4 7
./sleepsort.sh 8864569 7

С точки зрения производительности это ужасно (особенно второй пример). Ждать почти 3,5 месяца, чтобы отсортировать 2 числа, это довольно плохо.


3
Это кажется своего O(N)рода, но на самом деле ограничено тем, как ОС реализует таймеры.
Mooing Duck

7
В любом случае, это, вероятно, показывает лучший рост, чем bogosort.
Mooing Duck

8
Я вижу состояние гонки там.

5
Вы можете изменить sleep "$1"к sleep "0.$(printf "%010d" $1)"производительности для улучшения заметно. time ./sleepsort.sh 8864569 7затем запускается в 0,009 с на моем ноутбуке.
Сэм Келлетт

1
Это работает в сложности O (N) (зависит, конечно, от реализации таймера), это простая сортировка сегмента в другой форме.
Qwerty01

60

Сортировка звона, как описано здесь .

Вы передаете каждое значение в своем списке другому ребенку на Рождество. Дети, будучи ужасными людьми, будут сравнивать ценность своих даров и соответственно сортировать себя.


50

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

Лучший случай O (N) (первый раз, детка!) Худший случай O (Никогда)


4
Более интересным для анализа является средний случай , который ...?
Mooing Duck

4
Как говорят все лучшие учебники, это оставлено читателю как упражнение!
Даниэль

40
Mooing Duck: O (иногда)
Илья О.

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

5
Сложность O (N! * Z ^ N), где Z - размер множества возможных значений, а N - длина массива.
jakubiszon

30

Если вы сохраняете алгоритм осмысленным в любом случае, O(n!)это худшая верхняя граница, которую вы можете достичь.

Поскольку проверка каждой возможности для перестановок набора, который будет отсортирован, будет предпринимать n!шаги, хуже не будет.

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

list = someList
while (list not sorted):
    doNothing

14
Но требуется O (n), чтобы проверить, отсортирован ли он, так что вы можете получить O (n * n!)
erikkallen

3
@erikkallen: Конечно, мы можем придумать алгоритм проверки сортировки, который хуже, чем O (n). Например, для каждого элемента в массиве убедитесь, что он больше, чем все предыдущие, так же, как работает сортировка вставкой. Это алгоритм O (n ^ 2), и я уверен, что мог бы придумать хуже, если немного подумать.
Дэвид Торнли

7
@ Дэвид Торнли: следующий алгоритм проверки, возможно, продемонстрировал бы тот же дух, что и bogosort: выберите два случайных элемента, убедитесь, что один с меньшим индексом меньше или равен одному с большим индексом, а затем повторите. Сохраните квадратную битовую матрицу, чтобы увидеть, какие комбинации уже проверены. Конечно, проверка этой матрицы также может быть выполнена в случайной прогулке ...
Сванте

19

Bogobogosort. Да, это вещь. Богобогосорт, вы Богосорт первый элемент. Проверьте, отсортирован ли этот элемент. Будучи одним элементом, это будет. Затем вы добавляете второй элемент, и Bogosort эти два, пока он не отсортирован. Затем вы добавляете еще один элемент, затем Bogosort. Продолжайте добавлять элементы и Bogosorting, пока вы, наконец, не сделаете каждый элемент. Это было разработано, чтобы никогда не преуспеть с каким-либо значительным списком до тепловой смерти вселенной.


5
Святая Мать Кодекса. Я думаю, что мы можем даже сделать короткий Bogolplex.
MrKekson

19

Вы должны сделать некоторые исследования в захватывающей области пессимальных алгоритмов и анализа симплексности . Эти авторы работают над проблемой разработки сортировки с пессимальным лучшим случаем (лучший случай вашей богосорты - Омега (n), в то время как медленная сортировка (см. Статью) имеет неполиномиальную сложность времени лучшего случая).


19

Существует разновидность, которая называется богобогосорт. Сначала он проверяет первые 2 элемента и сортирует их. Затем он проверяет первые 3, bogosorts их, и так далее.

Если список в любой момент выходит из строя, он перезапускается путем повторной сортировки первых 2. Обычный богосорт имеет среднюю сложность O(N!), этот алгоритм имеет среднюю сложностьO(N!1!2!3!...N!)

Редактировать : чтобы дать вам представление о том, насколько велико это число, для 20элементов этот алгоритм занимает в среднем 3.930093*10^158 годы , значительно превышая предполагаемую тепловую смерть вселенной (если это произойдет) 10^100 лет ,

тогда как сортировка слиянием занимает около .0000004 секунд , пузырьковая сортировка .0000016 секунд , а bogosort - 308 годы , 139 дни , 19 часы , 35 минуты , 22.306 секунды , при условии, что год равен 365,242 дням, а компьютер выполняет 250 000 000 32-битных целочисленных операций в секунду.

Edit2 : этот алгоритм не такой медленный, как «алгоритм» чудо-сортировки, которая, вероятно, подобно этому виду, засунет компьютер в черную дыру, прежде чем он успешно отсортирует 20 элементов, но если это произойдет, я бы оценил среднюю сложность от 2^(32(the number of bits in a 32 bit integer)*N)(the number of elements)*(a number <=10^40) лет ,

поскольку гравитация ускоряет движение альфа-фишек, и существует 2 ^ N состояний, что составляет 2^640*10^40или около 5.783*10^216.762162762 года , хотя, если бы список начинался отсортированным, его сложность была бы только O(N)быстрее, чем сортировка слиянием, которая составляет только N log N даже в худшем случае.

Edit3 : этот алгоритм на самом деле медленнее, чем чудо-сортировка, так как размер становится очень большим, скажем 1000, так как мой алгоритм будет иметь время выполнения 2.83*10^1175546 лет , а алгоритм чудо-сортировки будет иметь 1.156*10^9657 годы работы .


1
отлично сработал ответ. грустно, что у него нет видимости
swyx

16

Вот 2 вида, которые я придумал со своим соседом по комнате в колледже

1) Проверить порядок 2) Может быть, случилось чудо, перейти к 1

и

1) проверить, в порядке ли он, если нет 2) поместить каждый элемент в пакет и вернуть его себе на удаленный сервер. Некоторые из этих пакетов будут возвращаться в другом порядке, поэтому перейдите к 1


Второе - почти эквивалент сорта Бозо. Первый умный, хотя.
Mooing Duck

1
Первый - это Чудо-Сортировка.
Чарльз

14

Всегда есть Богобогосорт (Bogoception!). Он выполняет Bogosort для все более больших подмножеств списка, а затем запускается заново, если список никогда не сортируется.

for (int n=1; n<sizeof(list); ++n) {
  while (!isInOrder(list, 0, n)) {
    shuffle(list, 0, n);
  }
  if (!isInOrder(list, 0, n+1)) { n=0; }
}

5
Мне нравится идея, что этот алгоритм предназначен для того, чтобы никогда не заканчивать «до тепловой смерти вселенной для какого-либо значительного списка»
А.Грандт

10

1 Поместите свои предметы для сортировки на учетные карточки.
2 Бросьте их в воздух в ветреный день, в миле от вашего дома.
2 Бросьте их в костер и убедитесь, что они полностью уничтожены.
3 Проверьте ваш кухонный пол на правильность заказа.
4 Повторите, если это не правильный порядок.

Лучший вариант сценария - O (∞)

Отредактируйте выше, основываясь на проницательных наблюдениях KennyTM.


9
Нет, это хуже, потому что нет шансов на успех. Как учетные карточки попадут на вашу кухню? Они дуют на улице. Это называется "Баттхедсорт".
Патрик Керхер

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

10
@ Патрик Квантовое туннелирование.
Kennytm

8
@KennyTM. Это на самом деле произошло со мной. Существует чрезвычайно малая, но ненулевая вероятность того, что любой объект может исчезнуть и вновь появиться в любой другой точке вселенной. Я предполагаю, что это может случиться с тысячей учетных карточек. , , Oi. Дангит, мой алгоритм ошибочен . Я исправлю это. , ,
Патрик Керхер

3
Это как чай и чай в одно и то же время. Или космическое путешествие с использованием бесконечной невероятной езды.
Барри Браун

9

"Что бы вы хотели, чтобы это было?" Сортировать

  1. Обратите внимание на системное время.
  2. Сортировка с использованием быстрой сортировки (или любой другой разумно разумной), пропуская самый последний обмен.
  3. Обратите внимание на системное время.
  4. Рассчитайте необходимое время. Требуется повышенная точность арифметики.
  5. Подождите необходимое время.
  6. Выполните последний обмен.

Мало того, что он может реализовать любое мыслимое значение O (x), кроме бесконечности, время, которое доказуемо корректно (если вы можете ждать так долго).


8

Ничто не может быть хуже бесконечности.


38
Бесконечность + 1. Джинкс, нет возврата.
зомбат

24
Не для очень больших значений 1;)
зомбат

8
Что действительно поражает меня в концепции бесконечности, так это то, что вы можете иметь разные «размеры» бесконечности. Например, рассмотрим множество всех целых чисел - оно бесконечно по размеру. Теперь рассмотрим набор всех четных целых чисел - он также бесконечен по размеру, но он также явно вдвое меньше первого набора. Оба бесконечные, но разных размеров. Так круто. Понятие «размер» просто не работает в контексте бесконечности.
зомбат

4
@zombat: Вы говорите о кардинальности, а не о бесконечности как о символе, указывающем тренд на реальной линии / сложной плоскости.
Kennytm

18
@zombat. Размер набора четных целых чисел совпадает с размером набора целых чисел, о чем свидетельствует тот факт, что вы можете поместить их в соответствие один к одному. Теперь, как показано Кантором, вещественных чисел больше, чем целых чисел.
Дэвид Торнли

5

Бозо-сортировка - это связанный алгоритм, который проверяет, отсортирован ли список, и, если нет, меняет два элемента наугад. У него такие же лучшие и худшие показатели, но я бы интуитивно ожидал, что средний случай будет длиннее, чем у Bogosort. Трудно найти (или получить) какие-либо данные о производительности этого алгоритма.


5

Сегменты π

Предположим, что π содержит все возможные комбинации конечных чисел. Смотрите вопрос math.stackexchange

  1. Определите количество необходимых цифр от размера массива.
  2. Используйте сегменты π мест в качестве индексов, чтобы определить, как переупорядочить массив. Если сегмент превышает границы размера для этого массива, отрегулируйте смещение на π и начните заново.
  3. Проверьте, отсортирован ли переупорядоченный массив. Если это woot, иначе отрегулируйте смещение и начните сначала.

4

Производительность O (∞) в худшем случае может даже не сделать его алгоритмом, согласно некоторым .

Алгоритм - это просто последовательность шагов, и вы всегда можете сделать хуже, если немного его настроить, чтобы получить желаемый результат в большем количестве шагов, чем раньше. Можно целенаправленно определить количество шагов, предпринятых в алгоритме, заставить его завершиться и получить правильный результат только после того, как Xколичество шагов было выполнено. Это Xвполне может быть порядка O (n 2 ) или O (n n! ) Или любого другого алгоритма. Это эффективно увеличит как его лучшие, так и средние оценки.

Но ваш худший сценарий не может быть превзойден :)


3

Мой любимый алгоритм медленной сортировки - сортировка марионеток:

void stooges(long *begin, long *end) {
   if( (end-begin) <= 1 ) return;
   if( begin[0] < end[-1] ) swap(begin, end-1);
   if( (end-begin) > 1 ) {
      int one_third = (end-begin)/3;
      stooges(begin, end-one_third);
      stooges(begin+one_third, end);
      stooges(begin, end-one_third);
   }
}

В худшем случае сложность такова O(n^(log(3) / log(1.5))) = O(n^2.7095...).

Другой алгоритм медленной сортировки фактически называется медленной сортировкой!

void slow(long *start, long *end) {
   if( (end-start) <= 1 ) return;
   long *middle = start + (end-start)/2;
   slow(start, middle);
   slow(middle, end);
   if( middle[-1] > end[-1] ) swap(middle-1, end-1);
   slow(start, end-1);
}

Это O(n ^ (log n))в лучшем случае ... даже медленнее, чем стогесорт.


3
Recursive Bogosort (probably still O(n!){
if (list not sorted)
list1 = first half of list.
list 2 = second half of list.
Recursive bogosort (list1);
Recursive bogosort (list2);
list = list1 + list2
while(list not sorted)
    shuffle(list);
}

2

Эта страница интересна для чтения по этой теме: http://home.tiac.net/~cri_d/cri/2001/badsort.html.

Мой личный фаворит - глупая сортировка Тома Даффа:

/*
 * The time complexity of this thing is O(n^(a log n))
 * for some constant a. This is a multiply and surrender
 * algorithm: one that continues multiplying subproblems
 * as long as possible until their solution can no longer
 * be postponed.
 */
void sillysort(int a[], int i, int j){
        int t, m;
        for(;i!=j;--j){
                m=(i+j)/2;
                sillysort(a, i, m);
                sillysort(a, m+1, j);
                if(a[m]>a[j]){ t=a[m]; a[m]=a[j]; a[j]=t; }
        }
}

2

Двойной богосорт

Bogosort дважды и сравните результаты (просто чтобы убедиться, что они отсортированы), если не сделать это снова


1

Вы можете замедлить любой алгоритм сортировки, выполнив шаг «отсортировано» случайным образом. Что-то вроде:

  1. Создайте массив логических значений того же размера, что и массив, который вы сортируете. Установите их всех в ложь.
  2. Запустить итерацию bogosort
  3. Выберите два случайных элемента.
  4. Если два элемента отсортированы по отношению друг к другу (i <j && array [i] <array [j]), пометьте индексы обоих в логическом массиве как true. Снова, начните сначала.
  5. Проверьте, все ли логические значения в массиве верны. Если нет, вернитесь к 3.
  6. Готово.

1

Да, SimpleSort, в теории он работает, O(-1)однако это эквивалентно тому,O(...9999) что, в свою очередь, эквивалентно O (∞ - 1), что, как это происходит, также эквивалентно O (∞). Вот мой пример реализации:

/* element sizes are uneeded, they are assumed */
void
simplesort (const void* begin, const void* end)
{
  for (;;);
}

1

Одна из них, над которой я только что работал, включает в себя выбор двух случайных точек, и, если они находятся в неправильном порядке, полностью изменяет поддиапазон между ними. Я нашел алгоритм на http://richardhartersworld.com/cri_d/cri/2001/badsort.html , который говорит, что средний случай, вероятно, где-то около O (n ^ 3) или O (n ^ 2 log n) ( он не совсем уверен)

Я думаю, что было бы возможно сделать это более эффективно, потому что я думаю, что было бы возможно сделать операцию обращения за время O (1).

На самом деле, я только что понял, что это сделало бы все, что я скажу, может быть, потому что я только что понял, что структура данных, которую я имел в виду, поставит доступ к случайным элементам в O (log n) и определит, нужно ли обращать в O (n) ).


1

Randomsubsetsort.

Учитывая массив из n элементов, выберите каждый элемент с вероятностью 1 / n, рандомизируйте эти элементы и проверьте, отсортирован ли массив. Повторите, пока не отсортировано.

Ожидаемое время оставлено в качестве упражнения для читателя.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.