Алгоритм Дейкстры — различия между версиями
м |
м |
||
Строка 26: | Строка 26: | ||
'''Сохранение'''. Покажем, что при каждой итерации инвариант сохраняется для каждой вершины, добавленной в <tex>S</tex>, для этого воспользуемся методом «от противного». Предположим, что <tex>u</tex> первая добавленная в <tex>S</tex> вершина, для которой равенство <tex>d[u] = \delta(s, u)</tex> не выполняется. Рассмотрим ситуацию, сложившуюся в начале итерации, в которой <tex>u</tex> будет добавлена в <tex>S</tex>. Рассмотрев кратчайший путь из <tex>s</tex> в <tex>u</tex>, можно получить противоречие, заключающееся в том, что на рассматриваемый момент справедливо равенство <tex>d[u] = \delta(s, u)</tex>. Должно выполняться условие <tex>u \neq s</tex>, так как <tex>s</tex> является первой вершиной, добавленной в <tex>S</tex> и в момент её добавления равенство <tex>d[u] = \delta(s, u)</tex> выполняется. Из условия <tex>u \neq s</tex> следует, в частности, что <tex>S</tex> не пусто. Из вершины <tex>s</tex> в вершину <tex>u</tex> должен существовать какой-нибудь путь, так как иначе выполняется соотношение <tex>d[u] = \delta(s, u) = \infty</tex>, нарушающее предположение о том, что равенство <tex>d[u] = \delta(s, u)</tex> не выполняется. Из существования пути следует, что существует и кратчайший путь <tex>p</tex> из <tex>s</tex> в <tex>u</tex>. Перед добавлением <tex>u</tex> в <tex>S</tex> путь <tex>p</tex> соединяет вершину из множества <tex>S</tex> с вершиной принадлежащей множеству <tex>V \setminus S</tex>. Рассмотрим первую вершину <tex>y</tex> на пути <tex>p</tex> принадлежащую <tex>V \setminus S</tex>, и положим, что её предшествует вершина <tex>x \in S</tex>. Тогда, как видно из рис.1, путь <tex>p</tex> можно разложить на составляющие <tex>s \overset{p_1}{\leadsto} x \to y \overset{p_2}{\leadsto} u</tex>. | '''Сохранение'''. Покажем, что при каждой итерации инвариант сохраняется для каждой вершины, добавленной в <tex>S</tex>, для этого воспользуемся методом «от противного». Предположим, что <tex>u</tex> первая добавленная в <tex>S</tex> вершина, для которой равенство <tex>d[u] = \delta(s, u)</tex> не выполняется. Рассмотрим ситуацию, сложившуюся в начале итерации, в которой <tex>u</tex> будет добавлена в <tex>S</tex>. Рассмотрев кратчайший путь из <tex>s</tex> в <tex>u</tex>, можно получить противоречие, заключающееся в том, что на рассматриваемый момент справедливо равенство <tex>d[u] = \delta(s, u)</tex>. Должно выполняться условие <tex>u \neq s</tex>, так как <tex>s</tex> является первой вершиной, добавленной в <tex>S</tex> и в момент её добавления равенство <tex>d[u] = \delta(s, u)</tex> выполняется. Из условия <tex>u \neq s</tex> следует, в частности, что <tex>S</tex> не пусто. Из вершины <tex>s</tex> в вершину <tex>u</tex> должен существовать какой-нибудь путь, так как иначе выполняется соотношение <tex>d[u] = \delta(s, u) = \infty</tex>, нарушающее предположение о том, что равенство <tex>d[u] = \delta(s, u)</tex> не выполняется. Из существования пути следует, что существует и кратчайший путь <tex>p</tex> из <tex>s</tex> в <tex>u</tex>. Перед добавлением <tex>u</tex> в <tex>S</tex> путь <tex>p</tex> соединяет вершину из множества <tex>S</tex> с вершиной принадлежащей множеству <tex>V \setminus S</tex>. Рассмотрим первую вершину <tex>y</tex> на пути <tex>p</tex> принадлежащую <tex>V \setminus S</tex>, и положим, что её предшествует вершина <tex>x \in S</tex>. Тогда, как видно из рис.1, путь <tex>p</tex> можно разложить на составляющие <tex>s \overset{p_1}{\leadsto} x \to y \overset{p_2}{\leadsto} u</tex>. | ||
− | Утверждается, что в момент добавления вершины <tex>u</tex> в множество <tex>S</tex>, выполняется равенство <tex>d[u] = \delta(s, y)</tex>. Так как вершина <tex>u</tex> выбрана как первая вершина, после добавления которой в множество <tex>S</tex> не выполянется соотношение <tex>d[u] = \delta(s, u)</tex>, то после добавления вершины <tex>x</tex> в <tex>S</tex> справедливо равенство <tex>d[x] = \delta(s, x) | + | Утверждается, что в момент добавления вершины <tex>u</tex> в множество <tex>S</tex>, выполняется равенство <tex>d[u] = \delta(s, y)</tex>. Так как вершина <tex>u</tex> выбрана как первая вершина, после добавления которой в множество <tex>S</tex> не выполянется соотношение <tex>d[u] = \delta(s, u)</tex>, то после добавления вершины <tex>x</tex> в <tex>S</tex> справедливо равенство <tex>d[x] = \delta(s, x)</tex>. В это время происходит релаксация ребра <tex>xy</tex>, поэтому вышеописанное утверждение выполняется. |
Поскольку на кратчайшем пути из <tex>s</tex> в <tex>u</tex> вершина <tex>y</tex> находиться перед <tex>u</tex> и вес каждого из ребер выражается неотрицательным значением, выполняется неравенство <tex>\delta(s, y) \leqslant \delta(s, u)</tex>, поэтому <tex>d[y] = \delta(s, y) \leqslant \delta(s, u) \leqslant d[u]</tex>. Но так как и вершина <tex>u</tex>, и вершина <tex>y</tex> во время выбора вершины <tex>u</tex> находились в множестве <tex>V \setminus S</tex>, выполняется неравенство <tex>d[u] \leqslant d[y]</tex>. Таким образом, оба <tex>d[y] = \delta(s, y) = \delta(s, u) = d[u]</tex>. | Поскольку на кратчайшем пути из <tex>s</tex> в <tex>u</tex> вершина <tex>y</tex> находиться перед <tex>u</tex> и вес каждого из ребер выражается неотрицательным значением, выполняется неравенство <tex>\delta(s, y) \leqslant \delta(s, u)</tex>, поэтому <tex>d[y] = \delta(s, y) \leqslant \delta(s, u) \leqslant d[u]</tex>. Но так как и вершина <tex>u</tex>, и вершина <tex>y</tex> во время выбора вершины <tex>u</tex> находились в множестве <tex>V \setminus S</tex>, выполняется неравенство <tex>d[u] \leqslant d[y]</tex>. Таким образом, оба <tex>d[y] = \delta(s, y) = \delta(s, u) = d[u]</tex>. |
Версия 23:39, 12 декабря 2010
В ориентированном взвешанном графе
, вес рёбер которого неотрицателен и определяется весовой функцией , Алгоритм Дейкстры находит длину кратчайшего пути из одной вершины до всех остальных.Алгоритм
В алгоритме поддерживается множество вершин
, для которых уже вычислены кратчайшие пути к ним из вершины . На каждой итерации основного цикла выбирается вершина , которой на текущий момент соответствует минимальная оценка кратчайшего пути. Вершина добавляется в множество и производится релаксация всех исходящих из неё рёбер.Псевдокод
Dijkstra(, , ) while do argmin( ) for do relax( , , )
Обоснование корректности работы
Теорема: |
После окончания работы алгоритма Дейкстры для всех вершин будет выполняться равенство |
Доказательство: |
Рассмотрим инвариант основного цикла: в начале каждой итерации для всех вершин выполняетсяИнициализация. Изначально множество пусто, инвариант выполняется.Сохранение. Покажем, что при каждой итерации инвариант сохраняется для каждой вершины, добавленной в , для этого воспользуемся методом «от противного». Предположим, что первая добавленная в вершина, для которой равенство не выполняется. Рассмотрим ситуацию, сложившуюся в начале итерации, в которой будет добавлена в . Рассмотрев кратчайший путь из в , можно получить противоречие, заключающееся в том, что на рассматриваемый момент справедливо равенство . Должно выполняться условие , так как является первой вершиной, добавленной в и в момент её добавления равенство выполняется. Из условия следует, в частности, что не пусто. Из вершины в вершину должен существовать какой-нибудь путь, так как иначе выполняется соотношение , нарушающее предположение о том, что равенство не выполняется. Из существования пути следует, что существует и кратчайший путь из в . Перед добавлением в путь соединяет вершину из множества с вершиной принадлежащей множеству . Рассмотрим первую вершину на пути принадлежащую , и положим, что её предшествует вершина . Тогда, как видно из рис.1, путь можно разложить на составляющие .Утверждается, что в момент добавления вершины в множество , выполняется равенство . Так как вершина выбрана как первая вершина, после добавления которой в множество не выполянется соотношение , то после добавления вершины в справедливо равенство . В это время происходит релаксация ребра , поэтому вышеописанное утверждение выполняется.Поскольку на кратчайшем пути из в вершина находиться перед и вес каждого из ребер выражается неотрицательным значением, выполняется неравенство , поэтому . Но так как и вершина , и вершина во время выбора вершины находились в множестве , выполняется неравенство . Таким образом, оба .Значит, Завершение. По завершении работы алгоритма множество , что противоречит нашему выбору вершины . Следовательно, во время добавления вершины в множество выполняется равенство , а следовательно, оно выполняется и в дальнейшем. пусто. Из этого равенства следует, что . Таким образом, для всех вершин выполняется равенство . |
Оценка сложности
Основной цикл выполняется
раз. Релаксация выполниться всего раз. В реализации алгоритма присутствует функция argmin, асимптотика её работы зависит от реализации.Таким образом:
Структура данных для хранения множества | Асимптотика времени работы |
---|---|
Наивная реализация | |
Куча | |
Куча Фибоначчи |
Литература
- Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд Алгоритмы: построение и анализ, 2-е издание. Пер. с англ. — М.:Издательский дом "Вильямс", 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)