Bogosort

Last updated

Bogosort
Class Sorting
Data structure Array
Worst-case performance Unbounded (randomized version), (deterministic version)
Best-case performance [1]
Average performance [1]
Worst-case space complexity

In computer science, bogosort [1] [2] (also known as permutation sort and stupid sort [3] ) is a sorting algorithm based on the generate and test paradigm. The function successively generates permutations of its input until it finds one that is sorted. It is not considered useful for sorting, but may be used for educational purposes, to contrast it with more efficient algorithms.

Contents

Two versions of this algorithm exist: a deterministic version that enumerates all permutations until it hits a sorted one, [2] [4] and a randomized version that randomly permutes its input. An analogy for the working of the latter version is to sort a deck of cards by throwing the deck into the air, picking the cards up at random, and repeating the process until the deck is sorted. In a worst-case scenario with this version, the random source is of low quality and happens to make the sorted permutation unlikely to occur. The algorithm's name is a portmanteau of the words bogus and sort. [5]

Description of the algorithm

Pseudocode

The following is a description of the randomized algorithm in pseudocode:

while not sorted(deck):     shuffle(deck)

C

An implementation in C:

#include<stdio.h>#include<stdlib.h>#include<time.h>// executes in-place bogo sort on a given arraystaticvoidbogo_sort(int*a,intsize);// returns 1 if given array is sorted and 0 otherwisestaticintis_sorted(int*a,intsize);// shuffles the given array into a random orderstaticvoidshuffle(int*a,intsize);voidbogo_sort(int*a,intsize){while(!is_sorted(a,size)){shuffle(a,size);}}intis_sorted(int*a,intsize){for(inti=0;i<size-1;i++){if(a[i]>a[i+1]){return0;}}return1;}voidshuffle(int*a,intsize){inttemp,random;for(inti=0;i<size;i++){random=(int)((double)rand()/((double)RAND_MAX+1)*size);temp=a[random];a[random]=a[i];a[i]=temp;}}intmain(){// example usageintinput[]={68,14,78,98,67,89,45,90,87,78,65,74};intsize=sizeof(input)/sizeof(*input);// initialize pseudo-random number generatorsrand(time(NULL));bogo_sort(input,size);// sorted result: 14 45 65 67 68 74 78 78 87 89 90 98printf("sorted result:");for(inti=0;i<size;i++){printf(" %d",input[i]);}printf("\n");return0;}

Python

An implementation in Python 3:

importrandom# this function checks whether or not the array is sorteddefis_sorted(random_array):foriinrange(1,len(random_array)):ifrandom_array[i]<random_array[i-1]:returnFalsereturnTrue# this function repeatedly shuffles the elements of the array until they are sorteddefbogo_sort(random_array):whilenotis_sorted(random_array):random.shuffle(random_array)returnrandom_array# this function generates an array with randomly chosen integer valuesdefgenerate_random_array(size,min_val,max_val):return[random.randint(min_val,max_val)for_inrange(size)]# the size, minimum value and maximum value of the randomly generated arraysize=10min_val=1max_val=100random_array=generate_random_array(size,min_val,max_val)print("Unsorted array:",random_array)sorted_arr=bogo_sort(random_array)print("Sorted array:",sorted_arr)

This code assumes that data is a simple, mutable, array-like data structure—like Python's built-in list—whose elements can be compared without issue.

Running time and termination

Experimental runtime of bogosort ExperimentalBogosort.png
Experimental runtime of bogosort

If all elements to be sorted are distinct, the expected number of comparisons performed in the average case by randomized bogosort is asymptotically equivalent to (e − 1)n!, and the expected number of swaps in the average case equals (n − 1)n!. [1] The expected number of swaps grows faster than the expected number of comparisons, because if the elements are not in order, this will usually be discovered after only a few comparisons, no matter how many elements there are; but the work of shuffling the collection is proportional to its size. In the worst case, the number of comparisons and swaps are both unbounded, for the same reason that a tossed coin might turn up heads any number of times in a row.

The best case occurs if the list as given is already sorted; in this case the expected number of comparisons is n − 1, and no swaps at all are carried out. [1]

For any collection of fixed size, the expected running time of the algorithm is finite for much the same reason that the infinite monkey theorem holds: there is some probability of getting the right permutation, so given an unbounded number of tries it will almost surely eventually be chosen.

