Кратчайший путь в ациклическом графе — различия между версиями
(→Решение) |
Roman (обсуждение | вклад) |
||
Строка 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 - | + | <font color=green>//w {{---}} матрица смежности</font> |
− | + | <font color=green>//d {{---}} массив кратчайших расстояний</font> | |
− | for i = 1 | + | <font color=green>//p {{---}} массив индексов вершин графа в порядке топологической сортировки</font> |
− | d[i] = infinity <br /> | + | '''for''' i = 1 .. n |
− | p = topSort(w) //топологическая сортировка графа < | + | d[i] = '''infinity''' |
− | + | d[u] = 0 <font color=green>// где u {{---}} начальная вершина</font><br /> | |
− | for i = 1 | + | 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 /> | ||
− | |||
==Пример== | ==Пример== | ||
− | [[Файл: | + | [[Файл:WayAcyclicGraph.png|thumb|right|500px|Граф из примера]] |
− | Пусть | + | Пусть дана матрица смежности графа '''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, что его суммарный вес входящих в него ребер минимален |
Содержание
Решение
Пусть топологической сортировки. Получаем следующие соотношения:
Так как мы обходим граф в порядке топологической сортировки, то на -ом шаге всем ( такие, что существует ребро из в ) уже присвоены оптимальные ответы, и, следовательно, также будет присвоен оптимальный ответ.
Реализация
Реализуем данный алгоритм:
//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.
Альтернативный способ решения
Задачу так же можно решить поиском в ширину. Для этого будем поддерживать массив кратчайший расстояний от начальной до текущей вершины. Обходя граф, будем для каждой вершины обновлять ответы у ее сыновей как минимум из старого значения и пути, проходящего через текущую вершину.
В силу особенности обхода графа, когда происходит обновление сыновей вершины, для нее самой уже найден оптимальный ответ.