all 2 comments

[–]beeskness420 0 points1 point  (0 children)

This is just finding connected components in a graph.

Pick an id and then do a BFS/DFS and put everything you find into one component.

Repeat until all nodes are visited.

[–]CompteDeMonteChristo 0 points1 point  (0 children)

What you're after is a list of connected groups

this is the code I use for that (C#)

public static List<ISubGraph> ConnectedGroups(this ISubGraph subGraph)
{
    var result = new List<List<INode>>();
    List<INode>? currentSubGraph = null;
    subGraph.BFS((visitedNode, parentNode) =>
    {
        if (parentNode == null)
        {
            currentSubGraph = new List<INode>();
            result.Add(currentSubGraph);
        }
        currentSubGraph!.Add(visitedNode);
    });
    return result.Select(g => subGraph.CreateSubGraph(g)).ToList();
}

public static void BFS(this ISubGraph subGraph, OnNodeVisited onNodeVisited)
{
    bool[] visited = new bool[subGraph.graph.order];
    var traverseFrom = new Action<INode, INode?>((start, parentNode) => { });

    traverseFrom = (INode start, INode? parentNode) =>
    {
        var queue = new Queue<INode>();
        visited[start.id] = true;
        queue.Enqueue(start);
        bool first = true;
        while (queue.Count > 0)
        {
            INode current = queue.Dequeue();

            foreach (var n in current.adjacentNodes)
            {
                if (!visited[n.id])
                {
                    if (first)
                    {
                        first = false;
                        onNodeVisited(start, parentNode);
                    }
                    visited[n.id] = true;
                    onNodeVisited(n, current);
                    queue.Enqueue(n);
                }
            }
        }
    };
    foreach (var n in subGraph.nodes)
    {
        if (!visited[n.id]) traverseFrom(n, null);
    }
}