Понятие графа
Первая работа по теории графов, принадлежащая известному швейцарскому математику Л. Эйлеру, появилась в 1736 г., связанная с
На практике вершины графа можно использовать для представления объектов, а дуги — для отношений между объектами
В настоящее время графы эффективно используются в теории планирования и управления, теории расписаний, социологии, экономике,
Спасибо за внимание!
2.61M
Category: programmingprogramming

Понятие графа

1. Понятие графа

вершина
дуга
- совокупность конечного
числа точек, называемых
вершинами графа, и попарно
соединяющих некоторые из
этих вершин линий,
ребро
называемых ребрами или
дугами графа.

2. Первая работа по теории графов, принадлежащая известному швейцарскому математику Л. Эйлеру, появилась в 1736 г., связанная с

решением известной головоломки о
мостах Кёнигсберга. Толчок к развитию теория графов
получила на рубеже ХIX и ХХ столетий, когда резко возросло
число работ в области топологии и комбинаторики.

3.

Благодаря использованию графов можно
упростить решение задач
«В Кенигсберге есть
остров, называемый
Кнейпгоф. Река,
омывающая его,
делится на два рукава,
через которые
перекинуто семь
мостов. Можно ли
обойти все эти мосты,
не побывав ни на одном
из них более раза?»

4. На практике вершины графа можно использовать для представления объектов, а дуги — для отношений между объектами

C
A
D
B
Л. Эйлеру удалось ответить на этот вопрос. Представим,
что мосты, соединяющие части города – это рёбра графа,
а части города – это вершины графа. Все вершины
должны быть четной степени, а это не так.

5. В настоящее время графы эффективно используются в теории планирования и управления, теории расписаний, социологии, экономике,

биологии, медицине, географии. Широкое применение
находят графы в таких областях, как программирование,
электроника, в решении вероятностных и комбинаторных задач,
нахождения кратчайшего расстояния и др.
Математические головоломки тоже являются частью теории графов.

6.

7.

8.

9.

10.

11.

Представление графов. Матрица инцидентности
Граф:
1-2
1-4
1-6
2-6
2-7
3-5
3-8
4-6
5-8
6-7
1
-1
1
1
-1
1
0
0
0
0
0
0
0
2
1
0
0
1
-1
1
0
0
0
0
0
3
0
0
0
0
0
-1
1
-1
1
0
0
0
Удобно:
4
0
-1
1
0
0
0
0
0
-1
1
0
0
Менять нагрузку на ребра
5
0
0
0
0
0
1
0
0
1
0
Проверять инцидентность
6
0
0
1
-1
1
0
0
0
1
0
-1
1
7
0
0
0
0
1
0
0
0
0
1
8
0
0
0
0
0
0
1
0
-1
1
0
3
1
2
3
1
2
4
5
6
5
4
2
3
1
6
6
7
8
Неудобно:
Добавлять и удалять вершины
Работать с разреженными графами

12.

13.

Матрица
смежности
1
2
3
4
5
1
0
1
0
0
0
2
0
0
0
1
1
3
1
0
0
1
0
4
1
0
1
0
0
5
0
0
0
0
0

14.

Представление графов. Матрица стоимостей
Граф:
3
1
2
3
4
5
6
5
4
2
3
1
2
3
4
5
6
7
8
1
0
3
0
0
0
5
0
0
2
0
0
0
0
0
0
2
0
3
0
0
0
0
1
0
0
4
4
2
0
0
0
0
6
0
0
5
0
0
0
0
0
0
0
0
6
0
3
0
0
0
0
6
0
7
0
0
0
0
0
0
0
0
8
0
0
0
0
1
0
0
0
1
2
1
6
6
7
8
Удобно:
Добавлять и удалять ребра
Проверять смежность вершин
Неудобно:
Добавлять и удалять вершины
Работать с разреженными графами

15.

16.

Представление графов. Списки смежности
Граф:
3
1
2
3
1
2
4
5
6
5
4
2
3
1
6
6
7
8
Удобно:
Искать вершины, смежные с данной
Добавлять ребра и вершины
Работать с разреженными графами
Неудобно:
Проверять наличие ребра
Удалять ребра и вершины
1
2
3
4
5
6
7
8
2
3
6
5
7
2
5
1
8
4
1
2
6
6
2
3
7
6
5
1

17.

18.

Представление графов. Список ребер
Граф:
3
1
2
3
1
2
4
5
6
2
3
5
4
1
6
6
7
8
1 2
3
1 6
5
2 7
2
3 5
1
3 8
4
4 1
2
4 6
6
6 2
3
6 7
6
8 5
6
Удобно:
Добавлять и удалять ребра
Упорядочивать ребра по возрастанию нагрузки
Представлять сильно разреженные графы
Неудобно:
Определять смежность вершин и ребер
Осуществлять перебор инцидентных заданной
вершине ребер

19.

