【问题标题】:Why am I getting lesser connected components than actual for my graph using DFS?为什么我使用 DFS 获得的连接组件比实际连接的组件少?
【发布时间】:2019-04-13 04:20:24
【问题描述】:

我正在尝试找到一个方法 countVertices(),它需要使用 DFS 返回给定顶点的同一连接组件中的顶点数。

我无法理解为什么当我的图表有 3 个连接组件(包括父组件)时我总是得到 2。我尝试的所有测试都出错了

我的方法代码如下所示:

public static int countVertices(Graph g, Graph.Vertex v) {
    Set<Graph.Vertex> known = new HashSet<>();
    int num = 0;

    if(g == null || v == null)
        return 0;

    for(Graph.Vertex u : g.getAllVertices()) {
        if(!known.contains(u)) {
            num++;
            DFS(g, u, known);
        }
    }

    return num;
}

public static void DFS(Graph g, Graph.Vertex v, Set<Graph.Vertex> known) {
    known.add(v);

    for(Graph.Vertex vertex : g.getNeighbours(v)) {
        if(!known.contains(vertex))
            DFS(g, vertex, known);
    }
}

我在main() 方法中尝试了以下方法:

 public static void main(String[] args){
     Graph g = new Graph();
     Graph.Vertex v = new Graph.Vertex(1);
     Graph.Vertex w = new Graph.Vertex(2);
     Graph.Vertex x = new Graph.Vertex(3);
     Graph.Vertex y = new Graph.Vertex(4);

     g.addVertex(v);
     g.addVertex(w);
     g.addVertex(x);
     g.addVertex(y);
     g.addEdge(v, w);
     g.addEdge(w, y);

     System.out.println(countVertices(g, v)); // this outputs 2, it should be 3
     System.out.println(countVertices(g, x)); // this outputs 2, it should be 1
}

我无法弄清楚我做错了什么?我将不胜感激。

编辑:

public static int countVertices(Graph g, Graph.Vertex v) {
    Set<Graph.Vertex> known = new HashSet<>();
    int num = 1;

    if(g == null || v == null)
        return 0;

    //for(Graph.Vertex u : g.getNeighbours(v)) {
        if(!known.contains(v)) {
    num++;
    DFS(g, v, known);
        }
    //}

    return num;
}

【问题讨论】:

    标签: java algorithm graph depth-first-search


    【解决方案1】:

    v-w 和 w-y 是属于同一组件的 2 条边。 x 是唯一孤立的顶点。因此,正确的输出是 2 个连通分量而不是 3 个。

    编辑:如果您删除 v-w 或 w-y 之间的边,您将拥有 3 个连通分量。

    我最近使用的一种方法是检查两个顶点是否具有相同的根。在您的情况下,如果我们以 v 作为根,则 w 是 v 的子级,y 是 w 的子级 => y 是 v 的子级,因此是一个组件。 x 是没有子节点的根顶点,因此是另一个组件。我希望这能让您对连接的组件有所了解。

    至于顶点的数量,你的int num = 0应该是int num = 1。这是因为如果图不为空,则图至少有一个顶点。

    // after a short discussion, we found the solution
    // return the size of HashSet known
    public static int countVertices(Graph g, Graph.Vertex v) {
        Set<Graph.Vertex> known = new HashSet<>();
        int num = 0;
    
        if(g == null || v == null)
            return 0;
    
        // no loop, call DFS method and it will call itself recursively
        // and it will call the get neighbors()    
        if(!known.contains(v)) {
            num++;
            DFS(g, v, known);
        }
        return known.size();
    }
    

    【讨论】:

    • 我认为 v-w-y 都是连接的,x 是单独的,所以对于 countVertices(g,x) 它应该是 1,对于其他人应该是 3。我正在尝试计算顶点数。
    • 我明白了,现在我明白你的问题了。但是,只有 2 个连通分量。你在你的问题中说有 3 个连接的组件因此造成了混乱。
    • 另外,您初始化了int num = 0,但如果图形不为空,则意味着它已经有一个顶点。这意味着在测试图表是否为空之后,您应该拥有int num = 1。这就是为什么你少了一个顶点
    • 我理解并且我尝试过这个,但问题是这样做之后它也会为countVertices(g,x) 提供 3。之前它给出了 2。所以我在想我的方法可能有问题。
    • 刚刚对您的功能进行了跟踪,它似乎工作正常。让我直截了当地说,你想计算给定组件中的顶点数吗?我对么?附言int num = 1 仍然是必需的。
    猜你喜欢
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 2012-06-28
    • 2017-06-17
    • 2014-06-14
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多