Существуют ли алгоритмы сортировки хуже, чем Bogosort (a.к. обезьяний сорт)? [закрытый]

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

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

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

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

26 ответов


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

введение

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

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

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

анализ

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

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

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

сделать сортировку постоянной во времени отрицает силу сортировщика. Этот Сортировщик существует вне времени, таким образом сортировка времени. Требовать времени к проверки подобного dimishes роль сортировщика. Таким образом... это частности вроде ущербна, и не может быть отнести к 'сортировщик'.

ересь!


много лет назад я изобрел (но так и не реализовал) 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 очевидный алгоритм использовать для этого шага.

EDIT: строго говоря, это не алгоритм, так как он не гарантированно завершится. Разве" не алгоритм "квалифицируется как " худший алгоритм"?


Квантовая Bogosort

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

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

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


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

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


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

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

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

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

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


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

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


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

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

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

list = someList
while (list not sorted):
    doNothing

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


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

1) Проверка заказа 2) может быть, чудо произошло, перейдите к 1

и

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


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


всегда есть Богобогосорт (Богоцепция!). Он выполняет 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; }
}

есть вид, который называется bogobogosort. Во-первых, он проверяет первые 2 элемента и богосортит их. Затем он проверяет первые 3, богосортит их и так далее. Если список будет не в порядке в любое время, он перезапускается, снова богосортируя первые 2. Регулярные bogosort имеет среднюю сложность о(n!), этот алгоритм имеет среднюю сложность O (N!1!2!3!...Н!) Edit: чтобы дать вам представление о том, насколько велико это число, для 20 элементов этот алгоритм занимает в среднем 3,930093*10^158 лет, значительно выше предполагаемой тепловой смерти Вселенной (если это произойдет) 10^100 лет, тогда как слияние Рода занимает около .0000004 секунды, сортировка пузырьков .0000016 секунд, и bogosort занимает 308 лет 139 дней, 19 часов, 35 минут, 22.306 секунд, предполагая, что в год 365.242 дней и компьютер не 250,000,000 32-битных целочисленных операций в секунду. Edit2: этот алгоритм не так медленен, как" алгоритм " miracle sort, который, вероятно, как этот вид, заставит компьютер засосать в черную дыру прежде чем он успешно сортирует 20 elemtnts, но если бы это было так, я бы оценил среднюю сложность 2^(32(количество бит в 32-битном целочисленном)N) (количество элементов)(число


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

лучший случай scenerio-O (∞)

редактировать выше на основе проницательное наблюдение по KennyTM.


"Что бы ты хотела?- сортировка!--1-->
  1. обратите внимание на системное время.
  2. сортировка с помощью Quicksort (или что-нибудь еще разумно разумное), опуская самый последний своп.
  3. обратите внимание на системное время.
  4. рассчитать необходимое время. Расширенная точность арифметики является требованием.
  5. подождите необходимое время.
  6. выполните последний своп.

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


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


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


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

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

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


отрезки π

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

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

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

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...).

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

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)) в лучшем случае... даже медленнее, чем stoogesort.


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);
}

в этом разделе это интересно читать на тему: 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; }
        }
}

двойной bogosort

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


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

  1. создайте массив логических значений того же размера, что и сортируемый массив. Установите для всех значение false.
  2. выполнить итерацию bogosort
  3. выберите два случайных элементов.
  4. если два элемента отсортированы относительно друг друга (i
  5. проверьте, все ли логические значения в массиве истинны. Если нет, вернитесь к 3.
  6. сделано.

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

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

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

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

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


Randomsubsetsort.

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

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