Как найти кратчайшее расстояние между городами

Расстояние между городами

Примеры расчета расстояний:

  • Расстояние от Москвы до Киева

  • Расстояние от Москвы до Питера

  • Расстояние от Москвы до Нижнего Новгорода

  • Расстояние от Москвы до Ярославля

  • Расстояние от Москвы до Владивостока

  • Расстояние от Москвы до Минска

  • Расстояние от Москвы до Твери

  • Расстояние от Москвы до Тулы

  • Расстояние от Москвы до Казани

  • Маршрут Воронеж – Москва

  • Маршрут Екатеринбург – Москва

  • Маршрут Ростов-на-Дону – Москва

  • Маршрут Рязань – Москва

  • Маршрут Кострома – Москва

  • Маршрут Владимир – Москва

  • Маршрут Смоленск – Москва

  • Маршрут Самара – Москва

  • Маршрут Калуга – Москва

Когда может пригодиться расчет расстояний?

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

  • Сервис расчета расстояний помогает проложить маршрут автопутешественнику, например, для летнего отдыха с семьей
    или при планировании деловой поездки на автомобиле.
    Зная расход бензина и среднюю цену за литр топлива, нетрудно рассчитать обязательные финансовые затраты в поездке.
  • Водителю-дальнобойщику расчет расстояния между городами позволяет проложить маршрут на карте при
    подготовке к дальнему рейсу.
  • Калькулятор расстояний пригодится грузоотправителю, чтобы определить километраж и в соответствии
    с тарифами транспортной компании оценить стоимость грузоперевозки.

Как пользоваться расчетом расстояний?

Для того чтобы рассчитать маршрут между городами,
начните вводить в поле “Откуда” название начального пункта маршрута.
Из выпадающей контекстной подсказки выберите нужный город.
По аналогии заполните поле “Куда” и нажмите кнопку “рассчитать”.

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

Полученный маршрут можно распечатать или, изменив некоторые параметры, повторить расчет.
В дополнительных настройках можно задать транзитные населенные пункты, а также скорректировать расчетную скорость
движения по дорогам каждого типа.
Ниже дополнительных настроек расположены поля ввода данных топливного калькулятора.
Внесите в них актуальный расход горючего вашей машины и среднюю цену 1 литра топлива.
При повторном расчете эти данные будут использованы для подсчета необходимого количества топлива и его стоимости.

Другие методы прокладки маршрута

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

Если курвиметра нет под рукой, то можно воспользоваться линейкой.
Приложите нулевую отметку линейки к начальному пункту маршрута и двигайте линейку, плотно примыкая ее к извилинам
дороги.

Рассчитать расстояние между городами также можно с помощью таблиц, которые опубликованы в атласах и
справочниках.
Это достаточно удобно для маршрутов, начинающихся и заканчивающихся в крупных городах.
Мелких населенных пунктов, как правило, нет в таблицах.

Алгоритм расчета расстояния между городами

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

Смотрите также:

Существует несколько подходов к определению расстояния между городами:

  • расстояние по автодорогам включает в себя длину автотрассы и соединяющих ее с городом дорог;
  • расстояние по прямой, или как его еще называют “по птичьему полету“, характеризуется меньшей протяженностью, но практически менее ценно, т.к. перемещение обычно происходит по дорогам.

В наших расчетах расстояния между городами берутся по автодорогам.

Расчет расстояний между городами — проложить маршрут на автомобиле

https://www.avtodispetcher.ru/distance/

Как рассчитываются расстояния между городами

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

Расчет сможет пригодиться в таких ситуациях:

  • планирование частной поездки в отпуск всем семейством на автомобиле или же определение оптимального варианта маршрута деловой поездки в командировку. Калькулятор поможет посчитать расходы на топливо в пути (нам известен средний расход горючего и его цена);
  • профессиональным водителям дальнего следования поможет проложить маршрут между городами;
  • опции калькулятора полезны отправителям грузов при определении стоимости услуг перевозки (километраж определяет калькулятор, тарифы дает перевозчик);

Как воспользоваться калькулятором по расчету расстояний?

