Топологическая сортировка
Пусть дан орграф без петель и кратных дуг. Требуется найти топологическую сортировку (topological sort) вершин этого орграфа, то есть указать такой линейный порядок на его вершинах, что любая дуга ведет от меньшей вершины к большей в смысле этого порядка. В случае, если орграф не является ациклическим и такого порядка не существует, то вывести сообщение об этом. Топологическую сортировку на диаграмме орграфа можно рассматривать как такое упорядочивание его вершин вдоль горизонтальной линии, что все его дуги направлены слева направо. Таким образом, топологическая сортировка существенно отличается от других видов сортировок.
Данная задача решается на основе метода обхода в глубину. Каждая вершина вначале белая. Будучи обнаруженной в процессе обхода, ее цвет становится серым. Цвет вершины станет черным, когда она будет полностью обработана, то есть когда список смежных с ней вершин будет просмотрен. Каждая вершина
попадает ровно в одно дерева обхода в глубину, так что эти деревья не пересекаются.
Несложно понять, что орграф не имеет циклов тогда и только тогда, когда обход в глубину не находит в нем обратных дуг. Действительно, обратная дуга соединяет потомка с предком и замыкает цикл, образованный дугами дерева. Обратная дуга будет обнаружена, если обход в процессе своей работы придет в вершину серого цвета. Из этого факта следует, что вершины орграфа могут быть топологически отсортированы тогда и только тогда, когда поиск глубину в нем не находит обратных дуг.
– исходный граф, в котором
– это множество вершин, а
– это множество ребер.
– массив для хранения цветов вершин графа
.
— булевская переменная, служащая индикатором того, является орграф ациклическим или нет. Переменная
принимает значение
, если орграф
является ациклическим, и значение
, если орграф содержит хотя бы один цикл.
— топологическая упорядоченная перестановка вершин орграфа
1 2 3 |
![]() ![]() ![]() ![]() |
TOPOLOGICAL_SORT(v)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
По завершению процедуры топологически упорядоченная перестановка вершин орграфа будет находится в списке , в случае, если исходный орграф
не является ациклическим. Если в исходном орграфе есть цикл, то его можно восстановить проходом по массиву предков. Процедуру восстановления цикла смотрите в статье, посвященной алгоритму проверки орграфа на ацикличность.
Рассмотрим ситуацию, в которой возникает задача о поиске топологической сортировке вершин орграфа. Пусть в некотором ВУЗе на определенной специальности преподают следующие предметы:
1. математический анализ (матан)
2. теория функций комплексного переменного (ТФКП)
3. функциональный анализ (функан)
4. языки программирования (ЯП)
5. алгебра
6. теория графов
7. криптография (crypto).
При этом, для того чтобы студентам понять содержание некоторых дисциплин, надо ранее обязательно прослушать другие предметы. Например, чтобы усвоить содержание лекций функционального анализа, необходимо прослушать курс по математическому анализу и теории функций комплексного переменного. Для того, чтобы запрограммировать лабораторные работы по теории графов необходимо сдать практику по языкам программирования. На рисунке ниже требуемые соотношения показаны в виде ориентированного графа: дуга означает, что предмет
должен быть понят для проведения занятий по предмету
.
Топологическая сортировка, тем самым, показывает один из порядков преподавания предметов на данной специальности. Один из таких порядков показан на рисунке ниже, где изучать предметы в показанном порядке. Все дуги идут слева направо.
Заметим, что данная топологическая сортировка не является единственной и для одного и того же орграфа может существовать несколько топологически упорядоченных перестановок его вершин. В примере с дисциплинами возможно сначала изучить языки программирования, а потом алгебру. Пример с предметами в ВУЗе является не единственным применением топологической сортировки. В общем случае при помощи выше описанного алгоритма можно построить корректную последовательность выполнения действий, всякое из которых зависит от другого: последовательность установки программ при помощи пакетного менеджера или сборки исходных текстов программ при помощи Makefile’ов.
Процесс инициализации массива осуществляется за
.
Процедура TOPOLOGICAL_SORT вызывается ровно по одному разу для каждой вершины орграфа, так как она вызывается только для белых вершин, то есть еще не обработанных. Первое, что она делает, это помечает переданную в качестве параметра вершину
процедуры как серую, строка
. В процессе выполнения процедуры TOPOLOGICAL_SORT цикл в строках
выполняется ровно
раз. Так как
, то общая стоимость выполнения строк
процедуры TOPOLOGICAL_SORT равна
. В строке
вершина
помечается как черная за
, так как становится обработанной. Добавление черной вершины
в начало списка
также можно реализовать за
.
Таким образом, асимптотическая сложность алгоритма поиска топологической сортировки вершин орграфа равна , то есть такая же, как и асимптотическая сложность алгоритма обхода в глубину.