tensor manipulations
adjacency matrix
connected components
matrix conversion
graph theory

How to convert known connected component to adjacency matrix with tensor manipulations only?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

This question usually hides an important ambiguity: a connected component is a set of vertices, while an adjacency matrix describes edges. If all you know is that a group of vertices belongs to the same connected component, you still do not know which edges exist between them, so there is no unique adjacency matrix to recover.

What Information Is Sufficient

Suppose the component contains vertices 3, 7, 9, and 12. Many different graphs could produce that same connected component. It could be a path, a tree, a cycle, or a complete graph. The component membership alone tells you the vertices are reachable from one another, not which vertex pairs are adjacent.

So the first rule is simple: if you only have the node list, you cannot reconstruct the original adjacency matrix exactly. You need one of these extra assumptions:

  • the actual edge list inside the component
  • a rule that defines the edges, such as clique construction
  • a source adjacency matrix for the full graph that you want to slice down to the component

Once you have edge information, tensor-only construction is straightforward.

Building the Matrix from an Edge List

Assume you know the vertices in the component and the edges that belong to that component. A practical tensor workflow is:

  1. Remap global vertex ids to local component indices.
  2. Scatter ones into a zero matrix at the edge locations.
  3. Mirror the assignments if the graph is undirected.

Here is a runnable PyTorch example:

python
1import torch
2
3# Global vertex ids that form one connected component
4component = torch.tensor([3, 7, 9, 12])
5
6# Known edges in global indexing
7edges = torch.tensor([
8    [3, 7],
9    [7, 9],
10    [9, 12],
11    [12, 3],
12])
13
14n = component.numel()
15
16# Map global ids to local indices 0..n-1
17lookup = torch.full((component.max().item() + 1,), -1, dtype=torch.long)
18lookup[component] = torch.arange(n)
19
20local_edges = lookup[edges]
21
22adj = torch.zeros((n, n), dtype=torch.int64)
23adj[local_edges[:, 0], local_edges[:, 1]] = 1
24adj[local_edges[:, 1], local_edges[:, 0]] = 1  # undirected graph
25
26print(adj)

Output:

text
1tensor([[0, 1, 0, 1],
2        [1, 0, 1, 0],
3        [0, 1, 0, 1],
4        [1, 0, 1, 0]])

This code does not loop over edges in Python. The indexing and assignment happen through tensor operations, which is usually what people mean by tensor manipulations only.

If You Already Have the Full Graph Matrix

If the full graph adjacency matrix already exists, conversion is even simpler. You do not rebuild anything; you extract the rows and columns for the component vertices.

python
1import torch
2
3full_adj = torch.tensor([
4    [0, 1, 0, 0, 0],
5    [1, 0, 1, 0, 0],
6    [0, 1, 0, 1, 0],
7    [0, 0, 1, 0, 1],
8    [0, 0, 0, 1, 0],
9])
10
11component = torch.tensor([1, 2, 3])
12sub_adj = full_adj[component][:, component]
13
14print(sub_adj)

This is the cleanest case because the edge information is already encoded in the source matrix.

If You Mean a Complete Subgraph

Sometimes the real intent is not to recover the original edges, but to build a matrix that connects every pair of vertices in the component. That is a clique, not a generic connected component. In that special case, you can generate the adjacency matrix directly:

python
1import torch
2
3n = 4
4adj = torch.ones((n, n), dtype=torch.int64)
5adj.fill_diagonal_(0)
6
7print(adj)

That result is valid only if your graph model defines every pair as adjacent.

Common Pitfalls

The biggest mistake is assuming connected component membership uniquely determines adjacency. It does not. A component tells you reachability, not exact edges.

Another common issue is forgetting to remap global ids to local matrix positions. If your component vertices are 3, 7, 9, and 12, you usually want a 4 x 4 matrix, not a sparse 13 x 13 matrix with mostly empty rows.

For undirected graphs, remember to write both adj[i, j] and adj[j, i]. If you skip the mirrored assignment, the result is a directed matrix even when your graph is not directed.

Summary

  • A connected component alone is not enough to reconstruct a unique adjacency matrix.
  • You need edge information, a full source matrix, or an explicit rule such as clique construction.
  • With an edge list, tensor indexing and scatter-style assignment are enough to build the matrix.
  • Remap global vertex ids to local indices before creating the component matrix.
  • Mirror assignments for undirected graphs and clear the diagonal if self-loops are not wanted.

Course illustration
Course illustration

All Rights Reserved.