【问题标题】:Is iterative-DFS faster than recursive-DFS?迭代 DFS 比递归 DFS 快吗?
【发布时间】:2015-02-27 17:11:23
【问题描述】:

我以迭代方式和递归方式实现了深度优先搜索算法。它们都适用于小尺寸(小于 1 MB)的文件。但是,当我尝试在 50 MB 的文件上运行它们时,似乎递归 DFS(9 秒)比使用迭代方法(至少几分钟)快得多。事实上,迭代方法需要很长时间才能完成。

我选择实现迭代 DFS 的唯一原因是我认为它可能比递归 DFS 更快。但事实似乎并非如此。 这是预期的吗?

请注意:我已经在使用java -Xmx1024m -Xms1024m -Xmn256m -Xss16m RunAlgo 来增加内存。

下面是我用来编写迭代 DFS 的代码。

class IterativeDFS{
long time;
LinkedList<Vertex>topological_sort_list = new LinkedList<Vertex>();

public IterativeDFS(Digraph G){
    dfs(G);
}

public void dfs(Digraph G){
    for(Vertex u : G.getAllVertices()){
        u.set_color("WHITE");
        u.set_pi(-1);
    }
    time = 0;

    for(Vertex u : G.getAllVertices()){
        if(u.get_color().equals("WHITE")){
            dfs_stack(G, u);
        }
    }
}

public void dfs_stack(Digraph G, Vertex u){
    int size =  G.getAllVertices().size();

    /*
     *  to be able to iterate over each adjacency list, keeping track of which
     *  vertex in each adjacency list needs to be explored next.
     */
    HashMap<Vertex, Iterator<Vertex>> adj_map = new HashMap<Vertex, Iterator<Vertex>>();
    for(Vertex i : G.getAllVertices()){
        adj_map.put(i, G.adjEdges(i).iterator());
    }

    Stack<Vertex> stack = new Stack<Vertex>();
    // time++;          // white vertex u has just been discovered
    u.set_d(time);
    u.set_color("GRAY");
    stack.push(u);

    while(!stack.empty()){

        Vertex k = stack.peek();

        Vertex v = null;
        if(adj_map.get(k).hasNext()){
            v = adj_map.get(k).next();          // explore edges (k,v)
            if(v.get_color().equals("WHITE")){
                v.set_pi(k.get_node());
                //  time++;
                v.set_d(time);
                v.set_color("GRAY");
                stack.push(v);
            }
        } else{
                // v's adjacency list is exhausted
                Vertex t = stack.pop();
                time++;
                t.set_f(time);
                t.set_color("BLACK");
                /*
                 *  Topological Sort :
                 *      1. call DFS(G) to compute finishing times v.f for each vertex v
                 *      2. as each vertex is finished, insert it onto FRONT of linked list
                 *      3. return linked list of vertices
                 */
                topological_sort_list.addFirst(t);
        }
    }
}

public LinkedList<Vertex> topological_sort(){
    return topological_sort_list;
}

}

【问题讨论】:

  • 您需要向我们展示代码...
  • 你为什么不分析你的程序。还发布像@SteveP 这样的代码。提到
  • 此类问题的答案应始终由实施确定。
  • 为什么要为每个顶点构造迭代器?为什么不根据需要将它们存储在堆栈中?
  • 因为我希望能够跟踪每个邻接列表中的哪个顶点接下来需要探索。

标签: java recursion depth-first-search


【解决方案1】:

如果您谈论的是时间复杂度,答案是它们都是相同的。无论实现如何,DFS 的运行时间都是 O(V),因为您应该只访问图中的每个顶点一次。此外,运行时间也是 Omega(V),因为无论输入大小如何,您都可以访问图中的所有顶点一次。这将 DFS 的运行时间留在 Theta(V)。 无论实现如何,整体 DFS 算法都保持不变。因此,递归与迭代 DFS 的运行时间应该相同,都为 Theta(V)。

【讨论】:

    猜你喜欢
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    相关资源
    最近更新 更多