Поуровневое размещение ориентированных графов Апанович З.В. apanovich@iis.nsk.su Тел:3309344 К. 217 Случайное размещение Силовое размещение Ортогональное изображение Круговое изображение Поуровневое изображение Пример большого поуровневого размещения Atlas of Cyberspaces (http://www.cybergeography.org/atl as/topology.html), показывает социальные связи внутри виртуального текстового пространства. Он является результатом проекта по коботам (http://www.cc.gatech.edu/fac/Char les.Isbell/projects/cobot/). Поуровневые изображения ориентированных графов Прямолинейные изображения, получаемые с помощью силовых алгоритмов, не всегда хороши: •Нет гарантии отсутствия пересечений ребер •Нет гарантии отсутствия пересечения ребер и вершин •Для многих приложений это просто неправильный шаблон (например, диаграммы потока управления, всевозможные хронологии). •Поэтому для ориентированных графов существует другая стратегия их изображения Поуровневое размещение ориентированных графов Будем полагать, что графы имеют некоторое общее направление потока. Это можно подчеркнуть, располагая все ребра в одном выделенном направлении. Более того, желательно, чтобы изображение удовлетворяло следующим критериям: 1) Не должно быть ребер, направленных в противоположную сторону 2а) Вершины должны быть распределены равномерно 2б) Ребра должны быть как можно короче 3) Количество пересечений ребер должно быть как можно меньше 4) Ребра должны быть как можно прямее/вертикальнее 5) Площадь изображения должна быть минимальна Поуровневое размещение ориентированных графов Не всегда возможно удовлетворить все ограничения одновременно: например, критерий минимальности высоты изображения часто вступает в противоречие с критерием минимальности количества пересечений. Также, достаточно часто критерий прямолинейности ребер вступает в противоречие с требованием равномерности распределения вершин Поуровневое размещение ориентированных графов • Даже построить изображение, которое удовлетворяет только некоторым из перечисленных критериев, и то не просто! • Поэтому было предложено разделить процесс построения изображения ориентированного графа на 4 этапа: • (Sugiyama K., Tagawa S., Toda M. Methods for visual understanding of hierarchical system structures 1981. Поуровневое размещение ориентированных графов Удаление циклов Чтобы сделать граф ациклическим, надо инвертировать минимальное количество ребер. По завершении работы все повернутые ребра будут повернуты еще раз и получат исходную ориентацию. Присваивание слоев Вычисляется разбиение на слои такое, что все ребра направлены вниз. Для алгоритмов последующих шагов требуется собственное разбиение на слои, когда ребра соединяют только смежные слои. Для достижения такого разбиения вводятся фиктивные вершины. Поуровневое размещение ориентированных графов Минимизация количества пересечений На каждом слое вычисляется упорядочение вершин. Это упорядочение должно быть построено таким образом, чтобы количество пересечений было минимально. Это осуществляется подсчетом количества пересечений между соседними слоями и перестановкой вершин с целью уменьшения количества пересечений. Поуровневое размещение ориентированных графов Присваивание x-координат и размещение ребер. • Ограничением на горизонтальные координаты вершин является то, что по возможности, никаких вершин не должно быть на прямой линии, соединяющей две смежные вершины. • Ребра должны быть либо как можно более прямолинейными либо вертикальными. • Ребра изображаются либо как полилинейные сегменты, либо как кривые. Поуровневое размещение ориентированных графов • Большая часть шагов является NP-полными проблемами, и для их реализации используются эвристики. При этом каждый шаг поуровневого размещения обычно независим от других и разные эвристики можно применять, не зная, что делалось на соседних этапах. • Не всегда требуется выполнять все шаги алгоритма. В некоторых случаях разбиение на слои задается вместе с графом, например, если изображаются события, связанные временной зависимостью. В этом случае выполняются только последние два шага. Удаление циклов • Проблема максимального ациклического подграфа: найти максимальное множество Ea E такое, что граф (V, Ea) не содержит циклов. • Эта проблема часто формулируется как проблема удаления минимального множества обратных ребер feedback arc set problem (FAS): • Найти минимальное множество Ef E такое, что граф (V, E\Ef) не содержит циклов. • Обычно, ребра Ef не удаляются, а просто разворачиваются в противоположную сторону • К сожалению, проблема поиска максимального ациклического подграфа является NP-трудной. Удаление циклов, замечание • Проблема поиска ребер, чье удаление делает граф ациклическим называется feedback arc set problem (FAS). • Проблема поиска ребер, чей разворот делает граф ациклическим называется feedback set problem (FS). • Это не одна и та же проблема. Примером является граф, состоящий из одного цикла. Если развернуть все ребра, то он от этого ациклическим не станет, а если удалить все ребра, то он будет ациклическим. Удаление циклов • Прежде всего следует отметить, что удаление одного ребра в цикле автоматически задает порядок на остальных ребрах и вершинах.Поэтому, если порядок существенен, нужны алгоритмы, учитывающие этот порядок. Удаление циклов Поиск в глубину на ориентированном графе • Поиск в глубину на ориентированном графе разбивает ребра на 4 группы: • Древесные ребра (v1,v5) • Прямые ребра(от предков к потомкам по дереву)(V1,V4) • Обратные ребра (от потомков к предкам по дереву) (v3,v1) • Поперечные ребра (соединяют узлы, не являющиеся ни предками ни потомками друг другу)(v8,v4) Поиск в глубину на ориентированном графе Легко заметить, что прямые и поперечные ребра циклов не создают. Значит, следует развернуть только обратные ребра •Такой метод не дает оценки количества обратных ребер! Теоретически, имеет смысл развернуть минимальное количество ребер. НО, вопервых, эта проблема NPполная. А, кроме того, нет гарантии, что ее решение улучшит изображение. • Эксперименты показали, что большинство ориентированных графов, возникающих из практических приложений, имеют естественное направление ребер, даже если там имеются циклы. Часто графы создаются поиском, выполненным каким-то другим инструментом. Разворот неподходящего ребра нарушает все изображение. • Например, даже если граф вызовов процедур имеет циклы, все-таки ожидается, что функции верхнего уровня будут расположены вверху изображения, а не где-то посередке. • В программе dot, реализованной в составе GraphViz [Gansner et al, 1973], использована следующая эвристика. • Выбирается по одной нетривиальной сильно связанной компоненте в произвольном порядке. Внутри каждой компоненты осуществляется поиск в глубину и к FS добавляется ребро, участвующее в наибольшем количестве циклов. Процесс повторяется до тех пор, пока не останется нетривиальных сильно связных компонент. Эта эвристика разворачивает те ребра, чье направление против потока является естественным. • • Удаление циклов поиском в глубину также делает более информативными изображения, которые получились бы сворачиванием всех вершин одного цикла в одну вершину, или при размещении всех вершин одного цикла на одном уровне, или при дублировании некоторой вершины цикла. Проблема максимального ациклического подмножества и упорядочение вершин • Можно перефразировать проблему поиска максимального ациклического подграфа в терминах последовательностей вершин. • Найти упорядочение вершин, то есть найти отображение o:V->{1, 2,..., |V|} такое, что количество ребер (u,v)E, у которых o(u)>o(v) минимально • Предположим, все вершины графа рисуются на горизонтальной линии. Тогда последовательность вершин - это просто список вершин в том порядке, как они появляются на этой линии. Чтобы найти минимальное множество обратных ребер, надо найти последовательность вершин, имеющую наименьшее количество ребер, указывающих назад. Проблема максимального ациклического подмножества и упорядочение вершин Если ребер, направленных назад, более половины, просто инвертировать порядок вершин Проблема максимального ациклического подмножества и упорядочение вершин Удаление циклов Еще одна эвристика, дающая оценку |Ea|≥|E| (v) – множество ребер, инцидентных вершине v • -(v) – множество входных вершин • +(v) – множество выходных вершин Жадный алгоритм Berger-Shor, 1990 • • • • • • • • • Вход Ориентированный граф G(V,E) Выход ациклическое множество ребер Ea Ea =; Foreach vV do If |+(v)| |-(v)| then Добавить +(v) к Ea Else Добавить -(v) к Ea Удалить (v)из G Жадный алгоритм Berger-Shor, 1990 Жадный алгоритм Berger-Shor, 1990 • Очевидное утверждение: Жадный алгоритм Berger-Shor вычисляет ациклическое множество |Ea|1/2|E| • за время O(n+m). • Этот алгоритм можно усовершенствовать, если заметить, что ребра, инцидентные истоку и стоку, не могут быть частью цикла. Алгоритм расширенная жадная эвриcтика (Eades et al, 1993) • • • • • • • • • • • • Вход ориентированный граф G(V, E) Выход ациклическое множество ребер Ea 1. Ea = ; 2. while G не пуст do{ 3. while G содержит хоть один сток v do{ 4. Добавить -(v) к Ea, Удалить v и -(v) из G; } 5. Удалить все изолированные вершины из G; 6. while G содержит хоть один исток v do{ 7. Добавить +(v) к Ea, Удалить v и +(v) из G; } Алгоритм расширенная жадная эвриcтика (Eades et al, 1993) • Если G не пуст то { • 9. Пусть v – это вершина в G с максимальным значением |+(v)|- |-(v)|; • 10. Добавить +(v) к Ea, Удалить v и (v)из G; • } • } Алгоритм расширенная жадная эвриcтика (Eades et al, 1993) Красные вершины – удаляемые, красные ребра - Ea Алгоритм расширенная жадная эвриcтика (Eades et al, 1993) • Теорема (Eades et al, 1993) • Дан связный ориентированный граф G =(V, E), не содержащий 2-циклов. • Алгоритм «расширенная жадная эвриcтика» вычисляет ациклическое множество Еа • |Ea| |E|/2 + |V|/6. • Сложность алгоритма O(n+m) • В случае, когда максимальная степень вершины в графе ≤ 3, |Ea| 2/3|E|. Разбиение на слои • Дано разбиение L множества вершин V. • L = {L1,L2,…,Lh} . • И характеристическая функция y: V->{1,2,…,}такая, что y(u) = i uLi. • L называется разбиением на слои, если выполняется условие: (u,v)E:y(u)>y(v). Разбиение на слои • Высота разбиения на слои равна количеству слоев • Ширина разбиения на слои равна количеству вершин в самом широком слое • Размах ребра равен y(u)-y(v). • Разбиение на слои называется собственным, если размах любого ребра не превышает 1. Разбиение на слои • При разбиении на слои желательно, чтобы высота и ширина разбиения на слои были бы минимальны • Большинство алгоритмов, использующихся на последующих шагах, требуют собственного разбиения на слои. • Это достигается введением фиктивных вершин для всех ребер, у которых размах больше 1. То есть вместо ребра (u,v) вводится путь (u = v1,v2,…vk= v) длины к. На каждом слое, находящемся между u и v, будет размещено по одной фиктивной вершине. Разбиение на слои Желательно, чтобы фиктивных вершин было не очень много, по следующим причинам: • Время вычислений на последующих шагах зависит от суммарного количества вершин обычных и фиктивных. • Сгибы образуются только при фиктивных вершинах, и значит, чем меньше фиктивных вершин, тем меньше сгибов, тем лучше читаемость изображения. • Чем больше фиктивных вершин, тем длинее ребра. Простые способы разбиения на слои для произвольных графов ( не ациклических) (Sander, 1996, VCG) • 1) вычислить y-координату каждой вершины поиском в глубину или поиском в ширину. Это дает какое-то разбиение за линейное время, но без заранее известных свойств; • 2) Вычислить минимальное остовное дерево на неориентированном варианте графа. Это полезно, если ребра имеют веса w(e). Стоимость каждого ребра приравнять 1/w(e). В этом случае ребра с высоким весом будут более короткими; • 3) Применить одномерный силовой алгоритм для вычисления только одной координаты y(v) . Таким способом можно получить разбиение на слои, в котором все ребра примерно одной длины. Разбиение на слои(Минимизация высоты) Теперь считаем, что граф G = (V,E) ациклический. • Следующий алгоритм вычисляет разбиение на слои минимальной высоты. • Все стоки графа помещаются в слой L1 • Для остальных вершин слой вычисляется рекурсивно по формуле: • Y(u):=max{i|vN+(u) = i} +1 • Где N+(u):={vV|(u,v)E}- вершины, в которые входят ребра от вершины u Разбиение на слои(Минимизация высоты) В результате получим разбиение на слои, в котором вершины cдвинуты максимально вниз. При этом ширина изображения может оказаться чрезмерной. Разбиение на слои заданной ширины • Для ширины, больше или равной 3, проблема разбиения на слои заданной ширины и минимальной высоты является NP-полной. • Пример неоптимальности жадной стратегии: n/2 изолированных вершин и путь длины n/2 Разбиение на слои заданной ширины, алгоритм Coffman-Graham • Жадное решение далеко от оптимального, потому что оно не рассматривает длинные пути в графе. • Это в точности то, что делает алгоритм Coffman-Graham (1972) • Он работает в 2 прохода. Первый проход упорядочивает вершины по их расстоянию до вершин-истоков в графе. • А второй проход уже присваивает вершины слоям. • Вершины, которые находятся далеко от истоков, будут располагаться как можно ниже. • Прежде всего вводится лексикографический порядок конечных целочисленных множеств S T • 1 S=, T; • 2 S, T max(S)<max(T); • 3 S, T max(S)= max(T) S\{ max(S)} T\{ max(T)}. • Пример: {4} или {1, 2}? Разбиение на слои заданной ширины, алгоритм Coffman-Graham • Вход: Ориентированный граф без транзитивных ребер • Выход: Разбиение на слои заданной ширины и, по возможности, минимальной высоты. • /*Первый проход*/ • For each vV do (v) := n+1; • For i =1 to |V| do{ • Выбрать вершину v с (v) = n + 1 и минимальным множеством входных вершин {(u)|(u,v)E } по отношению к порядку ; • (v):=i; • } Разбиение на слои заданной ширины, алгоритм Coffman-Graham первый проход Нумерация вершин. Начинаем с вершины, у которой минимальное множество входных вершин. На первом шаге это может быть только исток. На следующем шаге минимальным множеством (u) будут обладать потомки истоков, и т.д. Разбиение на слои заданной ширины, алгоритм Coffman-Graham, второй проход • k:=1; L1:=; множество ненумерованных вершин U:=V; • while U do • Выбрать uU такую, что каждая вершина в {v|(u,v)E} находится во множестве V\U и (u) максимально • if |Lk| < w и N+(u) L1L2 …Lk-1 then • добавить u к Lk • else • k:=k+1; Lk:={u}; • Удалить u из U; • } Разбиение на слои заданной ширины, алгоритм Coffman-Graham (1972) • Для укладки в первый слой выбирается вершина, все потомки которой уже уложены, то есть это стоки по убыванию номеров. Разбиение на слои заданной ширины, алгоритм Coffman-Graham (1972) • Lam и Seti (1977) доказали, что высота h полученного разбиения на слои ширины w ограничено величиной: • H ≤ (2-2/w)hopt • Значит алгоритм является точным при w ≤ 2. Разбиение на слои с минимизацией суммарного размаха ребер Эта задача эквивалентна минимизации количества фиктивных вершин. Было показано, что минимизация количества фиктивных вершин также гарантирует минимальную высоту разбиения. • Ее можно сформулировать и решить как задачу целочисленного программирования: • Min ( y (u ) y ( v ) ( u ,v )E При ограничениях: y(u)-y(v)1 для всех (u,v)E y(v) Z+ для всех vV Минимизация суммарного размаха ребер • Gansner et al 1993 предложили сетевой симплекс – метод разбиения на слои с минимальным количеством фиктивных вершин. Не была доказана полиномиальная сложность алгоритма, но на практике работает быстро. • Метод основан на идее, что остовное дерево неориентированного графа задает семейство эквивалентных разбиений на слои. • Алгоритм начинает с остовного дерева, которое на каждом шаге модифицируется таким образом, чтобы уменьшить количество фиктивных вершин. Минимизация суммарного размаха ребер • Допустимое разбиение на слои - это такое разбиение, которое удовлетворяет ограничению на длину ребер. • l(e) (e) для всех е, где l(e) - это реальная длина ребра, (e) – минимально допустимая длина ребра (обычно (e) =1). • Если имеется какое-то разбиение на слои, не обязательно допустимое, можно подсчитать резерв каждого ребра, равный разнице между реальной длиной и минимальной длиной: slack(e) = l(e)-(e). • Разбиение на слои допустимо, если резерв каждого ребра неотрицателен (slack(e) 0) . • Ребро называется точным, если резерв каждого ребра равен нулю (slack(e) = 0). Минимизация суммарного размаха ребер • Любое остовное дерево индуцирует некоторое разбиение на слои. • Это разбиение на слои строится выбором начальной вершины и присваиванием ей какого-то слоя. • Затем для каждой вершины, смежной с вершиной, уже имеющей номер слоя, присваивается номер слоя плюс или минус длина связывающего их ребра в зависимости от того, входное это или выходное ребро. • Процесс повторяется до тех пор, пока все вершины не получат номер слоя. • Если в результате получается допустимое разбиение на слои, то и остовное дерево называется допустимым Минимизация суммарного размаха ребер • Каждая итерация алгоритма минимизации суммарного размаха ребер удаляет одно ребро из остовного дерева, которое при этом распадается на две компоненты. • Затем к остовному дереву добавляется новое ребро , которое заново соединяет две компоненты и порождает новое остовное дерево. • При этом новое остовное дерево соответствует разбиению на слои с меньшим количеством фиктивных вершин. Минимизация суммарного размаха ребер • Для удаления из дерева, выбирается ребро с отрицательным значением разреза. • Значение разреза определяется для каждого древесного ребра следующим образом: При удалении одного ребра из остовного дерева, оно при этом распадается на две компоненты, голова и хвост. • Хвост – это компонента, содержащая хвост ребра e, а головная – содержит голову ребра е. Значение разреза – это количество ориентированных ребер, идущих от хвоста к голове включая е, минус количество ребер идущих от головы к хвосту. Минимизация суммарного размаха ребер • Отрицательное значение разреза для ребра означает, что можно уменьшить количество фиктивных вершин, удлиняя как можно сильнее ребро с отрицательным значением разреза до тех пор, пока одно из ребер от головы к хвосту не станет точным. Одно из точных ребер и будет добавлено вместо удаляемого ребра. Минимизация суммарного размаха ребер Пример работы сетевого симплексметода. Недревесные ребра показаны пунктиром, все ребра имеют вес = 1. 1)показан граф после начального разбиения на слои, разметка ребер указывает значения разреза. Например, значение разреза на ребре (g, h) равна –1, что соответствует весу ребра (g, h) минус веса ребер (a, e) (a, f) от головной компоненты до хвостовой компоненты. Минимизация суммарного размаха ребер ребро (g, h) с отрицательным значением разреза заменено на недревеcное ребро (a, e). Для всех древесных ребер показаны новые значения разреза. Поскольку все значения разрезов неотрицательные, решение оптимально и алгоритм останавливается. Значение разреза на ребре (a, e) = 2-1 =1 Минимизация суммарного размаха ребер(Gansner et al, 1993) • • • • • • • • • 1. procedure rank(){ 2. feasible_tree(); 3. while(e = leave_edge())nil do 4. f = enter_edge(e); 5. exchange(e,f); 6. } 7.normalize(); 8.balance(); 9.} Минимизация суммарного размаха ребер(Gansner et al, 1993) Симплекс метод начинает с допустимого решения и поддерживает этот инвариант. • leave_edge выдает древесное ребро с отрицательным значением разреза, или nil, если такового не нашлось. В таком случае считается, что решение оптимально. Любое ребро с отрицательным значением разреза считается кандидатом на удаление. • enter_edge находит не-древесное дерево, на которое заменяется удаленное ребро e. Это делается разрывом ребра e, которое делит дерево на головную и хвостовую части. Рассматриваются все ребра, идущие от головной части к хвостовой, и выбирается ребро с наименьшим резервом ( Это необходимо для поддержания допустимости). • При замене ребра обновляется дерево, и перевычисляются значения разрезов. • Вершины, имеющие одинаковое количество входных и выходных ребер, и много допустимых рядов, перемещаются в допустимый слой с наименьшим количеством вершин. Пример, показывающий, что разбиение на слои с минимальным количеством фиктивных вершин может оказаться слишком широким (если реальные вершины имеют размер) 2 слоя без фиктивных вершин 3 слоя 4 фиктивных вершины (не нарисованы)