Кратчайший путь в ациклическом графе — различия между версиями
IRomchig (обсуждение | вклад) |
|||
| Строка 1: | Строка 1: | ||
| − | {{Определение|definition= '''Кратчайший путь''' из '''u''' в '''v''' – это | + | ==Формулировка задачи== |
| − | + | Пусть дан ациклический взвешенный граф. Требуется найти вес кратчайшего пути из '''u''' в '''v''' | |
| − | *<tex> | + | {{Определение|definition= '''Кратчайший путь''' из '''u''' в '''v''' – это такой путь из '''u '''в '''v''', что его вес меньше или равен веса любого другого пути из '''u''' в '''v'''}} |
| + | ==Решение== | ||
| + | Пусть d — матрица, где d[i] — вес кратчайшего пути из '''u''' в '''i'''. Изначально значения d равны бесконечности, кроме d[u], который равен 0. Пусть w[i][j] - вес ребра из '''i''' в '''j'''. Будем обходить граф в порядке топологической сортировки. Получаем следующие соотношения: <br /> | ||
| + | * <tex> d[i] = \min\limits_{\mathop{j:j \rightsquigarrow i}} (d[j] + w[j][i]) </tex> | ||
| − | + | Так как мы обходим граф в порядке топологической сортировки, то на i-ом шаге во всех d[j] (j такие, что: /exist ребро из j в i) уже записаны оптимальные ответы, и следовательно в d[i] так же будет записан оптимальный ответ. | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | == == | + | ==Реализация== |
| + | Реализуем данный алгоритм методом "динамика вперед": | ||
| + | //d, w - матрицы как в описании, p - матрица индексов вершин графа в порядке топологической сортировки, i, j - счетчики <br /> | ||
| + | inputData() //считывание данных <br /> | ||
| + | for i = 1 to n | ||
| + | d[i] = infinity <br /> | ||
| + | topSort() //топологическая сортировка <br /> | ||
| + | d[p[u]] = 0 <br /> | ||
| + | for i = 1 to n | ||
| + | for j: /exist p[i] \rightsquigarrow j | ||
| + | d[j] = min(d[j], d[p[i]] + w[p[i]][j]) <br /> | ||
| + | writeData(); // запись данных | ||
| − | + | ==Пример== | |
| − | + | Пусть дан граф со следующими весами '''w''' ребер: <br /> | |
| − | + | {| class="wikitable" cellpadding="4" border="1" style="border-collapse: collapse;" | |
| − | + | |- | |
| + | | || '''1''' || '''2''' || '''3''' || '''4''' | ||
| + | |- | ||
| + | | '''1''' || 0 || 1 || 1 || 4 | ||
| + | |- | ||
| + | | '''2''' || - || 0 || - || 2 | ||
| + | |- | ||
| + | | '''3''' || - || - || 0 || 1 | ||
| + | |- | ||
| + | | '''4''' || - || - || - || 0 | ||
| + | |} | ||
| + | Требуется найти путь из '''1''' в '''4'''. матрица d будет выглядеть следующим образом: <br /> | ||
| + | {| class="wikitable" cellpadding="4" border="1" style="border-collapse: collapse;" | ||
| + | |- | ||
| + | | '''1''' || '''2''' || '''3''' || '''4''' | ||
| + | |- | ||
| + | | 0 || 1 || 1 || 2 | ||
| + | |} | ||
| + | Ответ будет равен 2. | ||
| + | ==Источники== | ||
| + | * [http://ru.wikipedia.org/wiki/Динамическое_программирование Википедия] | ||
[[Категория: Динамическое программирование ]] | [[Категория: Динамическое программирование ]] | ||
Версия 09:45, 28 ноября 2011
Формулировка задачи
Пусть дан ациклический взвешенный граф. Требуется найти вес кратчайшего пути из u в v
| Определение: |
| Кратчайший путь из u в v – это такой путь из u в v, что его вес меньше или равен веса любого другого пути из u в v |
Решение
Пусть d — матрица, где d[i] — вес кратчайшего пути из u в i. Изначально значения d равны бесконечности, кроме d[u], который равен 0. Пусть w[i][j] - вес ребра из i в j. Будем обходить граф в порядке топологической сортировки. Получаем следующие соотношения:
Так как мы обходим граф в порядке топологической сортировки, то на i-ом шаге во всех d[j] (j такие, что: /exist ребро из j в i) уже записаны оптимальные ответы, и следовательно в d[i] так же будет записан оптимальный ответ.
Реализация
Реализуем данный алгоритм методом "динамика вперед":
//d, w - матрицы как в описании, p - матрица индексов вершин графа в порядке топологической сортировки, i, j - счетчики
inputData() //считывание данных
for i = 1 to n d[i] = infinity
topSort() //топологическая сортировка
d[p[u]] = 0
for i = 1 to n for j: /exist p[i] \rightsquigarrow j d[j] = min(d[j], d[p[i]] + w[p[i]][j])
writeData(); // запись данных
Пример
Пусть дан граф со следующими весами w ребер:
| 1 | 2 | 3 | 4 | |
| 1 | 0 | 1 | 1 | 4 |
| 2 | - | 0 | - | 2 |
| 3 | - | - | 0 | 1 |
| 4 | - | - | - | 0 |
Требуется найти путь из 1 в 4. матрица d будет выглядеть следующим образом:
| 1 | 2 | 3 | 4 |
| 0 | 1 | 1 | 2 |
Ответ будет равен 2.