3 #ifndef ANDRES_GRAPH_GRID_GRAPH_HXX
4 #define ANDRES_GRAPH_GRID_GRAPH_HXX
11 #include <initializer_list>
13 #include "adjacency.hxx"
14 #include "visitor.hxx"
21 template <
unsigned char D = 2,
class VISITOR = IdleGraphVisitor<std::
size_t> >
51 class AdjacencyIterator
52 :
public std::iterator <
53 std::random_access_iterator_tag,
58 typedef std::iterator <
59 std::random_access_iterator_tag,
62 typedef typename Base::difference_type difference_type;
63 typedef typename Base::pointer pointer;
64 typedef typename Base::reference reference;
67 AdjacencyIterator(
const GraphType&);
68 AdjacencyIterator(
const GraphType&,
const size_type);
72 AdjacencyIterator& operator+=(
const difference_type);
73 AdjacencyIterator& operator-=(
const difference_type);
74 AdjacencyIterator& operator++();
75 AdjacencyIterator& operator--();
76 AdjacencyIterator operator++(
int);
77 AdjacencyIterator operator--(
int);
78 AdjacencyIterator operator+(
const difference_type)
const;
79 AdjacencyIterator operator-(
const difference_type)
const;
80 difference_type operator-(
const AdjacencyIterator&)
const;
83 bool operator==(
const AdjacencyIterator&)
const;
84 bool operator!=(
const AdjacencyIterator&)
const;
85 bool operator<(
const AdjacencyIterator&)
const;
86 bool operator<=(
const AdjacencyIterator&)
const;
87 bool operator>(
const AdjacencyIterator&)
const;
88 bool operator>=(
const AdjacencyIterator&)
const;
91 reference operator*();
93 reference operator[](
const difference_type);
96 const GraphType* graph_;
103 :
public AdjacencyIterator {
106 typedef AdjacencyIterator Base;
108 typedef typename Base::difference_type difference_type;
109 typedef value_type* pointer;
110 typedef value_type& reference;
113 VertexIterator(
const VertexIterator&);
114 VertexIterator(
const AdjacencyIterator&);
115 VertexIterator(
const GraphType&);
116 VertexIterator(
const GraphType&,
const size_type);
120 value_type operator*()
const;
121 value_type operator[](
const difference_type)
const;
125 pointer operator->()
const;
129 :
public AdjacencyIterator {
131 typedef GridGraph<DIMENSION, Visitor> GraphType;
132 typedef AdjacencyIterator Base;
134 typedef typename Base::difference_type difference_type;
135 typedef value_type* pointer;
136 typedef value_type& reference;
139 EdgeIterator(
const EdgeIterator&);
140 EdgeIterator(
const AdjacencyIterator&);
141 EdgeIterator(
const GraphType&);
142 EdgeIterator(
const GraphType&,
const size_type);
146 value_type operator*()
const;
147 value_type operator[](
const difference_type)
const;
149 pointer operator->()
const;
204 std::array<size_type, DIMENSION> edgeIndexOffsets_;
205 std::array<size_type, DIMENSION> vertexIndexOffsets_;
206 std::array<VertexCoordinate, DIMENSION> edgeShapes_;
220 template<
unsigned char D,
class VISITOR>
233 template<
unsigned char D,
class VISITOR>
239 : numberOfEdges_ (edgeIndexOffsets_[DIMENSION - 1]) {
248 template<
unsigned char D,
class VISITOR>
251 std::initializer_list<std::size_t> shape,
254 : numberOfEdges_ (edgeIndexOffsets_[DIMENSION - 1]) {
255 assert(shape.size()==D);
257 std::copy(shape.begin(), shape.end(), vCoord.begin());
266 template<
unsigned char D,
class VISITOR>
272 std::fill(shape.begin(), shape.end(), 0);
273 assign(shape, visitor);
281 template<
unsigned char D,
class VISITOR>
294 for(i = 0; i < DIMENSION; ++i) {
295 vertexIndexOffsets_[i] = cumprod;
296 cumprod *= shape_[i];
298 numberOfVertices_ = cumprod;
302 for(
size_type i = 0; i < DIMENSION; ++i) {
305 if(edgeShape[i] > 0) {
311 for(
size_type j = 1; j < DIMENSION; ++j) {
312 cumprod *= edgeShape[j];
314 edgeIndexOffsets_[i] = (edgeIndexOffset += cumprod);
328 template<
unsigned char D,
class VISITOR>
333 return VertexIterator(*
this, vertex, 0);
344 template<
unsigned char D,
class VISITOR>
349 return VertexIterator(*
this, vertex, numberOfEdgesFromVertex(vertex));
360 template<
unsigned char D,
class VISITOR>
365 return VertexIterator(*
this, vertex, 0);
376 template<
unsigned char D,
class VISITOR>
381 return VertexIterator(*
this, vertex, numberOfEdgesFromVertex(vertex));
392 template<
unsigned char D,
class VISITOR>
397 return EdgeIterator(*
this, vertex, 0);
408 template<
unsigned char D,
class VISITOR>
413 return EdgeIterator(*
this, vertex, numberOfEdgesFromVertex(vertex));
424 template<
unsigned char D,
class VISITOR>
429 return EdgeIterator(*
this, vertex, 0);
440 template<
unsigned char D,
class VISITOR>
445 return EdgeIterator(*
this, vertex, numberOfEdgesFromVertex(vertex));
456 template<
unsigned char D,
class VISITOR>
461 return AdjacencyIterator(*
this, vertex, 0);
472 template<
unsigned char D,
class VISITOR>
477 return AdjacencyIterator(*
this, vertex, numberOfEdgesFromVertex(vertex));
488 template<
unsigned char D,
class VISITOR>
493 return AdjacencyIterator(*
this, vertex, 0);
504 template<
unsigned char D,
class VISITOR>
509 return AdjacencyIterator(*
this, vertex, numberOfEdgesFromVertex(vertex));
514 template<
unsigned char D,
class VISITOR>
517 return numberOfVertices_;
522 template<
unsigned char D,
class VISITOR>
525 return numberOfEdges_;
534 template<
unsigned char D,
class VISITOR>
539 assert(vertex < numberOfVertices());
541 this->vertex(vertex, edgeCoordinate);
543 for(
size_type i = 0; i < DIMENSION; ++i) {
544 const size_type& coordinate = edgeCoordinate[i];
546 ++numEdgesFromVertex;
548 if(coordinate < (shape_[i] - 1)) {
549 ++numEdgesFromVertex;
552 return numEdgesFromVertex;
561 template<
unsigned char D,
class VISITOR>
566 return numberOfEdgesFromVertex(vertex);
574 template<
unsigned char D,
class VISITOR>
580 assert(edge < numberOfEdges());
583 this->edge(edge, edgeCoordinate);
589 return pivotIndex + vertexIndexOffsets_[edgeCoordinate.
dimension_];
601 template<
unsigned char D,
class VISITOR>
607 assert(j < numberOfEdgesFromVertex(vertex));
609 this->vertex(vertex, vertexCoordinate);
612 vertexFromVertex(vertexCoordinate, j, direction, isSmaller);
615 --pivotVertexCoordinate[direction];
631 template<
unsigned char D,
class VISITOR>
637 assert(j < numberOfEdgesToVertex(vertex));
638 return edgeFromVertex(vertex, j);
650 template<
unsigned char D,
class VISITOR>
656 assert(j < numberOfEdgesToVertex(vertex));
658 this->vertex(vertex, vertexCoordinate);
661 return vertexFromVertex(vertexCoordinate, j, direction, isSmaller);
674 template<
unsigned char D,
class VISITOR>
680 assert(j < numberOfEdgesToVertex(vertex));
681 return vertexFromVertex(vertex, j);
688 template<
unsigned char D,
class VISITOR>
694 assert(j < numberOfEdgesToVertex(vertex));
701 this->vertex(vertex, vertexCoordinate);
703 adjacencyFromVertex(vertexCoordinate, j, adjacentVertexIndex, adjacentEdgeIndex);
705 return AdjacencyType(adjacentVertexIndex, adjacentEdgeIndex);
714 template<
unsigned char D,
class VISITOR>
720 return adjacencyFromVertex(vertex, j);
732 template<
unsigned char D,
class VISITOR>
733 inline std::pair<bool, typename GridGraph<D, VISITOR>::size_type>
738 assert(vertex0 < numberOfVertices());
739 assert(vertex1 < numberOfVertices());
740 if(vertex0 < vertex1) {
743 for(i = 0; i < DIMENSION - 1; ++i) {
744 if(offset == vertexIndexOffsets_[i]) {
746 vertex(vertex0, vertexCoordinate0);
747 if(vertexCoordinate0[i] != shape_[i] - 1) {
749 const size_type edgeIndex = edge(edgeCoordinate);
750 return std::make_pair(
true, edgeIndex);
754 if(offset == vertexIndexOffsets_[i]) {
756 vertex(vertex0, vertexCoordinate0);
758 const size_type edgeIndex = edge(edgeCoordinate);
759 return std::make_pair(
true, edgeIndex);
765 for(i = 0; i < DIMENSION - 1; ++i) {
766 if(offset == vertexIndexOffsets_[i]) {
768 vertex(vertex1, vertexCoordinate1);
769 if(vertexCoordinate1[i] != shape_[i] - 1) {
771 const size_type edgeIndex = edge(edgeCoordinate);
772 return std::make_pair(
true, edgeIndex);
776 if(offset == vertexIndexOffsets_[i]) {
778 vertex(vertex1, vertexCoordinate1);
780 const size_type edgeIndex = edge(edgeCoordinate);
781 return std::make_pair(
true, edgeIndex);
784 return std::make_pair(
false, 0);
791 template<
unsigned char D,
class VISITOR>
803 template<
unsigned char D,
class VISITOR>
809 assert(vertexIndex0 < numberOfVertices());
810 assert(vertexIndex1 < numberOfVertices());
812 std::pair<bool, std::size_t> p = findEdge(vertexIndex0, vertexIndex1);
813 if(p.first ==
true) {
816 throw std::runtime_error(
"Edge not found.");
825 template<
unsigned char D,
class VISITOR>
831 assert(vertexIndex < numberOfVertices_);
833 for(i = 0; i < DIMENSION - 1; ++i) {
834 vertexCoordinate[i] = vertexIndex % shape_[i];
835 vertexIndex = vertexIndex / shape_[i];
837 vertexCoordinate[i] = vertexIndex;
844 template<
unsigned char D,
class VISITOR>
849 return shape_[dimension];
857 template<
unsigned char D,
class VISITOR>
862 size_type index = vertexCoordinate[DIMENSION - 1];
863 for(
size_type i = DIMENSION - 1; i > 0; --i) {
864 index = index * shape_[i - 1] + vertexCoordinate[i - 1];
876 template<
unsigned char D,
class VISITOR>
881 assert(edgeCoordinate.
dimension_ < DIMENSION);
887 size_type index = pivotCoordinate[DIMENSION - 1];
888 for(
size_type i = DIMENSION - 1; i > 0; --i) {
889 index = index * edgeShape[i - 1] + pivotCoordinate[i - 1];
892 const size_type& offset = edgeIndexOffsets_[dimension - 1];
908 template<
unsigned char D,
class VISITOR>
915 assert(edgeIndex < numberOfEdges());
918 for(direction = 0; edgeIndex >= edgeIndexOffsets_[direction]; ++direction);
920 const size_type& offset = edgeIndexOffsets_[direction - 1];
928 for(i = 0; i < DIMENSION - 1; ++i) {
929 pivotCoordinate[i] = edgeIndex % edgeShape[i];
930 edgeIndex = edgeIndex / edgeShape[i];
932 pivotCoordinate[i] = edgeIndex;
952 template<
unsigned char D,
class VISITOR>
955 const VertexCoordinate& vertexCoordinate,
957 size_type& direction,
960 assert(vertex(vertexCoordinate) < numberOfVertices());
961 VertexCoordinate modifieableVertexCoordinate = vertexCoordinate;
963 for(size_type i = DIMENSION; i > 0; --i) {
964 if(vertexCoordinate[i - 1] > 0) {
968 --modifieableVertexCoordinate[i - 1];
969 const size_type vertexIndex = vertex(modifieableVertexCoordinate);
975 for(size_type i = 0; i < DIMENSION; ++i) {
976 if(vertexCoordinate[i] < shape_[i] - 1) {
980 ++modifieableVertexCoordinate[i];
981 const size_type vertexIndex = vertex(modifieableVertexCoordinate);
987 throw std::out_of_range(
"vertex neighbor index out of range.");
990 template<
unsigned char D,
class VISITOR>
993 const VertexCoordinate& vertexCoordinate,
995 size_type& adjacentVertexIndex,
996 size_type& adjacentEdgeIndex
998 assert(vertex(vertexCoordinate) < numberOfVertices());
1001 adjacentVertexIndex = vertexFromVertex(vertexCoordinate, j, direction, isSmaller);
1003 VertexCoordinate pivotVertexCoordinate = vertexCoordinate;
1004 --pivotVertexCoordinate[direction];
1005 adjacentEdgeIndex = edge(EdgeCoordinate(pivotVertexCoordinate, direction));
1008 adjacentEdgeIndex = edge(EdgeCoordinate(vertexCoordinate, direction));
1023 template<
unsigned char D,
class VISITOR>
1027 const bool isSmaller
1029 : pivotCoordinate_(pivotCoordinate),
1030 dimension_(dimension) {
1040 template<
unsigned char D,
class VISITOR>
1049 template<
unsigned char D,
class VISITOR>
1056 template<
unsigned char D,
class VISITOR>
1059 const GraphType& graph
1067 template<
unsigned char D,
class VISITOR>
1069 GridGraph<D, VISITOR>::AdjacencyIterator::AdjacencyIterator(
1070 const GraphType& graph,
1077 assert(vertex < graph.numberOfVertices());
1080 template<
unsigned char D,
class VISITOR>
1082 GridGraph<D, VISITOR>::AdjacencyIterator::AdjacencyIterator(
1083 const GraphType& graph,
1089 adjacencyIndex_(adjacencyIndex),
1091 assert(vertex < graph.numberOfVertices());
1092 assert(adjacencyIndex <= graph.numberOfVertices());
1095 template<
unsigned char D,
class VISITOR>
1096 inline typename GridGraph<D, VISITOR>::AdjacencyIterator&
1097 GridGraph<D, VISITOR>::AdjacencyIterator::operator+=(
1098 const difference_type d
1100 adjacencyIndex_ += d;
1104 template<
unsigned char D,
class VISITOR>
1105 inline typename GridGraph<D, VISITOR>::AdjacencyIterator&
1106 GridGraph<D, VISITOR>::AdjacencyIterator::operator-=(
1107 const difference_type d
1109 adjacencyIndex_ -= d;
1113 template<
unsigned char D,
class VISITOR>
1114 inline typename GridGraph<D, VISITOR>::AdjacencyIterator&
1115 GridGraph<D, VISITOR>::AdjacencyIterator::operator++() {
1120 template<
unsigned char D,
class VISITOR>
1121 inline typename GridGraph<D, VISITOR>::AdjacencyIterator&
1122 GridGraph<D, VISITOR>::AdjacencyIterator::operator--() {
1127 template<
unsigned char D,
class VISITOR>
1128 inline typename GridGraph<D, VISITOR>::AdjacencyIterator
1129 GridGraph<D, VISITOR>::AdjacencyIterator::operator++(
int) {
1130 AdjacencyIterator copy = *
this;
1135 template<
unsigned char D,
class VISITOR>
1136 inline typename GridGraph<D, VISITOR>::AdjacencyIterator
1137 GridGraph<D, VISITOR>::AdjacencyIterator::operator--(
int) {
1138 AdjacencyIterator copy = *
this;
1143 template<
unsigned char D,
class VISITOR>
1144 inline typename GridGraph<D, VISITOR>::AdjacencyIterator
1145 GridGraph<D, VISITOR>::AdjacencyIterator::operator+(
1146 const difference_type d
1148 AdjacencyIterator copy = *
this;
1153 template<
unsigned char D,
class VISITOR>
1154 inline typename GridGraph<D, VISITOR>::AdjacencyIterator
1155 GridGraph<D, VISITOR>::AdjacencyIterator::operator-(
1156 const difference_type d
1158 AdjacencyIterator copy = *
this;
1163 template<
unsigned char D,
class VISITOR>
1164 inline typename GridGraph<D, VISITOR>::AdjacencyIterator::difference_type
1165 GridGraph<D, VISITOR>::AdjacencyIterator::operator-(
1166 const AdjacencyIterator& adjacencyIterator
1168 return adjacencyIndex_ - adjacencyIterator.adjacencyIndex_;
1171 template<
unsigned char D,
class VISITOR>
1173 GridGraph<D, VISITOR>::AdjacencyIterator::operator==(
1174 const AdjacencyIterator& other
1176 return adjacencyIndex_ == other.adjacencyIndex_
1177 && vertex_ == other.vertex_
1178 && graph_ == other.graph_;
1181 template<
unsigned char D,
class VISITOR>
1183 GridGraph<D, VISITOR>::AdjacencyIterator::operator!=(
1184 const AdjacencyIterator& other
1186 return adjacencyIndex_ != other.adjacencyIndex_
1187 || vertex_ != other.vertex_
1188 || graph_ != other.graph_;
1191 template<
unsigned char D,
class VISITOR>
1193 GridGraph<D, VISITOR>::AdjacencyIterator::operator<(
1194 const AdjacencyIterator& other
1196 return adjacencyIndex_ < other.adjacencyIndex_
1197 && vertex_ == other.vertex_
1198 && graph_ == other.graph_;
1201 template<
unsigned char D,
class VISITOR>
1203 GridGraph<D, VISITOR>::AdjacencyIterator::operator<=(
1204 const AdjacencyIterator& other
1206 return adjacencyIndex_ <= other.adjacencyIndex_
1207 && vertex_ == other.vertex_
1208 && graph_ == other.graph_;
1211 template<
unsigned char D,
class VISITOR>
1213 GridGraph<D, VISITOR>::AdjacencyIterator::operator>(
1214 const AdjacencyIterator& other
1216 return adjacencyIndex_ > other.adjacencyIndex_
1217 && vertex_ == other.vertex_
1218 && graph_ == other.graph_;
1221 template<
unsigned char D,
class VISITOR>
1223 GridGraph<D, VISITOR>::AdjacencyIterator::operator>=(
1224 const AdjacencyIterator& other
1226 return adjacencyIndex_ >= other.adjacencyIndex_
1227 && vertex_ == other.vertex_
1228 && graph_ == other.graph_;
1242 template<
unsigned char D,
class VISITOR>
1243 inline typename GridGraph<D, VISITOR>::AdjacencyIterator::reference
1244 GridGraph<D, VISITOR>::AdjacencyIterator::operator*() {
1245 adjacency_ = graph_->adjacencyFromVertex(vertex_, adjacencyIndex_);
1249 template<
unsigned char D,
class VISITOR>
1250 inline typename GridGraph<D, VISITOR>::AdjacencyIterator::pointer
1251 GridGraph<D, VISITOR>::AdjacencyIterator::operator->() {
1252 adjacency_ = graph_->adjacencyFromVertex(vertex_, adjacencyIndex_);
1256 template<
unsigned char D,
class VISITOR>
1257 inline typename GridGraph<D, VISITOR>::AdjacencyIterator::reference
1258 GridGraph<D, VISITOR>::AdjacencyIterator::operator[](
1259 const difference_type j
1261 adjacency_ = graph_->adjacencyFromVertex(vertex_, adjacencyIndex_ + j);
1267 template<
unsigned char D,
class VISITOR>
1269 GridGraph<D, VISITOR>::VertexIterator::VertexIterator()
1273 template<
unsigned char D,
class VISITOR>
1275 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1276 const GraphType& graph
1281 template<
unsigned char D,
class VISITOR>
1283 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1284 const GraphType& graph,
1287 : Base(graph, vertex)
1290 template<
unsigned char D,
class VISITOR>
1292 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1293 const GraphType& graph,
1297 : Base(graph, vertex, adjacencyIndex)
1300 template<
unsigned char D,
class VISITOR>
1302 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1303 const VertexIterator& it
1305 : Base(*(it.graph_), it.vertex_, it.adjacencyIndex_)
1308 template<
unsigned char D,
class VISITOR>
1310 GridGraph<D, VISITOR>::VertexIterator::VertexIterator(
1311 const AdjacencyIterator& it
1316 template<
unsigned char D,
class VISITOR>
1317 inline typename GridGraph<D, VISITOR>::VertexIterator::value_type
1318 GridGraph<D, VISITOR>::VertexIterator::operator*()
const {
1319 return Base::graph_->vertexFromVertex(Base::vertex_, Base::adjacencyIndex_);
1322 template<
unsigned char D,
class VISITOR>
1323 inline typename GridGraph<D, VISITOR>::VertexIterator::value_type
1324 GridGraph<D, VISITOR>::VertexIterator::operator[](
1325 const difference_type j
1327 return Base::graph_->vertexFromVertex(Base::vertex_, Base::adjacencyIndex_ + j);
1330 template<
unsigned char D,
class VISITOR>
1332 GridGraph<D, VISITOR>::VertexIterator::coordinate(
1335 const size_type opposite = Base::graph_->vertexFromVertex(Base::vertex_, Base::adjacencyIndex_);
1336 Base::graph_->vertex(opposite, vertexCoordinate);
1341 template<
unsigned char D,
class VISITOR>
1343 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator()
1347 template<
unsigned char D,
class VISITOR>
1349 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1350 const GraphType& graph
1355 template<
unsigned char D,
class VISITOR>
1357 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1358 const GraphType& graph,
1361 : Base(graph, vertex)
1364 template<
unsigned char D,
class VISITOR>
1366 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1367 const GraphType& graph,
1371 : Base(graph, vertex, adjacencyIndex)
1374 template<
unsigned char D,
class VISITOR>
1376 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1377 const EdgeIterator& it
1379 : Base(*(it.graph_), it.vertex_, it.adjacencyIndex_)
1382 template<
unsigned char D,
class VISITOR>
1384 GridGraph<D, VISITOR>::EdgeIterator::EdgeIterator(
1385 const AdjacencyIterator& it
1390 template<
unsigned char D,
class VISITOR>
1391 inline typename GridGraph<D, VISITOR>::EdgeIterator::value_type
1392 GridGraph<D, VISITOR>::EdgeIterator::operator*()
const {
1393 return Base::graph_->edgeFromVertex(Base::vertex_, Base::adjacencyIndex_);
1396 template<
unsigned char D,
class VISITOR>
1397 inline typename GridGraph<D, VISITOR>::EdgeIterator::value_type
1398 GridGraph<D, VISITOR>::EdgeIterator::operator[](
1399 const difference_type j
1401 return Base::graph_->edgeFromVertex(Base::vertex_, Base::adjacencyIndex_ + j);
1410 #endif // #ifndef ANDRES_GRAPH_GRID_GRAPH_HXX