Depth-first search with goal iterative

Question:

I have this piece of code here that is an iterative DFS algorithm, and right now it is giving an output of the nodes that it has visited. I want an output that only gives me a direct path to the goal node, how can I do that?

P.S I can’t do this the recursive way due to some constraints on my practice question

graph = {"A": ["D", "F", "B"],
         "B": ["C"],
         "C": [],
         "D": ["E"],
         "E": ["G"],
         "F": [],
         "G": []}


def dfs_non_recursive(graph, source, goal):
    if source is None or source not in graph:
        return "Invalid input"

    path = []

    stack = [source]

    while true:

        s = stack.pop()

        if s == goal:
            path.append(s)
            return path

        if s not in path:
            path.append(s)

        if s not in graph:
            # leaf node
            continue

        for neighbor in graph[s]:
            stack.append(neighbor)

    return path


DFS_path = dfs_non_recursive(graph, "A", "G")

print(DFS_path)

Current output: ['A', 'B', 'C', 'F', 'D', 'E', 'G']

Desired output: ['A', 'D', 'E', 'G']

Asked By: Zemelon

||

Answers:

You have to keep track of the parent of each visited node using a dictionary. Then once you reach your goal node, backtrack to source using dictionary.

graph = {"A": ["D", "F", "B"],
         "B": ["C"],
         "C": [],
         "D": ["E"],
         "E": ["G"],
         "F": [],
         "G": []}


def dfs_non_recursive(graph, source, goal):
    if source is None or source not in graph:
        return "Invalid input"

    path = []  # path to goal
    parent = {} # stores parent of each node

    stack = [source]

    while len(stack) != 0:

        s = stack.pop()

        if s == goal:
            path.append(goal)
            while(s in parent.keys()):
                path.append(parent[s])
                s = parent[s]
            return path[::-1]  # reverse of path

        if s not in graph:
            # leaf node
            continue

        for neighbor in graph[s]:
            stack.append(neighbor)
            parent[neighbor] = s

    return path


DFS_path = dfs_non_recursive(graph, "A", "G")
print(DFS_path)
Answered By: Bunny