Представление графа в файлах
Должно быть удобно и наглядно для пользователя, поэтому редко
используют матрицы смежности или инцидентности. Обычно бывает
достаточно двух текстовых файлов. В первом из них описываются
вершины, а во втором связи. Например, в простейшем случае для сети
автомобильных дорог текстовый файл может состоять из строк:
1 Йошкар-Ола город
2 Новый поселок
............................
Участки дорог представлены в другом текстовом файле в виде
1 5 20 +
2 7 15 –
.............
Здесь первые два номера определяют населенные пункты, далее
указывается протяженность дороги, а знаки определяют наличие
асфальтового покрытия. Представление в оперативной памяти этой
информации может быть разным.

20.

Матрица достижимости или транзитивное замыкание
матрицы смежности – матрица ,P из нулей и единиц (или true
и false), определяющая существование путей между
вершинами
Количество путей между вершинами Vi и Vj, состоящих ровно из
двух звеньев, определяется выражением
n
(
2
)
a
a a
ij
ik kj
k 1
Приведенное выражение определяет элементы матрицы A2.
Число путей длины не более m между всеми парами вершин:
B (m) = A + A2 + …+Am
Если между вершинами Vi и Vj есть пути, то bi j(n-1) > 0, откуда pi j = 1.

21.

,
Алгоритм Уоршелла построения
транзитивного замыкания
Строится последовательность матриц
P(0) → P(1) → ... → P(k) → ... → P(n)
Здесь P(0) – матрица смежности с элементами true и false, а P(n)
конечная матрица достижимости.
Элемент pi j(k) матрицы P(k) равен 1 или true, если существует путь
из вершины Vi в вершину Vj с номерами промежуточных вершин,
не превосходящими k, и 0 или false в противоположном случае.
Рекуррентное соотношение:
pi j(k+1) = pi j(k) || ( pi k+1(k) && pk+1 j(k) )
Здесь используются логические операции OR и AND.
Действительно, на k+1-м шаге либо такой путь уже был, либо он
обязан проходить через вершину Vk+1.

22.

Рекуррентная формула:
pi j(k+1) = pi j(k) || ( pi k+1(k) && pk+1 j(k) )
{1,2,…,k+1 }
i
j
{1,…,k}
1)
i
{1,…,k}
2)
i
j
pi j(k+1) = 1, если pi j(k) = 1
j
pi j(k+1) = 1, если pi k+1(k) = 1 и pk+1 j(k) = 1
{1,…,k}
K+1

23.

Обход графа в глубину. Рекурсивная процедура
Обход вершин и дуг графа, достижимых
из заданной вершины (v):
2
1
3
4
6
5
1. Пометить вершину (v) как пройденную
2. Цикл по дугам (e), инцидентным вершине
(v)
Если конец дуги не отмечен, то продолжение
обхода из конца дуги - вершины u
7
8
Задачи, которые можно решить с помощью этой процедуры:
1.
Определить вершины, достижимые из заданной;
2.
Обойти все вершины и дуги графа в определенной последовательности («в глубину»);
3.
Определить некоторые характеристики связности графа;
… и многие другие

24.

Program graf;
Исходный массив
1
Var n,v,u: integer;
1 2 3 4
gr: array [1..30, 1..30] of integer;
nov: array [1..15] of boolean;
1 0 0 1 1
4
3
procedure dfs (v: integer);
2 0 0 1 0
var u: integer;
3 1 1 0 0
Begin
Readln;
4 1 0 0 0
2
Write (v,’ ’);
nov [v]:=false;
Результат
For u:=1 to n do
Размерность
if (gr[v,u]=1) and (nov[u]) then dfs (u);
массива
End;
n =4
Begin
n:=4;
end;
For v:=1 to n do
end;
begin
For v:=1 to n do
nov [v]:= true;
if nov [v] then dfs (v);
Writeln;
Readln;
For u:=1 to n do
End.
begin
nov [u]:=true;
Write (‘ gr [‘ ,v,u, ‘ ]=‘);
Read (gr [v,u]);

25.

/Функция поиска в глубину dfs
void Depth_First_Search(int n, int **Graph, bool *Visited, int Node)
{
Visited[Node] = true;
cout << Node + 1 << endl;
for (int i = 0 ; i < n ; i++) if (Graph[Node][i] && !Visited[i])
Depth_First_Search(n,Graph,Visited,i);
}
/

26.

Поиск путей без циклов между двумя заданными вершинами
• Вероятно, является самой распространенной задачей на
графах. Поиск может быть реализован на основе обхода в
глубину.
• Если требуются все пути, вершины могут посещаться
неоднократно. В этом случае пройденные вершины
запрещаются только для текущего пути.
• Исключение из стека происходит в случае тупика либо после
нахождения очередного пути.
Основной недостаток: высокая вычислительная сложность.
Пример: для полного графа из N вершин число только самых
длинных путей из N -1 звена между двумя заданными вершинами
составляет (N - 2)! При N=30 это превышает 1028. Вопрос: при
нахождении 1010 путей в секунду сколько потребуется лет для
счета?

27.