Маршрут между городами задать и проложить не составит большого труда. Для этого потребуется ввести начальный пункт по маршруту в поле «Откуда». Создан удобный способ выбора городов. Аналогичным образом заполняется поле прибытия по заданному маршруту. После выбора городов нажимается кнопка по расчету.

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

  • расчетная длина маршрута;
  • время нахождения в пути;
  • сколько потребуется топлива на поездку.

Далее приводятся уточняющие данные в виде таблицы с такими параметрами:

  • какой тип дорог по маршруту движения;
  • маршрут разбит на отдельные участки с указанием длины и времени в пути.

Эти данные о маршруте можно вывести на печать и получить в удобном формате А4. При необходимости можно внести корректировки в расчет. Задайте нужные для поездки параметры и повторно запросите сделать расчет.

Дополнительные настройки дают возможность внести корректировки по расчету скорости для каждого типа дорожного покрытия. Существует опция по выбору транзитных населенных пунктов.

Очень полезным окажется топливный калькулятор. Подставляете в него параметры автомобиля (средний расход топлива) и действующие усредненные цены на 1 литр горючего. Это позволит узнать требуемое количество горючего и его стоимость.

Альтернативные методы прокладывания маршрутов

Если у вас есть под рукой атлас автодорог, то тогда можно с его помощью приблизительно определиться с маршрутом на карте. Курвиметр, если таковой имеется, поможет определить довольно приблизительно расстояние между городами.

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

На помощь могут прийти и данные из справочников, атласов о расстояниях между городами. Учтите, что в таких таблицах указаны, как правило, большие города.

Алгоритмы по расчету расстояний между городами

В основу расчетов маршрутов положен алгоритм на поиск пути по кратчайшему принципу. Расстояния между городами на автомобиле определяются на основании привязки спутником координат населенных пунктов и дорог. В результате про считывания на компьютере всех данных выдается результат как вариант моделирования. Не поленитесь при планировании дальней поездки позаботиться о резервных вариантах своих возможностей.

На практике существуют две основные методики подсчета расстояний между населенными пунктами:

  • исключительно по имеющимся автодорогам с учетом подъездов;
  • по прямой линии (как птица летит – прямо и свободно). Расстояние получается меньше, но на практике не имеет практического значения – дороги по такому маршруту отсутствуют.

Наша программа использует для расчетов расстояния между городами по автомобильным артериям, дорогам.

Конечно, возможно. Исходим из того, что длина меридиана 20 004 км, он делится на 180 градусов. Следовательно, в одном градусе широты 111,16 км. С долготой несколько сложнее. Экватор несколько длиннее меридиана, поэтому на экваторе 1 градус соответствует 111,3 км, а на произвольной параллели эту величину нужно умножить на косинус широты.

Т.о. алгоритм следующий:

  1. Находим меридианальное расстояние между двумя точками, умножив разницу в широте в градусах на 111,16 км, А.
  2. Находим расстояние по параллели точки с меньшей широтой, умножив разность долгот в градусах на 111,3 км и косинус точки с меньшей широтой, B.
  3. Находим искомое расстояние по теореме Пифагора в варианте для сферической поверхности как (C/R)^2 =(A/R)^2+(B/R)^2, где R = 6400 км – радиус Земли.

В качестве примера возьмем координаты Москвы 55° 45′ с.ш. 37° 37′ в.д.

Саратова – 51° 33′ с.ш. 46° 0′ в.д.

A = 4,2 гр х 111,16 км = 466,87 км

B = 8,38 гр х cos (51,55 гр) х 111,3 км = 579,98 км

С = 744,54 км.

Расстояние по автодороге – 860 км.

Графы дорожных сетей и алгоритмы работы с ними

Время на прочтение
7 мин

Количество просмотров 38K

В математике сети дорог (автомобильных и не только) представляются взвешенным графом. Населенные пункты (или перекрестки) — это вершины графа, ребра — дороги, веса ребер — расстояния по этим дорогам.

Для взвешенных графов предлагается множество алгоритмов. Например, популярный алгоритм Дейкстры для поиска кратчайшего пути от одной вершины до другой. У всех этих алгоритмов есть общая принципиальная (для математики) особенность — они универсальны, т.е. могут успешно применяться для графов любой конструкции. В частности, для каждого алгоритма известна его сложность – она примерно соответствует увеличению времени выполнения алгоритма в зависимости от числа вершин графа. Все это подробно можно прочитать, например, в википедии.

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

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

