Добавлен: 05.04.2023
Просмотров: 97
Скачиваний: 1
СОДЕРЖАНИЕ
1. Теоретические основы алгоритмов сортировки
1.1 Исторический аспект появления и развития методов сортировки
1.2 Математическая постановка задачи для сортировки данных
2. Характеристика алгоритмов сортировки
2.1 Алгоритм сортировки методом пузырька и прямым выбором
2.2 Эффективные алгоритмы сортировки
Таблица 2
Экспериментальное среднее время сортировки
Время Tc работы алгоритма C хорошо аппроксимируется выражением kcn log2n, где kc — коэффициент, зависящий от типа компьютера. Обозначим через g отношение Tp/Tc, где Tp — время пирамидальной сортировки. Значение g возрастает приблизительно от 1,6 до 4,5 для n = 108. Это свидетельствует о том, что время Tp растет быстрее, чем число операций, котороесогласно теории определяется выражением kpn log2n, где kp — коэффициент, т.е. сказываетсяувеличение удельного времени доступа к данным. Значение g и темп его изменения зависят от размера записи R и типа компьютера, точнее, от параметров иерархической структуры его памяти. В любом случае существует область больших значений n, где время Tp в несколько раз больше Tc. Это утверждение справедливо для всех разновидностей пирамидальной сортировки.
Чтобы сравнить метод слияния и метод QuickSort, рассмотрим последние результаты их оптимизации. Под оптимизацией сортировки [4] обычно понимается приближение среднего числа сравнений ключей к теоретико-информационному пределу log2(n!). В [7] для сортировки был выведен нижний предел n + Hn – 2 среднего числа транспозиций записей — перемещений записей или обмена их местами (Hn — гармоническое число). Сокращение числа транспозицийтакже будем называть оптимизацией. Под всесторонней оптимизацией будем понимать уменьшение среднего числа как основных действий, так и массовых вспомогательных действий, для которых может быть известен теоретический минимум.
Метод QuickSort реализует разделение массива на внешне упорядоченные части (ВУЧ). Каждая запись может изменять положение лишь в рамках ВУЧ. Разделение можно изобразить деревом ВУЧ, узлы которого представляют ВУЧ, так как весь массив и каждая ВУЧ, содержащая более одной записи, разделяются на меньшие ВУЧ. В итоге, когда каждая ВУЧ содержит единственную запись, массив становится упорядоченным.
Исследованию и усовершенствованию метода QuickSort посвящено немало работ, остановимся на последних [2; 8; 12; 13]. В них по-разному реализуются две главные идеи:
а) отказ от разделения многочисленных малых ВУЧ (ведет к сильному сокращению множества вспомогательных действий);
б) улучшение формы дерева ВУЧ, выражающееся в уменьшении средней глубины листьев дерева.
Упорядочение малых ВУЧ выполняют алгоритмом вставки или иным алгоритмом. Длина внешнего пути [12] дерева ВУЧ определяет число сравнений ключей. В алгоритме, описанномв [12] и названном нами алгоритмом B, ВУЧ, как правило, разделяется на пять частей, дерево ВУЧ имеет меньшую длину внешнего пути, чем в алгоритме A, однако действия в алгоритме B сложнее, так как при разделении ВУЧ используются два опорных элемента. Средний выигрыш в числе сравнений приблизительно равен
2nlnn– (1,9nlnn – 2,46n) = 0,1nlnn + 2,46n
(для алгоритма A среднее число сравнений ключей равно 2nlnn). В [13] было показано, как этот выигрыш увеличить до значения 0,2nlnn (приблизительно). В алгоритме B среднее число транспозиций, примерно равное 0,6nlnn, существенно больше, чем в алгоритме A. Поэтому оптимизацию нельзя считать сбалансированной: уменьшение среднего числа сравнений ключей сопровождается ростом числа транспозиций сортируемых записей.
Алгоритм C предложен в МЭИ [2]. В нем упорядочение малых ВУЧ проводится специальными алгоритмами, названными решетками, а форма дерева ВУЧ улучшается благодаря равномерному разделению ВУЧ, что достигается использованием в качестве опорного значения медианы пяти записей, взятых из разделяемой ВУЧ. Идея не нова, медиана трех элементов используется в известных реализациях QuickSort. Получение медианы — это дополнительные издержки времени, лишние операции. Важно их сократить и хотя бы частично совместить с операциями по разделению ВУЧ. Это было достигнуто при построении алгоритма C применительно к медианам пяти элементов ВУЧ. Согласно [2] в алгоритме C среднее число K сравнений ключей с ростом n приближается к значению 1,62nlnn – 1,35n, т.е. по сравнению с алгоритмом A выигрыш составляет примерно 0,38nlnn + 1,35n. Среднее число транспозиций составляет не более 0,5nlnn, и реализованы они как перемещения записей, тогда как в алгоритме B используются более сложные операции — обмены записей местами. Поэтому время сортировки алгоритмом C при n = 106 существенно меньше времени алгоритма B (рис. 5).
Рис.5. Сравнение времени сортировки алгоритмов В и С
Итак, по характеристикам алгоритм C лучше алгоритмов A и B. Однако достигнутые результаты оптимизации метода QuickSort далеки от идеала: значение K заметно больше значения log2(n!) ≈ 1,44n (ln n – 1). Среднее число транспозиций записей относительно мало, но существенно больше нижнего предела n + Hn – 2. Дальнейшее сокращение числа основных действий метода QuickSort, по-видимому, не имеет хорошей перспективы. Найдем альтернативу лучшим реализациям метода QuickSort.
Метод слияния обычно используется для сортировки файлов записей и редко применяется для сортировки массивов, так как требует значительной дополнительной памяти и выполняет больше транспозиций, чем метод QuickSort. Сильными сторонами слияния являются стабильность времени сортировки и близость среднего числа сравнений к теоретическому минимуму. Так называемое t-арное слияние выполняет слияния t упорядоченных частей массива вплоть до получения единой части, т.е. упорядоченного массива. На рис. 6 для t = 3 показана схема слияния 30 упорядоченных частей (ими могут быть отдельные записи). На каждой фазе слияния (они обозначены штриховыми линиями) все сортируемые записи перемещаются в памяти. Число перемещений отдельно взятой записи равно числу фаз L = ┌logt(n/m)┐, где m — максимальное число записей в одной исходной части. При t = ┌n/m┐ каждая запись перемещается однажды. Итак, возможно рекордно малое число P перемещений записей. В дальнейшем будем исследовать процесс t-арного слияния при больших значениях t.
Сокращая числа перемещений записей P, важно сохранить указанные выше преимущества слияния. Массовая операция, во время которой сравниваются ключи, — это выбор очередной наименьшей записи из остающихся записей. Простой перебор при сравнении записей неприемлем, он сильно снижает производительность метода при больших t. Найдем лучший вариант.
Обозначим X вычислительную сложность одной фазы слияния и выясним, каким должна быть X, чтобы получить приемлемую оценку сложности O(n log2n) всего процесса слияния.
Выбирая эту оценку как ориентир, учитываем указанный выше теоретико-информационный предел и тот факт, что сравнения ключей являются самой массовой операцией при сортировке.
Возьмем m = 1 и запишем равенство X ┌logt n┐ = O(n log2 n). Из него следует X = O(n log2n/logtn) = O(n log2t), а сложность выбора одной записи, включая ее пересылку, получает оценку O(log2t). Такую оценку имеет выбор среди t ключей экстремального ключа, реализуемый в простой пирамиде [4]. Асимптотическая оценка O(log2t) скрывает коэффициент при величине log2t, но если он будет велик, нельзя ожидать преимущества метода слияния по сравнению с методом QuickSort.
Рис.6. Реализация метода многопутевого слияния
Авторами был выполнен анализ использования (в качестве схемы выбора) простой и слабой [9] бинарных пирамид, 3-арной, 4-арной и 5-арной пирамид. Прежде всего определялся коэффициент k в формуле klog2tчисла сравнений при выборе записи. Наименьшее значение k
имеет слабая пирамида, для нее k ~ 1. Поскольку в ней выполняются и пересылки, и многочисленные вспомогательные операции, в целях сравнения проверялись улучшенные реализации прочих пирамид. По затратам времени выбора лучшими оказались слабая пирамида и простая бинарная пирамида, в которой для уменьшения числа сравнений использована идея Р. Флойда [10].
Время тратится и на построение пирамид, выполняемое примерно столько же раз, сколько узлов в схеме слияния (рис. 6), исключая листья дерева. Время построения 4-арной и 5-арной пирамид наименьшее, но эти пирамиды проигрывают бинарным пирамидам по общим затратам времени.
Таким образом, продолжена оптимизация t-арного слияния, начало которой было положено в [3]. В новых реализациях t-арного слияния помимо слабой пирамиды впервые используется схема выбора записей по принципу турнира.
Следующий шаг оптимизации — это выбор размера m исходных упорядоченных частей и способа их получения. Рассмотрим вариант, когда, неупорядоченный массив большой: пустьn = 107, m=1. Если t = 100, то потребуется упорядочить на 1-й фазе слияния 107/100 = 105 частей и для этого 105 раз построить схему выбора — пирамиду или турнирную схему, затратив больше времени. Для исключения такого рода фазы слияния описываемым ниже способом упорядочим части массива размером t(в последней части записей может быть меньше чем t). Для каждой части, сравнивая ключи, будем сортировать номера записей. Используя полученную последовательность номеров, переместим каждую запись (всего n пересылок записей, как и на исключенной фазе).
Были исследованы восемь способов упорядочения исходных частей. Алгоритмы естественного и простого бинарного слияния [4] оказались наилучшими по времени сортировки исходных частей. Для сокращения числа машинных операций была проведена оптимизация их программ. Для R = 48 среднее время сортировки одной части в условных единицах приведено в табл. 2. Оно зависит от размера записи R, но остается меньшим у алгоритмов слияния в рабочей области значений t. Например, для t = 1000 затрачивается примерно в 1,35 раза меньше времени, если взамен первой фазы применяется простое бинарное слияние.
Заключение
Как можно было убедиться, практическая польза от описанных алгоритмов есть, со своей задачей они с переменным успехом справляются. Абсолютным лидером стал Timsort — дающий заметное ускорение при увеличении степени упорядоченности данных и работающий на уровне Quicksort в обычных случах. Не зря он признан и встроен в Python, OpenJDK и Android JDK.
Про Smoothsort в сети довольно немного информации (по сравнению с остальными алгоритмами) и не спроста: из-за сложности идеи и спорной производительности он скорее является алгоритмическим изыском, нежели применимым методом. Я нашел всего лишь одно реальное применение этого алгоритма — в библиотеке sofia-sip, предназначенной для построения IM- и VoIP-приложений.
Появление Shellsort в данном тесте является довольно спорным моментом, потому что его асимптотическая сложность несколько больше, чем у остальных двух алгоритмов. Но у него есть два больших преимущества: простота идеи и алгоритма, которая позволяет почти всегда обходить Smoothsort по скорости работы и простота реализации — работающий код занимает всего пару десятков строк, в то время как хорошие реализации Timsort и Smoothsort требуют более сотни строк.
Список использованных источников
- Зубов В.С., Шевченко И.В. Об ускорении «быстрой сортировки» // Труды XXI международной НТК «Информационные средства и технологии». Т. 3. М.: Издательский дом МЭИ, 2013. С. 122—129.
- Зубов В.С., Шевченко И.В. Новый алгоритм сортировки по методу многопутевого слияния //Вестник МЭИ. 2014. № 6. С. 49—56.
- Кнут Д.Э. Искусство программирования. Т. 1. Основные алгоритмы: пер. с англ.; 3-е изд. — М.: Издательский дом «Вильямс», 2014. С. 449—451.
- Кнут Д.Э. Искусство программирования. Т. 3. Сортировка и поиск: пер. с англ.; 2-е изд. — М.: Издательский дом «Вильямс», 2014. – 832 с.
- Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн. Алгоритмы: построение и анализ— 2-е изд. — М.: Вильямс, 2016. — С. 1296
- Седжвик Р. Фундаментальные алгоритмы на C. Анализ/Структуры данных/Сортировка/Поиск— СПб.: ДиаСофтЮП, 2003. — С. 672.
- Шевченко И.В. Композиции быстрых алгоритмов сортировки. Электронный журнал «Вычислительные сети. Теория и практика» / Network-Journal. Theory and practice BC/NW. 2005. № 1 (6). http://network-journal.mpei.ac.ru/cgi-bit/main.pl?l=ru&n=6&pa=3&ar=4
- Aumüller M., Dietzfelbinger M. Optimal Partitioning for Dual Pivot Quicksort. Automata, Languages and Programming // Lecture Notes in Computer Science. 2013. Vol. 7965. P. 33—44.
- Dutton R.D. Weak-heap Sort // BIT. 2013. Vol. 33. P. 372—381.
- Floyd R.W. Algorithm 245: treesort 3 // Comm. ACM. Vol. 7. No 12. P. 701.
- Magnus Lie Hetland. Python Algorithms: Mastering Basic Algorithms in the Python Language. — Apress, 2015. — 336 с.
- Yaroslavskiy V. Dual pivot quicksort. 2014. http://iaroslavski.narod.ru/quicksort/DualPivotQuicksort.pdf
- Wild S., Nebel M.E. Average case analisys of Java 7’s dual pivot quicksort. Algorithms — ESA 2012 // Lecture Notes in Computer Science. 2012. Vol. 7501. P. 825—836.