Gorosort
A sorting algorithm introduced in the 2011 Google Code Jam. [6] As long as the list is not in order, a subset of all elements is randomly permuted. If this subset is optimally chosen each time this is performed, the expected value of the total number of times this operation needs to be done is equal to the number of misplaced elements.
Bogobogosort
An algorithm that recursively calls itself with smaller and smaller copies of the beginning of the list to see if they are sorted. The base case is a single element, which is always sorted. For other cases, it compares the last element to the maximum element from the previous elements in the list. If the last element is greater or equal, it checks if the order of the copy matches the previous version, and if so returns. Otherwise, it reshuffles the current copy of the list and restarts its recursive check. [7]
Bozosort
Another sorting algorithm based on random numbers. If the list is not in order, it picks two items at random and swaps them, then checks to see if the list is sorted. The running time analysis of a bozosort is more difficult, but some estimates are found in H. Gruber's analysis of "perversely awful" randomized sorting algorithms. [1] O(n!) is found to be the expected average case.
Worstsort
A pessimal sorting algorithm that is guaranteed to complete in finite time; however, its efficiency can be arbitrarily bad, depending on its configuration. The worstsort algorithm is based on a bad sorting algorithm, badsort. The badsort algorithm accepts two parameters: L, which is the list to be sorted, and k, which is a recursion depth. At recursion level k = 0, badsort merely uses a common sorting algorithm, such as bubblesort, to sort its inputs and return the sorted list. That is to say, badsort(L, 0) = bubblesort(L). Therefore, badsort's time complexity is O(n2) if k = 0. However, for any k > 0, badsort(L, k) first generates P, the list of all permutations of L. Then, badsort calculates badsort(P, k − 1), and returns the first element of the sorted P. To make worstsort truly pessimal, k may be assigned to the value of a computable increasing function such as (e.g. f(n) = A(n, n), where A is Ackermann's function). Therefore, to sort a list arbitrarily badly, one would execute worstsort(L, f) = badsort(L, f(length(L))), where length(L) is the number of elements in L. The resulting algorithm has complexity , where = factorial of n iterated m times. This algorithm can be made as inefficient as one wishes by picking a fast enough growing function f. [8]
Slowsort
A different humorous sorting algorithm that employs a misguided divide-and-conquer strategy to achieve massive complexity.
Quantum bogosort
A hypothetical sorting algorithm based on bogosort, created as an in-joke among computer scientists. The algorithm generates a random permutation of its input using a quantum source of entropy, checks if the list is sorted, and, if it is not, destroys the universe. Assuming that the many-worlds interpretation holds, the use of this algorithm will result in at least one surviving universe where the input was successfully sorted in O(n) time. [9]
Miracle sort
A sorting algorithm that checks if the array is sorted until a miracle occurs. It continually checks the array until it is sorted, never changing the order of the array. [10] Because the order is never altered, the algorithm has a hypothetical time complexity of O(), but it can still sort through events such as miracles or single-event upsets. Particular care must be taken in the implementation of this algorithm as optimizing compilers may simply transform it into a while(true) loop. However, the best case is O(n), which happens on a sorted list. Since it only makes comparisons, it is both strictly in-place and stable.
Bozobogo sort
A sorting algorithm that only works if the list is already in order, otherwise, the conditions of miracle sort are applied.
Divine sort
A sorting algorithm that takes a list and decides that because there is such a low probability that the list randomly occurred in its current permutation (a probability of 1/n!, where n is the number of elements), there must have been a reason for the list's order. Therefore, it should be considered sorted in a way we don't understand, and we do not have any right to sort it to our beliefs, as if it were sorted "as God intended." Also known as Intelligent Design sort. [11]

See also

Related Research Articles

<span class="mw-page-title-main">Heapsort</span> A sorting algorithm which uses the heap data structure

In computer science, heapsort is a comparison-based sorting algorithm which can be thought of as "an implementation of selection sort using the right data structure." Like selection sort, heapsort divides its input into a sorted and an unsorted region, and it iteratively shrinks the unsorted region by extracting the largest element from it and inserting it into the sorted region. Unlike selection sort, heapsort does not waste time with a linear-time scan of the unsorted region; rather, heap sort maintains the unsorted region in a heap data structure to efficiently find the largest element in each step.

<span class="mw-page-title-main">Insertion sort</span> Sorting algorithm

Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time by comparisons. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. However, insertion sort provides several advantages:

<span class="mw-page-title-main">Merge sort</span> Divide and conquer sorting algorithm

In computer science, merge sort is an efficient, general-purpose, and comparison-based sorting algorithm. Most implementations produce a stable sort, which means that the relative order of equal elements is the same in the input and output. Merge sort is a divide-and-conquer algorithm that was invented by John von Neumann in 1945. A detailed description and analysis of bottom-up merge sort appeared in a report by Goldstine and von Neumann as early as 1948.

Merge algorithms are a family of algorithms that take multiple sorted lists as input and produce a single list as output, containing all the elements of the inputs lists in sorted order. These algorithms are used as subroutines in various sorting algorithms, most famously merge sort.

<span class="mw-page-title-main">Sorting algorithm</span> Algorithm that arranges lists in order