Несколько важных понятий и условностей

1. Мы будем использовать взвешенные неориентированные графы с неотрицательными весами ребер. В частности, дороги в рамках региона (страны) представляют собой именно такой граф.

2. Матрица кратчайших расстояний (МКР) – ее маленький и простой пример можно найти во многих дорожных атласах. Эта табличка обычно называется примерно так: «расстояния между наиболее важными городами». Она выглядит как часть матрицы ниже или выше главной диагонали (из верхнего левого в нижний правый угол), потому что с другой стороны главной диагонали точно такие же цифры, другими словами элемент М(i,j)= М(j,i). Это происходит, потому что граф, как говорят математики, неориентированный. Строки и столбцы соответствуют городам (вершинам графа). В реальности такая таблица намного больше, так как в вершины графа, кроме городов, входят все деревни и перекрестки, но напечатать такую большую таблицу в атласе, естественно, невозможно.

Первым делом продолжим (мысленно) нашу таблицу на верхнюю часть, получим МКР, симметричную относительно главной диагонали и далее будем иметь в виду именно такую таблицу. В этом случае, столбец с некоторым номером равен строке с таким же номером и все равно, какое из понятий использовать. Мы используем и то, и другое, чтобы их пересекать между собой.

Наша МКР может быть: а) известна заранее, потому что мы ее подсчитали одним из методов поиска МКР; б) мы можем не знать МКР, а определять ее построчно по мере необходимости. Построчно – это значит, что для требуемой строки рассчитываются расстояния только от соответствующей ей вершины до остальных вершин, например, методом Дейкстры.

3. Еще пара понятий. Эксцентриситет данной вершины – это расстояние от этой вершины до самой удаленной от нее. Радиус графа – это наименьший из эксцентриситетов всех вершин. Центр графа – вершина, эксцентриситет которой равен радиусу.

Как это выглядит на практике. Центр дорожной сети – это город или перекресток, наименее удаленный от всех остальных пунктов этой сети. Радиус – максимальное расстояние от этого центрального узла до самого удаленного.

4. Степень вершины – количество ребер, которое присоединено к вершине.
У графов дорожных сетей, средняя степень всех вершин находится в районе от 2 до 4. Это вполне естественно – сложно и дорого строить перекрестки с большим количеством примыкающих дорог, не менее сложно потом пользоваться такой дорожной сетью. Графы, с невысокой средней степенью вершин называются разреженными, как видим, графы дорожных сетей именно такие.

Задача 1. Поиск радиус и центра графа по матрице кратчайших расстояний

Заметим, что у графа может быть несколько центров, но мы хотим найти любой из них.

Как задача решается в общем случае? Полным просмотром МКР. Ищется максимальный элемент в строке (эксцентриситет каждой вершины), а потом из этих максимальных элементов находится минимальный.

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

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

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

Допустим, мы нашли значения всего лишь в двух строках А и В. При этом, максимальное значение в строке А равно минимальному значению в строке В (эта величина будет стоять на пересечении столбца А и строки В). Несложно доказать, что А – центр графа, а найденное значение – его радиус. Задача решена.

Здорово, но такая ситуация на графах дорожных сетей маловероятна и решать задачу таким образом не получится. Поступим хитрее.
Возьмем пару строк В1 и В2. Из них сформируем вектор М таким образом: М(i)=max[B1(i),B2(i)]. Несложно доказать, что если для всех строк i значение min(M(i)) равно максимальному значению в столбце А, то, опять таки, А – центр, а найденное min(M(i)) – радиус.
Если пары строк окажется недостаточно, можно взять несколько строк, например три: B1, B2 и B3, тогда М(i)=max[B1(i),B2(i),B3(i)]. Особенность графов дорожных сетей состоит в том, что много строк не понадобится (удастся уложиться в десяток). Это легко проверить, поэкспериментировав на существующих графах сетей, скачав их из интернета: ссылка.

В общем случае и с точки зрения математики это, конечно, не так. Вполне можно построить теоретический граф в котором придется использовать очень много строк В (почти все, кроме, А). Вот только невозможно построить реальную дорожную сеть такого вида — денег не хватит.

