Кратчайший путь в ациклическом графе — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Решение)
Строка 2: Строка 2:
 
{{Определение|definition= '''Кратчайший путь''' из '''u''' в '''v''' – это такой путь из '''u '''в '''v''', что его суммарный вес входящих в него ребер минимален}}
 
{{Определение|definition= '''Кратчайший путь''' из '''u''' в '''v''' – это такой путь из '''u '''в '''v''', что его суммарный вес входящих в него ребер минимален}}
 
==Решение==
 
==Решение==
Пусть <tex>d</tex> — функция, где <tex>d(i)</tex> — вес кратчайшего пути из <tex>u</tex> в <tex>i</tex>. Ясно, что <tex>d(u)</tex> равен 0. Пусть <tex>w(i, j)</tex> - вес ребра из <tex>i</tex> в <tex>j</tex>. Будем обходить граф в порядке [[Использование_обхода_в_глубину_для_топологической_сортировки | топологической сортировки]]. Получаем следующие соотношения: <br />
+
Пусть <tex>d</tex> — функция, где <tex>d(i)</tex> — вес кратчайшего пути из <tex>u</tex> в <tex>i</tex>. Ясно, что <tex>d(u)</tex> равен <tex>0</tex>. Пусть <tex>w(i, j)</tex> - вес ребра из <tex>i</tex> в <tex>j</tex>. Будем обходить граф в порядке [[Использование_обхода_в_глубину_для_топологической_сортировки | топологической сортировки]]. Получаем следующие соотношения: <br />
 
: <tex> d(i) = \min\limits_{\mathop{j:j \rightsquigarrow i}} (d(j) + w(j, i)) </tex>
 
: <tex> d(i) = \min\limits_{\mathop{j:j \rightsquigarrow i}} (d(j) + w(j, i)) </tex>
  
Так как мы обходим граф в порядке топологической сортировки, то на <tex>i</tex>-ом шаге всем <tex>d(j)</tex> (<tex>j</tex> такие, что существует ребро из <tex>j</tex> в <tex>i</tex>) уже присвоены оптимальные ответы, и, следовательно, <tex>d(i)</tex> также будет присвоен оптимальный ответ.
+
Так как мы обходим граф в порядке [[Использование_обхода_в_глубину_для_топологической_сортировки |топологической сортировки]], то на <tex>i</tex>-ом шаге всем <tex>d(j)</tex> (<tex>j</tex> такие, что существует ребро из <tex>j</tex> в <tex>i</tex>) уже присвоены оптимальные ответы, и, следовательно, <tex>d(i)</tex> также будет присвоен оптимальный ответ.
  
 
==Реализация==
 
==Реализация==
 
Реализуем данный алгоритм:
 
Реализуем данный алгоритм:
   //w - матрицы как в описании, d - массив как в описании, p - массив индексов вершин графа в порядке топологической сортировки, i, j - счетчики <br />
+
   <font color=green>//w {{---}} матрица смежности</font>
  inputData() //считывание данных <br />
+
  <font color=green>//d {{---}} массив кратчайших расстояний</font>
   for i = 1 to n
+
  <font color=green>//p {{---}} массив индексов вершин графа в порядке топологической сортировки</font>
     d[i] = infinity <br />
+
   '''for''' i = 1 .. n
   p = topSort(w) //топологическая сортировка графа <br />
+
     d[i] = '''infinity'''
  d[u] = 0 <br />
+
  d[u] = 0 <font color=green>// где u {{---}} начальная вершина</font><br />
   for i = 1 to n
+
   p = topSort(w) <font color=green>//топологическая сортировка графа</font>
     for j: есть ребро из p[i] в j
+
   '''for''' i = 1 .. n
 +
     '''for''' j: есть ребро из p[i] в j
 
       d[j] = min(d[j], d[p[i]] + w[p[i]][j]) <br />
 
       d[j] = min(d[j], d[p[i]] + w[p[i]][j]) <br />
  writeData(); // запись данных
 
  
 
==Пример==
 
==Пример==
[[Файл:Index1.jpg|thumb|right|180px|граф из примера]]
+
[[Файл:WayAcyclicGraph.png|thumb|right|500px|Граф из примера]]
Пусть дан граф со следующими весами '''w''' ребер: <br />
+
Пусть дана матрица смежности графа '''w''' со следующими весами ребер: <br />
 