In computer science, a sorting algorithm is an algorithm that puts elements of a list into an order. The most frequently used orders are numerical order and lexicographical order, and either ascending or descending. Efficient sorting is important for optimizing the efficiency of other algorithms that require input data to be in sorted lists. Sorting is also often useful for canonicalizing data and for producing human-readable output.

In computer science, best, worst, and average cases of a given algorithm express what the resource usage is at least, at most and on average, respectively. Usually the resource being considered is running time, i.e. time complexity, but could also be memory or some other resource. Best case is the function which performs the minimum number of steps on input data of n elements. Worst case is the function which performs the maximum number of steps on input data of size n. Average case is the function which performs an average number of steps on input data of n elements.

<span class="mw-page-title-main">Bucket sort</span> Sorting algorithm

Bucket sort, or bin sort, is a sorting algorithm that works by distributing the elements of an array into a number of buckets. Each bucket is then sorted individually, either using a different sorting algorithm, or by recursively applying the bucket sorting algorithm. It is a distribution sort, a generalization of pigeonhole sort that allows multiple keys per bucket, and is a cousin of radix sort in the most-to-least significant digit flavor. Bucket sort can be implemented with comparisons and therefore can also be considered a comparison sort algorithm. The computational complexity depends on the algorithm used to sort each bucket, the number of buckets to use, and whether the input is uniformly distributed.

Introsort or introspective sort is a hybrid sorting algorithm that provides both fast average performance and (asymptotically) optimal worst-case performance. It begins with quicksort, it switches to heapsort when the recursion depth exceeds a level based on (the logarithm of) the number of elements being sorted and it switches to insertion sort when the number of elements is below some threshold. This combines the good parts of the three algorithms, with practical performance comparable to quicksort on typical data sets and worst-case O(n log n) runtime due to the heap sort. Since the three algorithms it uses are comparison sorts, it is also a comparison sort.

A random permutation is a random ordering of a set of objects, that is, a permutation-valued random variable. The use of random permutations is common in games of chance and in randomized algorithms in coding theory, cryptography, and simulation. A good example of a random permutation is the fair shuffling of a standard deck of cards: this is ideally a random permutation of the 52 cards.

Library sort or gapped insertion sort is a sorting algorithm that uses an insertion sort, but with gaps in the array to accelerate subsequent insertions. The name comes from an analogy:

Suppose a librarian were to store their books alphabetically on a long shelf, starting with the As at the left end, and continuing to the right along the shelf with no spaces between the books until the end of the Zs. If the librarian acquired a new book that belongs to the B section, once they find the correct space in the B section, they will have to move every book over, from the middle of the Bs all the way down to the Zs in order to make room for the new book. This is an insertion sort. However, if they were to leave a space after every letter, as long as there was still space after B, they would only have to move a few books to make room for the new one. This is the basic principle of the Library Sort.

<span class="mw-page-title-main">Comparison sort</span> Type of sorting algorithm that works by comparing pairs of elements

A comparison sort is a type of sorting algorithm that only reads the list elements through a single abstract comparison operation that determines which of two elements should occur first in the final sorted list. The only requirement is that the operator forms a total preorder over the data, with:

  1. if ab and bc then ac (transitivity)
  2. for all a and b, ab or ba (connexity).
<span class="mw-page-title-main">Quicksort</span> Divide and conquer sorting algorithm

Quicksort is an efficient, general-purpose sorting algorithm. Quicksort was developed by British computer scientist Tony Hoare in 1959 and published in 1961. It is still a commonly used algorithm for sorting. Overall, it is slightly faster than merge sort and heapsort for randomized data, particularly on larger distributions.

sort is a generic function in the C++ Standard Library for doing comparison sorting. The function originated in the Standard Template Library (STL).

An American flag sort is an efficient, in-place variant of radix sort that distributes items into buckets. Non-comparative sorting algorithms such as radix sort and American flag sort are typically used to sort large objects such as strings, for which comparison is not a unit-time operation. American flag sort iterates through the bits of the objects, considering several bits of each object at a time. For each set of bits, American flag sort makes two passes through the array of objects: first to count the number of objects that will fall in each bin, and second to place each object in its bucket. This works especially well when sorting a byte at a time, using 256 buckets. With some optimizations, it is twice as fast as quicksort for large sets of strings.

<span class="mw-page-title-main">Fisher–Yates shuffle</span> Algorithm for generating a random permutation of a finite set

The Fisher–Yates shuffle is an algorithm for shuffling a finite sequence. The algorithm takes a list of all the elements of the sequence, and continually determines the next element in the shuffled sequence by randomly drawing an element from the list until no elements remain. The algorithm produces an unbiased permutation: every permutation is equally likely. The modern version of the algorithm takes time proportional to the number of items being shuffled and shuffles them in place.

