Graphs are often encoded by their adjacency matrix: a symmetric matrix where in the entry
means there is an edge between vertices labeled
and
. Another useful encoding is the incidence matrix, in which rows correspond to edges and columns to vertices (or the other way around). Having
in the entry
means that
th edge is incident to
th vertex. Simply put, each row contains exactly two nonzero entries, which indicate the endpoints of an edge.
An incidence matrix is generally rectangular. It is the square matrix when the graph has as many edges as vertices. For example, the 4-cycle has incidence matrix
(up to relabeling of vertices). This matrix is not invertible. Indeed, , which is a reflection of the fact that the graph is bipartite. Indeed, for any bipartite graph the
vector describing a 2-coloring of the vertices belongs to the kernel of the incidence matrix.
The incidence matrix of an odd cycle is invertible, however. What other such “invertible” graphs exist? Clearly, the disjoint union of “invertible” graphs is itself invertible, so we can focus on connected graphs.
There are no invertible graphs on 1 or 2 vertices. For 3 through 8 vertices, exhaustive search yields the following counts:
- 1 graph on 3 vertices (3-cycle)
- 1 graph on 4 vertices (3-cycle with an edge attached)
- 4 graphs on 5 vertices
- 8 graphs on 6 vertices
- 23 graphs on 7 vertices
- 55 graphs on 8 vertices
The numbers match the OEIS sequence A181688 but it’s not clear whether this is for real or a coincidence. The brute force search takes long for more than 8 vertices. It’s probably better to count such graphs by using their (folklore?) characterization as “trees planted on an odd cycle”, described by Chris Godsil on MathOverflow.
Some examples:
The examples were found and plotted by this Python script.
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
from itertools import combinations
def is_invertible(graph, n):
matrix = []
for i in range(n):
row = [0]*n
row[graph[i][0]] = 1
row[graph[i][1]] = 1
matrix.append(row)
return abs(np.linalg.det(matrix)) > 0.5
n = 6 # number of vertices
graphs = combinations(combinations(range(n), 2), n)
inv = []
for g in graphs:
if is_invertible(g, n):
gr = nx.Graph(g)
if nx.is_connected(gr) and not any([nx.is_isomorphic(gr, gr2) for gr2 in inv]):
inv.append(gr)
nx.draw_networkx(gr)
plt.savefig("graph{}_{}.png".format(n, len(inv)))
plt.clf()
print("There are {} connected invertible graphs with {} vertices".format(len(inv), n))