{| class="wikitable" cellpadding="4" border="1" style="border-collapse: collapse;"
 
{| class="wikitable" cellpadding="4" border="1" style="border-collapse: collapse;"
 
|-
 
|-
Строка 61: Строка 61:
 
Ответ равен 5.
 
Ответ равен 5.
  
==Источники==
+
==Альтернативный способ решения==
 +
Задачу так же можно решить [[Обход_в_ширину |поиском в ширину]]. Для этого будем поддерживать массив кратчайший расстояний от начальной до текущей вершины. Обходя граф, будем для каждой вершины обновлять ответы у ее сыновей как минимум из старого значения и пути, проходящего через текущую вершину.
 +
 
 +
В силу особенности обхода графа, когда происходит обновление сыновей вершины, для нее самой уже найден оптимальный ответ.
 +
 
 +
==Смотри также==
 +
*[[Обход_в_ширину | Обход в ширину]]
 +
*[[Алгоритм_Флойда_—_Уоршалла |Алгоритм Флойда—Уоршалла]]
 +
*[[Алгоритм_Дейкстры |Алгоритм Дейкстры]]
 +
*[[Алгоритм_Форда-Беллмана |Алгоритм Форда-Беллмана]]
 +
 
 +
==Источники информации==
 
*[http://www.ics.uci.edu/~eppstein/161/960208.html Алгоритмы поиска кратчайшего пути в графе]
 
*[http://www.ics.uci.edu/~eppstein/161/960208.html Алгоритмы поиска кратчайшего пути в графе]
 
*[[Динамическое_программирование#.D0.9F.D1.80.D0.B8.D0.BD.D1.86.D0.B8.D0.BF_.D0.BE.D0.BF.D1.82.D0.B8.D0.BC.D0.B0.D0.BB.D1.8C.D0.BD.D0.BE.D1.81.D1.82.D0.B8_.D0.BD.D0.B0_.D0.BF.D1.80.D0.B5.D1.84.D0.B8.D0.BA.D1.81.D0.B5|Принцип оптимальности на префиксе]]
 
*[[Динамическое_программирование#.D0.9F.D1.80.D0.B8.D0.BD.D1.86.D0.B8.D0.BF_.D0.BE.D0.BF.D1.82.D0.B8.D0.BC.D0.B0.D0.BB.D1.8C.D0.BD.D0.BE.D1.81.D1.82.D0.B8_.D0.BD.D0.B0_.D0.BF.D1.80.D0.B5.D1.84.D0.B8.D0.BA.D1.81.D0.B5|Принцип оптимальности на префиксе]]

Версия 17:11, 14 декабря 2014

Пусть дан ациклический ориентированный взвешенный граф. Требуется найти вес кратчайшего пути из u в v

Определение:
Кратчайший путь из u в v – это такой путь из u в v, что его суммарный вес входящих в него ребер минимален

Решение

Пусть [math]d[/math] — функция, где [math]d(i)[/math] — вес кратчайшего пути из [math]u[/math] в [math]i[/math]. Ясно, что [math]d(u)[/math] равен [math]0[/math]. Пусть [math]w(i, j)[/math] - вес ребра из [math]i[/math] в [math]j[/math]. Будем обходить граф в порядке топологической сортировки. Получаем следующие соотношения:

[math] d(i) = \min\limits_{\mathop{j:j \rightsquigarrow i}} (d(j) + w(j, i)) [/math]

Так как мы обходим граф в порядке топологической сортировки, то на [math]i[/math]-ом шаге всем [math]d(j)[/math] ([math]j[/math] такие, что существует ребро из [math]j[/math] в [math]i[/math]) уже присвоены оптимальные ответы, и, следовательно, [math]d(i)[/math] также будет присвоен оптимальный ответ.

Реализация

Реализуем данный алгоритм:

 //w — матрица смежности
 //d — массив кратчайших расстояний 
 //p — массив индексов вершин графа в порядке топологической сортировки
 for i = 1 .. n
   d[i] = infinity
 d[u] = 0 // где u — начальная вершина
p = topSort(w) //топологическая сортировка графа for i = 1 .. n for j: есть ребро из p[i] в j d[j] = min(d[j], d[p[i]] + w[p[i]][j])

Пример

Граф из примера

Пусть дана матрица смежности графа w со следующими весами ребер:

1 2 3 4 5 6 7 8
1 - - - 5 - - - -
2 1 - 1 - 4 3 - -
3 - - - - - 1 - -
4 - - - - - - - -
5 - - - 3 - - - 1
6 - - - 5 - - 2 -
7 - - - 2 - - - -
8 - - - 1 - - - -

Требуется найти путь из 2 в 4.
Массив p будет выглядеть следующим образом:

1 2 3 4 5 6 7 8
2 3 6 7 1 5 8 4

Массив d будет выглядеть следующим образом:

1 2 3 4 5 6 7 8
1 0 1 5 3 2 4 4

Ответ равен 5.

Альтернативный способ решения

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

В силу особенности обхода графа, когда происходит обновление сыновей вершины, для нее самой уже найден оптимальный ответ.

Смотри также

Источники информации