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

169
03 апреля 2019, 11:50

Дано n точек, и координату вершины с какой начинаем, найти кратчайший путь, для обхода всех точек от заданой, и также вернутся назад к ней.Так званая задача о коммивояжёрe.Это довольно легко сделать за сложность O(n!) просто генерируя все перестановки длины n и сумировать расстояния, но ето очень медленно. Буду очень благодарен коду на языке С++, Python, Paskal или идею для решения.

Начинаем в точке с координатами (0,0)
Тест:
    N - 3
    1   4
    -2  7
    -1 -1
Вывод: 
    4.4605544059
Ограничения:
    n = 20
    -1000 <= x, y <= 1000
Answer 1

Ну, для 20 вершин полным перебором уже никак не решить.
Но поскольку у вас точки на плоскости - для них справедливо неравенство треугольника, т.е. что путь AB будет не длиннее пути ACB - существует приближенный полиномиальный алгоритм, дающий решение, которое не более чем в 2 раза хуже оптимального.

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

Подробнее см. в книге Алгоритмы. Построение и анализ Кормена-Лейзерсона-Ривеста-Штайна.

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

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

Но раз у вас в тегах - динамическое программирование, рекомендовал бы, например, эту статью - Динамическое программирование для задачи коммивояжера, описывать которую здесь не получится за отсутствием места на полях (с) Ферма :), или глянуть в Википедию. А вот тут имеется даже код на Питоне...

READ ALSO
Анимация кнопки с помощью Timeline

Анимация кнопки с помощью Timeline

Здесь я нашел способ, с помощью которого участник сообщества анимировал геометрическую фигуруВ моем случае требуется анимировать кнопку

180
Twilio VideoView и Android SurfaceView

Twilio VideoView и Android SurfaceView

Я изучаю Андроид по урокам и хочу подключить Twilio в урок посвященный камере В том уроке используется SurfaceView, а в Twilio некий свой VideoView, как описано...

169
Цикл for и его секреты, если они есть?

Цикл for и его секреты, если они есть?

Хотелось бы узнать как будет выполняться цикл for: 1) Вот так:

151