File indexing completed on 2025-01-18 09:37:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_GRAPH_GRID_GRAPH_HPP
0011 #define BOOST_GRAPH_GRID_GRAPH_HPP
0012
0013 #include <cmath>
0014 #include <functional>
0015 #include <numeric>
0016
0017 #include <boost/array.hpp>
0018 #include <boost/limits.hpp>
0019 #include <boost/graph/graph_traits.hpp>
0020 #include <boost/graph/properties.hpp>
0021 #include <boost/iterator/counting_iterator.hpp>
0022 #include <boost/iterator/transform_iterator.hpp>
0023 #include <boost/property_map/property_map.hpp>
0024
0025 #define BOOST_GRID_GRAPH_TEMPLATE_PARAMS \
0026 std::size_t DimensionsT, typename VertexIndexT, typename EdgeIndexT
0027
0028 #define BOOST_GRID_GRAPH_TYPE \
0029 grid_graph< DimensionsT, VertexIndexT, EdgeIndexT >
0030
0031 #define BOOST_GRID_GRAPH_TRAITS_T typename graph_traits< BOOST_GRID_GRAPH_TYPE >
0032
0033 namespace boost
0034 {
0035
0036
0037 template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS > class grid_graph;
0038
0039
0040
0041
0042
0043 template < typename Graph, typename Descriptor, typename Index >
0044 struct grid_graph_index_map
0045 {
0046 public:
0047 typedef Index value_type;
0048 typedef Index reference_type;
0049 typedef reference_type reference;
0050 typedef Descriptor key_type;
0051 typedef readable_property_map_tag category;
0052
0053 grid_graph_index_map() {}
0054
0055 grid_graph_index_map(const Graph& graph) : m_graph(&graph) {}
0056
0057 value_type operator[](key_type key) const
0058 {
0059 return (m_graph->index_of(key));
0060 }
0061
0062 friend inline Index get(
0063 const grid_graph_index_map< Graph, Descriptor, Index >& index_map,
0064 const typename grid_graph_index_map< Graph, Descriptor,
0065 Index >::key_type& key)
0066 {
0067 return (index_map[key]);
0068 }
0069
0070 protected:
0071 const Graph* m_graph;
0072 };
0073
0074 template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS >
0075 struct property_map< BOOST_GRID_GRAPH_TYPE, vertex_index_t >
0076 {
0077 typedef grid_graph_index_map< BOOST_GRID_GRAPH_TYPE,
0078 BOOST_GRID_GRAPH_TRAITS_T::vertex_descriptor,
0079 BOOST_GRID_GRAPH_TRAITS_T::vertices_size_type >
0080 type;
0081 typedef type const_type;
0082 };
0083
0084 template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS >
0085 struct property_map< BOOST_GRID_GRAPH_TYPE, edge_index_t >
0086 {
0087 typedef grid_graph_index_map< BOOST_GRID_GRAPH_TYPE,
0088 BOOST_GRID_GRAPH_TRAITS_T::edge_descriptor,
0089 BOOST_GRID_GRAPH_TRAITS_T::edges_size_type >
0090 type;
0091 typedef type const_type;
0092 };
0093
0094
0095
0096
0097
0098 template < typename Descriptor > struct grid_graph_reverse_edge_map
0099 {
0100 public:
0101 typedef Descriptor value_type;
0102 typedef Descriptor reference_type;
0103 typedef reference_type reference;
0104 typedef Descriptor key_type;
0105 typedef readable_property_map_tag category;
0106
0107 grid_graph_reverse_edge_map() {}
0108
0109 value_type operator[](const key_type& key) const
0110 {
0111 return (value_type(key.second, key.first));
0112 }
0113
0114 friend inline Descriptor get(
0115 const grid_graph_reverse_edge_map< Descriptor >& rev_map,
0116 const typename grid_graph_reverse_edge_map< Descriptor >::key_type& key)
0117 {
0118 return (rev_map[key]);
0119 }
0120 };
0121
0122 template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS >
0123 struct property_map< BOOST_GRID_GRAPH_TYPE, edge_reverse_t >
0124 {
0125 typedef grid_graph_reverse_edge_map<
0126 BOOST_GRID_GRAPH_TRAITS_T::edge_descriptor >
0127 type;
0128 typedef type const_type;
0129 };
0130
0131
0132
0133
0134
0135 namespace detail
0136 {
0137
0138
0139 template < typename Graph > struct grid_graph_vertex_at
0140 {
0141
0142 typedef typename graph_traits< Graph >::vertex_descriptor result_type;
0143
0144 grid_graph_vertex_at() : m_graph(0) {}
0145
0146 grid_graph_vertex_at(const Graph* graph) : m_graph(graph) {}
0147
0148 result_type operator()(
0149 typename graph_traits< Graph >::vertices_size_type vertex_index)
0150 const
0151 {
0152 return (vertex(vertex_index, *m_graph));
0153 }
0154
0155 private:
0156 const Graph* m_graph;
0157 };
0158
0159
0160 template < typename Graph > struct grid_graph_out_edge_at
0161 {
0162
0163 private:
0164 typedef
0165 typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
0166
0167 public:
0168 typedef typename graph_traits< Graph >::edge_descriptor result_type;
0169
0170 grid_graph_out_edge_at() : m_vertex(), m_graph(0) {}
0171
0172 grid_graph_out_edge_at(
0173 vertex_descriptor source_vertex, const Graph* graph)
0174 : m_vertex(source_vertex), m_graph(graph)
0175 {
0176 }
0177
0178 result_type operator()(
0179 typename graph_traits< Graph >::degree_size_type out_edge_index)
0180 const
0181 {
0182 return (out_edge_at(m_vertex, out_edge_index, *m_graph));
0183 }
0184
0185 private:
0186 vertex_descriptor m_vertex;
0187 const Graph* m_graph;
0188 };
0189
0190
0191 template < typename Graph > struct grid_graph_in_edge_at
0192 {
0193
0194 private:
0195 typedef
0196 typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
0197
0198 public:
0199 typedef typename graph_traits< Graph >::edge_descriptor result_type;
0200
0201 grid_graph_in_edge_at() : m_vertex(), m_graph(0) {}
0202
0203 grid_graph_in_edge_at(
0204 vertex_descriptor target_vertex, const Graph* graph)
0205 : m_vertex(target_vertex), m_graph(graph)
0206 {
0207 }
0208
0209 result_type operator()(
0210 typename graph_traits< Graph >::degree_size_type in_edge_index)
0211 const
0212 {
0213 return (in_edge_at(m_vertex, in_edge_index, *m_graph));
0214 }
0215
0216 private:
0217 vertex_descriptor m_vertex;
0218 const Graph* m_graph;
0219 };
0220
0221
0222 template < typename Graph > struct grid_graph_edge_at
0223 {
0224
0225 typedef typename graph_traits< Graph >::edge_descriptor result_type;
0226
0227 grid_graph_edge_at() : m_graph(0) {}
0228
0229 grid_graph_edge_at(const Graph* graph) : m_graph(graph) {}
0230
0231 result_type operator()(
0232 typename graph_traits< Graph >::edges_size_type edge_index) const
0233 {
0234 return (edge_at(edge_index, *m_graph));
0235 }
0236
0237 private:
0238 const Graph* m_graph;
0239 };
0240
0241
0242 template < typename Graph > struct grid_graph_adjacent_vertex_at
0243 {
0244
0245 public:
0246 typedef typename graph_traits< Graph >::vertex_descriptor result_type;
0247
0248 grid_graph_adjacent_vertex_at(
0249 result_type source_vertex, const Graph* graph)
0250 : m_vertex(source_vertex), m_graph(graph)
0251 {
0252 }
0253
0254 result_type operator()(
0255 typename graph_traits< Graph >::degree_size_type adjacent_index)
0256 const
0257 {
0258 return (target(
0259 out_edge_at(m_vertex, adjacent_index, *m_graph), *m_graph));
0260 }
0261
0262 private:
0263 result_type m_vertex;
0264 const Graph* m_graph;
0265 };
0266
0267 }
0268
0269
0270
0271
0272
0273 template < std::size_t Dimensions, typename VertexIndex = std::size_t,
0274 typename EdgeIndex = VertexIndex >
0275 class grid_graph
0276 {
0277
0278 private:
0279 typedef boost::array< bool, Dimensions > WrapDimensionArray;
0280 grid_graph() {};
0281
0282 public:
0283 typedef grid_graph< Dimensions, VertexIndex, EdgeIndex > type;
0284
0285
0286 typedef VertexIndex vertices_size_type;
0287 typedef EdgeIndex edges_size_type;
0288 typedef EdgeIndex degree_size_type;
0289
0290
0291 typedef boost::array< VertexIndex, Dimensions > vertex_descriptor;
0292 typedef std::pair< vertex_descriptor, vertex_descriptor > edge_descriptor;
0293
0294
0295 typedef counting_iterator< vertices_size_type > vertex_index_iterator;
0296 typedef detail::grid_graph_vertex_at< type > vertex_function;
0297 typedef transform_iterator< vertex_function, vertex_index_iterator >
0298 vertex_iterator;
0299
0300
0301 typedef counting_iterator< edges_size_type > edge_index_iterator;
0302 typedef detail::grid_graph_edge_at< type > edge_function;
0303 typedef transform_iterator< edge_function, edge_index_iterator >
0304 edge_iterator;
0305
0306
0307 typedef counting_iterator< degree_size_type > degree_iterator;
0308 typedef detail::grid_graph_out_edge_at< type > out_edge_function;
0309 typedef transform_iterator< out_edge_function, degree_iterator >
0310 out_edge_iterator;
0311
0312
0313 typedef detail::grid_graph_in_edge_at< type > in_edge_function;
0314 typedef transform_iterator< in_edge_function, degree_iterator >
0315 in_edge_iterator;
0316
0317
0318 typedef detail::grid_graph_adjacent_vertex_at< type >
0319 adjacent_vertex_function;
0320 typedef transform_iterator< adjacent_vertex_function, degree_iterator >
0321 adjacency_iterator;
0322
0323
0324 typedef directed_tag directed_category;
0325 typedef disallow_parallel_edge_tag edge_parallel_category;
0326 struct traversal_category : virtual public incidence_graph_tag,
0327 virtual public adjacency_graph_tag,
0328 virtual public vertex_list_graph_tag,
0329 virtual public edge_list_graph_tag,
0330 virtual public bidirectional_graph_tag,
0331 virtual public adjacency_matrix_tag
0332 {
0333 };
0334
0335 static inline vertex_descriptor null_vertex()
0336 {
0337 vertex_descriptor maxed_out_vertex;
0338 std::fill(maxed_out_vertex.begin(), maxed_out_vertex.end(),
0339 (std::numeric_limits< vertices_size_type >::max)());
0340
0341 return (maxed_out_vertex);
0342 }
0343
0344
0345 grid_graph(vertex_descriptor dimension_lengths)
0346 : m_dimension_lengths(dimension_lengths)
0347 {
0348
0349 std::fill(m_wrap_dimension.begin(), m_wrap_dimension.end(), false);
0350
0351 precalculate();
0352 }
0353
0354
0355
0356 grid_graph(vertex_descriptor dimension_lengths, bool wrap_all_dimensions)
0357 : m_dimension_lengths(dimension_lengths)
0358 {
0359
0360 std::fill(m_wrap_dimension.begin(), m_wrap_dimension.end(),
0361 wrap_all_dimensions);
0362
0363 precalculate();
0364 }
0365
0366
0367
0368 grid_graph(
0369 vertex_descriptor dimension_lengths, WrapDimensionArray wrap_dimension)
0370 : m_dimension_lengths(dimension_lengths), m_wrap_dimension(wrap_dimension)
0371 {
0372
0373 precalculate();
0374 }
0375
0376
0377 inline std::size_t dimensions() const { return (Dimensions); }
0378
0379
0380 inline vertices_size_type length(std::size_t dimension) const
0381 {
0382 return (m_dimension_lengths[dimension]);
0383 }
0384
0385
0386 inline bool wrapped(std::size_t dimension) const
0387 {
0388 return (m_wrap_dimension[dimension]);
0389 }
0390
0391
0392
0393 vertex_descriptor next(vertex_descriptor vertex,
0394 std::size_t dimension_index, vertices_size_type distance = 1) const
0395 {
0396
0397 vertices_size_type new_position = vertex[dimension_index] + distance;
0398
0399 if (wrapped(dimension_index))
0400 {
0401 new_position %= length(dimension_index);
0402 }
0403 else
0404 {
0405
0406 new_position = (std::min)(
0407 new_position, vertices_size_type(length(dimension_index) - 1));
0408 }
0409
0410 vertex[dimension_index] = new_position;
0411
0412 return (vertex);
0413 }
0414
0415
0416
0417 vertex_descriptor previous(vertex_descriptor vertex,
0418 std::size_t dimension_index, vertices_size_type distance = 1) const
0419 {
0420
0421
0422
0423 vertex[dimension_index] = (distance > vertex[dimension_index])
0424 ? (wrapped(dimension_index) ? (length(dimension_index)
0425 - (distance % length(dimension_index)))
0426 : 0)
0427 : vertex[dimension_index] - distance;
0428
0429 return (vertex);
0430 }
0431
0432 protected:
0433
0434 inline vertices_size_type num_vertices() const { return (m_num_vertices); }
0435
0436
0437 inline edges_size_type num_edges() const { return (m_num_edges); }
0438
0439
0440 inline edges_size_type num_edges(std::size_t dimension_index) const
0441 {
0442 return (m_edge_count[dimension_index]);
0443 }
0444
0445
0446 vertices_size_type index_of(vertex_descriptor vertex) const
0447 {
0448
0449 vertices_size_type vertex_index = 0;
0450 vertices_size_type index_multiplier = 1;
0451
0452 for (std::size_t dimension_index = 0; dimension_index < Dimensions;
0453 ++dimension_index)
0454 {
0455
0456 vertex_index += (vertex[dimension_index] * index_multiplier);
0457 index_multiplier *= length(dimension_index);
0458 }
0459
0460 return (vertex_index);
0461 }
0462
0463
0464
0465 vertex_descriptor vertex_at(vertices_size_type vertex_index) const
0466 {
0467
0468 boost::array< vertices_size_type, Dimensions > vertex;
0469 vertices_size_type index_divider = 1;
0470
0471 for (std::size_t dimension_index = 0; dimension_index < Dimensions;
0472 ++dimension_index)
0473 {
0474
0475 vertex[dimension_index]
0476 = (vertex_index / index_divider) % length(dimension_index);
0477
0478 index_divider *= length(dimension_index);
0479 }
0480
0481 return (vertex);
0482 }
0483
0484
0485
0486
0487 edge_descriptor edge_at(edges_size_type edge_index) const
0488 {
0489
0490
0491 std::size_t dimension_index = 0;
0492 edges_size_type dimension_edges = num_edges(0);
0493
0494 while (edge_index >= dimension_edges)
0495 {
0496 edge_index -= dimension_edges;
0497 ++dimension_index;
0498 dimension_edges = num_edges(dimension_index);
0499 }
0500
0501 vertex_descriptor vertex_source, vertex_target;
0502 bool is_forward
0503 = ((edge_index / (num_edges(dimension_index) / 2)) == 0);
0504
0505 if (wrapped(dimension_index))
0506 {
0507 vertex_source = vertex_at(edge_index % num_vertices());
0508 vertex_target = is_forward
0509 ? next(vertex_source, dimension_index)
0510 : previous(vertex_source, dimension_index);
0511 }
0512 else
0513 {
0514
0515
0516
0517
0518
0519
0520
0521
0522 edges_size_type vertex_offset
0523 = edge_index % num_edges(dimension_index);
0524
0525
0526
0527
0528 vertices_size_type index_divider = 1;
0529
0530 for (std::size_t dimension_index_iter = 0;
0531 dimension_index_iter < Dimensions; ++dimension_index_iter)
0532 {
0533
0534 std::size_t dimension_length
0535 = (dimension_index_iter == dimension_index)
0536 ? length(dimension_index_iter) - 1
0537 : length(dimension_index_iter);
0538
0539 vertex_source[dimension_index_iter]
0540 = (vertex_offset / index_divider) % dimension_length;
0541
0542 index_divider *= dimension_length;
0543 }
0544
0545 if (is_forward)
0546 {
0547 vertex_target = next(vertex_source, dimension_index);
0548 }
0549 else
0550 {
0551
0552
0553 vertex_target = vertex_source;
0554 ++vertex_source[dimension_index];
0555 }
0556
0557 }
0558
0559 return (std::make_pair(vertex_source, vertex_target));
0560 }
0561
0562
0563 edges_size_type index_of(edge_descriptor edge) const
0564 {
0565 vertex_descriptor source_vertex = source(edge, *this);
0566 vertex_descriptor target_vertex = target(edge, *this);
0567
0568 BOOST_ASSERT(source_vertex != target_vertex);
0569
0570
0571
0572 std::size_t different_dimension_index = 0;
0573
0574 while (source_vertex[different_dimension_index]
0575 == target_vertex[different_dimension_index])
0576 {
0577
0578 ++different_dimension_index;
0579 }
0580
0581 edges_size_type edge_index = 0;
0582
0583
0584
0585 for (std::size_t dimension_index = 0;
0586 dimension_index < different_dimension_index; ++dimension_index)
0587 {
0588
0589 edge_index += num_edges(dimension_index);
0590 }
0591
0592
0593 vertices_size_type source_position
0594 = source_vertex[different_dimension_index];
0595 vertices_size_type target_position
0596 = target_vertex[different_dimension_index];
0597
0598
0599 bool is_forward = true;
0600
0601 if (wrapped(different_dimension_index))
0602 {
0603
0604
0605
0606
0607
0608 if (((target_position < source_position)
0609 && ((source_position - target_position) == 1))
0610 || ((source_position < target_position)
0611 && ((target_position - source_position) > 1)))
0612 {
0613
0614 is_forward = false;
0615 }
0616 }
0617 else if (target_position < source_position)
0618 {
0619 is_forward = false;
0620 }
0621
0622
0623 if (!is_forward)
0624 {
0625 edge_index += (num_edges(different_dimension_index) / 2);
0626 }
0627
0628
0629 if (wrapped(different_dimension_index))
0630 {
0631 edge_index += index_of(source_vertex);
0632 }
0633 else
0634 {
0635 vertices_size_type index_multiplier = 1;
0636
0637 if (!is_forward)
0638 {
0639 --source_vertex[different_dimension_index];
0640 }
0641
0642 for (std::size_t dimension_index = 0; dimension_index < Dimensions;
0643 ++dimension_index)
0644 {
0645
0646 edge_index
0647 += (source_vertex[dimension_index] * index_multiplier);
0648 index_multiplier
0649 *= (dimension_index == different_dimension_index)
0650 ? length(dimension_index) - 1
0651 : length(dimension_index);
0652 }
0653 }
0654
0655 return (edge_index);
0656 }
0657
0658
0659 degree_size_type out_degree(vertex_descriptor vertex) const
0660 {
0661
0662 degree_size_type out_edge_count = 0;
0663
0664 for (std::size_t dimension_index = 0; dimension_index < Dimensions;
0665 ++dimension_index)
0666 {
0667
0668
0669
0670
0671 if ((vertex[dimension_index] == 0)
0672 || (vertex[dimension_index] == (length(dimension_index) - 1)))
0673 {
0674 out_edge_count += (wrapped(dimension_index) ? 2 : 1);
0675 }
0676 else
0677 {
0678
0679 out_edge_count += 2;
0680 }
0681 }
0682
0683 return (out_edge_count);
0684 }
0685
0686
0687
0688 edge_descriptor out_edge_at(
0689 vertex_descriptor vertex, degree_size_type out_edge_index) const
0690 {
0691
0692 edges_size_type edges_left = out_edge_index + 1;
0693 std::size_t dimension_index = 0;
0694 bool is_forward = false;
0695
0696
0697
0698 while (edges_left > 0)
0699 {
0700
0701 if (!wrapped(dimension_index))
0702 {
0703 if (!is_forward && (vertex[dimension_index] == 0))
0704 {
0705 is_forward = true;
0706 continue;
0707 }
0708 else if (is_forward
0709 && (vertex[dimension_index]
0710 == (length(dimension_index) - 1)))
0711 {
0712 is_forward = false;
0713 ++dimension_index;
0714 continue;
0715 }
0716 }
0717
0718 --edges_left;
0719
0720 if (edges_left > 0)
0721 {
0722 is_forward = !is_forward;
0723
0724 if (!is_forward)
0725 {
0726 ++dimension_index;
0727 }
0728 }
0729 }
0730
0731 return (std::make_pair(vertex,
0732 is_forward ? next(vertex, dimension_index)
0733 : previous(vertex, dimension_index)));
0734 }
0735
0736
0737 inline degree_size_type in_degree(vertex_descriptor vertex) const
0738 {
0739 return (out_degree(vertex));
0740 }
0741
0742
0743
0744 edge_descriptor in_edge_at(
0745 vertex_descriptor vertex, edges_size_type in_edge_index) const
0746 {
0747
0748 edge_descriptor out_edge = out_edge_at(vertex, in_edge_index);
0749 return (
0750 std::make_pair(target(out_edge, *this), source(out_edge, *this)));
0751 }
0752
0753
0754 void precalculate()
0755 {
0756 m_num_vertices = std::accumulate(m_dimension_lengths.begin(),
0757 m_dimension_lengths.end(), vertices_size_type(1),
0758 std::multiplies< vertices_size_type >());
0759
0760
0761 m_num_edges = 0;
0762
0763 for (std::size_t dimension_index = 0; dimension_index < Dimensions;
0764 ++dimension_index)
0765 {
0766
0767 if (wrapped(dimension_index))
0768 {
0769 m_edge_count[dimension_index] = num_vertices() * 2;
0770 }
0771 else
0772 {
0773 m_edge_count[dimension_index]
0774 = (num_vertices()
0775 - (num_vertices() / length(dimension_index)))
0776 * 2;
0777 }
0778
0779 m_num_edges += num_edges(dimension_index);
0780 }
0781 }
0782
0783 const vertex_descriptor m_dimension_lengths;
0784 WrapDimensionArray m_wrap_dimension;
0785 vertices_size_type m_num_vertices;
0786
0787 boost::array< edges_size_type, Dimensions > m_edge_count;
0788 edges_size_type m_num_edges;
0789
0790 public:
0791
0792
0793
0794
0795 friend inline std::pair< typename type::vertex_iterator,
0796 typename type::vertex_iterator >
0797 vertices(const type& graph)
0798 {
0799 typedef typename type::vertex_iterator vertex_iterator;
0800 typedef typename type::vertex_function vertex_function;
0801 typedef typename type::vertex_index_iterator vertex_index_iterator;
0802
0803 return (std::make_pair(
0804 vertex_iterator(vertex_index_iterator(0), vertex_function(&graph)),
0805 vertex_iterator(vertex_index_iterator(graph.num_vertices()),
0806 vertex_function(&graph))));
0807 }
0808
0809 friend inline typename type::vertices_size_type num_vertices(
0810 const type& graph)
0811 {
0812 return (graph.num_vertices());
0813 }
0814
0815 friend inline typename type::vertex_descriptor vertex(
0816 typename type::vertices_size_type vertex_index, const type& graph)
0817 {
0818
0819 return (graph.vertex_at(vertex_index));
0820 }
0821
0822
0823
0824
0825
0826 friend inline std::pair< typename type::out_edge_iterator,
0827 typename type::out_edge_iterator >
0828 out_edges(typename type::vertex_descriptor vertex, const type& graph)
0829 {
0830 typedef typename type::degree_iterator degree_iterator;
0831 typedef typename type::out_edge_function out_edge_function;
0832 typedef typename type::out_edge_iterator out_edge_iterator;
0833
0834 return (std::make_pair(out_edge_iterator(degree_iterator(0),
0835 out_edge_function(vertex, &graph)),
0836 out_edge_iterator(degree_iterator(graph.out_degree(vertex)),
0837 out_edge_function(vertex, &graph))));
0838 }
0839
0840 friend inline typename type::degree_size_type out_degree(
0841 typename type::vertex_descriptor vertex, const type& graph)
0842 {
0843 return (graph.out_degree(vertex));
0844 }
0845
0846 friend inline typename type::edge_descriptor out_edge_at(
0847 typename type::vertex_descriptor vertex,
0848 typename type::degree_size_type out_edge_index, const type& graph)
0849 {
0850 return (graph.out_edge_at(vertex, out_edge_index));
0851 }
0852
0853
0854
0855
0856
0857 friend typename std::pair< typename type::adjacency_iterator,
0858 typename type::adjacency_iterator >
0859 adjacent_vertices(
0860 typename type::vertex_descriptor vertex, const type& graph)
0861 {
0862 typedef typename type::degree_iterator degree_iterator;
0863 typedef
0864 typename type::adjacent_vertex_function adjacent_vertex_function;
0865 typedef typename type::adjacency_iterator adjacency_iterator;
0866
0867 return (std::make_pair(adjacency_iterator(degree_iterator(0),
0868 adjacent_vertex_function(vertex, &graph)),
0869 adjacency_iterator(degree_iterator(graph.out_degree(vertex)),
0870 adjacent_vertex_function(vertex, &graph))));
0871 }
0872
0873
0874
0875
0876
0877 friend inline typename type::edges_size_type num_edges(const type& graph)
0878 {
0879 return (graph.num_edges());
0880 }
0881
0882 friend inline typename type::edge_descriptor edge_at(
0883 typename type::edges_size_type edge_index, const type& graph)
0884 {
0885 return (graph.edge_at(edge_index));
0886 }
0887
0888 friend inline std::pair< typename type::edge_iterator,
0889 typename type::edge_iterator >
0890 edges(const type& graph)
0891 {
0892 typedef typename type::edge_index_iterator edge_index_iterator;
0893 typedef typename type::edge_function edge_function;
0894 typedef typename type::edge_iterator edge_iterator;
0895
0896 return (std::make_pair(
0897 edge_iterator(edge_index_iterator(0), edge_function(&graph)),
0898 edge_iterator(edge_index_iterator(graph.num_edges()),
0899 edge_function(&graph))));
0900 }
0901
0902
0903
0904
0905
0906 friend inline std::pair< typename type::in_edge_iterator,
0907 typename type::in_edge_iterator >
0908 in_edges(typename type::vertex_descriptor vertex, const type& graph)
0909 {
0910 typedef typename type::in_edge_function in_edge_function;
0911 typedef typename type::degree_iterator degree_iterator;
0912 typedef typename type::in_edge_iterator in_edge_iterator;
0913
0914 return (std::make_pair(in_edge_iterator(degree_iterator(0),
0915 in_edge_function(vertex, &graph)),
0916 in_edge_iterator(degree_iterator(graph.in_degree(vertex)),
0917 in_edge_function(vertex, &graph))));
0918 }
0919
0920 friend inline typename type::degree_size_type in_degree(
0921 typename type::vertex_descriptor vertex, const type& graph)
0922 {
0923 return (graph.in_degree(vertex));
0924 }
0925
0926 friend inline typename type::degree_size_type degree(
0927 typename type::vertex_descriptor vertex, const type& graph)
0928 {
0929 return (graph.out_degree(vertex) * 2);
0930 }
0931
0932 friend inline typename type::edge_descriptor in_edge_at(
0933 typename type::vertex_descriptor vertex,
0934 typename type::degree_size_type in_edge_index, const type& graph)
0935 {
0936 return (graph.in_edge_at(vertex, in_edge_index));
0937 }
0938
0939
0940
0941
0942
0943 friend std::pair< typename type::edge_descriptor, bool > edge(
0944 typename type::vertex_descriptor source_vertex,
0945 typename type::vertex_descriptor destination_vertex, const type& graph)
0946 {
0947
0948 std::pair< typename type::edge_descriptor, bool > edge_exists
0949 = std::make_pair(
0950 std::make_pair(source_vertex, destination_vertex), false);
0951
0952 for (std::size_t dimension_index = 0; dimension_index < Dimensions;
0953 ++dimension_index)
0954 {
0955
0956 typename type::vertices_size_type dim_difference = 0;
0957 typename type::vertices_size_type source_dim
0958 = source_vertex[dimension_index],
0959 dest_dim = destination_vertex[dimension_index];
0960
0961 dim_difference = (source_dim > dest_dim) ? (source_dim - dest_dim)
0962 : (dest_dim - source_dim);
0963
0964 if (dim_difference > 0)
0965 {
0966
0967
0968
0969
0970 if (edge_exists.second)
0971 {
0972 edge_exists.second = false;
0973 break;
0974 }
0975
0976
0977
0978
0979
0980 if ((dim_difference == 1)
0981 || (graph.wrapped(dimension_index)
0982 && (((source_dim == 0)
0983 && (dest_dim
0984 == (graph.length(dimension_index) - 1)))
0985 || ((dest_dim == 0)
0986 && (source_dim
0987 == (graph.length(dimension_index) - 1))))))
0988 {
0989
0990 edge_exists.second = true;
0991
0992 }
0993 else
0994 {
0995
0996
0997 edge_exists.second = false;
0998 break;
0999 }
1000 }
1001
1002 }
1003
1004 return (edge_exists);
1005 }
1006
1007
1008
1009
1010
1011 friend inline typename type::vertices_size_type get(vertex_index_t,
1012 const type& graph, typename type::vertex_descriptor vertex)
1013 {
1014 return (graph.index_of(vertex));
1015 }
1016
1017 friend inline typename type::edges_size_type get(
1018 edge_index_t, const type& graph, typename type::edge_descriptor edge)
1019 {
1020 return (graph.index_of(edge));
1021 }
1022
1023 friend inline grid_graph_index_map< type, typename type::vertex_descriptor,
1024 typename type::vertices_size_type >
1025 get(vertex_index_t, const type& graph)
1026 {
1027 return (grid_graph_index_map< type, typename type::vertex_descriptor,
1028 typename type::vertices_size_type >(graph));
1029 }
1030
1031 friend inline grid_graph_index_map< type, typename type::edge_descriptor,
1032 typename type::edges_size_type >
1033 get(edge_index_t, const type& graph)
1034 {
1035 return (grid_graph_index_map< type, typename type::edge_descriptor,
1036 typename type::edges_size_type >(graph));
1037 }
1038
1039 friend inline grid_graph_reverse_edge_map< typename type::edge_descriptor >
1040 get(edge_reverse_t, const type& graph)
1041 {
1042 return (
1043 grid_graph_reverse_edge_map< typename type::edge_descriptor >());
1044 }
1045
1046 template < typename Graph, typename Descriptor, typename Index >
1047 friend struct grid_graph_index_map;
1048
1049 template < typename Descriptor > friend struct grid_graph_reverse_edge_map;
1050
1051 };
1052
1053 }
1054
1055 #undef BOOST_GRID_GRAPH_TYPE
1056 #undef BOOST_GRID_GRAPH_TEMPLATE_PARAMS
1057 #undef BOOST_GRID_GRAPH_TRAITS_T
1058
1059 #endif