Осталась последняя задача. Как быстро найти эти удачные строки B1, B2 и т.д. Для графов реальных дорожных сетей это сделать очень просто и быстро. Это будут максимально удаленные друг от друга вершины, но не обязательно самые удаленные (говоря математически, находить диаметр графа нам не требуется). Берем любую вершину, находим для нее самую дальнюю, для новой опять самую дальнюю и так, пока пара вершин не окажется самой дальней друг для друга.

Мы получили пару вершин В1 и В2. Находим для пары вектор М, как описано выше. Строка, в которой мы нашли min(M(i)) — претендент на центр, обозначим его А. Если в столбце А значение min(M(i)) – максимальное, то уже найдены центр и радиус. Если же нет, значит максимальное значение в столбце А соответствует расстоянию до другой вершины (не B1 и не B2). Значит, мы получили новую вершину B3 в список на поиск вектора М. Как вариант, можно и для B3 поискать самую удаленную вершину и если она не В1 и не B2, добавить ее как В4. Таким образом, увеличиваем список вершин B, пока центр и радиус не будут найдены.

Более строго, с алгоритмом и нужными доказательствами этот алгоритм описан в , там же приведены результаты его использования на некоторых графах дорожных сетей США, а в ссылка и ссылка он описан менее академически, но более понятно.

Задача 2. Поиск матрицы кратчайших расстояний

Наиболее популярные алгоритмы поиска МКР (Флойда-Уоршелла, например) описаны здесь . Все они универсальные, причем один из них – алгоритм Дейкстры с двоичной кучей – учитывает такое понятие как разреженный граф. Однако он тоже не использует особенности дорожных сетей.

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

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

Начнем с простого, с вершины со степенью 1. Ее можно удалить в любом случае. Через нее не проходит никаких кратчайших путей, кроме путей к самой вершине, причем идут они именно через ту вершину, к которой была присоединена удаляемая вершина.

Пусть А – вершина со степенью 2 и присоединена она в вершинам В1 и В2. Если маршрут В1-А-В2 длиннее или равен ребру В1-В2, через точку А не проходит никаких маршрутов, кроме маршрутов к самой точке А (все остальные проходят через В1-В2). Значит, точку А можно удалить. В ином случае, т.е. если В1-А-В2 короче В1-В2 или ребра В1-В2 вообще нет, вершину А можно удалить, установив вес ребра В1-В2 равным сумме весов: |В1-А|+|А-В2|. Маршрут от А до других точек проходит либо через В1, либо через В2, если будут известны расстояния для В1 и В2, расстояния от А так же легко вычислить.

По такому же принципу можно удалить вершину с любой степенью, заменяя, по мере необходимости, Вi-А-Вj на Bi-Bj. Правда, нужно понимать, что чем больше степень вершины, тем больше возможных ребер надо проверить. Для вершины степени n это число равно n(n-1)/2.

Теоретически, таким способом можно удалить все вершины в любом графе, однако, в общем случае, нас ждет неприятность, связанная с ростом числа ребер. При удалении вершины со степенью n, степень вершин, смежной с удаляемой, может: уменьшится на -1, не измениться, увеличится до n-2. Отсюда следует, что при удалении вершин со степенью 3 и выше, степень остальных вершин, в общем случае, растет, граф становится все менее разреженным и, в конце концов, удаление вершин превратится в довольно трудоемкую задачу. Алгоритм, в общем случае, является крайне трудоемким и практически бесполезным, но это именно в общем случае.

Графы дорожных сетей имеют уникальную особенность такого рода: многие вершины могут быть удалены не только без роста, но и с уменьшением степени смежных вершин. Причем, если некоторая вершина не может быть «успешно» удалена сейчас, она может быть «успешно» удалена позже, после удаления некоторых, смежных с ней вершин.

Соответственно, нам просто требуется на каждом шаге правильно выбирать вершины на удаление, начиная с тех, которые удаляются более «удачно».

Сам алгоритм более подробно можно посмотреть здесь. Там описано, как удалить вершину, сохраняя расстояния и пути между оставшимися. Этот процесс называется разборкой. Там описано, как восстановить потом граф обратно, добавляя вершины в обратном порядке по одной, как пересчитывать при этом МКР. Этот процесс называется сборкой.

