Bogosort
Сегодня на собеседовании (я всё ещё ищу пайтонистов, ау) всплыли алгоритмы сортировки и я решил немного почитать на эту тему. Оказывается есть смешной алгоритм сортировки Bogosort, который на практике не применяется, а служит только иллюстративным целям:
Bogosort (также рандомная сортировка, сортировка ружья или обезьянья сортировка) является очень неэффективным алгоритмом сортировки. Её используют только в образовательных целях, противопоставляя другим, более реалистичным алгоритмам. Если bogosort использовать для сортировки колоды карт, то сначала в алгоритме нужно проверить, лежат ли все карты по порядку, и если не лежат, то подбросить колоду в воздух, проверить лежат ли теперь все карты по порядку, и повторять процесс, пока не отсортируется колода.
Я, для интереса, написал его на Пайтоне и поразвлекался с запускам на разных данных. Вот код, если интересно:
from random import shuffle
from itertools import izip, islice
def bogosorted(arr):
for x, y in izip(islice(arr, 1, None), islice(arr, 0, len(arr) - 1)):
if y > x: return False
return True
def bogosort(arr):
while arr and not bogosorted(arr):
shuffle(arr)
return arr
print bogosort([1, 1, 3, 2, 2, 2])
Комментарии 27
while not all(x
if current_val < last_var return false
last_var = current_val
Я вот хоть убей не понимаю, зачем ты сделал это через izip. Другое мышление?
Вот можно почитать http://en.wikipedia.org/wiki/Randomized_algorithm
Комментарий для gogis:
Мне совершенно непонятно что тут может быть неясно. Там итераторы работают. Это позволяет увеличить скорость на больших массивах.
Комментарий для zero_sharp:
Я не пишу на питоне и не пользовался итераторами(чтение статьи в википедии не в счет), но мне совершенно непонятно, почему это быстрее, чем просто пробежаться по исходному массиву в цикле. Потому и не ясно.
Комментарий для gogis:
У менякак-то смешались в сознании два комментария, ваш и zero_sharp'a, каюсь.
как-то разнообразить, я использую итераторы. Мой первый вариант был примерно похож на ваш.
Мне нравится использовать итераторы. Писать «влоб» такие задачки — скучно, поэтому, чтобы хоть
Дело собственно в том, что для больших объёмов данных часто бывает возможно оценить степень упорядоченности данных довольно быстро, но не отсортировать их. Поэтому делают
Сколько раз надо шаффлить массив, пока он не отсортируется таким образом.
Комментарий для Евгения Степанищева:
Каким образом?
А если итератор бесконечный? Или конечный, но очень большой?
И зачем преобразовывать итератор в list, чтобы по нему опять итерироваться?
Гм. Похоже, что не убъёт. Мы сегодня с art делали эксперимент, показалось, что убивает. Сильно удивились. А сейчас я попробовал сделать замеры, не подтвердилось.
Значит, мы ошиблись. all тут вполне подойдёт.
Проверить просто: all(xrange(1000000000)) завершается сразу, а all(xrange(1, 100000000)) не сжирает всю память (сравни с list вместо all).
К list'у приводит itertools.cycle, потому что у него нет другого выхода. На вход могут подать не просто iterable, а именно итератор, который нельзя отмотать назад. Но и он не сразу приводит к списку, а складывает значения по одному.
Комментарий для fulc.ru:
Я просто сунул функцию в свой пример, которая печатала и возвращала то, что ей дали. Не понимаю в чём дело, но нам с art'ом показалось, что она не смогла съесть итератор.
А сейчас, дома, у меня получается, что превосходно его ест. Непонятно.
Признаю́, что zero_sharp прав.
while arr != sorted(arr)…
Глупее — да :) Но ломает алгоритм,из-за того, что содержит сортировку.