@keddad
Ученик

Как найти кратчайший маршрут в графе с дополнительными требованиями к маршруту?

У меня есть граф, на каждом ребре - некоторый положительный вес. Для поиска кратчайшего маршрута между двумя точками я использую алгоритм Дейкстры. У меня появляется дополнительное условие: система заправок. Т.е. в некоторых из вершин есть "заправки", которые восполняют наш запас хода, и без заправок я могу передвинуться только на некоторое n (n - сумма пройденных от заправки весов ребер). Как в таком случае мне следует минимизировать кол-во заправок на маршруте? Если мы находимся в ноде с заправкой, мы не обязательно должны ее использовать.
  • Вопрос задан
  • 248 просмотров
Пригласить эксперта
Ответы на вопрос 3
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Сначала ищем все возможные пути с заправками: ([текущая заправка:на какое расстояние заправляет] + [текущий запас топлива: на какое макс.расстояние можно проехать без заправки] - [сумма рёбер пути от текущего узла до следующей заправки или пункта назначения] ) > 0.
Выбираем все возможные варианты, чтобы всегда было топливо в баке.

Потом, уже только из них, ищем минимальное кол-во заправок на кратчайшем пути.
Ответ написан
Комментировать
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
При данных ограничениях можно создать искусственный граф, где каждая вершина соответствует вершине в исходном графе и некоторому запасу топлива (я обозначу такую вершину как (v, f) - в вершине v с топливом f).
Вершин в таком графе будет до 500*10000. Для каждого ребра v->u длинной l в исходном графе создаем ребро из вершины (v, f) в вершину (u, f-l) для всех f (т.е. из вершины v, имея f топлива, можно попасть в вершину u, имея f-l топлива). Эти ребра ценой 0. Также, в каждую вершину v, где есть заправка, добавьте ребро (v, f) -> (v, n) ценой 1 (заправились до упора). В графе будет до 500*10000 + 500*10000 ребер.

Теперь запустите там обход в ширину с двумя очередями или deque из вершины (start, n) пока не найдете путь в любую вершину (finish, f). Длина пути будет равна количеству заправок. Преходы по ребрам ценой 1 - это процесс заправки, по ребрам цены 0 - просто передвижения в исходном графе.

Это известное обобщение обхода в ширину на 0-1 графе:
Когда берете вершину из deque и смотрите всех ее соседей, если длина ребра до соседа 1, то кладете конец ребра в конец deque, а если цена 0 - то в начало. С двумя очередями делается так: пока очереди не пусты, берем вершину из текущей очереди и кладем ее соседей на расстоянии 0 в конец той же очереди, а соседей через ребро длины 1 - во вторую очередь. Когда текущая очередь опустеет, переходим к другой и так далее.
Ответ написан
@Mercury13
Программист на «си с крестами» и не только
ВАРИАНТ 1. Расстояние приоритетнее кол-ва заправок.

Моё решение — в каждой вершине хранить не просто цифру пройденного расстояния, а список: «расстояние/запас топлива/предыдущая вершина». И расстояние, и топливо не убывают.

С этими списками можно делать такие операции:

1. Добавить расстояние + израсходовать топливо. Для каждого элемента списка расстояние′ = расстояние + x, топливо′ = топливо − y. Если получается нехватка топлива — что ж, не повезло, этого элемента в списке не будет.
2. Добавить расстояние + израсходовать топливо + заправиться. Аналогично, но оставляем один элемент — соответствующий наименьшему расстоянию, где хватает топлива. расстояние′ = расстояние + x, топливо′ = полный бак.
3. Добавить очередной элемент в список. Тогда удаляем из списка те элементы, где расстояние не меньше, а запас топлива не больше.

После этого на оптимальном маршруте проводим оптимизацию заправок.

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

Можно также вместо расстояния хранить список «расстояние, кол-во заправок» с лексикографическим порядком на ней и другой операцией «прибавить+заправиться».

ВАРИАНТ 2. Кол-во заправок приоритетнее расстояния.

Аналогично первому, только роль расстояния играет пара «кол-во заправок, расстояние» с лексикографическим порядком на ней.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы