Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting all circles in a graph

I have a directed graph stored in a Map data structure, where the key is the node's ID and the [value] is the array of the nodeIds of the nodes which are pointed by the key node.

Map<String, String[]> map = new HashMap<String, String[]>();
map.put("1", new String[] {"2", "5"});
map.put("2", new String[] {"3"});
map.put("3", new String[] {"4"});
map.put("4", new String[] {"4"});
map.put("5", new String[] {"5", "9"});
map.put("6", new String[] {"5"});
map.put("7", new String[] {"6"});
map.put("8", new String[] {"6"});
map.put("9", new String[] {"10"});
map.put("10", new String[] {"5"});
map.put("11", new String[] {"11"});

I wrote a recursive searching algorithm which tries to locate the circle in the graph.

Set<String> nodes = map.keySet();

    for(String node : nodes) {
        List<String> forbiddens = new ArrayList<>(); // This list stores the touched nodes, during the process.
        forbiddens.add(node);
        recursiveSearch(node, forbiddens);
    }

The function is called by the code above.

private void recursiveSearch(String nodeId, List<String> forbiddens) {
    String[] neighbours = map.get(nodeId); // The given node's neighbours
    for(String neighbour : neighbours) {
        for(String forbidden : forbiddens) {
            if(neighbour.equals(forbidden)) {
                ways.add( getClone(forbidden) ); //getClone returns the copy of a given List, "ways" is a List<List<String>> which contains the lists of paths which are leading to a circle in the graph
                return;
            }
        }
        forbiddens.add(neighbour);
        recursiveSearch(neighbour, forbiddens);
        forbiddens.remove(neighbour);
    }
}

Some paths contains extra nodes (which aren't in the circle) that I would like to get rid of. I would like to ask for help to select the nodes from the "ways" lists to get the actual nodes of the circle.

Can this algorithm find ALL the circles in the graph?

like image 520
tyutyi Avatar asked Sep 28 '22 10:09

tyutyi


1 Answers

Since a circle in a directed graph represents a strongly connected component, you can use any of the algorithms referenced on the wikipedia page for finding strongly connected components https://en.wikipedia.org/wiki/Strongly_connected_component - for instance Tarjan's algorithm which is based on depth-first search: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm

Edit: It is possible that a strongly connected component contains multiple circles that share nodes with each other. So, a manual checking of each component must follow, but should be easy.

like image 159
DubioserKerl Avatar answered Oct 01 '22 01:10

DubioserKerl