在 DepthFirstSearch 中寻找目标

Finding goal in DepthFirstSearch

我只是想知道把这段代码放在哪里

if(node == goal){
            System.out.print("Found path: ");
            for(int n : stack){
                System.out.print(n + " ");
            }
        }

在这个方法中:

public void performRecursiveDFS(Graph G, int node, int goal) {
    Stack<Integer> stack = new Stack<Integer>();
    stack.push(node);
    while (!stack.isEmpty()) {
        node = stack.pop();
         if (!visited[node]) {
            visited[node] = true;
            for (int w : G.adjList(node)) {
                stack.push(w);
            }
        }
    }
}

原因是,我想打印从起始节点到目标节点的路径。比如像这样,Found path: 0 1 2 3 4 7。我试着把它放在 node = stack.pop() 之后,但它向我显示了类似 Found path: 3 的内容。有 reason/suggestion 吗?我的代码有问题吗?如果是这样,请详细指导我。欢迎提问。提前致谢。

堆栈当前正在存储要检查的下一个节点,而不是已经检查到当前点的节点。

要获取路径,您需要创建一个列表并将选中的每个节点添加到该列表。

一旦你得到一个节点,你可以检查该节点是否是目标节点,然后你可以打印出列表

您已经实施了 DFS 的一部分来跟踪访问的节点,您可以扩展它以了解源路径,也就是 link 到下一个节点

完整的 DFS 实现如下所示,它也将处理路径请求

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;


public class DirectedDFS {

    private final Digraph g;
    private final int source;

    private boolean[] marked;
    private int[] edgeFrom;

    public DirectedDFS(Digraph g, int source) {
        this.g = g;
        this.source = source;
        init(g);
        dfs(g, source);
    }

    private void init(Digraph g) {
        this.marked = new boolean[g.V()];
        this.edgeFrom = new int[g.V()];
        Arrays.fill(edgeFrom, -1);
    }

    private void dfs(Digraph g, int source) {

        marked[source] = true;
        for (int vertex : g.adj(source)) {
            if (!marked[vertex]) {
                edgeFrom[vertex] = source;
                dfs(g, vertex);
            }
        }
    }

    public boolean hasPath(int v) {
        return marked[v];
    }

    public Iterable<Integer> path(int v) {
        if (hasPath(v)) {
            final Deque<Integer> paths = new ArrayDeque<>();
            int vertex = v;
            paths.push(v);
            while ((vertex = edgeFrom[vertex]) != -1) {
                paths.push(vertex);
            }
            return paths;
        }
        return (Iterable<Integer>) Collections.emptyIterator();
    }

}

您目前没有存储当前节点的路径,因此无法打印它。实现此目的的一种相当简单的方法是使用地图绘制返回原点的路径。这可以代替您对 visited 数组的使用。

这是它的样子:

public void performRecursiveDFS(Graph G, int start, int goal) {
    Stack<Integer> remaining = new Stack<Integer>();
    remaining.push(start);
    Map<Integer, Integer> previous = new HashMap<>();
    while (!remaining .isEmpty()) {
        int current = remaining.pop();
        if (current == goal) {
            Deque<Integer> path = new LinkedList<>();
            path.addFirst(current);
            while (previous.containsKey(path.peek())
                path.addFirst(previous.get(path.peek()));
            // print path
        } else if (!previous.containsKey(current)) {
            for (int w : G.adjList(current)) {
                previous.put(w, current);
                remaining.push(w);
            }
        }
    }
}