Нахождение кратчайшего пути с прохождением только определенного ребра, меньшего или равного одному разу в графике

#algorithm #data-structures #graph #shortest-path #dijkstra

#алгоритм #структуры данных #График #кратчайший путь #dijkstra

Вопрос:

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

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

Я знаю, что могу получить кратчайший путь с помощью алгоритма Дейкстры, но во время процесса, как я могу изменить алгоритм в соответствии с требованиями ограничения?

Большое спасибо, что ответили на мой вопрос!

Комментарии:

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

2. @trincot Это первое, о чем вы упомянули, я изменю свой вопрос, чтобы он был более четким, большое спасибо!

Ответ №1:

Решение состоит в том, чтобы дублировать график следующим образом:

  • Дублируйте вершины таким образом, чтобы для каждой исходной вершины A у вас были A и A’.
  • Если в исходном графике есть нормальное ребро между A и B, то в новом графике поместите ребро между A и B, а также между A’ и B’
  • Если в исходном графике есть определенное ребро между A и B, то в новом графике поместите (направленное) ребро от A до B’ (не обратное!) и от B до A’ (опять же: не обратное!). Эти края должны быть направлены.

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

Комментарии:

1. О, я думаю, что понимаю смысл, но если график неориентирован, должен ли я добавить новое ребро между Aamp;B’ и A’amp;B?

2. Я обновил свой ответ, чтобы сделать некоторые аспекты более ясными.

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

4. Да, потому что после посещения «акцентированного» узла невозможно вернуться к узлам без акцента.

5. Спасибо за ваш полезный ответ! Я думаю, что я полностью осознал!

Ответ №2:

Учитывая n конкретные ребра, время поиска Дейкстры n увеличивается.
При каждом запуске одному из n узлов (назовем его узлом i ) должен быть установлен его реальный вес, а всем остальным n-1 узлам-бесконечное значение. В конце каждого прогона сохраняйте кратчайший путь и шаг i
В конце всех запусков выберите из сохраненных путей самый короткий.

 set all n edges weight to infinity  for i=0; i lt; n ; i   {  set edge i to it real weight   run run Dijkstra's search   store path   set all n edges weight to infinity  }  select the shortest path from the stored paths.