Arbitrary shape GridGraph
Admittedly the implementation below is not as simple or efficient as I wished. Some of the visualizations are a bit messy, but I think it works correctly.
Basically it tracks the planar graph boundary and tries to add new edges in regularity-admitting locations. Regular planar tilings are trivially present, but this code also generates Platonic graphs corresponding to regular Platonic polyhedra (these close on themselves, and don't have a "boundary"), and graphs corresponding to tilings in hyperbolic geometry.
Module[{regularGraphBoundary, takeClosestVertexGroup,
selectAdmissableArcs, addNewEdges, tryAddPolygon},
regularGraphBoundary[g_Graph, nvertices_Integer] :=
Graph[First /@
Select[Tally[Sort /@ Flatten@FindCycle[g, {nvertices}, All]],
Last@# == 1 &]];
takeClosestVertexGroup[g_Graph, groups_List] :=
First@TakeSmallestBy[
groups, Min[GraphDistance[g, 1, #] & /@ #] &, 1];
selectAdmissableArcs[g_Graph, candidates_List, nvertices_Integer,
targetdegree_Integer] :=
Select[
candidates,
VertexDegree[g, First@#] < targetdegree &&
And @@ (VertexDegree[g, #] == targetdegree & /@ #[[2 ;; -2]]) &&
VertexDegree[g, Last@#] < targetdegree &];
addNewEdges[g_Graph, oldvertices_List, nvertices_Integer] :=
GraphUnion[g,
Graph[UndirectedEdge @@@
Partition[{First@oldvertices,
Sequence @@ (Unique[] & /@
Range[nvertices - Length@oldvertices]),
Last@oldvertices},
2, 1]]];
tryAddPolygon[g_Graph, vertices_Integer, targetdegree_Integer] :=
Module[{graphboundary, admissablearcgroups},
graphboundary = regularGraphBoundary[g, vertices];
If[EmptyGraphQ@graphboundary,
g,
admissablearcgroups =
Flatten[
Table[
selectAdmissableArcs[g,
Partition[First /@ First@FindCycle@graphboundary, n, 1, 1],
vertices, targetdegree],
{n, vertices, 2, -1}],
1];
addNewEdges[
g, takeClosestVertexGroup[g, admissablearcgroups], vertices]]];
Grid[Table[
HighlightGraph[#, regularGraphBoundary[#, v]] &@
Nest[tryAddPolygon[#, v, d] &, CycleGraph[v], 150], {v, 3, 7}, {d,
3, 7}], Frame -> All]]
IGraph/M now has some new lattice graph generation features that might be useful (though not every graph of the type you describe can be generated through these functions).
Here's a demo through a few examples:
IGTriangularLattice[5]
IGTriangularLattice[{4, 5}]
IGBetheLattice[5]
There is IGLatticeMesh
which uses (a post-processed version of) Mathematica's built-in periodic tiling data to generate various meshes. These can be converted to graphs using IGMeshGraph
, or to face-face adjacency graphs (i.e. the dual) using IGMeshCellAdjacencyGraph[mesh, 2, VertexCoordinates -> Automatic]
.
IGLatticeMesh["Hexagonal"]
IGLatticeMesh["Hexagonal", {3, 2}]
IGLatticeMesh["Hexagonal", Polygon@CirclePoints[4, 6]]
IGLatticeMesh["Trihexagonal"]
Convert to graphs:
IGMeshGraph[%]
IGMeshCellAdjacencyGraph[%%, 2, VertexCoordinates -> Automatic]
In this last graph, not all non-boundary vertices have the same number of neighbours. I included it as an illustration of how to extract the dual lattice, which may be useful for some other tilings.