Разбор задачи: Все пути от источника к цели

Предложенный нами код:

 def allPathsSourceTarget(graph, i = 0, q = [0]):
        if i == 0: 
            global res
            res = []
        if i == len(graph) - 1: 
            res.append(q)
        for index in graph[i]: 
            allPathsSourceTarget(graph, index, q + [index])
        return res

Рассмотрим предложенный код, который решает задачу поиска всех путей от узла 0 до узла n−1n-1 в направленном ациклическом графе. Решение основано на рекурсивном подходе.


Код функции

def allPathsSourceTarget(graph, i = 0, q = [0]):
    if i == 0: 
        global res
        res = []
    if i == len(graph) - 1: 
        res.append(q)
    for index in graph[i]: 
        allPathsSourceTarget(graph, index, q + [index])
    return res

Разбор фрагментов кода

  1. Объявление функции с аргументами по умолчанию:

    def allPathsSourceTarget(graph, i = 0, q = [0]):
    
    • graph: список смежности, задающий граф. Каждый элемент graph[i] — это список вершин, в которые есть ребро из вершины i.
    • i: текущий узел, с которого начинается поиск. По умолчанию это узел 0.
    • q: текущий путь, по которому проходит рекурсивная функция. По умолчанию содержит только узел 0.
  2. Инициализация глобальной переменной res:

    if i == 0: 
        global res
        res = []
    
    • При первом вызове функции (i == 0) создается глобальная переменная res, которая будет хранить все найденные пути.
  3. Условие окончания пути:

    if i == len(graph) - 1: 
        res.append(q)
    
    • Если текущий узел i является последним узлом графа (целевым узлом), текущий путь q добавляется в результат.
  4. Рекурсивный обход графа:

    for index in graph[i]: 
        allPathsSourceTarget(graph, index, q + [index])
    
    • Цикл перебирает все узлы, в которые можно перейти из текущего узла i.
    • Для каждого узла выполняется рекурсивный вызов, при этом к текущему пути q добавляется узел index.
  5. Возврат результата:

    return res
    
    • В конце возвращается глобальная переменная res, содержащая список всех найденных путей.

Пример работы алгоритма

Рассмотрим пример:

graph = [[1, 2], [3], [3], []]
result = allPathsSourceTarget(graph)
  1. Инициализация:
    • res = [] (пустой список для хранения результатов).
    • i = 0 (стартуем с узла 0).
    • q = [0] (текущий путь содержит только стартовый узел).
  2. Рекурсивные вызовы:
    • Узел 0 ведет к узлам 1 и 2.
      • Для узла 1:
        • Текущий путь: [0, 1].
        • Узел 1 ведет к узлу 3:
          • Текущий путь: [0, 1, 3].
          • Добавляем путь в res.
      • Для узла 2:
        • Текущий путь: [0, 2].
        • Узел 2 ведет к узлу 3:
          • Текущий путь: [0, 2, 3].
          • Добавляем путь в res.
  3. Результат:
    • res = [[0, 1, 3], [0, 2, 3]].

 



Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии