Здравствуйте прошла курсы на тему Алгоритмы С++. Но не пришел сертификат и не доступен.Где и как можно его скаачат? |
Поразрядная сортировка
Сортировки с сублинейным временем выполнения
Основной вывод, который можно сделать по результатам анализа, проведенного в разделе 10.6, состоит в том, что время выполнения различных видов поразрядной сортировки может быть сублинейным по отношению к общему количеству информации в ключах. В данном разделе мы проанализируем практические следствия из этого факта.
Реализация LSD-сортировки, приведенная в разделе 10.5, выполняет bytesword проходов по файлу. Увеличив R, мы получим эффективный метод сортировки — для достаточно больших N и при наличии достаточной памяти для R счетчиков. Как отмечалось при доказательстве свойства 10.5, лучше сделать так, чтобы значение lg R (количество битов в байте) было равно примерно четверти размера слова — тогда поразрядная сортировка будет состоять из четырех проходов распределяющей сортировки. Проверяется каждый бит каждого ключа, но каждый ключ содержит всего четыре цифры. Этот пример является прямой аналогией архитектуры многих компьютеров: в типичной организации используются 32-разрядные слова, состоящие из четырех 8-разрядных байтов. Мы извлекаем из слов байты, а не биты, и на многих компьютерах этот подход гораздо более эффективен. Теперь каждый проход распределяющего подсчета линеен по времени, а поскольку их всего четыре, то и вся сортировка линейна — вряд ли для сортировки можно надеяться на лучший результат.
На самом деле оказывается, что можно обойтись всего лишь двумя проходами распределяющего подсчета. Это следует из того, что файл будет почти отсортирован уже после использования лишь w/2 старших разрядов w-разрядных ключей. Как и в случае быстрой сортировки, после этого можно эффективно завершить упорядочение, выполнив сортировку всего файла методом вставок. Этот метод является тривиальной модификацией программы 10.4.
Чтобы выполнить сортировку слава направо по старшей половине ключей, надо просто начать внешний цикл со значения byteword/2-1, а не с byteword-1. Затем полученный почти упорядоченный файл обрабатывается сортировкой вставками. рис. 10.3 и 10.18 представляют собой убедительное доказательство того, что файл, отсортированный по старшим разрядам, достаточно хорошо упорядочен. Для упорядочения файла, изображенного в четвертом столбце на рис. 10.3, сортировка вставками выполняет всего лишь шесть перестановок, а на рис. 10.18 рис. 10.18 показано, что сортировка вставками позволяет эффективно упорядочивать и большие файлы, отсортированные только по старшей половине разрядов.
Если ключи представляют собой последовательности случайных битов, то сортировка файла по старшим разрядам ключей почти упорядочивает файл. На этой диаграмме шестипроходная LSD-сортировка (слева) файла со случайными 6-разрядными ключами сравнивается с трехпроходной LSD-сортировкой, после которой может быть еще один проход сортировки вставками (справа). Второй способ быстрее почти в два раза.
Для некоторых размеров файлов, возможно, имеет смысл использовать дополнительную память (которая иначе была бы отведена под вспомогательный массив), чтобы попытаться обойтись всего лишь одним проходом распределяющего подсчета, выполняя переупорядочение на месте. Например, сортировка 1 миллиона 32-разрядных случайных ключей может быть выполнена за один проход распределяющего подсчета по 20 старшим разрядам с последующей сортировкой вставками. Для этого требуется память только для (1 миллиона) счетчиков — значительно меньше, чем нужно для вспомогательного массива. Использование этого метода равносильно использованию стандартной MSD-сортировки при R=220, хотя для сортировки таким методом небольших файлов важно применять небольшие основания системы счисления (см. обсуждение леммы 10.4).
LSD-подход к поразрядной сортировке получил широкое распространение в силу того, что ему нужны лишь исключительно простые управляющие структуры, а его базовые операции очень удобны для реализации в машинных командах и могут быть легко адаптированы к использованию специализированных высокопроизводительных аппаратных средств. В такой среде наибольшее быстродействие может быть достигнуто при использовании полной LSD-сортировки. Ценой затрат дополнительной памяти лишь для размещения N дополнительных ссылок (и R счетчиков) можно получить метод, который может сортировать случайно упорядоченные файлы всего за три-четыре прохода.
В обычных средах программирования внутренний цикл программы распределяющего подсчета, который служит основой поразрядных сортировок, содержит гораздо большее количество инструкций, чем внутренние циклы быстрой сортировки или сортировки слиянием. Из этого свойства программных реализаций следует, что описанные выше сублинейные методы во многих случаях не могут быть настолько быстрее (например) быстрой сортировки, как можно было бы ожидать.
Алгоритмы общего назначения, такие как быстрая сортировка, нашли более широкое применение, чем поразрядная сортировка, поскольку они могут быть адаптированы к более широкому диапазону приложений. Основная причина такого положения дел заключается в том, что абстракция ключа, на которой построена поразрядная сортировка, обладает меньшей универсальностью, чем та, которая использовалась в главах 6—9 (с функцией сравнения). Например, один из широко распространенных способов взаимодействия со служебной программой сортировки заключается в том, что клиент сам обеспечивает функцию сравнения. Примером может служить интерфейс, используемый программой qsort из библиотеки программ на C++. Это соглашение не только годится в ситуациях, когда клиент может, воспользовавшись специальными сведениями о составных ключах, реализовать быстрое сравнение, но и позволяет выполнять сортировку, используя отношения порядка, которые могут вообще обходиться без ключей. Один такой алгоритм будет рассмотрен в "Кратчайшие пути" .
Если возможно использование быстрой сортировки и различных алгоритмов поразрядной сортировки из рассмотренных в данной главе, то выбор между ними (и различными родственными версиями быстрой сортировки!) будет зависеть не только от свойств приложения (таких как размеры ключей, записей и файла), но также и от свойств среды программирования и аппаратуры, которые определяют эффективность доступа и использования отдельных битов и байтов. В таблица 10.1 и таблица 10.2 приведены эмпирические результаты, которые подтверждают вывод, что линейная или сублинейная производительности, рассмотренные нами для различных приложений поразрядной сортировки, делают эти методы сортировки привлекательными для различных подходящих приложений.
Приведенные относительные временные показатели различных видов поразрядной сортировки случайно упорядоченных файлов из N 32-разрядных чисел (во всех применяется переход на сортировку вставками для N, меньших 16) показывают, что при аккуратном применении поразрядные сортировки входят в число самых быстрых. При использовании очень большого основания системы счисления для маленьких файлов все преимущества MSD-сортировки будут сведены на нет, но выбор основания, меньшего размера файла, использует все ее достоинства. Самым быстрым методом сортировки целых ключей является LSD-сортировка по старшей половине разрядов, быстродействие которой можно повысить еще больше с помощью тщательной оптимизации внутреннего цикла (см. упражнение 10.45).
N | Q | 4-разрядные байты | 8-разрядные байты | 16-разрядные байты | |||||
---|---|---|---|---|---|---|---|---|---|
M | L | M | L | L* | M | L | M* | ||
12500 | 2 | 7 | 11 | 28 | 4 | 2 | 52 | 5 | 8 |
25000 | 5 | 14 | 21 | 29 | 8 | 4 | 54 | 8 | 15 |
50000 | 10 | 49 | 43 | 35 | 18 | 9 | 58 | 15 | 39 |
100000 | 21 | 77 | 92 | 47 | 39 | 18 | 67 | 30 | 77 |
200000 | 49 | 133 | 185 | 72 | 81 | 39 | 296 | 56 | 98 |
400000 | 102 | 278 | 377 | 581 | 169 | 88 | 119398 | 110 | 297 |
800000 | 223 | 919 | 732 | 6064 | 328 | 203 | 1532492 | 219 | 2309 |
Обозначения: | |
Q | Быстрая сортировка, стандартная (программа 7.1) |
M | MSD-сортировка, стандартная (программа 10.2) |
L | LSD-сортировка (программа 10.4) |
M* | MSD-сортировка, с адаптацией основания системы счисления под размер файла |
L* | LSD-сортировка по MSD-разрядам. |
N | Q | T | M | F | R | X | X* |
---|---|---|---|---|---|---|---|
12500 | 7 | 6 | 9 | 9 | 8 | 6 | 5 |
25000 | 14 | 12 | 18 | 19 | 15 | 11 | 10 |
50000 | 34 | 26 | 39 | 49 | 34 | 25 | 24 |
100000 | 83 | 61 | 87 | 114 | 71 | 57 | 54 |
Обозначения: | |
Q | Быстрая сортировка, стандартная (программа 7.1) |
T | Быстрая сортировка с трехпутевым разбиением (программа 7.5) |
M | Сортировка слиянием (программа 8.2) |
F | Пирамидальная сортировка с усовершенствованием Флойда (см. раздел 9.4 "Очереди с приоритетами и пирамидальная сортировка" ) |
R | MSD-сортировка (программа 10.2) |
X | Трехпутевая поразрядная быстрая сортировка (программа 10.3) |
X* | Трехпутевая поразрядная быстрая сортировка (с отсечениями) |
Приведенные относительные временные показатели различных сортировок первых N слов из книги " Моби Дик " (во всех применяется переход на сортировку вставками для N, меньших 16) показывают эффективность подхода " сначала MSD " для строковых данных. Отсечение малых подфайлов в трехпутевой поразрядной быстрой сортировке дает меньший выигрыш, чем в других методах, и совсем бесполезно, если не исключить в сортировке вставками просмотр старших разрядов ключей (см. упражнение 10.46).
Упражнения
10.44. Каков основной недостаток выполнения LSD-сортировки по старшим битам ключей с последующей " зачисткой " сортировкой вставками?
10.45. Разработайте реализацию LSD-сортировки по 32-разрядным ключам с минимально возможным количеством инструкций во внутреннем цикле.
10.46. Реализуйте трехпутевую поразрядную быструю сортировку таким образом, чтобы сортировка вставками небольших файлов не выполняла сравнения старших байтов, о которых известно, что они равны.
10.47. Пусть имеется 1 миллион 32-разрядных ключей. Определите такой размер байта, для которого время выполнения сортировки будет минимальным, если используется метод, использующий LSD-сортировку по двум первым байтам с последующей " зачисткой " сортировкой вставками.
10.48. Выполните упражнение 10.47 для 1 миллиарда 64-разрядных ключей.
10.49. Выполните упражнение 10.48 для трехпроходной LSD-сортировки.