Топологическая сортировка вершин ориентированного графа без циклов.
DAG – Directed Acyclic Graph – ориентированный граф без циклов
1
2
3
4
6
5
7
8
9
Интерпретация: вершины – элементарные работы;
дуги – зависимость работ друг от друга.
Задача: выстроить работы в последовательности, в которой никакая следующая
задача не может зависеть от предыдущей (дуги направлены только вперед)
4
2
7
9
5
1
3
8
6

28.

Топологическая сортировка вершин ориентированного графа без циклов.
3
1
2
2
7
6
1
4
3
6
5
8
4
7
9
8
5
9
«Наивный» алгоритм нумерации вершин:
1.
Находим какую-либо вершину, в которую не входят дуги, нумеруем ее.
2.
Помечаем дуги, выходящие из помеченной вершины, как «не существующие».
3.
Повторяем шаги (1) и (2), пока не будут занумерованы все вершины.
Оценка времени работы алгоритма.
1.
2.
3.
Построение очереди с приоритетами из вершин графа
Выборка вершин из очереди
Коррекция очереди при пометке дуг
Проверка ацикличности графа.
n log n
n log n
m log n
Итого:
(m+2n) log n
Граф содержит цикл, если на шаге (1) не удается найти вершину, в которую не входят дуги.

29.

Топологическая сортировка вершин ориентированного графа без циклов
6
1
2
2
3
5
1
4
7
6
5
3
9
8
7
8
4
9
«Эффективный» алгоритм нумерации вершин:
1.
2.
3.
Производим обход графа с помощью рекурсивной процедуры обхода, начиная
с произвольной вершины.
Нумеруем каждую вершину при «прохождении ее назад» максимальным из номеров
(то есть нумерация происходит в порядке убывания номеров).
Повторяем шаги (1) и (2), пока не останется непройденных вершин.
Оценка времени работы алгоритма = время обхода = (m+n).

30.

Схема обхода в ширину
procedure ОБХОД-В-ШИРИНУ( : вершина);
begin
Поместить начальную вершину в пустую очередь O;
while очередь O не пуста do
Отметить и обработать первую вершину из очереди O;
Поместить в конец все ее смежные неотмеченные вершины;
Продвинуть очередь O;
end
end;

31.

//Описание функции алгоритма поиска в ширину
void Breadth_First_Search(int n, int **Graph, bool *Visited, int Node)
{
int *List = new int[n];
//очередь
int Count, Head;
// указатели очереди
int i;
// начальная инициализация
for (i = 0; i < n ; i++) List[i] = 0;
Count = Head = 0;
// помещение в очередь вершины Node
List[Count++] = Node; Visited[Node] = true;
while ( Head < Count )
{
//взятие вершины из очереди
Node = List[Head++];
cout << Node + 1 << endl;
// просмотр всех вершин, связанных с вершиной
for (i = 0 ; i < n ; i++)
// если вершина ранее не просмотрена
if (Graph[Node][i] && !Visited[i])
{
// заносим ее в очередь
List[Count++] = i; Visited[i] = true;
}
}
}

32.

Поиск кратчайших путей в ненагруженном графе
Граф:
Алгоритм обхода графа с помощью очереди
позволяет построить дерево кратчайших путей
из заданной вершины и вычислить их длины.
2
1
3
1
2
4
n
1
5
3
6
7
8
4
6
5
π
7
8
d
0
2
3
4
5
6
7
8
1
2
1
1
4
5
5
1
2
1
1
2
2
2

33.

Задача:
• Имеется ориентированный граф. Длиной пути считается число
имеющихся в нем звеньев. Заданы две разные вершины
(начало и конец) и целое число L, определяющее макимально
допустимую длину. Требуется построить минимальный граф
путей ограниченной длины из начала в конец, то есть усечь
граф так, чтобы:
• новый граф содержал все пути, соединяющие начало с концом
и имеющие длины, не превышающие макимально допустимую;
• исключение любой вершины или дуги нового графа вело к
нарушению первого условия.
Решение:
1) Поиском в ширину для каждой вершины Vi находятся
минимальные длины ui и vi от начала до Vi и от Vi до конца.
2) В цикле по вершинам: Vi вместе с инцидентными дугами
отсекается, если ui + vi > L.
3) В цикле по дугам: дуга i → j отсекается, если ui + vj +1 > L.

34.

Поиск кратчайших путей в нагруженном графе
Кратчайший путь между двумя вершинами – это путь с минимальным суммарным
весом составляющих этот путь ребер
Кратчайшие пути из вершины (10):
1
2
1
2
10
3
5
3
1
6
4
2
5
3
5
5
4
2
7
3
1
8
4
4
9
V
Длина
Путь через
1
3
2
2
2
3
3
4
6
2, 1
5
4
2
6
4
3
7
8
2, 8 или 3, 6
8
6
2
9
7
2, 8
Кратчайший путь между двумя вершинами существует,
если в графе нет цикла с суммарным отрицательным весом.
Наиболее распространены алгоритмы Дейкстры и Флойда

35. Спасибо за внимание!

English     Русский Rules