Там же приведены результаты использования алгоритма на графах дорожных сетей США по ссылке.

Вывод

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

 

Рассмотрим пример нахождение кратчайшего пути. Дана сеть автомобильных дорог, соединяющих области города. Некоторые дороги односторонние. Найти кратчайшие пути от центра города до каждого города области.

Для решения указанной задачи можно использовать алгоритм Дейкстры — алгоритм на графах, изобретённый нидерландским ученым Э. Дейкстрой в 1959 году. Находит кратчайшее расстояние от одной из вершин графа до всех остальных. Работает только для графов без рёбер отрицательного веса.

Пусть требуется найти кратчайшие расстояния от 1-й вершины до всех остальных.

Кружками обозначены вершины, линиями – пути между ними (ребра графа). В кружках обозначены номера вершин, над ребрами обозначен их вес – длина пути. Рядом с каждой вершиной красным обозначена метка – длина кратчайшего пути в эту вершину из вершины 1.
Задача

Инициализация

Метка самой вершины 1 полагается равной 0, метки остальных вершин – недостижимо большое число (в идеале — бесконечность). Это отражает то, что расстояния от вершины 1 до других вершин пока неизвестны. Все вершины графа помечаются как непосещенные.
Инициализация

Первый шаг

Минимальную метку имеет вершина 1. Её соседями являются вершины 2, 3 и 6. Обходим соседей вершины по очереди.

Первый сосед вершины 1 – вершина 2, потому что длина пути до неё минимальна. Длина пути в неё через вершину 1 равна сумме кратчайшего расстояния до вершины 1 (значению её метки) и длины ребра, идущего из 1-й во 2-ю, то есть 0 + 7 = 7. Это меньше текущей метки вершины 2 (10000), поэтому новая метка 2-й вершины равна 7.
Шаг 1
Аналогично находим длины пути для всех других соседей (вершины 3 и 6).

Все соседи вершины 1 проверены. Текущее минимальное расстояние до вершины 1 считается окончательным и пересмотру не подлежит. Вершина 1 отмечается как посещенная.

Второй шаг

Шаг 1 алгоритма повторяется. Снова находим «ближайшую» из непосещенных вершин. Это вершина 2 с меткой 7.

Снова пытаемся уменьшить метки соседей выбранной вершины, пытаясь пройти в них через 2-ю вершину. Соседями вершины 2 являются вершины 1, 3 и 4.

Вершина 1 уже посещена. Следующий сосед вершины 2 — вершина 3, так как имеет минимальную метку из вершин, отмеченных как не посещённые. Если идти в неё через 2, то длина такого пути будет равна 17 (7 + 10 = 17). Но текущая метка третьей вершины равна 9, а 9 < 17, поэтому метка не меняется.
Шаг 2
Ещё один сосед вершины 2 — вершина 4. Если идти в неё через 2-ю, то длина такого пути будет равна 22 (7 + 15 = 22). Поскольку 22<10000, устанавливаем метку вершины 4 равной 22.

Все соседи вершины 2 просмотрены, помечаем её как посещенную.

Третий шаг

Повторяем шаг алгоритма, выбрав вершину 3. После её «обработки» получим следующие результаты.
Шаг 3

Четвертый шаг

Шаг 4

Пятый шаг

Шаг 5

Шестой шаг

Шаг 6
Таким образом, кратчайшим путем из вершины 1 в вершину 5 будет путь через вершины 1 — 3 — 6 — 5, поскольку таким путем мы набираем минимальный вес, равный 20.

 
Займемся выводом кратчайшего пути. Мы знаем длину пути для каждой вершины, и теперь будем рассматривать вершины с конца. Рассматриваем конечную вершину (в данном случае — вершина 5), и для всех вершин, с которой она связана, находим длину пути, вычитая вес соответствующего ребра из длины пути конечной вершины.
Так, вершина 5 имеет длину пути 20. Она связана с вершинами 6 и 4.
Для вершины 6 получим вес 20 — 9 = 11 (совпал).
Для вершины 4 получим вес 20 — 6 = 14 (не совпал).
Если в результате мы получим значение, которое совпадает с длиной пути рассматриваемой вершины (в данном случае — вершина 6), то именно из нее был осуществлен переход в конечную вершину. Отмечаем эту вершину на искомом пути.
Далее определяем ребро, через которое мы попали в вершину 6. И так пока не дойдем до начала.
Если в результате такого обхода у нас на каком-то шаге совпадут значения для нескольких вершин, то можно взять любую из них — несколько путей будут иметь одинаковую длину.

