Алгоритм Комлоса
Алгоритм Комло́са — алгоритм, разработанный Яношем Комлосом (венг. Komlós János). Алгоритм предназначен для поиска ребра с наибольшим весом на путях между каждой парой вершин в подвешенных деревьях. Поиск таких рёбер используется при верификации минимального остовного дерева путем проверки критерия Тарьяна.
Пусть существует некоторый взвешенный неориентированный граф
и его остовное дерево . Допустим, что для каждого ребра графа , не входящего в дерево , существует способ найти ребро с наибольшим весом в пути между вершинами в дереве . Тогда для проверки критерия Тарьяна достаточно сравнить веса таких рёбер с весами рёбер .Описание алгоритма
Случай полного ветвящегося дерева
Общее описание подхода
Рассмотрим полное ветвящееся дерево
, т.е. такое дерево, у вершин которого либо 0, либо 2 и более потомков, и все листья находятся на одном уровне. Для такого дерева Комлосом был показан вариант алгоритма, который находит ребро с максимальным весом на пути для каждой пары листьев, используя операций сравнения. Алгоритм разбивает путь между листьями на две части, начинающихся в листе и заканчивающихся в наименьшем общем предке этих листьев, и находит ребро с наибольшим весом в каждой части. После чего, одно из двух рёбер с большим весом выбирается ребром с наибольшим весом на пути из одной вершины в другую.Алгоритм вычисляет вес для каждой части пути следующим образом. Пусть
— ребро максимального веса на пути из корня в некоторый лист , проходящий через вершину , ограниченном на отрезке (т.е. удалены все вершины от корня до предка v). Обозначим . Предположим, что — вершина-потомок , и известно множество . Рассмотрим случай одного листа . Очевидно, что все пути из корня в , проходящие через , также проходят через . Так как ребро связывает и , получим, что , где - вес ребра . Следовательно, для того, чтобы найти , достаточно сравнить веса рёбер из с весом ребра . Данное сравнение можно эффективно выполнить с помощью двоичного поиска. Итоговое множество получается путем объединением множеств рёбер, полученных для каждого потомка. Таким образом, алгоритм, начиная с корня дерева, спускается до листьев графа и конструирует множества для каждой вершины.После нахождения множеств алгоритма Тарьяна со сложностью . Пусть для некоторых двух листьев их наименьший общий предок . Тогда ребром с наибольшим весом на пути из в будет ребро .
, алгоритм находит ребро с наибольшим весом на пути между двумя листьями следующим образом. Для всех листьев в дереве находится их наименьший общий предок, например, с помощьюКомлос показал, что
, что дает верхнюю границу для количества операций сравнений, используемых алгоритмом.Эффективная реализация при помощи битового сжатия
В работе Валери Кинг был предложен метод сведения общего случая остовного дерева к полному ветвящемуся дереву, а также предложена эффективная реализация алгоритма Комлоса с использованием битового сжатия[1]. Описанные в работе структуры данных и битовые операции, которые возможно предвычислить и сохранить в таблице, обращение к которой занимает константное количество операций, позволяют выполнить алгоритм Комлоса за линейное время.
Обозначим за алгоритма Кинг. Вершины в дереве нумеруются битовыми словами следующим образом:
полное ветвящееся дерево, полученное с помощью- Каждый лист помечается порядковым номером 0, 1, 2... в двоичном представлении в порядке встречи листов при обходе в глубину.
- Каждый не-лист помечается номером своего потомка, содержащим наибольшее количество ведущих нулей.
Рёбра в дереве получают тег, который формируется следующим образом. Рассмотрим ребро
, где находится дальше от корня. Пусть обозначает расстояние от вершины до корня, а — номер младшей единицы в номере вершины . Тогда тег ребра — строка размера , записанная как последовательность . В оригинальной работе было показано, что имея тег ребра и номер вершины, можно обнаружить ребро в графе за константное время.Для каждой вершины
создается вектор длины , обозначаемый как , чей бит с номером i равен 1 тогда, когда существует путь из листа в поддереве с корнем в лист в другом поддереве, наивысшая по уровню вершина которого (иначе говоря, наименьший общий предок двух листьев) находится на расстоянии от .Далее, вершины делятся на два класса. Если
, то вершина считается большой; в противном случае вершина считается малой. Для больших вершин создаются списки , для малых — . содержит теги рёбер из в порядке неубывания длин путей из корня в листья, соответствующих рёбрам. Для хранения такого списка требуется памяти.Для малой вершины
обозначим за ближайшего большого предка. Список содержит либо теги рёбер из , либо, если ребро из содержится в интервале от корня до , указатель на вершины , содержащий тег для . Для каждой малой вершины запоминается номер первого элемента в , являющимся тегом. Элементы списка, идущие после первого тега, тоже являются тегами. Для хранения требуется одно битовое слово.Анализ сложности
Было показано, что в реализации с битовым сжатием операции для малых вершин выполняются за константное время. Если вершина большая, то стоимость предвычислений для неё составляет
операций. Следовательно, общая сложность предвычислений составляет операций. Дополнительно алгоритм тратит операций для построения списков , операций для обработки таблиц с предвычисленными значениями и операций сравнения для нахождения ребра с максимальным весом из двух половин.В завершении алгоритма, требуется сравнить веса рёбер графа, которые не входят в остовное дерево, с найденными в остовном дереве рёбрами наибольшего веса, что потребует дополнительных
операций сравнения, где — количество рёбер в исходном графе.См. также
Источники информации
- Komlós, J. Linear verification for spanning trees. Combinatorica 5, 57–65 (1985). https://doi.org/10.1007/BF02579443
Примечания
- ↑ King, V. A simpler minimum spanning tree verification algorithm. Algorithmica 18, 263–270 (1997). https://doi.org/10.1007/BF02526037