Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Graph Cycle Detection with Java

I'm studying cycle detection in DAGs, and I've implemented my version of the algorithm using DFS, here is the code;

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;

    }

}

And here is the testing class:

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!");
        }

    }

}

For this case in particular the result should print that the graph has a cycle since the graph we are dealing with is this one:

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

But my output is getting false, like there is no cycle, I just can't find the bug in my implementation. Can someone help ?

like image 576
Pj- Avatar asked Mar 17 '26 13:03

Pj-


1 Answers

You are missing the purpose of the line:

DFS.dfs(graph, neighborVertex);

If this call returns true, the method also should return true.

EDIT: It should be like this:

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;
}
like image 163
ram Avatar answered Mar 19 '26 02:03

ram



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!