Samplesort is a sorting algorithm that is a divide and conquer algorithm often used in parallel processing systems. Conventional divide and conquer sorting algorithms partitions the array into sub-intervals or buckets. The buckets are then sorted individually and then concatenated together. However, if the array is non-uniformly distributed, the performance of these sorting algorithms can be significantly throttled. Samplesort addresses this issue by selecting a sample of size s from the n-element sequence, and determining the range of the buckets by sorting the sample and choosing p−1 < s elements from the result. These elements then divide the array into p approximately equal-sized buckets. Samplesort is described in the 1970 paper, "Samplesort: A Sampling Approach to Minimal Storage Tree Sorting", by W. D. Frazer and A. C. McKellar.

Timsort is a hybrid, stable sorting algorithm, derived from merge sort and insertion sort, designed to perform well on many kinds of real-world data. It was implemented by Tim Peters in 2002 for use in the Python programming language. The algorithm finds subsequences of the data that are already ordered (runs) and uses them to sort the remainder more efficiently. This is done by merging runs until certain criteria are fulfilled. Timsort has been Python's standard sorting algorithm since version 2.3, and is used to sort arrays of non-primitive type in Java SE 7, on the Android platform, in GNU Octave, on V8, Swift, and inspired the sorting algorithm used in Rust.

<span class="mw-page-title-main">Bubble sort</span> Simple comparison sorting algorithm

Bubble sort, sometimes referred to as sinking sort, is a simple sorting algorithm that repeatedly steps through the input list element by element, comparing the current element with the one after it, swapping their values if needed. These passes through the list are repeated until no swaps have to be performed during a pass, meaning that the list has become fully sorted. The algorithm, which is a comparison sort, is named for the way the larger elements "bubble" up to the top of the list.

<span class="mw-page-title-main">Cycle sort</span> Comparison sorting algorithm

Cycle sort is an in-place, unstable sorting algorithm, a comparison sort that is theoretically optimal in terms of the total number of writes to the original array, unlike any other in-place sorting algorithm. It is based on the idea that the permutation to be sorted can be factored into cycles, which can individually be rotated to give a sorted result.

<span class="mw-page-title-main">Heap's algorithm</span> Method of generating all permutations of n objects

Heap's algorithm generates all possible permutations of n objects. It was first proposed by B. R. Heap in 1963. The algorithm minimizes movement: it generates each permutation from the previous one by interchanging a single pair of elements; the other n−2 elements are not disturbed. In a 1977 review of permutation-generating algorithms, Robert Sedgewick concluded that it was at that time the most effective algorithm for generating permutations by computer.

References

  1. 1 2 3 4 5 6 Gruber, H.; Holzer, M.; Ruepp, O. (2007), "Sorting the slow way: an analysis of perversely awful randomized sorting algorithms", 4th International Conference on Fun with Algorithms, Castiglioncello, Italy, 2007 (PDF), Lecture Notes in Computer Science, vol. 4475, Springer-Verlag, pp. 183–197, doi:10.1007/978-3-540-72914-3_17, ISBN   978-3-540-72913-6 .
  2. 1 2 Kiselyov, Oleg; Shan, Chung-chieh; Friedman, Daniel P.; Sabry, Amr (2005), "Backtracking, interleaving, and terminating monad transformers: (functional pearl)", Proceedings of the Tenth ACM SIGPLAN International Conference on Functional Programming (ICFP '05) (PDF), SIGPLAN Notices, pp. 192–203, doi:10.1145/1086365.1086390, S2CID   1435535, archived from the original (PDF) on 26 March 2012, retrieved 22 June 2011
  3. E. S. Raymond. "bogo-sort". The New Hacker’s Dictionary. MIT Press, 1996.
  4. Naish, Lee (1986), "Negation and quantifiers in NU-Prolog", Proceedings of the Third International Conference on Logic Programming, Lecture Notes in Computer Science, vol. 225, Springer-Verlag, pp. 624–634, doi:10.1007/3-540-16492-8_111, ISBN   978-3-540-16492-0 .
  5. "bogosort". xlinux.nist.gov. Retrieved 11 November 2020.
  6. Google Code Jam 2011, Qualification Rounds, Problem D
  7. Bogobogosort
  8. Lerma, Miguel A. (2014). "How inefficient can a sort algorithm be?". arXiv: 1406.1077 [cs.DS].
  9. The Other Tree (23 October 2009). "Quantum Bogosort" (PDF). MathNEWS. 111 (3): 13. Archived (PDF) from the original on 5 July 2020. Retrieved 20 March 2022.
  10. "Miracle Sort". The Computer Science Handbook. Retrieved 9 September 2022.
  11. "Intelligent Design Sort". www.dangermouse.net. Retrieved 6 November 2024.