findConnectedComponents.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /**
  2. * This examples shows how to find all connected components of a graph.
  3. *
  4. * Created in response to https://github.com/anvaka/ngraph.graph/issues/18
  5. */
  6. module.exports = function findConnectedComponents(graph) {
  7. var nodeIdToComponentId = new Map();
  8. var connectedComponents = [];
  9. var lastComponentId = 0;
  10. graph.forEachNode(function(node) {
  11. if (nodeIdToComponentId.has(node.id)) {
  12. // we already seen this cluster. Ignore it.
  13. return;
  14. }
  15. // We found a new connected component:
  16. nodeIdToComponentId.set(node.id, lastComponentId);
  17. var currentComponent = [node.id];
  18. connectedComponents.push(currentComponent);
  19. // Let's find what other nodes belong to this component
  20. dfs(graph, node.id, otherNode => {
  21. let componentId = nodeIdToComponentId.get(otherNode.id)
  22. if (componentId !== undefined && componentId === lastComponentId) {
  23. // this is possible when we have a loop. Just ignore the node.
  24. return false;
  25. } else if (componentId !== undefined) {
  26. throw new Error('Reached a component from another component. DFS is broken?');
  27. }
  28. currentComponent.push(otherNode.id);
  29. nodeIdToComponentId.set(otherNode.id, lastComponentId);
  30. return true; // let's visit neighbors
  31. });
  32. lastComponentId += 1;
  33. });
  34. return connectedComponents;
  35. }
  36. function dfs(graph, startFromNodeId, visitor) {
  37. graph.forEachLinkedNode(startFromNodeId, function(otherNode) {
  38. if (visitor(otherNode)) dfs(graph, otherNode.id, visitor);
  39. });
  40. }