Grid Graph
A multi-dimensional, rectangular grid of vertices with user-defined dimension lengths and optional wrapping per dimension.
Defined in: <boost/graph/grid_graph.hpp>
Models: IncidenceGraph, AdjacencyGraph, VertexListGraph, EdgeListGraph,
BidirectionalGraph, AdjacencyMatrix
grid_graph does not support bundled properties. To associate data with
grid cells (e.g. terrain costs), maintain an external container indexed by the
grid’s vertex index: std::vector<double> cost(num_vertices(g));
|
Flat grid
The simplest case: a rectangular grid with no wrapping. Corner vertices have fewer neighbors than interior vertices.
#include <boost/graph/grid_graph.hpp>
#include <boost/array.hpp>
#include <iostream>
int main() {
using namespace boost;
using Graph = grid_graph<2>;
using Vertex = graph_traits<Graph>::vertex_descriptor;
// 3x3 flat grid (no wrapping)
boost::array<std::size_t, 2> lengths = {{ 3, 3 }};
Graph g(lengths);
std::cout << num_vertices(g) << " vertices, "
<< num_edges(g) << " edges\n";
// Corner vertex has 2 neighbors, edge vertex has 3, center has 4
for (auto vi = vertices(g).first; vi != vertices(g).second; ++vi) {
Vertex v = *vi;
std::cout << "(" << v[0] << "," << v[1] << ") degree="
<< out_degree(v, g) << "\n";
}
}
9 vertices, 24 edges
(0,0) degree=2
(1,0) degree=3
(2,0) degree=2
(0,1) degree=3
(1,1) degree=4
(2,1) degree=3
(0,2) degree=2
(1,2) degree=3
(2,2) degree=2
Torus (all dimensions wrap)
Pass true as the second constructor argument to wrap all dimensions. Every
vertex now has the same degree.
#include <boost/graph/grid_graph.hpp>
#include <boost/array.hpp>
#include <iostream>
int main() {
using namespace boost;
using Graph = grid_graph<2>;
using Vertex = graph_traits<Graph>::vertex_descriptor;
// 3x3 torus (all dimensions wrap)
boost::array<std::size_t, 2> lengths = {{ 3, 3 }};
Graph g(lengths, true);
std::cout << num_vertices(g) << " vertices, "
<< num_edges(g) << " edges\n";
// Every vertex has exactly 4 neighbors on a torus
for (auto vi = vertices(g).first; vi != vertices(g).second; ++vi) {
Vertex v = *vi;
std::cout << "(" << v[0] << "," << v[1] << ") degree="
<< out_degree(v, g) << "\n";
}
}
9 vertices, 36 edges
(0,0) degree=4
(1,0) degree=4
(2,0) degree=4
(0,1) degree=4
(1,1) degree=4
(2,1) degree=4
(0,2) degree=4
(1,2) degree=4
(2,2) degree=4
Cylinder (mixed wrapping)
Pass a boost::array<bool, Dimensions> to control wrapping per dimension.
Here dimension 0 wraps (cylinder) but dimension 1 does not.
#include <boost/graph/grid_graph.hpp>
#include <boost/array.hpp>
#include <iostream>
int main() {
using namespace boost;
using Graph = grid_graph<2>;
using Vertex = graph_traits<Graph>::vertex_descriptor;
// 4x3 cylinder: dimension 0 wraps, dimension 1 does not
boost::array<std::size_t, 2> lengths = {{ 4, 3 }};
boost::array<bool, 2> wrap = {{ true, false }};
Graph g(lengths, wrap);
std::cout << num_vertices(g) << " vertices, "
<< num_edges(g) << " edges\n";
// Navigate: wrapping in dimension 0
Vertex corner = vertex(0, g);
Vertex wrapped = g.previous(corner, 0); // wraps to (3,0)
std::cout << "\nFrom (" << corner[0] << "," << corner[1] << "):\n";
std::cout << " previous in dim 0 (wraps) = ("
<< wrapped[0] << "," << wrapped[1] << ")\n";
// Navigate: no wrapping in dimension 1
Vertex same = g.previous(corner, 1); // stays at (0,0)
std::cout << " previous in dim 1 (stops) = ("
<< same[0] << "," << same[1] << ")\n";
}
12 vertices, 40 edges
From (0,0):
previous in dim 0 (wraps) = (3,0)
previous in dim 1 (stops) = (0,0)
Higher dimensions
The Dimensions template parameter is a compile-time constant. A 3D grid
works the same way.
#include <boost/graph/grid_graph.hpp>
#include <boost/array.hpp>
#include <iostream>
int main() {
using namespace boost;
using Graph = grid_graph<3>;
using Vertex = graph_traits<Graph>::vertex_descriptor;
// 3x3x3 cube (no wrapping)
boost::array<std::size_t, 3> lengths = {{ 3, 3, 3 }};
Graph g(lengths);
std::cout << num_vertices(g) << " vertices, "
<< num_edges(g) << " edges\n";
// Corner vertex: 3 neighbors. Center vertex: 6 neighbors.
Vertex corner = vertex(0, g);
Vertex center = {{ 1, 1, 1 }};
std::cout << "corner (" << corner[0] << "," << corner[1] << ","
<< corner[2] << ") degree=" << out_degree(corner, g) << "\n";
std::cout << "center (" << center[0] << "," << center[1] << ","
<< center[2] << ") degree=" << out_degree(center, g) << "\n";
}
27 vertices, 108 edges
corner (0,0,0) degree=3
center (1,1,1) degree=6
Synopsis
template <std::size_t Dimensions,
typename VertexIndex = std::size_t,
typename EdgeIndex = VertexIndex>
class grid_graph;
Template Parameters
| Parameter | Description | Default |
|---|---|---|
|
Number of dimensions (compile-time constant). |
|
|
Integer type for vertex indices. |
|
|
Integer type for edge indices. |
same as |
Constructors
grid_graph(boost::array<VertexIndex, Dimensions> lengths);
Create an unwrapped grid with the given dimension lengths.
grid_graph(boost::array<VertexIndex, Dimensions> lengths,
bool wrap_all);
Create a grid where all dimensions wrap (true) or none wrap (false).
grid_graph(boost::array<VertexIndex, Dimensions> lengths,
boost::array<bool, Dimensions> wrap_per_dim);
Create a grid with per-dimension wrapping control.
Member Functions
std::size_t dimensions();
Returns the number of dimensions.
VertexIndex length(std::size_t dim);
Returns the length of dimension dim.
bool wrapped(std::size_t dim);
Returns whether dimension dim wraps.
vertex_descriptor next(vertex_descriptor v, std::size_t dim,
vertices_size_type distance = 1);
vertex_descriptor previous(vertex_descriptor v, std::size_t dim,
vertices_size_type distance = 1);
Move along a dimension. In an unwrapped dimension, next stops at the last
vertex and previous stops at the first. In a wrapped dimension, movement
wraps around.
Indexing
Vertices and edges can be addressed by integer index:
vertex_descriptor vertex(vertices_size_type idx, const grid_graph& g);
edges_size_type get(edge_index_t, const grid_graph& g, edge_descriptor e);
edge_descriptor edge_at(edges_size_type idx, const grid_graph& g);
The vertex descriptor is a boost::array<VertexIndex, Dimensions> that can
be indexed by dimension: v[0] is the position in dimension 0, v[1] in
dimension 1, etc.