Блинная сортировка
| НЕТ ВОЙНЕ |
|
24 февраля 2022 года российское руководство во главе с Владимиром Путиным развязало агрессивную войну против Украины. В глазах всего мира это военное преступление совершено от лица всей страны, всех россиян. Будучи гражданами Российской Федерации, мы против своей воли оказались ответственными за нарушение международного права, военное вторжение и массовую гибель людей. Чудовищность совершенного преступления не оставляет возможности промолчать или ограничиться пассивным несогласием. Мы убеждены в абсолютной ценности человеческой жизни, в незыблемости прав и свобод личности. Режим Путина — угроза этим ценностям. Наша задача — обьединить все силы для сопротивления ей. Эту войну начали не россияне, а обезумевший диктатор. И наш гражданский долг — сделать всё, чтобы её остановить. Антивоенный комитет России |
| Распространяйте правду о текущих событиях, оберегайте от пропаганды своих друзей и близких. Изменение общественного восприятия войны - ключ к её завершению. |
| meduza.io, Популярная политика, Новая газета, zona.media, Майкл Наки. |
Блинная сортировка (англ. pancake sorting) — алгоритм сортировки с помощью одной операции — переворота элементов последовательности до какого-то индекса (префикса последовательности). Разумеется, разрешены сравнения, при оценке времени работы этого алгоритма оценивается количество переворотов, а не сравнений. Название алгоритма пошло от изначальной задачи отсортировать стопку блинов по возрастанию размера.
Содержание
Корректность
Для начала покажем, что любую последовательность можно отсортировать с помощью блинной сортировки. Для этого будет предложен алгоритм, позволяющий отсортировать любой массив, сделав не более операций, где — размер массива.
Найдём максимальный элемент последовательности с номером и развернём префикс массива до -го элемента. Теперь максимальный элемент находится в начале массива. Развернём весь массив, теперь максимальный элемент находится в конце массива. Сделаем то же самое рекуррентно для префикса длины . Переместим второй по возрастанию элемент в конец подотрезка, после чего последние два элемента будут отсортированы, и продолжим для префикса длины . Таким образом, на каждой итерации мы сделаем две операции, и всего итераций будет не больше (их может быть меньше : если после -ой итерации отсортированным окажется суффикс длины больше, чем , можно рекурсивно запустить алгоритм на префиксе длины вместо ). Тогда суммарное количество операций не превосходит и любая последовательность может быть отсортирована таким образом.
Оценки на количество операций
Существуют простые оценки: сверху и, для , снизу. Более сложные границы были предложены в 1978 году Биллом Гейтсом и Христосом Пападимитриу, и улучшить их получилось лишь в 2008.
Наивные
Верхняя
Оценка в операций следует из доказательства корректности алгоритма, в котором предлагается алгоритм сортировки любой последовательности за операций. Она может быть улучшена до чуть более умной сортировкой последних элементов.
Нижняя
Назовём соседством в массиве пару элементов, которые идут последовательно в массиве и для которых нет элемента, большего одного из них и меньшего другого. Если максимальный элемент находится в конце массива, это тоже будет считаться соседством (будем считать, что массив сортируется по возрастанию).
Для любого существует массив, в котором нет соседств. С другой стороны, отсортированный массив имеет соседств, и за один переворот можно добавить не больше одного соседства, поэтому отсортировать массив, сделав меньше, чем переворотов, невозможно.
Продвинутые
Для начала введём некоторые обозначения.
Пусть — множество перестановок элементов массива длины . Будем считать перестановки строками в , где . Введём бинарное отношение : тогда и только тогда, когда и , где и обозначает развёрнутую .
Пусть — перестановка, тогда — наименьшее такое, что существует последовательность перестановок , где . Тогда для числа будем обозначать за максимальное среди всех .
Пусть — перестановка из . Тогда — число номер в перестановке для . Соседством в назовём пару такую, что . Также будем называть соседством пару , если . Для будем обозначать длину как .
Пусть , . будем называть блоком, если для любого такого, что , пара — соседство, при этом пары и не являются соседствами. Если не является частью блока, то есть и — не соседства, элемент будем называть свободным.
За будем обозначать элемент из . Подразумевается, что сложение проводится по модулю .
Верхняя
Будет предложен алгоритм, который изменит перестановку так, чтобы в ней было соседств. После этого отсортировать массив можно не более чем за 4 действия (в иллюстрациях дальше показана последовательность действий, состояние в следующей строке получается из состояния в предыдущей одним разворотом префикса):
Алгоритм
Алгоритм:
- входные данные: перестановка
- выходные данные: перестановка с соседством
Циклически повторять следующее. Пусть — первый элемент (). Как минимум одно из условий выполняется, выполнить соответствующее действие:
- свободный, свободный. Выполнить разворот ,
- свободный, — первый элемент блока. Выполнить разворот ,
- свободный, и , и — последние элементы в блоке. Выполнить развороты ,
- в блоке, свободен. Выполнить разворот ,
- в блоке, — первый элемент блока. Выполнить разворот ,
- в блоке с последним элементом (), — последний элемент другого блока, и свободен. Выполнить перевороты или в зависимости от расположения блоков,
- в блоке с последним элементом (), — последний элемент другого блока, и в блоке. Выполнить развороты или в зависимости от того, в начале или в конце блока находится элемент ,
- ничего из перечисленного выше. В перестановке соседство. Завершить работу алгоритма.
Необходимые развороты:
Корректность алгоритма
| Теорема: |
Предложенный алгоритм создает перестановку с соседствами не более чем за итераций. |
| Доказательство: |
|
Алгоритм всегда завершит работу. На каждой итерации при условии, что в перестановке меньше соседств, выполнится одно из условий . На каждой итерации создается не меньше одного соседства и ни одного соседства не разрушается, поэтому алгоритм создаст нужную перестановку не больше чем за итераций. Будем называть случай 1 действием 1, случай 2 действием 2, случаи 3 и 6 действием 3, случаи 4, 5 и 7 действиями 4, 5 и 7 соответственно. Пусть обозначает количество действий типа , выполненных за время работы алгоритма. Суммарное число разворотов составит
умножено на количество разворотов, выполняемых за это действие. Действие 3 может быть разделено на 4 случая. Перед предпоследним разворотом самый левый элемент массива и элемент после могут
Эти 4 варианта учитываются, если считать . В таблице 1 записано, как каждое действие увеличивается количество соседств. Суммарное количество соседств можно записать в виде суммы
Если — количество блоков в изначальной перестановке, то, поскольку каждое действие изменяет количество блоков так, как показано в таблице 1, а в конечной перестановке 1 блок, имеем
Поскольку , из первого равенства следует
Таким образом, для нахождения худшего случая нужно максимизировать
так, чтобы выполнялось равенство
и неравенство
Утверждается, что максимальное значение достигается при , , , В таком случае максимизируемое значение . Для доказательства этого утверждения воспользуемся теоремой о двойственности Данцига-фон Неймана, из которой следует, что максимальное значение равно минимальному значению двойной линейной задачи: минимизировать при условиях , , , , , , , , , . Для доказательства утверждения достаточно найти пару , удовлетворяющую этим условиям, при которой . Такая пара — . Граница получается прибавлением лишних действий, нужных, чтобы добавить последнее соседство. Алгоритм для этого был описан выше. |
| Таблица 1 | |||||||||
| Действие | |||||||||
| Количество разворотов | |||||||||
| Увеличение количества соседств | |||||||||
| Изменение количества блоков | |||||||||
Нижняя
Для нижней границы построим последовательность, которая может быть отсортирована не менее чем за разворотов.
Пусть . Для положительного целого будем обозначать , в которой каждое число увеличено на , как . Другими словами, , где . Пусть перестановка , где — чётное целое число, и пусть .
| Теорема: |
Число разворотов, необходимое для сортировки последовательности , не меньше . |
Задача о подгоревших блинах
Изначально задача по подгоревших блинах (англ. burnt pancake problem) формулировалась так:
Каждый блин в стопке подгорел с одной стороны. Требуется отсортировать блины по возрастанию (убыванию) диаметра так, чтобы они все лежали на тарелке подгоревшей стороной вниз.
Другими словами, нужно предложить алгоритм блинной сортировки, в котором каждый элемент будет развёрнут чётное число раз.