get_components.m 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. function [comps,comp_sizes] = get_components(adj)
  2. % GET_COMPONENTS Connected components
  3. %
  4. % [comps,comp_sizes] = get_components(adj);
  5. %
  6. % Returns the components of an undirected graph specified by the binary and
  7. % undirected adjacency matrix adj. Components and their constitutent nodes are
  8. % assigned the same index and stored in the vector, comps. The vector, comp_sizes,
  9. % contains the number of nodes beloning to each component.
  10. %
  11. % Inputs: adj, binary and undirected adjacency matrix
  12. %
  13. % Outputs: comps, vector of component assignments for each node
  14. % comp_sizes, vector of component sizes
  15. %
  16. % Note: disconnected nodes will appear as components of size 1
  17. %
  18. % J Goni, University of Navarra and Indiana University, 2009/2011
  19. if size(adj,1)~=size(adj,2)
  20. error('this adjacency matrix is not square');
  21. end
  22. if ~any(adj-triu(adj))
  23. adj = adj | adj';
  24. end
  25. %if main diagonal of adj do not contain all ones, i.e. autoloops
  26. if sum(diag(adj))~=size(adj,1)
  27. %the main diagonal is set to ones
  28. adj = adj|speye(size(adj));
  29. end
  30. %Dulmage-Mendelsohn decomposition
  31. [~,p,~,r] = dmperm(adj);
  32. %p indicates a permutation (along rows and columns)
  33. %r is a vector indicating the component boundaries
  34. % List including the number of nodes of each component. ith entry is r(i+1)-r(i)
  35. comp_sizes = diff(r);
  36. % Number of components found.
  37. num_comps = numel(comp_sizes);
  38. % initialization
  39. comps = zeros(1,size(adj,1));
  40. % first position of each component is set to one
  41. comps(r(1:num_comps)) = ones(1,num_comps);
  42. % cumulative sum produces a label for each component (in a consecutive way)
  43. comps = cumsum(comps);
  44. %re-order component labels according to adj.
  45. comps(p) = comps;