Реализация алгоритма Дейкстры

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

1 2 3 4 5 6
1 0 7 9 0 0 14
2 7 0 10 15 0 0
3 9 10 0 11 0 2
4 0 15 11 0 6 0
5 0 0 0 6 0 9
6 14 0 2 0 9 0

Реализация на C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define SIZE 6
int main()
{
  int a[SIZE][SIZE]; // матрица связей
  int d[SIZE]; // минимальное расстояние
  int v[SIZE]; // посещенные вершины
  int temp, minindex, min;
  int begin_index = 0;
  system(“chcp 1251”);
  system(“cls”);
  // Инициализация матрицы связей
  for (int i = 0; i<SIZE; i++)
  {
    a[i][i] = 0;
    for (int j = i + 1; j<SIZE; j++) {
      printf(“Введите расстояние %d – %d: “, i + 1, j + 1);
      scanf(“%d”, &temp);
      a[i][j] = temp;
      a[j][i] = temp;
    }
  }
  // Вывод матрицы связей
  for (int i = 0; i<SIZE; i++)
  {
    for (int j = 0; j<SIZE; j++)
      printf(“%5d “, a[i][j]);
    printf(“n”);
  }
  //Инициализация вершин и расстояний
  for (int i = 0; i<SIZE; i++)
  {
    d[i] = 10000;
    v[i] = 1;
  }
  d[begin_index] = 0;
  // Шаг алгоритма
  do {
    minindex = 10000;
    min = 10000;
    for (int i = 0; i<SIZE; i++)
    { // Если вершину ещё не обошли и вес меньше min
      if ((v[i] == 1) && (d[i]<min))
      { // Переприсваиваем значения
        min = d[i];
        minindex = i;
      }
    }
    // Добавляем найденный минимальный вес
    // к текущему весу вершины
    // и сравниваем с текущим минимальным весом вершины
    if (minindex != 10000)
    {
      for (int i = 0; i<SIZE; i++)
      {
        if (a[minindex][i] > 0)
        {
          temp = min + a[minindex][i];
          if (temp < d[i])
          {
            d[i] = temp;
          }
        }
      }
      v[minindex] = 0;
    }
  } while (minindex < 10000);
  // Вывод кратчайших расстояний до вершин
  printf(“nКратчайшие расстояния до вершин: n”);
  for (int i = 0; i<SIZE; i++)
    printf(“%5d “, d[i]);

  // Восстановление пути
  int ver[SIZE]; // массив посещенных вершин
  int end = 4; // индекс конечной вершины = 5 – 1
  ver[0] = end + 1; // начальный элемент – конечная вершина
  int k = 1; // индекс предыдущей вершины
  int weight = d[end]; // вес конечной вершины

  while (end != begin_index) // пока не дошли до начальной вершины
  {
    for (int i = 0; i<SIZE; i++) // просматриваем все вершины
      if (a[i][end] != 0)   // если связь есть
      {
        int temp = weight – a[i][end]; // определяем вес пути из предыдущей вершины
        if (temp == d[i]) // если вес совпал с рассчитанным
        {                 // значит из этой вершины и был переход
          weight = temp; // сохраняем новый вес
          end = i;       // сохраняем предыдущую вершину
          ver[k] = i + 1; // и записываем ее в массив
          k++;
        }
      }
  }
  // Вывод пути (начальная вершина оказалась в конце массива из k элементов)
  printf(“nВывод кратчайшего путиn”);
  for (int i = k – 1; i >= 0; i–)
    printf(“%3d “, ver[i]);
  getchar(); getchar();
  return 0;
}

Результат выполнения
Алгоритм Дейкстры

Назад: Алгоритмизация

Добавить комментарий