Я нашел способ перечислить все пути, включая бесконечные, содержащие циклы.
http://blog.vjeux.com/2009/project/project-shortest-path.html
Поиск атомных путей и циклов
Definition
То, что мы хотим сделать, - это найти все возможные пути, идущие из точки А в точку Б. Поскольку существуют циклы, вы не можете просто пройти и перечислить их все. Вместо этого вам нужно будет найти атомарный путь, который не зацикливается, и наименьшие возможные циклы (вы не хотите, чтобы ваш цикл повторялся).
Первое определение атомного пути, которое я принял, - это путь, который не проходит через один и тот же узел дважды. Однако я узнал, что это не все возможности. После некоторого размышления я понял, что узлы не важны, как бы то ни было ребра! Так что атомный путь - это путь, который не проходит через одно и то же ребро дважды.
Это определение удобно, оно также работает для циклов: атомный цикл в точке A - это атомный путь, который идет из точки A и заканчивается в точке A.
Осуществление
Atomic Paths A -> B
Чтобы получить весь путь, начиная с точки А, мы собираемся рекурсивно пройти по графику из точки А. При прохождении дочернего объекта мы собираемся сделать ссылку дочерний -> родительский, чтобы узнать все края мы уже пересекли. Прежде чем перейти к этому дочернему элементу, мы должны пройти по этому связанному списку и убедиться, что указанное ребро еще не прошло.
Когда мы прибудем в пункт назначения, мы можем сохранить найденный путь.
Freeing the list
Проблема возникает, когда вы хотите освободить связанный список. Это в основном дерево в цепочке в обратном порядке. Решением будет двойная связь этого списка, и когда все атомные пути будут найдены, освободите дерево от начальной точки.
Но разумным решением является использование подсчета ссылок (по мотивам Сборщика мусора). Каждый раз, когда вы добавляете ссылку на родителя, вы добавляете ее к счетчику ссылок. Затем, когда вы достигаете конца пути, вы возвращаетесь назад и освобождаетесь, пока счетчик ссылок равен 1. Если он выше, вы просто удаляете один и останавливаетесь.
Atomic Cycle A
Поиск атомного цикла А - это то же самое, что поиск атомного пути от А к А. Однако мы можем сделать несколько оптимизаций. Во-первых, когда мы достигаем точки назначения, мы хотим сохранить путь только в том случае, если сумма стоимости ребер отрицательна: мы хотим пройти только поглощающие циклы.
Как вы видели ранее, весь граф просматривается при поиске атомного пути. Вместо этого мы можем ограничить область поиска до сильно связанного компонента, содержащего A. Для нахождения этих компонентов требуется простой обход графа с помощью алгоритма Тарьяна.
Объединение атомных путей и циклов
На данный момент у нас есть все атомные пути, которые идут от А до В, и все атомные циклы каждого узла, предоставленные нам, чтобы организовать все, чтобы получить кратчайший путь. Отныне мы будем изучать, как найти лучшую комбинацию атомных циклов на атомном пути.