Топологическая сортировка
Топологическая сортировка — упорядочивание вершин ациклического ориентированного графа согласно частичному порядку , заданному рёбрами орграфа на множестве его вершин.
Например, для графа:
G
=
(
{
2
,
3
,
5
,
7
,
8
,
9
,
10
,
11
}
,
{
(
3
,
8
)
,
(
3
,
10
)
,
(
5
,
11
)
,
(
7
,
11
)
,
(
7
,
8
)
,
(
8
,
9
)
,
(
11
,
2
)
,
(
11
,
9
)
,
(
11
,
10
)
}
)
{\displaystyle G={\Bigl (}{\bigl \{}2,3,5,7,8,9,10,11{\bigr \}},{\bigl \{}(3,8),(3,10),(5,11),(7,11),(7,8),(8,9),(11,2),(11,9),(11,10){\bigr \}}{\Bigr )}}
существует несколько согласованных последовательностей его вершин, которые могут быть получены при помощи топологической сортировки, в частности:
7
,
5
,
11
,
3
,
8
,
2
,
9
,
10
{\displaystyle 7,5,11,3,8,2,9,10}
3
,
7
,
5
,
8
,
11
,
10
,
9
,
2
{\displaystyle 3,7,5,8,11,10,9,2}
В последовательности могут быть переставлены любые две стоящие рядом вершины, которые не входят в отношение частичного порядка
E
{\displaystyle E}
.
Ациклический ориентированный граф
Топологическая сортировка широко применяется в различных отраслях например, с её помощью можно построить последовательность прохождения учебных курсов студентами, последовательность установки программ при помощи пакетного менеджера , последовательность сборки исходных текстов программ по данным сборочных файлов, можно построить список отображения объектов в изометрической проекции зная парные порядковые отношения между объектами (какой из двух объектов должен быть прорисован раньше).
Алгоритм Кана
Один из первых алгоритмов, и наиболее приспособленный к исполнению вручную разработан Артуром Каном в 1962 году .
Пусть дан ациклический ориентированный простой граф
G
=
(
V
,
E
)
{\displaystyle G=(V,E)}
. Через
A
(
v
)
,
v
∈ ∈ -->
V
{\displaystyle A(v),v\in V}
обозначим множество таких вершин
u
∈ ∈ -->
V
{\displaystyle u\in V}
, что
∃ ∃ -->
(
u
,
v
)
∈ ∈ -->
E
{\displaystyle \exists ~(u,v)\in E}
. То есть
A
(
v
)
{\displaystyle A(v)}
— множество всех вершин, из которых есть дуга в вершину
v
{\displaystyle v}
. Пусть
P
{\displaystyle P}
— искомая последовательность вершин.
пока
|
P
|
<
|
V
|
{\displaystyle |P|<|V|}
выбрать любую вершину
v
{\displaystyle v}
такую, что
A
(
v
)
=
∅ ∅ -->
{\displaystyle A(v)=\varnothing }
и
v
∉ ∉ -->
P
{\displaystyle v\notin P}
P
← ← -->
P
,
v
{\displaystyle P\gets P,v}
удалить
v
{\displaystyle v}
из всех
A
(
u
)
,
u
≠ ≠ -->
v
{\displaystyle A(u),u\neq v}
Наличие хотя бы одного цикла в графе приведёт к тому, что на определённой итерации цикла не удастся выбрать новую вершину
v
{\displaystyle v}
.
Например, если задан граф:
G
=
(
{
a
,
b
,
c
,
d
,
e
}
,
{
(
a
,
b
)
,
(
a
,
c
)
,
(
a
,
d
)
,
(
a
,
e
)
,
(
b
,
d
)
,
(
c
,
d
)
,
(
c
,
e
)
,
(
d
,
e
)
}
)
{\displaystyle G={\Bigl (}{\bigl \{}a,b,c,d,e{\bigr \}},{\bigl \{}(a,b),(a,c),(a,d),(a,e),(b,d),(c,d),(c,e),(d,e){\bigr \}}{\Bigr )}}
,
алгоритм выполнится следующим образом:
шаг
v
{\displaystyle v}
A
(
a
)
{\displaystyle A(a)}
A
(
b
)
{\displaystyle A(b)}
A
(
c
)
{\displaystyle A(c)}
A
(
d
)
{\displaystyle A(d)}
A
(
e
)
{\displaystyle A(e)}
P
{\displaystyle P}
0
− − -->
{\displaystyle -}
∅ ∅ -->
{\displaystyle \varnothing }
a
{\displaystyle a}
a
{\displaystyle a}
a
,
b
,
c
{\displaystyle a,b,c}
a
,
c
,
d
{\displaystyle a,c,d}
∅ ∅ -->
{\displaystyle \varnothing }
1
a
{\displaystyle a}
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
b
,
c
{\displaystyle b,c}
c
,
d
{\displaystyle c,d}
a
{\displaystyle a}
2
c
{\displaystyle c}
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
b
{\displaystyle b}
d
{\displaystyle d}
a
,
c
{\displaystyle a,c}
3
b
{\displaystyle b}
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
d
{\displaystyle d}
a
,
c
,
b
{\displaystyle a,c,b}
4
d
{\displaystyle d}
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
a
,
c
,
b
,
d
{\displaystyle a,c,b,d}
5
e
{\displaystyle e}
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
∅ ∅ -->
{\displaystyle \varnothing }
a
,
c
,
b
,
d
,
e
{\displaystyle a,c,b,d,e}
На втором шаге вместо
c
{\displaystyle c}
может быть выбрана вершина
b
{\displaystyle b}
, поскольку порядок между
b
{\displaystyle b}
и
c
{\displaystyle c}
не задан.
Алгоритм Тарьяна
С использованием вычислительной техники топологическую сортировку можно выполнить за
O
(
n
)
{\displaystyle O(n)}
времени и памяти, если обойти все вершины, используя поиск в глубину , и выводить вершины в момент выхода из неё — алгоритм разработан Робертом Тарьяном в 1976 году .
Изначально все вершины помечаются как белые, для каждой вершины осуществляется шаг алгоритма:
если вершина чёрная, ничего делать не надо,
если вершина серая — найден цикл, топологическая сортировка невозможна,
если вершина белая, то:
красится в серый,
применяется шаг алгоритма для всех вершин, в которые можно попасть из текущей,
вершина красится в чёрный и помещается в начало окончательного списка.
Например, на графе:
G
=
(
{
a
,
b
,
c
,
d
,
e
}
,
{
(
a
,
b
)
,
(
a
,
c
)
,
(
a
,
d
)
,
(
a
,
e
)
,
(
b
,
d
)
,
(
c
,
d
)
,
(
c
,
e
)
,
(
d
,
e
)
}
)
{\displaystyle G={\Bigl (}{\bigl \{}a,b,c,d,e{\bigr \}},{\bigl \{}(a,b),(a,c),(a,d),(a,e),(b,d),(c,d),(c,e),(d,e){\bigr \}}{\Bigr )}}
с порядком обхода
c
,
d
,
e
,
a
,
b
{\displaystyle c,d,e,a,b}
алгоритм отрабатывает следующим образом:
Шаг
Текущая
Белые
Стек (серые)
Выход (чёрные)
0
—
a
,
b
,
c
,
d
,
e
{\displaystyle a,b,c,d,e}
—
—
1
c
{\displaystyle c}
a
,
b
,
d
,
e
{\displaystyle a,b,d,e}
c
{\displaystyle c}
—
2
d
{\displaystyle d}
a
,
b
,
e
{\displaystyle a,b,e}
c
,
d
{\displaystyle c,d}
—
3
e
{\displaystyle e}
a
,
b
{\displaystyle a,b}
c
,
d
,
e
{\displaystyle c,d,e}
—
4
d
{\displaystyle d}
a
,
b
{\displaystyle a,b}
c
,
d
{\displaystyle c,d}
e
{\displaystyle e}
5
c
{\displaystyle c}
a
,
b
{\displaystyle a,b}
c
{\displaystyle c}
d
,
e
{\displaystyle d,e}
6
—
a
,
b
{\displaystyle a,b}
—
c
,
d
,
e
{\displaystyle c,d,e}
7
d
{\displaystyle d}
a
,
b
{\displaystyle a,b}
—
c
,
d
,
e
{\displaystyle c,d,e}
8
e
{\displaystyle e}
a
,
b
{\displaystyle a,b}
—
c
,
d
,
e
{\displaystyle c,d,e}
9
a
{\displaystyle a}
b
{\displaystyle b}
a
{\displaystyle a}
c
,
d
,
e
{\displaystyle c,d,e}
10
b
{\displaystyle b}
—
a
,
b
{\displaystyle a,b}
c
,
d
,
e
{\displaystyle c,d,e}
11
a
{\displaystyle a}
—
a
{\displaystyle a}
b
,
c
,
d
,
e
{\displaystyle b,c,d,e}
12
—
—
—
a
,
b
,
c
,
d
,
e
{\displaystyle a,b,c,d,e}
13
b
{\displaystyle b}
—
—
a
,
b
,
c
,
d
,
e
{\displaystyle a,b,c,d,e}
См. также
Литература
Ссылки
Теория Обменные Выбором Вставками Слиянием Без сравнений Гибридные Прочее Непрактичные