Find the connected components in an undirected graph represented by a matrix. Args: order (np.ndarray): A matrix with values 0 or 1 indicating undirected graph edges. `order[i][j] = 1` means an edge between `i` and `j`, and `0` means no edge. Returns:
(order: np.ndarray)
| 51 | |
| 52 | @no_type_check |
| 53 | def components(order: np.ndarray) -> List[List[int]]: |
| 54 | """ |
| 55 | Find the connected components in an undirected graph represented by a matrix. |
| 56 | |
| 57 | Args: |
| 58 | order (np.ndarray): A matrix with values 0 or 1 indicating |
| 59 | undirected graph edges. `order[i][j] = 1` means an edge between `i` |
| 60 | and `j`, and `0` means no edge. |
| 61 | |
| 62 | Returns: |
| 63 | List[List[int]]: A list of List where each List contains the indices of |
| 64 | nodes in the same connected component. |
| 65 | |
| 66 | Example: |
| 67 | order = np.array([ |
| 68 | [1, 1, 0, 0], |
| 69 | [1, 1, 1, 0], |
| 70 | [0, 1, 1, 0], |
| 71 | [0, 0, 0, 1] |
| 72 | ]) |
| 73 | components(order) |
| 74 | # [[0, 1, 2], [3]] |
| 75 | """ |
| 76 | |
| 77 | i2g: Dict[int, int] = {} # index to group mapping |
| 78 | next_group = 0 |
| 79 | n = order.shape[0] |
| 80 | for i in range(n): |
| 81 | connected_groups = {i2g[j] for j in np.nonzero(order[i, :])[0] if j in i2g} |
| 82 | |
| 83 | # If the node is not part of any group |
| 84 | # and is not connected to any groups, assign a new group |
| 85 | if not connected_groups: |
| 86 | i2g[i] = next_group |
| 87 | next_group += 1 |
| 88 | else: |
| 89 | # If the node is connected to multiple groups, we merge them |
| 90 | main_group = min(connected_groups) |
| 91 | for j in np.nonzero(order[i, :])[0]: |
| 92 | if i2g.get(j) in connected_groups: |
| 93 | i2g[j] = main_group |
| 94 | i2g[i] = main_group |
| 95 | |
| 96 | # Convert i2g to a list of Lists |
| 97 | groups: Dict[int, List[int]] = {} |
| 98 | for index, group in i2g.items(): |
| 99 | if group not in groups: |
| 100 | groups[group] = [] |
| 101 | groups[group].append(index) |
| 102 | |
| 103 | return list(groups.values()) |
no test coverage detected
searching dependent graphs…