How do I find the adjacency matrix for the nodes of an n-dimensional finite grid?

1.7k Views Asked by At

I have an orthotopic grid, in n-dimensions (usually small ~<3), where each node is connected to it's orthogonal neighbours. The grid may be any number of nodes long, but is finite (and usually small - ~<10) in each dimension. The edges of the grid are undirected.

Given the grid dimensions (e.g. (3,4,3)), how can I generate an adjacency matrix for the nodes (1=edge, 0=no edge)?

2

There are 2 best solutions below

0
On

Ok, so I worked it out, after a lot of trial and error. Here is the code that I'm using in python. If there is a better way of doing this, I would happily accept another answer.

import numpy as np

def _unserialise_coordinate(serial, spacing):
    coord = []
    for i in range(len(spacing)):
        coord.append(int(np.floor(serial/spacing[i])))
        serial = int(serial % spacing[i])

    return(coord)

def _serialise_coordinate(coord, spacing):
    return(np.dot(coord, spacing))

def _generate_adjacency_matrix(grid_dimensions):
    """Generate an adjacency matrix for nodes of an orthotopic grid with
    dimensions given by grid_dimensions
    """
    n_centres = np.prod(grid_dimensions)

    adjacency = np.zeros((n_centres, n_centres))

    spacing = [int(np.prod(grid_dimensions[(k+1):])) for k in range(len(grid_dimensions))]

    for i in range(n_centres):
        coord = _unserialise_coordinate(i, spacing)
        neighbours = []
        for d in range(len(grid_dimensions)):
            if coord[d] > 0:
                down = coord.copy()
                down[d] -= 1
                neighbours.append(down)
            if coord[d] < (grid_dimensions[d] - 1):
                up = coord.copy()
                up[d] += 1
                neighbours.append(up)

        for neighbour in neighbours:
            serial = _serialise_coordinate(neighbour, spacing)
            adjacency[i,serial] = 1

    return(adjacency)
1
On

Assuming "orthopic" grid is the carteisan product of $P_n$ and $P_m$ you can do it in a few lines with sage

sage: graphs.PathGraph(3).cartesian_product(graphs.PathGraph(4)).am()

[0 1 0 0 1 0 0 0 0 0 0 0] [1 0 1 0 0 1 0 0 0 0 0 0] [0 1 0 1 0 0 1 0 0 0 0 0] [0 0 1 0 0 0 0 1 0 0 0 0] [1 0 0 0 0 1 0 0 1 0 0 0] [0 1 0 0 1 0 1 0 0 1 0 0] [0 0 1 0 0 1 0 1 0 0 1 0] [0 0 0 1 0 0 1 0 0 0 0 1] [0 0 0 0 1 0 0 0 0 1 0 0] [0 0 0 0 0 1 0 0 1 0 1 0] [0 0 0 0 0 0 1 0 0 1 0 1] [0 0 0 0 0 0 0 1 0 0 1 0]