Поиск пути между всеми точками с использованием алгоритма аппроксимации

1‹=n‹=1000 городов. Мне нужно найти путь, соединяющий все города (каждый город можно посетить только один раз), который начинается и заканчивается в городе номер 1. В этом пути максимальная длина между двумя городами должна быть как можно короче.

Eg:

введите здесь описание изображения

Вход:

coordinates of cities

Выход:

5 1 3 //longest connection is 5 and it is between cities 1 and 3
1 3 6 4 5 2 1 //path

person Paulina    schedule 22.01.2013    source источник
comment
@ phant0m, это неверно, так как ограничения разные, максимальная длина и общая сумма.   -  person Толя    schedule 22.01.2013
comment
Вам нужен примерный алгоритм? Если это так, вы должны добавить это к вопросу, а не только к заголовку. Я понял, что вам нужен примерный алгоритм из ваших тегов, а не заголовка.   -  person Paresh    schedule 22.01.2013


Ответы (2)


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

  1. Считайте граф полным — между каждой парой вершин есть ребро, всего n(n-1)/2 ребер.
  2. Отсортируйте ребра в порядке убывания их веса/расстояния.
  3. Итерировать от ребра с наибольшим расстоянием до ребра с наименьшим расстоянием и удалить его, если после удаления этого ребра обе его конечные точки по-прежнему имеют степень не ниже ceil(n/2) (теорема Дирака для обеспечения существования гамильтонова цикла). Вы можете использовать более сильный результат, например теорему Оре, чтобы обрезать еще больше ребер, но сложность вычислений возрастет.
  4. На оставшемся графике используйте жадный алгоритм, чтобы найти гамильтонов цикл. Жадный алгоритм в основном начинает с 1 и продолжает выбирать ребро с наименьшим расстоянием до узла, который еще не является частью цикла. Так что в вашем примере он сначала выберет 1 -> 2, затем 2-> 4, затем 4-> 5 и так далее. Последняя выбранная вершина будет иметь обратный путь к 1.

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

person Paresh    schedule 22.01.2013

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

Моя мысль примерно такая:

create edges between each pair of cities
while (true)
  next = nextLongestEdge
  if (graph.canRemove(next)) // this function may be somewhat complicated,
                             // note that it must at the very least check that every node has at least 2 edges
    graph.remove(next)
  else
    return any path starting and ending at 1 from the remaining edges
person Bernhard Barker    schedule 22.01.2013
comment
this function may be somewhat complicated Я улыбнулась :) - person phant0m; 22.01.2013
comment
@ phant0m Да, но я думаю, что это намного проще, чем исходная задача - вам просто нужно найти единственный путь от оставшихся краев. Это может помочь добавить немного интеллекта, чтобы избежать поиска в глубину (например, если степень любой вершины ‹ 2, ошибка). Обратите внимание, что чем выше средняя степень, тем больше шансов быстро найти решение, чем ниже средняя степень, тем быстрее она выполняется. - person Bernhard Barker; 22.01.2013
comment
@Dukeling Для правильного алгоритма вам нужно будет проверить, что граф является гамильтоновым после удаления ребра, которое является NP-полным в общих графах. И ваш алгоритм будет вычислять это для каждого вызова canRemove(). - person Paresh; 22.01.2013
comment
@Paresh Для первого вызова canRemove граф будет настолько плотным, что DFS вернет результат с возвратом не более одного раза (таким образом, O (m)). Когда граф становится разреженным, расчет будет намного быстрее. Для первого, если вы выполняете поиск в глубину, отдавая предпочтение кратчайшим ребрам, вы можете получить решение, которое останется действительным, даже если несколько других ребер будут удалены (что вы можете запомнить и продолжить, если оно больше недействительно ( таким образом, в основном сводя его к решению одного экземпляра)). Но, да, это, вероятно, все еще будет слишком медленным. - person Bernhard Barker; 22.01.2013
comment
@Dukeling DFS не дает цикла. Это дает дерево. Вы не можете использовать DFS для поиска гамильтонова цикла. Если бы вы могли, нахождение гамильтонова цикла не было бы NP-полным. Обратите внимание, что DFS линейна по количеству ребер и вершин. - person Paresh; 22.01.2013
comment
@Dukeling Чтобы уточнить, TSP находит гамильтонов цикл максимального общего веса. Вы не можете решить это с помощью DFS. - person Paresh; 22.01.2013
comment
Проверить существование гамильтонова цикла можно, но найти его NP-решение. - person Толя; 23.01.2013