【问题标题】:Graph Cycle Detection with Java使用 Java 进行图循环检测
【发布时间】:2017-06-14 01:29:14
【问题描述】:

我正在研究 DAG 中的循环检测,并且我已经使用 DFS 实现了我的算法版本,这是代码;

public class DFS {

    public static boolean hasCycle(Graph graph) {

        for (Vertex vertex : graph.getVertices()) {
            if (detectCycle(graph, vertex)) {
                return true;
            }
        }

        return false;

    }

    private static boolean detectCycle(Graph graph, Vertex root) {

        for (Vertex vertex : graph.getVertices()) {
            vertex.setBeingVisited(false);
            vertex.setVisited(false);
        }

        return DFS.dfs(graph, root);

    }

    private static boolean dfs(Graph graph, Vertex root) {
        root.setBeingVisited(true);

        for (Edge edge : root.getNeighbors()) {
            Vertex neighborVertex = edge.getEndPoint();
            if (neighborVertex.isBeingVisited()) {
                return true;
            } else if (!neighborVertex.isVisited()) {
                DFS.dfs(graph, neighborVertex);
            }
        }

        root.setVisited(true);
        root.setBeingVisited(false);
        return false;

    }

}

这里是测试类:

public class App {

    public static void main(String[] args) {
        Vertex a = new Vertex("A");
        Vertex b = new Vertex("B");
        Vertex c = new Vertex("C");
        Vertex d = new Vertex("D");
        Vertex e = new Vertex("E");

        Edge e1 = new Edge(a, b);
        Edge e2 = new Edge(a, c);
        a.addNeighbor(e1);
        a.addNeighbor(e2);

        Edge e3 = new Edge(b, d);
        b.addNeighbor(e3);

        Edge e4 = new Edge(c, e);
        c.addNeighbor(e4);

        Edge e5 = new Edge(d, a);
        d.addNeighbor(e5);

        List<Vertex> vertices = new ArrayList<>();
        vertices.add(a);
        vertices.add(b);
        vertices.add(c);
        vertices.add(d);
        vertices.add(e);

        Graph graph = new Graph(vertices);
        System.out.println(DFS.hasCycle(graph));
        if (DFS.hasCycle(graph)) {
            System.out.println("It does have a cycle!");
        } else {
            System.out.println("It doesn't have cycle!");
        }

    }

}

对于这种情况,特别是结果应该打印出该图有一个循环,因为我们正在处理的图是这个:

   >b --> d
  /       |
 a<-------
  \
   > c --> e

但是我的输出是假的,就像没有循环一样,我只是在我的实现中找不到错误。有人可以帮忙吗?

【问题讨论】:

    标签: java graph detection cycle microsoft-distributed-file-system


    【解决方案1】:

    你错过了这条线的目的:

    DFS.dfs(graph, neighborVertex);
    

    如果此调用返回true,该方法也应该返回true

    编辑:应该是这样的:

    private static boolean dfs(Graph graph, Vertex root) {
        root.setBeingVisited(true);
    
        for (Edge edge : root.getNeighbors()) {
            Vertex neighborVertex = edge.getEndPoint();
            if (neighborVertex.isBeingVisited()) {
                return true;
            } else if (!neighborVertex.isVisited() && DFS.dfs(graph, neighborVertex)) {
                return true;
            }
        }
    
        root.setVisited(true);
        root.setBeingVisited(false);
        return false;
    }
    

    【讨论】:

    • 更改为 ' if (neighborVertex.isBeingVisited()) { return true; } if (!neighborVertex.isVisited()) { return DFS.dfs(graph, neighborVertex); }' 让它工作!谢谢!!
    • @Pj- 实际上这是不正确的,尽管它可能适用于您的特定示例。如果直接返回dfs返回的内容,那么你并没有更新rootbeingVisitedvisited属性,这会导致它失败:失败的一个简单例子是a -> b -> c,并在order (b, a, c):它会说它有循环。正确阅读我的答案:仅当DFS.dfs(graph, neighborVertex) 返回true 时才返回true。如果false,继续处理其他邻居。我希望现在很清楚。
    • 哦,对不起,你是说它应该是这样的:'if (!neighborVertex.isVisited()) { if (DFS.dfs(graph, neighborVertex)) { return true; } else { DFS.dfs(图,neighborVertex); } }' ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    • 2011-01-25
    • 2018-12-17
    • 1970-01-01
    相关资源
    最近更新 更多