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

Я знаю, что для неориентированного графа эта проблема является NP-полной, поэтому мы должны использовать грубую силу, чтобы проверить все возможные пути. Как мы можем это сделать? Пожалуйста, предложите псевдокод и расскажите мне о сложности этого алгоритма.

Если есть оптимизации, то это было бы здорово!


person Narek    schedule 19.02.2014    source источник
comment
Вы должны поставить дополнительные ограничения. Иначе путь бесконечен ...   -  person hivert    schedule 19.02.2014
comment
Каждая вершина входит в путь, только одна - это простой путь.   -  person Narek    schedule 19.02.2014
comment
Просто потому, что это NP-полный, не означает, что вы должны использовать грубую силу. Конечно, вы не можете (насколько известно) добиться большего, чем экспоненциальное время в худшем случае, но худшие случаи редки, и, если привести пару примеров, экземпляры 3-SAT с тысячами предложений и переменных и экземпляры TSP с тысячами городов решаются в обычном порядке, явно не с применением грубой силы.   -  person harold    schedule 19.02.2014
comment
невзвешенный: https://stackoverflow.com/questions/2525316/longest-acyclic-path-in-a-directed-unweighted-graph   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 13.11.2017


Ответы (2)


Наивный подход мог бы перебрать все возможные перестановки вершин.

Для каждой перестановки {v1, ..., vN} вы проверяете, можете ли вы перейти от v1 к v2, затем от v2 к v3 и т. Д. Если можете, добавьте соответствующую длину ребра к текущей длине пути. Если нет, переходите к следующей перестановке.

Самый длинный из таких путей - ваш ответ.


Или вы можете сделать то же самое, используя рекурсию.

path = 0
bestPath = 0
used = new bool[N] // initialize with falses
for(u = 0; u < N; u++)
    Path(u); // build paths starting from u
print bestPath

где

Path(u)
    used[u] = true
    foreach v in neighborhood(u)
        if(!used[v])
            path += distance(u, v)
            bestPath = max(bestPath, path)
            Path(v)
            path -= distance(u, v)
    used[u] = false

Сложность времени ужасна O(N * N^N).

person AlexD    schedule 19.02.2014
comment
Это тривиальное решение методом перебора. - person Bas Swinckels; 19.02.2014
comment
Хорошо, а как насчет модификации DFS для этого перебора? - person Narek; 19.02.2014
comment
@BasSwinckels Конечно. Но вопрос гласит: мы должны сделать Brute Force, чтобы проверить все возможные пути. Как мы можем это сделать ?. Мне показалось, что грубая сила - это нормально. - person AlexD; 19.02.2014
comment
@ Нарек Что именно ты имеешь в виду? Для любой вершины R мы можем построить дерево, где R - корень, а количество уровней в дереве (меньше или) равно количеству вершин в нашем графе. Тогда каждому листу соответствует свой путь, и нам нужно найти самый дальний. - person AlexD; 19.02.2014
comment
@Narek Я обновил свой ответ. По сути, это очень похожий на DFS подход, без явного построения дерева. - person AlexD; 19.02.2014
comment
@AlexD как жаль, что вы удалили свое первое сообщение. Этот и тот, который вы написали ранее, были ценными. Спасибо за вашу помощь. - person Narek; 20.02.2014
comment
Это решение настолько не интуитивно понятно. Он очень похож на DFS, но немного отличается, и я не чувствую разницы, почему этот не в DFS, а в брутфорсе :) - person Narek; 20.02.2014
comment
Event не уверен, что это работает. :( Есть что-нибудь, что я могу прочитать об этом решении, или это просто ваше решение - вы придумали :) - person Narek; 20.02.2014
comment
позвольте нам продолжить это обсуждение в чате - person AlexD; 20.02.2014
comment
Это n ^ 3, а не n * n ^ n - person CME64; 03.06.2019
comment
@ CME64 Разве это не означало бы, что NP-сложная задача была решена за полиномиальное время)? - person AlexD; 25.06.2019
comment
@AlexD Распространенное заблуждение состоит в том, что NP в NP-hard означает неполиномиальные, хотя на самом деле это означает недетерминированные полиномиальные приемлемые проблемы. Хотя есть подозрение, что не существует алгоритмов с полиномиальным временем для NP-сложных задач, это не было доказано. Более того, класс P, в котором все задачи могут быть решены за полиномиальное время, содержится в классе NP. Источник: википедия - person CME64; 27.06.2019

Если ваш график является особым случаем, когда он направлен и ацикличен, вы можете применить подход динамического программирования, такой как описанный здесь. Вы в основном сортируете свой граф топологически, затем в топологическом порядке для каждого узла V вы проверяете всех его соседей и обновляете их значение «расстояния», если оно больше, чем «расстояние», уже запомненное (инициализированное с помощью -infinity или что-то в этом роде).

В противном случае в общем случае задача действительно NP-полная, поскольку сводится к гамильтонову циклу. Единственное, что вы могли бы сделать, - это свести на нет все грани и попробовать алгоритм Беллмана-Форда. Однако помните, что это не хорошо для отрицательных циклов.

person webuster    schedule 19.02.2014
comment
как насчет неориентированных ациклических графов, он все еще NP-полный? - person Sush; 14.12.2020
comment
неориентированный ациклический граф - это дерево, поэтому проблема заключается в нахождении диаметра дерева, который является линейным временем. - person Megadardery; 05.02.2021