aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/boost/graph
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 12:29:46 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 13:14:22 +0300
commit9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch)
treea8fb3181d5947c0d78cf402aa56e686130179049 /contrib/restricted/boost/graph
parenta44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff)
downloadydb-9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80.tar.gz
publishFullContrib: true for ydb
<HIDDEN_URL> commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
Diffstat (limited to 'contrib/restricted/boost/graph')
-rw-r--r--contrib/restricted/boost/graph/.yandex_meta/devtools.copyrights.report1144
-rw-r--r--contrib/restricted/boost/graph/.yandex_meta/devtools.licenses.report421
-rw-r--r--contrib/restricted/boost/graph/.yandex_meta/licenses.list.txt477
-rw-r--r--contrib/restricted/boost/graph/include/boost/detail/algorithm.hpp83
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/adj_list_serialize.hpp130
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/adjacency_list_io.hpp405
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/adjacency_matrix.hpp1296
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/astar_search.hpp655
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/bandwidth.hpp94
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/bc_clustering.hpp169
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/bellman_ford_shortest_paths.hpp226
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/betweenness_centrality.hpp645
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/biconnected_components.hpp440
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/bipartite.hpp403
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/boyer_myrvold_planar_test.hpp262
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/bron_kerbosch_all_cliques.hpp312
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/chrobak_payne_drawing.hpp251
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/circle_layout.hpp61
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/closeness_centrality.hpp151
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/clustering_coefficient.hpp160
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/core_numbers.hpp375
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/create_condensation_graph.hpp86
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/cuthill_mckee_ordering.hpp181
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/cycle_canceling.hpp191
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/degree_centrality.hpp135
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/augment.hpp66
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/connected_components.hpp206
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/empty_header.hpp10
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/geodesic.hpp138
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/incidence_iterator.hpp98
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/incremental_components.hpp92
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/index.hpp78
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/labeled_graph_traits.hpp232
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/list_base.hpp206
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/permutation.hpp211
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/self_avoiding_walk.hpp483
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/shadow_iterator.hpp183
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/detail/sparse_ordering.hpp210
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp235
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/dimacs.hpp375
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/directed_graph.hpp795
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/dominator_tree.hpp483
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/eccentricity.hpp121
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/edge_coloring.hpp201
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/edge_connectivity.hpp188
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/edge_list.hpp330
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/edmonds_karp_max_flow.hpp245
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/edmunds_karp_max_flow.hpp22
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/erdos_renyi_generator.hpp221
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/exterior_property.hpp114
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/find_flow_cost.hpp57
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/floyd_warshall_shortest.hpp223
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/fruchterman_reingold.hpp460
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/geodesic_distance.hpp217
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/graph_archetypes.hpp326
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/graph_as_tree.hpp156
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/graph_stats.hpp148
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/graph_utility.hpp488
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/grid_graph.hpp1059
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/gursoy_atun_layout.hpp338
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/hawick_circuits.hpp409
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/howard_cycle_ratio.hpp643
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/incremental_components.hpp234
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/is_kuratowski_subgraph.hpp295
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/is_straight_line_drawing.hpp209
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/isomorphism.hpp781
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/iteration_macros_undef.hpp22
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/johnson_all_pairs_shortest.hpp198
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/kamada_kawai_spring_layout.hpp688
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/king_ordering.hpp346
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/kruskal_min_spanning_tree.hpp152
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/labeled_graph.hpp1010
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/leda_graph.hpp942
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/loop_erased_random_walk.hpp141
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/make_biconnected_planar.hpp96
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/make_connected.hpp79
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/make_maximal_planar.hpp213
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/matrix_as_graph.hpp167
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/max_cardinality_matching.hpp844
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/maximum_adjacency_search.hpp399
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/maximum_weighted_matching.hpp1313
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/mcgregor_common_subgraphs.hpp1117
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/mesh_graph_generator.hpp184
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/metis.hpp369
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/metric_tsp_approx.hpp316
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/minimum_degree_ordering.hpp760
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/neighbor_bfs.hpp326
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/one_bit_color_map.hpp104
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/page_rank.hpp179
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/planar_canonical_ordering.hpp205
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/planar_detail/add_edge_visitors.hpp54
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp1813
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/planar_detail/bucket_sort.hpp118
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/planar_detail/face_handles.hpp453
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/planar_detail/face_iterators.hpp332
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/planar_face_traversal.hpp178
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/plod_generator.hpp275
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/point_traits.hpp31
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/prim_minimum_spanning_tree.hpp84
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/profile.hpp44
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/property_iter_range.hpp120
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/property_maps/container_property_map.hpp70
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/property_maps/matrix_property_map.hpp68
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/push_relabel_max_flow.hpp860
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/r_c_shortest_paths.hpp727
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/random.hpp290
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/random_layout.hpp35
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/random_spanning_tree.hpp144
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/read_dimacs.hpp370
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/rmat_graph_generator.hpp663
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/sequential_vertex_coloring.hpp126
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/simple_point.hpp23
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/sloan_ordering.hpp448
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/small_world_generator.hpp132
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/smallest_last_ordering.hpp152
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/ssca_graph_generator.hpp197
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/st_connected.hpp89
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/stanford_graph.hpp586
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/stoer_wagner_min_cut.hpp383
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp255
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/tiernan_all_cycles.hpp372
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/topology.hpp702
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/transitive_closure.hpp392
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/transitive_reduction.hpp137
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/tree_traits.hpp48
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/two_graphs_common_spanning_trees.hpp852
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/undirected_dfs.hpp269
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/undirected_graph.hpp822
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/vector_as_graph.hpp334
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/vertex_and_edge_range.hpp158
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/vf2_sub_graph_iso.hpp1301
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/wavefront.hpp125
-rw-r--r--contrib/restricted/boost/graph/include/boost/graph/write_dimacs.hpp75
-rw-r--r--contrib/restricted/boost/graph/include/boost/pending/bucket_sorter.hpp158
-rw-r--r--contrib/restricted/boost/graph/include/boost/pending/detail/disjoint_sets.hpp93
-rw-r--r--contrib/restricted/boost/graph/include/boost/pending/disjoint_sets.hpp211
-rw-r--r--contrib/restricted/boost/graph/include/boost/pending/fenced_priority_queue.hpp160
-rw-r--r--contrib/restricted/boost/graph/include/boost/pending/fibonacci_heap.hpp320
-rw-r--r--contrib/restricted/boost/graph/include/boost/pending/property_serialize.hpp99
-rw-r--r--contrib/restricted/boost/graph/include/boost/pending/relaxed_heap.hpp743
-rw-r--r--contrib/restricted/boost/graph/include/boost/pending/stringtok.hpp116
141 files changed, 47116 insertions, 0 deletions
diff --git a/contrib/restricted/boost/graph/.yandex_meta/devtools.copyrights.report b/contrib/restricted/boost/graph/.yandex_meta/devtools.copyrights.report
new file mode 100644
index 0000000000..02724c3c19
--- /dev/null
+++ b/contrib/restricted/boost/graph/.yandex_meta/devtools.copyrights.report
@@ -0,0 +1,1144 @@
+# File format ($ symbol means the beginning of a line):
+#
+# $ # this message
+# $ # =======================
+# $ # comments (all commentaries should starts with some number of spaces and # symbol)
+# $ IGNORE_FILES {file1.ext1} {file2.ext2} - (optional) ignore listed files when generating license macro and credits
+# $ RENAME {original license id} TO {new license id} # user comments - (optional) use {new license id} instead {original license id} in ya.make files
+# $ # user comments
+# $
+# ${action} {license id} {license text hash}
+# $BELONGS ./ya/make/file/relative/path/1/ya.make ./ya/make/2/ya.make
+# ${all_file_action} filename
+# $ # user commentaries (many lines)
+# $ generated description - files with this license, license text... (some number of lines that starts with some number of spaces, do not modify)
+# ${action} {license spdx} {license text hash}
+# $BELONGS ./ya/make/file/relative/path/3/ya.make
+# ${all_file_action} filename
+# $ # user commentaries
+# $ generated description
+# $ ...
+#
+# You can modify action, all_file_action and add commentaries
+# Available actions:
+# keep - keep license in contrib and use in credits
+# skip - skip license
+# remove - remove all files with this license
+# rename - save license text/links into licenses texts file, but not store SPDX into LINCENSE macro. You should store correct license id into devtools.license.spdx.txt file
+#
+# {all file action} records will be generated when license text contains filename that exists on filesystem (in contrib directory)
+# We suppose that that files can contain some license info
+# Available all file actions:
+# FILE_IGNORE - ignore file (do nothing)
+# FILE_INCLUDE - include all file data into licenses text file
+# =======================
+
+KEEP COPYRIGHT_SERVICE_LABEL 00d8c23eb547d50de392cb17b51e426e
+BELONGS ya.make
+ License text:
+ // Copyright 2002 Indiana University.
+ // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/adjacency_iterator.hpp [2:3]
+ include/boost/graph/create_condensation_graph.hpp [2:3]
+ include/boost/graph/dag_shortest_paths.hpp [2:3]
+ include/boost/graph/detail/incremental_components.hpp [2:4]
+ include/boost/graph/detail/list_base.hpp [2:3]
+ include/boost/graph/exception.hpp [2:3]
+ include/boost/graph/graph_archetypes.hpp [2:3]
+ include/boost/graph/graph_selectors.hpp [2:3]
+ include/boost/graph/iteration_macros_undef.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 01ee5bf19060374ef2efda82af9fc108
+BELONGS ya.make
+ License text:
+ // Copyright Michael Drexl 2005, 2006.
+ // Distributed under the Boost Software License, Version 1.0.
+ // (See accompanying file LICENSE_1_0.txt or copy at
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/r_c_shortest_paths.hpp [3:5]
+
+KEEP COPYRIGHT_SERVICE_LABEL 0248c07689d63f8e0b5cff0f09a2737a
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2012 Flavio De Lorenzi (fdlorenzi@gmail.com)
+ // Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark
+ // (jlandersen@imada.sdu.dk)
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/vf2_sub_graph_iso.hpp [2:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 09990d303a67b1a0c87b3ccf09c2097c
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2006 Tiago de Paula Peixoto <tiago@forked.de>
+ // Copyright (C) 2004,2009 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ src/graphml.cpp [1:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL 0a1ddf2f633492698f29966f2ba00d47
+BELONGS ya.make
+ License text:
+ // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+ // Copyright (C) Vladimir Prus 2003
+ // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/random.hpp [2:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 0b29116922cfef70c51094e6d835a79b
+BELONGS ya.make
+ License text:
+ // (C) Copyright Francois Faure, iMAGIS-GRAVIR / UJF, 2001.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/property_iter_range.hpp [2:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL 1503802c606bb498fc119fbf3329ccce
+BELONGS ya.make
+ License text:
+ // Copyright (c) Jeremy Siek 2001
+ // Copyright (c) Douglas Gregor 2004
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/biconnected_components.hpp [1:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL 1638af8b9d8a13b7d2e95217a0492d14
+BELONGS ya.make
+ License text:
+ // (C) Copyright Andrew Sutton 2007
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/geodesic_distance.hpp [1:1]
+ include/boost/graph/property_maps/null_property_map.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 1a243be6fc839e64391e9bd0d3aea29a
+BELONGS ya.make
+ License text:
+ // (c) Copyright Juergen Hunold 2008
+ // Use, modification and distribution is subject to the Boost Software
+ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/edmunds_karp_max_flow.hpp [2:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 1b49b31378926fed6bad2e9e34790202
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/pending/container_traits.hpp [1:5]
+ include/boost/pending/detail/disjoint_sets.hpp [1:3]
+ include/boost/pending/detail/property.hpp [1:3]
+ include/boost/pending/fibonacci_heap.hpp [1:3]
+ include/boost/pending/property.hpp [1:3]
+ include/boost/pending/queue.hpp [1:3]
+ include/boost/pending/stringtok.hpp [1:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 1bf87741a9385d7452ade49e1b079010
+BELONGS ya.make
+ License text:
+ // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+ // Copyright 2010 Thomas Claveirole
+ // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/adjacency_list.hpp [2:4]
+ include/boost/graph/bellman_ford_shortest_paths.hpp [3:4]
+ include/boost/graph/breadth_first_search.hpp [3:4]
+ include/boost/graph/cuthill_mckee_ordering.hpp [2:5]
+ include/boost/graph/depth_first_search.hpp [2:4]
+ include/boost/graph/detail/adj_list_edge_iterator.hpp [3:4]
+ include/boost/graph/detail/adjacency_list.hpp [3:5]
+ include/boost/graph/detail/array_binary_tree.hpp [3:4]
+ include/boost/graph/detail/connected_components.hpp [2:3]
+ include/boost/graph/detail/edge.hpp [3:4]
+ include/boost/graph/detail/incidence_iterator.hpp [3:4]
+ include/boost/graph/detail/self_avoiding_walk.hpp [2:3]
+ include/boost/graph/detail/sparse_ordering.hpp [2:5]
+ include/boost/graph/dijkstra_shortest_paths.hpp [2:3]
+ include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp [2:4]
+ include/boost/graph/edge_list.hpp [2:3]
+ include/boost/graph/filtered_graph.hpp [2:3]
+ include/boost/graph/graph_as_tree.hpp [3:4]
+ include/boost/graph/graph_concepts.hpp [3:4]
+ include/boost/graph/graph_traits.hpp [2:3]
+ include/boost/graph/graph_utility.hpp [3:4]
+ include/boost/graph/johnson_all_pairs_shortest.hpp [2:3]
+ include/boost/graph/king_ordering.hpp [2:5]
+ include/boost/graph/kruskal_min_spanning_tree.hpp [3:4]
+ include/boost/graph/leda_graph.hpp [2:6]
+ include/boost/graph/matrix_as_graph.hpp [3:4]
+ include/boost/graph/named_function_params.hpp [2:3]
+ include/boost/graph/neighbor_bfs.hpp [3:4]
+ include/boost/graph/prim_minimum_spanning_tree.hpp [2:3]
+ include/boost/graph/properties.hpp [2:3]
+ include/boost/graph/random.hpp [2:4]
+ include/boost/graph/read_dimacs.hpp [2:3]
+ include/boost/graph/relax.hpp [2:3]
+ include/boost/graph/sequential_vertex_coloring.hpp [2:4]
+ include/boost/graph/smallest_last_ordering.hpp [2:3]
+ include/boost/graph/strong_components.hpp [3:4]
+ include/boost/graph/topological_sort.hpp [3:4]
+ include/boost/graph/transpose_graph.hpp [3:4]
+ include/boost/graph/undirected_dfs.hpp [3:4]
+ include/boost/graph/vector_as_graph.hpp [2:5]
+ include/boost/graph/visitors.hpp [2:3]
+ include/boost/pending/bucket_sorter.hpp [3:4]
+ include/boost/pending/disjoint_sets.hpp [3:4]
+ include/boost/pending/indirect_cmp.hpp [3:4]
+ include/boost/pending/is_heap.hpp [3:4]
+ include/boost/pending/mutable_heap.hpp [3:4]
+ include/boost/pending/mutable_queue.hpp [3:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 1e6c23354a6747a6c3eef56fb2537b44
+BELONGS ya.make
+ License text:
+ // Copyright (c) 2006, Stephan Diederich
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/boykov_kolmogorov_max_flow.hpp [1:1]
+ include/boost/graph/write_dimacs.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 22403f1361a990fb6fd5cc8b876e046d
+BELONGS ya.make
+ License text:
+ // Copyright (c) 2004 Kristopher Beevers
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/astar_search.hpp [5:5]
+
+KEEP COPYRIGHT_SERVICE_LABEL 22b8921218f5846e7fc7d4a2ac8c34c0
+BELONGS ya.make
+ License text:
+ // Copyright 2004-2006 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/plod_generator.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 26ec38d4689211b14e2c5b53e9a78f76
+BELONGS ya.make
+ License text:
+ // Copyright 2009 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/detail/histogram_sort.hpp [1:1]
+ include/boost/graph/topology.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 29b0154b5b9497e05eafdea58aee1ec9
+BELONGS ya.make
+ License text:
+ // Copyright 2000 University of Notre Dame.
+ // Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/edge_connectivity.hpp [2:3]
+ include/boost/graph/edmonds_karp_max_flow.hpp [2:3]
+ include/boost/graph/push_relabel_max_flow.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 2e933bb084c95d7e3472974501e28c75
+BELONGS ya.make
+ License text:
+ // Copyright (c) Jeremy Siek 2001, Marc Wintermantel 2002
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/bandwidth.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 351746b3263b8ecde03d30e68809a8c2
+BELONGS ya.make
+ License text:
+ // Copyright 2005 Trustees of Indiana University
+ // Authors: Andrew Lumsdaine, Douglas Gregor
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/simple_point.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 35f3967788124fb1166bf637d6cd211a
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/transitive_closure.hpp [1:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 368bc0676fed97d8e20cb5e9e1a4530f
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2009 Andrew Sutton
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/detail/labeled_graph_traits.hpp [1:1]
+ include/boost/graph/graph_mutability_traits.hpp [1:1]
+ include/boost/graph/labeled_graph.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 3761f0e38b5da4769378918141293e40
+BELONGS ya.make
+ License text:
+ // Copyright 2002 Rensselaer Polytechnic Institute
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/floyd_warshall_shortest.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 3e8210b2d067c6fa6eca9745ccdb03df
+BELONGS ya.make
+ License text:
+ // Copyright 2008
+ // Author: Matyas W Egyhazy
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/metric_tsp_approx.hpp [3:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 471d4b0a42c396158389600e3135b118
+BELONGS ya.make
+ License text:
+ // Copyright 2001 University of Notre Dame.
+ // Copyright 2003 Jeremy Siek
+ // Authors: Lie-Quan Lee, Jeremy Siek, and Douglas Gregor
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/dll_import_export.hpp [2:4]
+ include/boost/graph/graphviz.hpp [2:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 483fdf5158d0f8518198f5ac2c492f5f
+BELONGS ya.make
+ License text:
+ // (C) Copyright Jeremy Siek 2001.
+ // Distributed under the Boost Software License, Version 1.0. (See accompany-
+ // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/detail/algorithm.hpp [1:3]
+ include/boost/graph/detail/permutation.hpp [1:3]
+ include/boost/graph/detail/set_adaptor.hpp [1:3]
+ include/boost/graph/detail/shadow_iterator.hpp [1:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 4a4c85d50d7786e732eb8f9d7ce88a13
+BELONGS ya.make
+ License text:
+ // (C) Copyright 2007 Andrew Sutton
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/detail/geodesic.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 4c7e1f597f1997587410c32f9a6d6fdb
+BELONGS ya.make
+ License text:
+ // Copyright (c) 2005 Aaron Windsor
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/max_cardinality_matching.hpp [2:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL 4cf14bcc6afe3ad08dfd547e89ac0920
+BELONGS ya.make
+ License text:
+ // Copyright 2010 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/loop_erased_random_walk.hpp [1:1]
+ include/boost/graph/random_spanning_tree.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 4d26b7ae91cf6f8491cee13434ff5797
+BELONGS ya.make
+ License text:
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/detail/algorithm.hpp [19:20]
+
+KEEP COPYRIGHT_SERVICE_LABEL 572b131daaeb41ada07b46e9bcc351e8
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2005-2010 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/one_bit_color_map.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 586afb33401cfbc0d9c28c9f0b024801
+BELONGS ya.make
+ License text:
+ // Copyright 2005 Jeremy G. Siek
+ // Authors: Jeremy G. Siek
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/adj_list_serialize.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 5bb192a3ec0466664f95da7b439ee5e7
+BELONGS ya.make
+ License text:
+ // Copyright 2012 Fernando Vilas
+ // 2010 Daniel Trebbien
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/maximum_adjacency_search.hpp [3:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 670e9fea8b553fd6cefa4f9a295c8a0a
+BELONGS ya.make
+ License text:
+ // Copyright 2012 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/detail/is_distributed_selector.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 686307e753ad6e1d636dbc622eedb324
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2006 Tiago de Paula Peixoto <tiago@forked.de>
+ // Copyright (C) 2004 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/graphml.hpp [1:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL 69913f770ab644c0c626ffe368b41c06
+BELONGS ya.make
+ License text:
+ // (C) Copyright Jeremiah Willcock 2004
+ // Distributed under the Boost Software License, Version 1.0. (See
+ // accompanying file LICENSE_1_0.txt or copy at
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/pending/fenced_priority_queue.hpp [1:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 6b1ab40ae46ff90ccb7c47e8c55973bc
+BELONGS ya.make
+ License text:
+ // Copyright Daniel Trebbien 2010.
+ // Distributed under the Boost Software License, Version 1.0.
+ // (See accompanying file LICENSE_1_0.txt or the copy at
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/buffer_concepts.hpp [1:3]
+ include/boost/graph/stoer_wagner_min_cut.hpp [1:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 6faaf754e301184e7a07944b24799553
+BELONGS ya.make
+ License text:
+ // Copyright 2004 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/bc_clustering.hpp [1:1]
+ include/boost/graph/betweenness_centrality.hpp [1:1]
+ include/boost/graph/circle_layout.hpp [1:1]
+ include/boost/graph/gursoy_atun_layout.hpp [1:1]
+ include/boost/graph/kamada_kawai_spring_layout.hpp [1:1]
+ include/boost/graph/leda_graph.hpp [2:6]
+ include/boost/graph/overloading.hpp [1:1]
+ include/boost/graph/random_layout.hpp [1:1]
+ include/boost/graph/sequential_vertex_coloring.hpp [2:4]
+ include/boost/graph/small_world_generator.hpp [1:1]
+ include/boost/graph/vertex_and_edge_range.hpp [1:1]
+ include/boost/pending/relaxed_heap.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 7154f956948b41d87bf8a2b73a07d675
+BELONGS ya.make
+ License text:
+ // (C) Copyright Jeremy Siek 1999.
+ // Distributed under the Boost Software License, Version 1.0. (See
+ // accompanying file LICENSE_1_0.txt or copy at
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/tree_traits.hpp [1:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 740b8b21c73d73ca167354e62df16207
+BELONGS ya.make
+ License text:
+ * Copyright (c) 2010 Matthias Walter (xammy@xammy.homelinux.net)
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/bipartite.hpp [3:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 779f3f74aa28c6ec9cbf99f210980137
+BELONGS ya.make
+ License text:
+ // Copyright 2007 Stanford University
+ // Authors: David Gleich
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/core_numbers.hpp [3:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 7da1e963669f385bf3784df6bc8f2553
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2005-2006 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/two_bit_color_map.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 807dea3c55c068fbbaf4810187c7c84b
+BELONGS ya.make
+ License text:
+ // (C) Copyright 2007-2009 Andrew Sutton
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/bron_kerbosch_all_cliques.hpp [1:1]
+ include/boost/graph/closeness_centrality.hpp [1:1]
+ include/boost/graph/clustering_coefficient.hpp [1:1]
+ include/boost/graph/degree_centrality.hpp [1:1]
+ include/boost/graph/detail/index.hpp [1:1]
+ include/boost/graph/directed_graph.hpp [1:1]
+ include/boost/graph/eccentricity.hpp [1:1]
+ include/boost/graph/exterior_property.hpp [1:1]
+ include/boost/graph/numeric_values.hpp [1:1]
+ include/boost/graph/property_maps/constant_property_map.hpp [1:1]
+ include/boost/graph/property_maps/container_property_map.hpp [1:1]
+ include/boost/graph/property_maps/matrix_property_map.hpp [1:1]
+ include/boost/graph/tiernan_all_cycles.hpp [1:1]
+ include/boost/graph/undirected_graph.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 89b41c99892d77117372460a7f90d72f
+BELONGS ya.make
+ License text:
+ // Copyright 2004-5 The Trustees of Indiana University.
+ // Copyright 2002 Brad King and Douglas Gregor
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/page_rank.hpp [1:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL 8aaadc898368c37b5d90c024f9104351
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2012, Michele Caini.
+ // Distributed under the Boost Software License, Version 1.0.
+ // (See accompanying file LICENSE_1_0.txt or copy at
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/two_graphs_common_spanning_trees.hpp [1:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 9207c14a0f73cfde357a50e86305b641
+BELONGS ya.make
+ License text:
+ // Copyright 2004-9 Trustees of Indiana University
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/detail/read_graphviz_new.hpp [1:1]
+ include/boost/graph/detail/read_graphviz_spirit.hpp [1:1]
+ src/read_graphviz_new.cpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL 96b2ef2696a6c6919d3372f54d0dcce4
+BELONGS ya.make
+ License text:
+ // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+ // Copyright 2009 Trustees of Indiana University.
+ // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Michael Hansen
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/detail/d_ary_heap.hpp [3:4]
+ include/boost/graph/detail/incremental_components.hpp [2:4]
+ include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp [2:4]
+ include/boost/graph/grid_graph.hpp [2:3]
+ include/boost/graph/incremental_components.hpp [3:5]
+ include/boost/graph/lookup_edge.hpp [2:3]
+ include/boost/graph/mcgregor_common_subgraphs.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL 98be8460f5eeedee67d327e5aa099ae2
+BELONGS ya.make
+ License text:
+ // Copyright 2004-5 The Trustees of Indiana University.
+ // Copyright 2002 Brad King and Douglas Gregor
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/page_rank.hpp [1:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL 9cf9d5ea6d40a88eeda2127bd41fc81a
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2012 Flavio De Lorenzi (fdlorenzi@gmail.com)
+ // Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark
+ // (jlandersen@imada.sdu.dk)
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/vf2_sub_graph_iso.hpp [2:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL 9d08918c66a0d366cbbae02999f8438d
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/transitive_closure.hpp [1:4]
+ include/boost/graph/vector_as_graph.hpp [2:5]
+
+KEEP COPYRIGHT_SERVICE_LABEL a717e4b7c213ca28bbeaec4750bb98ec
+BELONGS ya.make
+ License text:
+ // Copyright 2004, 2005 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/erdos_renyi_generator.hpp [1:1]
+ include/boost/graph/fruchterman_reingold.hpp [1:1]
+ include/boost/graph/mesh_graph_generator.hpp [1:1]
+ include/boost/graph/point_traits.hpp [1:1]
+ include/boost/graph/rmat_graph_generator.hpp [1:1]
+ include/boost/graph/ssca_graph_generator.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL a7831931571cb11df5942e281a68009f
+BELONGS ya.make
+ License text:
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/detail/algorithm.hpp [7:8]
+
+KEEP COPYRIGHT_SERVICE_LABEL a9d5074bdc20d985f64135ae02f955a0
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/pending/container_traits.hpp [1:5]
+
+KEEP COPYRIGHT_SERVICE_LABEL ab71254ad02f316b826c74cda23fc7de
+BELONGS ya.make
+ License text:
+ // Copyright 2001 Universite Joseph Fourier, Grenoble.
+ // Author: Francois Faure
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/adjacency_list_io.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL ac019423baf07909ddd9038922e85359
+BELONGS ya.make
+ License text:
+ // Copyright 2005 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/detail/indexed_properties.hpp [1:1]
+ include/boost/graph/dimacs.hpp [1:1]
+ include/boost/graph/graph_stats.hpp [1:1]
+ include/boost/graph/metis.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL b1820d2cd3cc81402964cf6c2c64f349
+BELONGS ya.make
+ License text:
+ // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+ // Copyright 2010 Thomas Claveirole
+ // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/adjacency_list.hpp [2:4]
+ include/boost/graph/detail/adjacency_list.hpp [3:5]
+
+KEEP COPYRIGHT_SERVICE_LABEL b608aafcf17c3fbc3a9abfa54ff163ce
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2007 Douglas Gregor
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/named_graph.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL ba5506df7530081f1cb89a1a0c3dde35
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/vector_as_graph.hpp [2:5]
+
+KEEP COPYRIGHT_SERVICE_LABEL baf28d14712b3b53f3b722d4d80fdb6c
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/pending/container_traits.hpp [1:5]
+
+KEEP COPYRIGHT_SERVICE_LABEL bd84a09c4319b7c30ed8c9bc63531fff
+BELONGS ya.make
+ License text:
+ // Copyright (c) 2018 Yi Ji
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/maximum_weighted_matching.hpp [2:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL bda792b52a7a784797c1280c82f443a0
+BELONGS ya.make
+ License text:
+ // (C) Copyright David Abrahams 2000.
+ // Distributed under the Boost Software License, Version 1.0. (See
+ // accompanying file LICENSE_1_0.txt or copy at
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/reverse_graph.hpp [1:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL c02bfefa74f87417f2dbc10a0395ffac
+BELONGS ya.make
+ License text:
+ // Copyright 2018 Peter Dimov
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/detail/empty_header.hpp [4:4]
+ include/boost/graph/detail/mpi_include.hpp [4:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL c3a440d06912f47e5190235167d26eea
+BELONGS ya.make
+ License text:
+ // Copyright 2001 University of Notre Dame.
+ // Copyright 2006 Trustees of Indiana University
+ // Authors: Jeremy G. Siek and Douglas Gregor <dgregor@cs.indiana.edu>
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/adjacency_matrix.hpp [2:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL c43f1a8f551d96ac636a4afde37c7277
+BELONGS ya.make
+ License text:
+ // (C) Copyright 2009 Eric Bose-Wolf
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/transitive_reduction.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL c44aa21684966e124d964b7f61ceb274
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2006 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/st_connected.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL c6f32cbdc60da329c029d3eceb822cb5
+BELONGS ya.make
+ License text:
+ // Copyright 2001 Indiana University
+ // Author: Jeremy G. Siek
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/iteration_macros.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL c8b2225195e675e39283e940da8d4aca
+BELONGS ya.make
+ License text:
+ // Copyright 2013 Maciej Piechotka
+ // Authors: Maciej Piechotka
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/edge_coloring.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL c91df6862997c9f36164f1308b236bf7
+BELONGS ya.make
+ License text:
+ // Copyright 2007 Aaron Windsor
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/boyer_myrvold_planar_test.hpp [2:2]
+ include/boost/graph/is_kuratowski_subgraph.hpp [2:2]
+ include/boost/graph/is_straight_line_drawing.hpp [2:2]
+ include/boost/graph/make_biconnected_planar.hpp [2:2]
+ include/boost/graph/make_connected.hpp [2:2]
+ include/boost/graph/make_maximal_planar.hpp [2:2]
+ include/boost/graph/planar_detail/add_edge_visitors.hpp [2:2]
+ include/boost/graph/planar_detail/bucket_sort.hpp [2:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL cc20f3be80fcae2741d451fd54843c93
+BELONGS ya.make
+ License text:
+ // Copyright 2001 University of Notre Dame.
+ // Copyright 2006 Trustees of Indiana University
+ // Authors: Jeremy G. Siek and Douglas Gregor <dgregor@cs.indiana.edu>
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/adjacency_matrix.hpp [2:4]
+ include/boost/graph/dll_import_export.hpp [2:4]
+ include/boost/graph/graphviz.hpp [2:4]
+ include/boost/graph/subgraph.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL cde0b758663026af6e7dea405ee6bf38
+BELONGS ya.make
+ License text:
+ // Copyright Louis Dionne 2013
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/hawick_circuits.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL d08ee88acc4c1b352aea89d4523daace
+BELONGS ya.make
+ License text:
+ // Copyright 2009, Andrew Sutton
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/graph_concepts.hpp [6:6]
+
+KEEP COPYRIGHT_SERVICE_LABEL d52e2e3deec2da9a498dcf40b8dc3655
+BELONGS ya.make
+ License text:
+ // Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch)
+ // ETH Zurich, Center of Structure Technologies
+ // (https://web.archive.org/web/20050307090307/http://www.structures.ethz.ch/)
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/profile.hpp [3:5]
+ include/boost/graph/sloan_ordering.hpp [3:5]
+ include/boost/graph/wavefront.hpp [3:5]
+
+KEEP COPYRIGHT_SERVICE_LABEL d91946878c8cc10edec238acbae07c4c
+BELONGS ya.make
+ License text:
+ // Copyright 2005-2009 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/compressed_sparse_row_graph.hpp [1:1]
+ include/boost/graph/detail/compressed_sparse_row_struct.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL d9d3f9179a9781a228af49eebba2dba2
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/leda_graph.hpp [2:6]
+
+KEEP COPYRIGHT_SERVICE_LABEL e52d2d00c0bddf195fcd2e865710a087
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2001 Jeremy Siek, Douglas Gregor, Brian Osman
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/isomorphism.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL e660351224f73455ec6e8b19ff54015b
+BELONGS ya.make
+ License text:
+ // Copyright 2013 University of Warsaw.
+ // Authors: Piotr Wygocki
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/cycle_canceling.hpp [2:3]
+ include/boost/graph/detail/augment.hpp [2:3]
+ include/boost/graph/find_flow_cost.hpp [2:3]
+ include/boost/graph/successive_shortest_path_nonnegative_weights.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL e948c32bb4fec5a27e9bbe3a45398269
+BELONGS ya.make
+ License text:
+ // (C) Copyright Jeremy Siek 2006
+ // Distributed under the Boost Software License, Version 1.0. (See
+ // accompanying file LICENSE_1_0.txt or copy at
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/pending/property_serialize.hpp [1:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL e9c139c5d04d10ee2bf656ff900cbbaf
+BELONGS ya.make
+ License text:
+ // Copyright (c) Aaron Windsor 2007
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/chrobak_payne_drawing.hpp [2:2]
+ include/boost/graph/planar_canonical_ordering.hpp [2:2]
+ include/boost/graph/planar_detail/boyer_myrvold_impl.hpp [2:2]
+ include/boost/graph/planar_detail/face_handles.hpp [2:2]
+ include/boost/graph/planar_detail/face_iterators.hpp [2:2]
+ include/boost/graph/planar_face_traversal.hpp [2:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL edd357e5bb31d28a8d2f7af650d68345
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2006-2009 Dmitry Bufistov and Andrey Parfenov
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/howard_cycle_ratio.hpp [1:1]
+
+KEEP COPYRIGHT_SERVICE_LABEL f135edc02c00b6582ebdd933caabbc00
+BELONGS ya.make
+ License text:
+ // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+ // Copyright 2003 Bruce Barr
+ // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/depth_first_search.hpp [2:4]
+
+KEEP COPYRIGHT_SERVICE_LABEL f1f8468601bd581bae0bf23eba4b070b
+BELONGS ya.make
+ License text:
+ // Copyright (c) Jeremy Siek 2001
+ // Copyright (c) Douglas Gregor 2004
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/biconnected_components.hpp [1:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL f2afe39f6ff7491f267ce9bc28a07daa
+BELONGS ya.make
+ License text:
+ // Copyright 1997-2001 University of Notre Dame.
+ // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/connected_components.hpp [3:4]
+ include/boost/graph/copy.hpp [3:4]
+ include/boost/graph/incremental_components.hpp [3:5]
+ include/boost/graph/minimum_degree_ordering.hpp [3:4]
+ include/boost/graph/stanford_graph.hpp [2:3]
+
+KEEP COPYRIGHT_SERVICE_LABEL fd6578dd286e9257f73d8cc59e377eb7
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2005-2009 Jongsoo Park <jongsoo.park -at- gmail.com>
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/dominator_tree.hpp [2:2]
+
+KEEP COPYRIGHT_SERVICE_LABEL fda42ec6f8d7fcf06eb7924a33f02d3c
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/cuthill_mckee_ordering.hpp [2:5]
+ include/boost/graph/detail/sparse_ordering.hpp [2:5]
+ include/boost/graph/king_ordering.hpp [2:5]
+
+KEEP COPYRIGHT_SERVICE_LABEL ff121923a9c0b6799597434faafbacb1
+BELONGS ya.make
+ License text:
+ // Copyright (C) 2006 Tiago de Paula Peixoto <tiago@forked.de>
+ // Copyright (C) 2004 The Trustees of Indiana University.
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/graph/graphml.hpp [1:2]
+ src/graphml.cpp [1:2]
diff --git a/contrib/restricted/boost/graph/.yandex_meta/devtools.licenses.report b/contrib/restricted/boost/graph/.yandex_meta/devtools.licenses.report
new file mode 100644
index 0000000000..5826ab2c9c
--- /dev/null
+++ b/contrib/restricted/boost/graph/.yandex_meta/devtools.licenses.report
@@ -0,0 +1,421 @@
+# File format ($ symbol means the beginning of a line):
+#
+# $ # this message
+# $ # =======================
+# $ # comments (all commentaries should starts with some number of spaces and # symbol)
+# $ IGNORE_FILES {file1.ext1} {file2.ext2} - (optional) ignore listed files when generating license macro and credits
+# $ RENAME {original license id} TO {new license id} # user comments - (optional) use {new license id} instead {original license id} in ya.make files
+# $ # user comments
+# $
+# ${action} {license id} {license text hash}
+# $BELONGS ./ya/make/file/relative/path/1/ya.make ./ya/make/2/ya.make
+# ${all_file_action} filename
+# $ # user commentaries (many lines)
+# $ generated description - files with this license, license text... (some number of lines that starts with some number of spaces, do not modify)
+# ${action} {license spdx} {license text hash}
+# $BELONGS ./ya/make/file/relative/path/3/ya.make
+# ${all_file_action} filename
+# $ # user commentaries
+# $ generated description
+# $ ...
+#
+# You can modify action, all_file_action and add commentaries
+# Available actions:
+# keep - keep license in contrib and use in credits
+# skip - skip license
+# remove - remove all files with this license
+# rename - save license text/links into licenses texts file, but not store SPDX into LINCENSE macro. You should store correct license id into devtools.license.spdx.txt file
+#
+# {all file action} records will be generated when license text contains filename that exists on filesystem (in contrib directory)
+# We suppose that that files can contain some license info
+# Available all file actions:
+# FILE_IGNORE - ignore file (do nothing)
+# FILE_INCLUDE - include all file data into licenses text file
+# =======================
+
+KEEP BSL-1.0 05954ae47dedb48ccaf95b3af88bc2aa
+BELONGS ya.make
+ License text:
+ // Use, modification and distribution is subject to the Boost Software
+ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ // http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 96.88
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/detail/labeled_graph_traits.hpp [3:5]
+ include/boost/graph/dimacs.hpp [3:5]
+ include/boost/graph/edmunds_karp_max_flow.hpp [3:5]
+ include/boost/graph/graph_mutability_traits.hpp [3:5]
+ include/boost/graph/graph_stats.hpp [3:5]
+ include/boost/graph/graphml.hpp [4:6]
+ include/boost/graph/howard_cycle_ratio.hpp [3:5]
+ include/boost/graph/labeled_graph.hpp [3:5]
+ include/boost/graph/mesh_graph_generator.hpp [3:5]
+ include/boost/graph/metis.hpp [3:5]
+ include/boost/graph/named_graph.hpp [3:5]
+ include/boost/graph/overloading.hpp [3:5]
+ include/boost/graph/point_traits.hpp [3:5]
+ include/boost/graph/rmat_graph_generator.hpp [3:5]
+ include/boost/graph/ssca_graph_generator.hpp [3:5]
+ include/boost/graph/st_connected.hpp [3:5]
+ include/boost/graph/vertex_and_edge_range.hpp [3:5]
+ include/boost/pending/relaxed_heap.hpp [3:5]
+ src/graphml.cpp [4:6]
+
+KEEP BSL-1.0 2cc71fe4bd12718a9884bf7ff37269f3
+BELONGS ya.make
+ License text:
+ // Distributed under the Boost Software License, Version 1.0.
+ // (See accompanying file LICENSE_1_0.txt or copy at
+ // http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 100.00
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/bc_clustering.hpp [3:5]
+ include/boost/graph/betweenness_centrality.hpp [3:5]
+ include/boost/graph/circle_layout.hpp [3:5]
+ include/boost/graph/compressed_sparse_row_graph.hpp [3:5]
+ include/boost/graph/detail/compressed_sparse_row_struct.hpp [3:5]
+ include/boost/graph/detail/histogram_sort.hpp [3:5]
+ include/boost/graph/detail/indexed_properties.hpp [3:5]
+ include/boost/graph/detail/is_distributed_selector.hpp [3:5]
+ include/boost/graph/detail/read_graphviz_new.hpp [3:5]
+ include/boost/graph/detail/read_graphviz_spirit.hpp [3:5]
+ include/boost/graph/dominator_tree.hpp [4:6]
+ include/boost/graph/erdos_renyi_generator.hpp [3:5]
+ include/boost/graph/floyd_warshall_shortest.hpp [3:5]
+ include/boost/graph/fruchterman_reingold.hpp [3:5]
+ include/boost/graph/gursoy_atun_layout.hpp [3:5]
+ include/boost/graph/kamada_kawai_spring_layout.hpp [3:5]
+ include/boost/graph/loop_erased_random_walk.hpp [3:5]
+ include/boost/graph/max_cardinality_matching.hpp [4:6]
+ include/boost/graph/maximum_weighted_matching.hpp [4:6]
+ include/boost/graph/one_bit_color_map.hpp [3:5]
+ include/boost/graph/page_rank.hpp [4:6]
+ include/boost/graph/plod_generator.hpp [3:5]
+ include/boost/graph/random_layout.hpp [3:5]
+ include/boost/graph/random_spanning_tree.hpp [3:5]
+ include/boost/graph/small_world_generator.hpp [3:5]
+ include/boost/graph/topology.hpp [3:5]
+ include/boost/graph/two_bit_color_map.hpp [3:5]
+ src/read_graphviz_new.cpp [3:5]
+
+KEEP BSL-1.0 3483ad6500a5ec5c1eed3d256900b057
+BELONGS ya.make
+ License text:
+ // Distributed under the Boost Software License, Version 1.0.
+ // (See accompanying file LICENSE_1_0.txt or copy at
+ // http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 100.00
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/boykov_kolmogorov_max_flow.hpp [28:30]
+ include/boost/graph/write_dimacs.hpp [28:30]
+
+KEEP BSL-1.0 47a0454637d4fa45d78eb2557ccd70c4
+BELONGS ya.make
+ License text:
+ // Distributed under the Boost Software License, Version 1.0. (See
+ // accompanying file LICENSE_1_0.txt or copy at
+ // http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 100.00
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/adj_list_serialize.hpp [5:7]
+ include/boost/graph/adjacency_iterator.hpp [5:7]
+ include/boost/graph/adjacency_list.hpp [6:8]
+ include/boost/graph/adjacency_list_io.hpp [5:7]
+ include/boost/graph/adjacency_matrix.hpp [6:8]
+ include/boost/graph/astar_search.hpp [7:9]
+ include/boost/graph/bandwidth.hpp [3:5]
+ include/boost/graph/bellman_ford_shortest_paths.hpp [6:8]
+ include/boost/graph/biconnected_components.hpp [4:6]
+ include/boost/graph/boyer_myrvold_planar_test.hpp [4:6]
+ include/boost/graph/breadth_first_search.hpp [6:8]
+ include/boost/graph/chrobak_payne_drawing.hpp [4:6]
+ include/boost/graph/connected_components.hpp [6:8]
+ include/boost/graph/copy.hpp [6:8]
+ include/boost/graph/core_numbers.hpp [6:8]
+ include/boost/graph/create_condensation_graph.hpp [5:7]
+ include/boost/graph/cuthill_mckee_ordering.hpp [7:9]
+ include/boost/graph/cycle_canceling.hpp [5:7]
+ include/boost/graph/dag_shortest_paths.hpp [5:7]
+ include/boost/graph/depth_first_search.hpp [6:8]
+ include/boost/graph/detail/adj_list_edge_iterator.hpp [6:8]
+ include/boost/graph/detail/adjacency_list.hpp [7:9]
+ include/boost/graph/detail/array_binary_tree.hpp [6:8]
+ include/boost/graph/detail/augment.hpp [5:7]
+ include/boost/graph/detail/connected_components.hpp [5:7]
+ include/boost/graph/detail/d_ary_heap.hpp [6:8]
+ include/boost/graph/detail/edge.hpp [6:8]
+ include/boost/graph/detail/incidence_iterator.hpp [6:8]
+ include/boost/graph/detail/incremental_components.hpp [6:8]
+ include/boost/graph/detail/list_base.hpp [5:7]
+ include/boost/graph/detail/permutation.hpp [2:4]
+ include/boost/graph/detail/self_avoiding_walk.hpp [5:7]
+ include/boost/graph/detail/set_adaptor.hpp [2:4]
+ include/boost/graph/detail/shadow_iterator.hpp [2:4]
+ include/boost/graph/detail/sparse_ordering.hpp [7:9]
+ include/boost/graph/dijkstra_shortest_paths.hpp [5:7]
+ include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp [6:8]
+ include/boost/graph/dll_import_export.hpp [6:8]
+ include/boost/graph/edge_coloring.hpp [5:7]
+ include/boost/graph/edge_connectivity.hpp [5:7]
+ include/boost/graph/edge_list.hpp [5:7]
+ include/boost/graph/edmonds_karp_max_flow.hpp [5:7]
+ include/boost/graph/exception.hpp [5:7]
+ include/boost/graph/filtered_graph.hpp [5:7]
+ include/boost/graph/find_flow_cost.hpp [5:7]
+ include/boost/graph/graph_archetypes.hpp [5:7]
+ include/boost/graph/graph_as_tree.hpp [6:8]
+ include/boost/graph/graph_concepts.hpp [8:10]
+ include/boost/graph/graph_selectors.hpp [5:7]
+ include/boost/graph/graph_traits.hpp [5:7]
+ include/boost/graph/graph_utility.hpp [6:8]
+ include/boost/graph/graphviz.hpp [6:8]
+ include/boost/graph/grid_graph.hpp [5:7]
+ include/boost/graph/incremental_components.hpp [7:9]
+ include/boost/graph/is_kuratowski_subgraph.hpp [4:6]
+ include/boost/graph/is_straight_line_drawing.hpp [4:6]
+ include/boost/graph/isomorphism.hpp [3:5]
+ include/boost/graph/iteration_macros.hpp [5:7]
+ include/boost/graph/iteration_macros_undef.hpp [5:7]
+ include/boost/graph/johnson_all_pairs_shortest.hpp [5:7]
+ include/boost/graph/king_ordering.hpp [7:9]
+ include/boost/graph/kruskal_min_spanning_tree.hpp [6:8]
+ include/boost/graph/leda_graph.hpp [8:10]
+ include/boost/graph/lookup_edge.hpp [5:7]
+ include/boost/graph/make_biconnected_planar.hpp [4:6]
+ include/boost/graph/make_connected.hpp [4:6]
+ include/boost/graph/make_maximal_planar.hpp [4:6]
+ include/boost/graph/matrix_as_graph.hpp [6:8]
+ include/boost/graph/maximum_adjacency_search.hpp [6:8]
+ include/boost/graph/mcgregor_common_subgraphs.hpp [5:7]
+ include/boost/graph/metric_tsp_approx.hpp [6:8]
+ include/boost/graph/minimum_degree_ordering.hpp [6:8]
+ include/boost/graph/named_function_params.hpp [5:7]
+ include/boost/graph/neighbor_bfs.hpp [6:8]
+ include/boost/graph/planar_canonical_ordering.hpp [4:6]
+ include/boost/graph/planar_detail/add_edge_visitors.hpp [4:6]
+ include/boost/graph/planar_detail/boyer_myrvold_impl.hpp [4:6]
+ include/boost/graph/planar_detail/bucket_sort.hpp [4:6]
+ include/boost/graph/planar_detail/face_handles.hpp [4:6]
+ include/boost/graph/planar_detail/face_iterators.hpp [4:6]
+ include/boost/graph/planar_face_traversal.hpp [4:6]
+ include/boost/graph/prim_minimum_spanning_tree.hpp [5:7]
+ include/boost/graph/profile.hpp [7:9]
+ include/boost/graph/properties.hpp [5:7]
+ include/boost/graph/property_iter_range.hpp [4:6]
+ include/boost/graph/push_relabel_max_flow.hpp [5:7]
+ include/boost/graph/random.hpp [6:8]
+ include/boost/graph/read_dimacs.hpp [5:7]
+ include/boost/graph/relax.hpp [5:7]
+ include/boost/graph/reverse_graph.hpp [2:4]
+ include/boost/graph/sequential_vertex_coloring.hpp [6:8]
+ include/boost/graph/simple_point.hpp [5:7]
+ include/boost/graph/sloan_ordering.hpp [7:9]
+ include/boost/graph/smallest_last_ordering.hpp [5:7]
+ include/boost/graph/stanford_graph.hpp [5:7]
+ include/boost/graph/strong_components.hpp [6:8]
+ include/boost/graph/subgraph.hpp [5:7]
+ include/boost/graph/successive_shortest_path_nonnegative_weights.hpp [5:7]
+ include/boost/graph/topological_sort.hpp [6:8]
+ include/boost/graph/transitive_closure.hpp [3:5]
+ include/boost/graph/transpose_graph.hpp [6:8]
+ include/boost/graph/tree_traits.hpp [2:4]
+ include/boost/graph/undirected_dfs.hpp [6:8]
+ include/boost/graph/vector_as_graph.hpp [7:9]
+ include/boost/graph/vf2_sub_graph_iso.hpp [10:12]
+ include/boost/graph/visitors.hpp [5:7]
+ include/boost/graph/wavefront.hpp [7:9]
+ include/boost/pending/bucket_sorter.hpp [6:8]
+ include/boost/pending/disjoint_sets.hpp [6:8]
+ include/boost/pending/fibonacci_heap.hpp [2:4]
+ include/boost/pending/indirect_cmp.hpp [6:8]
+ include/boost/pending/is_heap.hpp [6:8]
+ include/boost/pending/mutable_heap.hpp [6:8]
+ include/boost/pending/mutable_queue.hpp [6:8]
+
+KEEP BSL-1.0 50dc18b27f34dab68ff41aa3f7880dda
+BELONGS ya.make
+ License text:
+ // Distributed under the Boost Software License, Version 1.0.
+ // (See accompanying file LICENSE_1_0.txt or copy at
+ // http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 100.00
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/two_graphs_common_spanning_trees.hpp [2:4]
+
+KEEP BSL-1.0 56683ba341300dc4497f873f670c97b9
+BELONGS ya.make
+ License text:
+ // Distributed under the Boost Software License, Version 1.0.
+ // (See accompanying file LICENSE_1_0.txt or copy at
+ // http://boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 96.30
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/r_c_shortest_paths.hpp [4:6]
+
+KEEP BSL-1.0 8abbac2c705b0911702566954b0ebe9b
+BELONGS ya.make
+ License text:
+ // Distributed under the Boost Software License, Version 1.0. (See
+ // accompanying file LICENSE_1_0.txt or copy at
+ // http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 100.00
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/pending/container_traits.hpp [4:6]
+ include/boost/pending/detail/disjoint_sets.hpp [2:4]
+ include/boost/pending/detail/property.hpp [2:4]
+ include/boost/pending/fenced_priority_queue.hpp [2:4]
+ include/boost/pending/property.hpp [2:4]
+ include/boost/pending/property_serialize.hpp [2:4]
+ include/boost/pending/queue.hpp [2:4]
+ include/boost/pending/stringtok.hpp [2:4]
+
+KEEP Mit-Old-Style 99b210ed9efe704d061e43a6c4c4beb3
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: LicenseRef-scancode-mit-old-style
+ Score : 100.00
+ Match type : TEXT
+ Links : http://fedoraproject.org/wiki/Licensing:MIT#Old_Style, https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit-old-style.LICENSE
+ Files with this license:
+ include/boost/detail/algorithm.hpp [22:28]
+
+KEEP BSL-1.0 a4b06853a77321815bca2cbd7654b649
+BELONGS ya.make
+ License text:
+ // Distributed under the Boost Software License, Version 1.0. (See accompany-
+ // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 96.30
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/detail/algorithm.hpp [2:3]
+
+KEEP BSL-1.0 b03e7ad31a88c7f7892fe8557944edb4
+BELONGS ya.make
+ License text:
+ // Use, modification and distribution are subject to the
+ // Boost Software License, Version 1.0 (See accompanying file
+ // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 93.75
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/bron_kerbosch_all_cliques.hpp [3:5]
+ include/boost/graph/closeness_centrality.hpp [3:5]
+ include/boost/graph/clustering_coefficient.hpp [3:5]
+ include/boost/graph/degree_centrality.hpp [3:5]
+ include/boost/graph/detail/empty_header.hpp [6:8]
+ include/boost/graph/detail/geodesic.hpp [3:5]
+ include/boost/graph/detail/index.hpp [3:5]
+ include/boost/graph/detail/mpi_include.hpp [6:8]
+ include/boost/graph/directed_graph.hpp [3:5]
+ include/boost/graph/eccentricity.hpp [3:5]
+ include/boost/graph/exterior_property.hpp [3:5]
+ include/boost/graph/geodesic_distance.hpp [3:5]
+ include/boost/graph/numeric_values.hpp [3:5]
+ include/boost/graph/property_maps/constant_property_map.hpp [3:5]
+ include/boost/graph/property_maps/container_property_map.hpp [3:5]
+ include/boost/graph/property_maps/matrix_property_map.hpp [3:5]
+ include/boost/graph/property_maps/null_property_map.hpp [3:5]
+ include/boost/graph/tiernan_all_cycles.hpp [3:5]
+ include/boost/graph/transitive_reduction.hpp [3:5]
+ include/boost/graph/undirected_graph.hpp [3:5]
+
+KEEP Mit-Old-Style b202f5e6061e3eeef6c7dcc2414164b3
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: LicenseRef-scancode-mit-old-style
+ Score : 100.00
+ Match type : TEXT
+ Links : http://fedoraproject.org/wiki/Licensing:MIT#Old_Style, https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit-old-style.LICENSE
+ Files with this license:
+ include/boost/detail/algorithm.hpp [10:16]
+
+KEEP BSL-1.0 bb0492d92471ff074c380f255ab94b94
+BELONGS ya.make
+ License text:
+ // Use, modification and distribution is subject to the Boost Software
+ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
+ // at http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 96.88
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/hawick_circuits.hpp [3:5]
+
+KEEP BSL-1.0 bf0fd55850dbf83aac86f825081dbe20
+BELONGS ya.make
+ License text:
+ // Distributed under the Boost Software License, Version 1.0.
+ // (See accompanying file LICENSE_1_0.txt or the copy at
+ // http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 96.43
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/buffer_concepts.hpp [2:4]
+ include/boost/graph/stoer_wagner_min_cut.hpp [2:4]
+
+KEEP MIT e8fa61ad26065c016c4c968298a683bd
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: MIT
+ Score : 100.00
+ Match type : TEXT
+ Links : http://opensource.org/licenses/mit-license.php, https://spdx.org/licenses/MIT
+ Files with this license:
+ include/boost/graph/boykov_kolmogorov_max_flow.hpp [5:24]
+ include/boost/graph/write_dimacs.hpp [5:24]
+
+KEEP BSL-1.0 f20f9faff5dff60d6b8844771d700dd5
+BELONGS ya.make
+ License text:
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 100.00
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/graph/bipartite.hpp [7:9]
diff --git a/contrib/restricted/boost/graph/.yandex_meta/licenses.list.txt b/contrib/restricted/boost/graph/.yandex_meta/licenses.list.txt
new file mode 100644
index 0000000000..9498d0c9c3
--- /dev/null
+++ b/contrib/restricted/boost/graph/.yandex_meta/licenses.list.txt
@@ -0,0 +1,477 @@
+====================BSL-1.0====================
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or the copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Distributed under the Boost Software License, Version 1.0. (See accompany-
+// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
+// at http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================COPYRIGHT====================
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+
+
+====================COPYRIGHT====================
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+
+
+====================COPYRIGHT====================
+ * Copyright (c) 2010 Matthias Walter (xammy@xammy.homelinux.net)
+
+
+====================COPYRIGHT====================
+// Copyright Daniel Trebbien 2010.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or the copy at
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2012, Michele Caini.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+
+
+====================COPYRIGHT====================
+// (C) Copyright David Abrahams 2000.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+
+
+====================COPYRIGHT====================
+// (C) Copyright Jeremiah Willcock 2004
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+
+
+====================COPYRIGHT====================
+// (C) Copyright Jeremy Siek 1999.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+
+
+====================COPYRIGHT====================
+// (C) Copyright Jeremy Siek 2004
+// (C) Copyright Thomas Claveirole 2010
+// (C) Copyright Ignacy Gawedzki 2010
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+
+
+====================COPYRIGHT====================
+// (C) Copyright Jeremy Siek 2006
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+
+
+====================COPYRIGHT====================
+// Copyright (c) 2006, Stephan Diederich
+
+
+====================COPYRIGHT====================
+// (C) Copyright 2007 Andrew Sutton
+
+
+====================COPYRIGHT====================
+// (C) Copyright 2007-2009 Andrew Sutton
+
+
+====================COPYRIGHT====================
+// (C) Copyright 2009 Eric Bose-Wolf
+
+
+====================COPYRIGHT====================
+// (C) Copyright Andrew Sutton 2007
+
+
+====================COPYRIGHT====================
+// (C) Copyright Francois Faure, iMAGIS-GRAVIR / UJF, 2001.
+
+
+====================COPYRIGHT====================
+// (C) Copyright Jeremy Siek 2001.
+// Distributed under the Boost Software License, Version 1.0. (See accompany-
+// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+====================COPYRIGHT====================
+// (c) Copyright Juergen Hunold 2008
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2001 Jeremy Siek, Douglas Gregor, Brian Osman
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2001 Vladimir Prus <ghost@cs.msu.su>
+// Copyright (C) 2001 Jeremy Siek <jsiek@cs.indiana.edu>
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2005-2006 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2005-2009 Jongsoo Park <jongsoo.park -at- gmail.com>
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2005-2010 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2006 Tiago de Paula Peixoto <tiago@forked.de>
+// Copyright (C) 2004 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2006 Tiago de Paula Peixoto <tiago@forked.de>
+// Copyright (C) 2004,2009 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2006 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2006-2009 Dmitry Bufistov and Andrey Parfenov
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2007 Douglas Gregor
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2009 Andrew Sutton
+
+
+====================COPYRIGHT====================
+// Copyright (C) 2012 Flavio De Lorenzi (fdlorenzi@gmail.com)
+// Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark
+// (jlandersen@imada.sdu.dk)
+
+
+====================COPYRIGHT====================
+// Copyright (c) 2004 Kristopher Beevers
+
+
+====================COPYRIGHT====================
+// Copyright (c) 2005 Aaron Windsor
+
+
+====================COPYRIGHT====================
+// Copyright (c) 2018 Yi Ji
+
+
+====================COPYRIGHT====================
+// Copyright (c) Aaron Windsor 2007
+
+
+====================COPYRIGHT====================
+// Copyright (c) Jeremy Siek 2001
+// Copyright (c) Douglas Gregor 2004
+
+
+====================COPYRIGHT====================
+// Copyright (c) Jeremy Siek 2001, Marc Wintermantel 2002
+
+
+====================COPYRIGHT====================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright (C) Vladimir Prus 2003
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+
+
+====================COPYRIGHT====================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2003 Bruce Barr
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+
+
+====================COPYRIGHT====================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004 The Trustees of Indiana University.
+// Copyright 2007 University of Karlsruhe
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Douglas Gregor,
+// Jens Mueller
+
+
+====================COPYRIGHT====================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004, 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
+// Doug Gregor, D. Kevin McGrath
+
+
+====================COPYRIGHT====================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2006 The Trustees of Indiana University.
+// Copyright (C) 2001 Vladimir Prus <ghost@cs.msu.su>
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Douglas Gregor
+
+
+====================COPYRIGHT====================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2009 Trustees of Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Michael Hansen
+
+
+====================COPYRIGHT====================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2010 Thomas Claveirole
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole
+
+
+====================COPYRIGHT====================
+// Copyright 1997-2001 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+
+
+====================COPYRIGHT====================
+// Copyright 2000 University of Notre Dame.
+// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+
+
+====================COPYRIGHT====================
+// Copyright 2001 Indiana University
+// Author: Jeremy G. Siek
+
+
+====================COPYRIGHT====================
+// Copyright 2001 Universite Joseph Fourier, Grenoble.
+// Author: Francois Faure
+
+
+====================COPYRIGHT====================
+// Copyright 2001 University of Notre Dame.
+// Copyright 2003 Jeremy Siek
+// Authors: Lie-Quan Lee, Jeremy Siek, and Douglas Gregor
+
+
+====================COPYRIGHT====================
+// Copyright 2001 University of Notre Dame.
+// Copyright 2006 Trustees of Indiana University
+// Authors: Jeremy G. Siek and Douglas Gregor <dgregor@cs.indiana.edu>
+
+
+====================COPYRIGHT====================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+
+
+====================COPYRIGHT====================
+// Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch)
+// ETH Zurich, Center of Structure Technologies
+// (https://web.archive.org/web/20050307090307/http://www.structures.ethz.ch/)
+
+
+====================COPYRIGHT====================
+// Copyright 2002 Rensselaer Polytechnic Institute
+
+
+====================COPYRIGHT====================
+// Copyright 2004 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright 2004, 2005 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright 2004-2006 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright 2004-5 The Trustees of Indiana University.
+// Copyright 2002 Brad King and Douglas Gregor
+
+
+====================COPYRIGHT====================
+// Copyright 2004-9 Trustees of Indiana University
+
+
+====================COPYRIGHT====================
+// Copyright 2005 Jeremy G. Siek
+// Authors: Jeremy G. Siek
+
+
+====================COPYRIGHT====================
+// Copyright 2005 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Douglas Gregor
+
+
+====================COPYRIGHT====================
+// Copyright 2005-2009 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright 2007 Aaron Windsor
+
+
+====================COPYRIGHT====================
+// Copyright 2007 Stanford University
+// Authors: David Gleich
+
+
+====================COPYRIGHT====================
+// Copyright 2008
+// Author: Matyas W Egyhazy
+
+
+====================COPYRIGHT====================
+// Copyright 2009 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright 2009, Andrew Sutton
+
+
+====================COPYRIGHT====================
+// Copyright 2010 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright 2012 Fernando Vilas
+// 2010 Daniel Trebbien
+
+
+====================COPYRIGHT====================
+// Copyright 2012 The Trustees of Indiana University.
+
+
+====================COPYRIGHT====================
+// Copyright 2013 Maciej Piechotka
+// Authors: Maciej Piechotka
+
+
+====================COPYRIGHT====================
+// Copyright 2013 University of Warsaw.
+// Authors: Piotr Wygocki
+
+
+====================COPYRIGHT====================
+// Copyright 2018 Peter Dimov
+
+
+====================COPYRIGHT====================
+// Copyright Louis Dionne 2013
+
+
+====================COPYRIGHT====================
+// Copyright Michael Drexl 2005, 2006.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+
+
+====================MIT====================
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE.
+
+
+====================Mit-Old-Style====================
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+
+
+====================Mit-Old-Style====================
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
diff --git a/contrib/restricted/boost/graph/include/boost/detail/algorithm.hpp b/contrib/restricted/boost/graph/include/boost/detail/algorithm.hpp
new file mode 100644
index 0000000000..9b3195cbf0
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/detail/algorithm.hpp
@@ -0,0 +1,83 @@
+// (C) Copyright Jeremy Siek 2001.
+// Distributed under the Boost Software License, Version 1.0. (See accompany-
+// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef BOOST_ALGORITHM_HPP
+#define BOOST_ALGORITHM_HPP
+
+// Algorithms on sequences
+//
+// The functions in this file have not yet gone through formal
+// review, and are subject to change. This is a work in progress.
+// They have been checked into the detail directory because
+// there are some graph algorithms that use these functions.
+
+#include <algorithm>
+#include <vector>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/range/algorithm/equal.hpp>
+#include <boost/range/algorithm/sort.hpp>
+#include <boost/range/algorithm/stable_sort.hpp>
+#include <boost/range/algorithm/find_if.hpp>
+#include <boost/range/algorithm/count.hpp>
+#include <boost/range/algorithm/count_if.hpp>
+#include <boost/range/algorithm_ext/is_sorted.hpp>
+#include <boost/range/algorithm_ext/iota.hpp>
+
+namespace boost
+{
+
+template < typename InputIterator, typename Predicate >
+bool any_if(InputIterator first, InputIterator last, Predicate p)
+{
+ return std::find_if(first, last, p) != last;
+}
+
+template < typename Container, typename Predicate >
+bool any_if(const Container& c, Predicate p)
+{
+ return any_if(boost::begin(c), boost::end(c), p);
+}
+
+template < typename InputIterator, typename T >
+bool container_contains(InputIterator first, InputIterator last, T value)
+{
+ return std::find(first, last, value) != last;
+}
+template < typename Container, typename T >
+bool container_contains(const Container& c, const T& value)
+{
+ return container_contains(boost::begin(c), boost::end(c), value);
+}
+
+} // namespace boost
+
+#endif // BOOST_ALGORITHM_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/adj_list_serialize.hpp b/contrib/restricted/boost/graph/include/boost/graph/adj_list_serialize.hpp
new file mode 100644
index 0000000000..85f7e2ed41
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/adj_list_serialize.hpp
@@ -0,0 +1,130 @@
+//=======================================================================
+// Copyright 2005 Jeremy G. Siek
+// Authors: Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_ADJ_LIST_SERIALIZE_HPP
+#define BOOST_GRAPH_ADJ_LIST_SERIALIZE_HPP
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/pending/property_serialize.hpp>
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <boost/serialization/collections_save_imp.hpp>
+#include <boost/serialization/collections_load_imp.hpp>
+#include <boost/serialization/split_free.hpp>
+
+namespace boost
+{
+
+namespace serialization
+{
+
+ // Turn off tracking for adjacency_list. It's not polymorphic, and we
+ // need to do this to enable saving of non-const adjacency lists.
+ template < class OEL, class VL, class D, class VP, class EP, class GP,
+ class EL >
+ struct tracking_level< boost::adjacency_list< OEL, VL, D, VP, EP, GP, EL > >
+ {
+ typedef mpl::integral_c_tag tag;
+ typedef mpl::int_< track_never > type;
+ BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value);
+ };
+
+ template < class Archive, class OEL, class VL, class D, class VP, class EP,
+ class GP, class EL >
+ inline void save(Archive& ar,
+ const boost::adjacency_list< OEL, VL, D, VP, EP, GP, EL >& graph,
+ const unsigned int /* file_version */
+ )
+ {
+ typedef adjacency_list< OEL, VL, D, VP, EP, GP, EL > Graph;
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+
+ int V = num_vertices(graph);
+ int E = num_edges(graph);
+ ar << BOOST_SERIALIZATION_NVP(V);
+ ar << BOOST_SERIALIZATION_NVP(E);
+
+ // assign indices to vertices
+ std::map< Vertex, int > indices;
+ int num = 0;
+ BGL_FORALL_VERTICES_T(v, graph, Graph)
+ {
+ indices[v] = num++;
+ ar << serialization::make_nvp(
+ "vertex_property", get(vertex_all_t(), graph, v));
+ }
+
+ // write edges
+ BGL_FORALL_EDGES_T(e, graph, Graph)
+ {
+ ar << serialization::make_nvp("u", indices[source(e, graph)]);
+ ar << serialization::make_nvp("v", indices[target(e, graph)]);
+ ar << serialization::make_nvp(
+ "edge_property", get(edge_all_t(), graph, e));
+ }
+
+ ar << serialization::make_nvp(
+ "graph_property", get_property(graph, graph_all_t()));
+ }
+
+ template < class Archive, class OEL, class VL, class D, class VP, class EP,
+ class GP, class EL >
+ inline void load(
+ Archive& ar, boost::adjacency_list< OEL, VL, D, VP, EP, GP, EL >& graph,
+ const unsigned int /* file_version */
+ )
+ {
+ typedef adjacency_list< OEL, VL, D, VP, EP, GP, EL > Graph;
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::edge_descriptor Edge;
+
+ unsigned int V;
+ ar >> BOOST_SERIALIZATION_NVP(V);
+ unsigned int E;
+ ar >> BOOST_SERIALIZATION_NVP(E);
+
+ std::vector< Vertex > verts(V);
+ int i = 0;
+ while (V-- > 0)
+ {
+ Vertex v = add_vertex(graph);
+ verts[i++] = v;
+ ar >> serialization::make_nvp(
+ "vertex_property", get(vertex_all_t(), graph, v));
+ }
+ while (E-- > 0)
+ {
+ int u;
+ int v;
+ ar >> BOOST_SERIALIZATION_NVP(u);
+ ar >> BOOST_SERIALIZATION_NVP(v);
+ Edge e;
+ bool inserted;
+ boost::tie(e, inserted) = add_edge(verts[u], verts[v], graph);
+ ar >> serialization::make_nvp(
+ "edge_property", get(edge_all_t(), graph, e));
+ }
+ ar >> serialization::make_nvp(
+ "graph_property", get_property(graph, graph_all_t()));
+ }
+
+ template < class Archive, class OEL, class VL, class D, class VP, class EP,
+ class GP, class EL >
+ inline void serialize(Archive& ar,
+ boost::adjacency_list< OEL, VL, D, VP, EP, GP, EL >& graph,
+ const unsigned int file_version)
+ {
+ boost::serialization::split_free(ar, graph, file_version);
+ }
+
+} // serialization
+} // boost
+
+#endif // BOOST_GRAPH_ADJ_LIST_SERIALIZE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/adjacency_list_io.hpp b/contrib/restricted/boost/graph/include/boost/graph/adjacency_list_io.hpp
new file mode 100644
index 0000000000..4a85bebd99
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/adjacency_list_io.hpp
@@ -0,0 +1,405 @@
+//=======================================================================
+// Copyright 2001 Universite Joseph Fourier, Grenoble.
+// Author: Francois Faure
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_ADJACENCY_LIST_IO_HPP
+#define BOOST_GRAPH_ADJACENCY_LIST_IO_HPP
+
+#include <iostream>
+#include <vector>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <cctype>
+
+// Method read to parse an adjacency list from an input stream. Examples:
+// cin >> read( G );
+// cin >> read( G, NodePropertySubset(), EdgepropertySubset() );
+//
+// Method write to print an adjacency list to an output stream. Examples:
+// cout << write( G );
+// cout << write( G, NodePropertySubset(), EdgepropertySubset() );
+
+namespace boost
+{
+
+/* outline
+ - basic property input
+ - get property subset
+ - graph parser
+ - property printer
+ - graph printer
+ - user methods
+*/
+
+//===========================================================================
+// basic property input
+
+template < class Tag, class Value, class Next >
+std::istream& operator>>(std::istream& in, property< Tag, Value, Next >& p)
+{
+ in >> p.m_value >> p.m_base; // houpla !!
+ return in;
+}
+
+template < class Tag, class Value >
+std::istream& operator>>(
+ std::istream& in, property< Tag, Value, no_property >& p)
+{
+ in >> p.m_value;
+ return in;
+}
+
+inline std::istream& operator>>(std::istream& in, no_property&) { return in; }
+
+// basic property input
+//===========================================================================
+// get property subsets
+
+// get a single property tagged Stag
+template < class Tag, class Value, class Next, class V, class Stag >
+void get(property< Tag, Value, Next >& p, const V& v, Stag s)
+{
+ get(p.m_base, v, s);
+}
+
+template < class Value, class Next, class V, class Stag >
+void get(property< Stag, Value, Next >& p, const V& v, Stag)
+{
+ p.m_value = v;
+}
+
+// get a subset of properties tagged Stag
+template < class Tag, class Value, class Next, class Stag, class Svalue,
+ class Snext >
+void getSubset(
+ property< Tag, Value, Next >& p, const property< Stag, Svalue, Snext >& s)
+{
+ get(p, s.m_value, Stag());
+ getSubset(p, s.m_base);
+}
+
+template < class Tag, class Value, class Next, class Stag, class Svalue >
+void getSubset(property< Tag, Value, Next >& p,
+ const property< Stag, Svalue, no_property >& s)
+{
+ get(p, s.m_value, Stag());
+}
+
+inline void getSubset(no_property&, const no_property&) {}
+
+#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
+template < typename T, typename U > void getSubset(T& p, const U& s) { p = s; }
+
+template < typename T > void getSubset(T&, const no_property&) {}
+
+#endif
+
+// get property subset
+//===========================================================================
+// graph parser
+typedef enum
+{
+ PARSE_NUM_NODES,
+ PARSE_VERTEX,
+ PARSE_EDGE
+} GraphParserState;
+
+template < class Graph_t, class VertexProperty, class EdgeProperty,
+ class VertexPropertySubset, class EdgePropertySubset >
+struct GraphParser
+{
+
+ typedef Graph_t Graph;
+
+ GraphParser(Graph* g) : graph(g) {}
+
+ GraphParser& operator()(std::istream& in)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ std::vector< Vertex > nodes;
+
+ GraphParserState state = PARSE_VERTEX;
+
+ unsigned int numLine = 1;
+ char c;
+ while (in.get(c))
+ {
+ if (c == '#')
+ skip(in);
+ else if (c == 'n')
+ state = PARSE_NUM_NODES;
+ else if (c == 'v')
+ state = PARSE_VERTEX;
+ else if (c == 'e')
+ state = PARSE_EDGE;
+ else if (c == '\n')
+ numLine++;
+ else if (!std::isspace(c))
+ {
+ in.putback(c);
+ if (state == PARSE_VERTEX)
+ {
+ VertexPropertySubset readProp;
+ if (in >> readProp)
+ {
+ VertexProperty vp;
+ getSubset(vp, readProp);
+ nodes.push_back(add_vertex(vp, *graph));
+ }
+ else
+ std::cerr << "read vertex, parse error at line"
+ << numLine << std::endl;
+ }
+ else if (state == PARSE_EDGE)
+ {
+ int source, target;
+ EdgePropertySubset readProp;
+ in >> source >> target;
+ if (in >> readProp)
+ {
+ EdgeProperty ep;
+ getSubset(ep, readProp);
+ add_edge(nodes[source], nodes[target], ep, *graph);
+ }
+ else
+ std::cerr << "read edge, parse error at line" << numLine
+ << std::endl;
+ }
+ else
+ { // state == PARSE_NUM_NODES
+ int n;
+ if (in >> n)
+ {
+ for (int i = 0; i < n; ++i)
+ nodes.push_back(add_vertex(*graph));
+ }
+ else
+ std::cerr << "read num_nodes, parse error at line "
+ << numLine << std::endl;
+ }
+ }
+ }
+ return (*this);
+ }
+
+protected:
+ Graph* graph;
+
+ void skip(std::istream& in)
+ {
+ char c = 0;
+ while (c != '\n' && !in.eof())
+ in.get(c);
+ in.putback(c);
+ }
+};
+
+// parser
+//=======================================================================
+// property printer
+
+#if defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
+template < class Graph, class Property > struct PropertyPrinter
+{
+ typedef typename Property::value_type Value;
+ typedef typename Property::tag_type Tag;
+ typedef typename Property::next_type Next;
+
+ PropertyPrinter(const Graph& g) : graph(&g) {}
+
+ template < class Val >
+ PropertyPrinter& operator()(std::ostream& out, const Val& v)
+ {
+ typename property_map< Graph, Tag >::const_type ps = get(Tag(), *graph);
+ out << ps[v] << " ";
+ PropertyPrinter< Graph, Next > print(*graph);
+ print(out, v);
+ return (*this);
+ }
+
+private:
+ const Graph* graph;
+};
+#else
+template < class Graph, typename Property > struct PropertyPrinter
+{
+ PropertyPrinter(const Graph& g) : graph(&g) {}
+
+ template < class Val >
+ PropertyPrinter& operator()(std::ostream& out, const Val& v)
+ {
+ out << (*graph)[v] << " ";
+ return (*this);
+ }
+
+private:
+ const Graph* graph;
+};
+
+template < class Graph, typename Tag, typename Value, typename Next >
+struct PropertyPrinter< Graph, property< Tag, Value, Next > >
+{
+ PropertyPrinter(const Graph& g) : graph(&g) {}
+
+ template < class Val >
+ PropertyPrinter& operator()(std::ostream& out, const Val& v)
+ {
+ typename property_map< Graph, Tag >::const_type ps = get(Tag(), *graph);
+ out << ps[v] << " ";
+ PropertyPrinter< Graph, Next > print(*graph);
+ print(out, v);
+ return (*this);
+ }
+
+private:
+ const Graph* graph;
+};
+#endif
+
+template < class Graph > struct PropertyPrinter< Graph, no_property >
+{
+ PropertyPrinter(const Graph&) {}
+
+ template < class Val >
+ PropertyPrinter& operator()(std::ostream&, const Val&)
+ {
+ return *this;
+ }
+};
+
+// property printer
+//=========================================================================
+// graph printer
+
+template < class Graph_t, class EdgeProperty > struct EdgePrinter
+{
+
+ typedef Graph_t Graph;
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+
+ EdgePrinter(const Graph& g) : graph(g) {}
+
+ const EdgePrinter& operator()(std::ostream& out) const
+ {
+ // assign indices to vertices
+ std::map< Vertex, int > indices;
+ int num = 0;
+ BGL_FORALL_VERTICES_T(v, graph, Graph) { indices[v] = num++; }
+
+ // write edges
+ PropertyPrinter< Graph, EdgeProperty > print_Edge(graph);
+ out << "e" << std::endl;
+ BGL_FORALL_EDGES_T(e, graph, Graph)
+ {
+ out << indices[source(e, graph)] << " " << indices[target(e, graph)]
+ << " ";
+ print_Edge(out, e);
+ out << std::endl;
+ }
+ out << std::endl;
+ return (*this);
+ }
+
+protected:
+ const Graph& graph;
+};
+
+template < class Graph, class V, class E >
+struct GraphPrinter : public EdgePrinter< Graph, E >
+{
+ GraphPrinter(const Graph& g) : EdgePrinter< Graph, E >(g) {}
+
+ const GraphPrinter& operator()(std::ostream& out) const
+ {
+ PropertyPrinter< Graph, V > printNode(this->graph);
+ out << "v" << std::endl;
+ BGL_FORALL_VERTICES_T(v, this->graph, Graph)
+ {
+ printNode(out, v);
+ out << std::endl;
+ }
+
+ EdgePrinter< Graph, E >::operator()(out);
+ return (*this);
+ }
+};
+
+template < class Graph, class E >
+struct GraphPrinter< Graph, no_property, E > : public EdgePrinter< Graph, E >
+{
+ GraphPrinter(const Graph& g) : EdgePrinter< Graph, E >(g) {}
+
+ const GraphPrinter& operator()(std::ostream& out) const
+ {
+ out << "n " << num_vertices(this->graph) << std::endl;
+ EdgePrinter< Graph, E >::operator()(out);
+ return (*this);
+ }
+};
+
+// graph printer
+//=========================================================================
+// user methods
+
+/// input stream for reading a graph
+template < class Graph, class VP, class EP, class VPS, class EPS >
+std::istream& operator>>(
+ std::istream& in, GraphParser< Graph, VP, EP, VPS, EPS > gp)
+{
+ gp(in);
+ return in;
+}
+
+/// graph parser for given subsets of internal vertex and edge properties
+template < class EL, class VL, class D, class VP, class EP, class GP, class VPS,
+ class EPS >
+GraphParser< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP, VPS, EPS > read(
+ adjacency_list< EL, VL, D, VP, EP, GP >& g, VPS vps, EPS eps)
+{
+ return GraphParser< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP, VPS,
+ EPS >(&g);
+}
+
+/// graph parser for all internal vertex and edge properties
+template < class EL, class VL, class D, class VP, class EP, class GP >
+GraphParser< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP, VP, EP > read(
+ adjacency_list< EL, VL, D, VP, EP, GP >& g)
+{
+ return GraphParser< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP, VP,
+ EP >(&g);
+}
+
+/// output stream for writing a graph
+template < class Graph, class VP, class EP >
+std::ostream& operator<<(
+ std::ostream& out, const GraphPrinter< Graph, VP, EP >& gp)
+{
+ gp(out);
+ return out;
+}
+
+/// write the graph with given property subsets
+template < class EL, class VL, class D, class VP, class EP, class GP, class VPS,
+ class EPS >
+GraphPrinter< adjacency_list< EL, VL, D, VP, EP, GP >, VPS, EPS > write(
+ const adjacency_list< EL, VL, D, VP, EP, GP >& g, VPS, EPS)
+{
+ return GraphPrinter< adjacency_list< EL, VL, D, VP, EP, GP >, VPS, EPS >(g);
+}
+
+/// write the graph with all internal vertex and edge properties
+template < class EL, class VL, class D, class VP, class EP, class GP >
+GraphPrinter< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP > write(
+ const adjacency_list< EL, VL, D, VP, EP, GP >& g)
+{
+ return GraphPrinter< adjacency_list< EL, VL, D, VP, EP, GP >, VP, EP >(g);
+}
+
+// user methods
+//=========================================================================
+} // boost
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/adjacency_matrix.hpp b/contrib/restricted/boost/graph/include/boost/graph/adjacency_matrix.hpp
new file mode 100644
index 0000000000..8d6990cb30
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/adjacency_matrix.hpp
@@ -0,0 +1,1296 @@
+//=======================================================================
+// Copyright 2001 University of Notre Dame.
+// Copyright 2006 Trustees of Indiana University
+// Authors: Jeremy G. Siek and Douglas Gregor <dgregor@cs.indiana.edu>
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_ADJACENCY_MATRIX_HPP
+#define BOOST_ADJACENCY_MATRIX_HPP
+
+#include <boost/config.hpp>
+#include <vector>
+#include <memory>
+#include <iterator>
+#include <boost/assert.hpp>
+#include <boost/limits.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_mutability_traits.hpp>
+#include <boost/graph/graph_selectors.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/graph/adjacency_iterator.hpp>
+#include <boost/graph/detail/edge.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/filter_iterator.hpp>
+#include <boost/range/irange.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/property_map/transform_value_property_map.hpp>
+#include <boost/property_map/function_property_map.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < class Directed, class Vertex >
+ class matrix_edge_desc_impl : public edge_desc_impl< Directed, Vertex >
+ {
+ typedef edge_desc_impl< Directed, Vertex > Base;
+
+ public:
+ matrix_edge_desc_impl() {}
+ matrix_edge_desc_impl(
+ bool exists, Vertex s, Vertex d, const void* ep = 0)
+ : Base(s, d, ep), m_exists(exists)
+ {
+ }
+ bool exists() const { return m_exists; }
+
+ private:
+ bool m_exists;
+ };
+
+ struct does_edge_exist
+ {
+ template < class Edge > bool operator()(const Edge& e) const
+ {
+ return e.exists();
+ }
+ };
+
+ // Note to self... The int for get_edge_exists and set_edge exist helps
+ // make these calls unambiguous.
+ template < typename EdgeProperty >
+ bool get_edge_exists(
+ const std::pair< bool, EdgeProperty >& stored_edge, int)
+ {
+ return stored_edge.first;
+ }
+ template < typename EdgeProperty >
+ void set_edge_exists(
+ std::pair< bool, EdgeProperty >& stored_edge, bool flag, int)
+ {
+ stored_edge.first = flag;
+ }
+
+ template < typename EdgeProxy >
+ bool get_edge_exists(const EdgeProxy& edge_proxy, ...)
+ {
+ return edge_proxy;
+ }
+ template < typename EdgeProxy >
+ EdgeProxy& set_edge_exists(EdgeProxy& edge_proxy, bool flag, ...)
+ {
+ edge_proxy = flag;
+ return edge_proxy; // just to avoid never used warning
+ }
+
+ // NOTE: These functions collide with the get_property function for
+ // accessing bundled graph properties. Be excplicit when using them.
+ template < typename EdgeProperty >
+ const EdgeProperty& get_edge_property(
+ const std::pair< bool, EdgeProperty >& stored_edge)
+ {
+ return stored_edge.second;
+ }
+ template < typename EdgeProperty >
+ EdgeProperty& get_edge_property(
+ std::pair< bool, EdgeProperty >& stored_edge)
+ {
+ return stored_edge.second;
+ }
+
+ template < typename StoredEdgeProperty, typename EdgeProperty >
+ inline void set_edge_property(
+ std::pair< bool, StoredEdgeProperty >& stored_edge,
+ const EdgeProperty& ep, int)
+ {
+ stored_edge.second = ep;
+ }
+
+ inline const no_property& get_edge_property(const char&)
+ {
+ static no_property s_prop;
+ return s_prop;
+ }
+ inline no_property& get_edge_property(char&)
+ {
+ static no_property s_prop;
+ return s_prop;
+ }
+ template < typename EdgeProxy, typename EdgeProperty >
+ inline void set_edge_property(EdgeProxy, const EdgeProperty&, ...)
+ {
+ }
+
+ //=======================================================================
+ // Directed Out Edge Iterator
+
+ template < typename VertexDescriptor, typename MatrixIter,
+ typename VerticesSizeType, typename EdgeDescriptor >
+ struct dir_adj_matrix_out_edge_iter
+ : iterator_adaptor< dir_adj_matrix_out_edge_iter< VertexDescriptor,
+ MatrixIter, VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ {
+ typedef iterator_adaptor<
+ dir_adj_matrix_out_edge_iter< VertexDescriptor, MatrixIter,
+ VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ super_t;
+
+ dir_adj_matrix_out_edge_iter() {}
+
+ dir_adj_matrix_out_edge_iter(const MatrixIter& i,
+ const VertexDescriptor& src, const VerticesSizeType& n)
+ : super_t(i), m_src(src), m_targ(0), m_n(n)
+ {
+ }
+
+ void increment()
+ {
+ ++this->base_reference();
+ ++m_targ;
+ }
+
+ inline EdgeDescriptor dereference() const
+ {
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
+ m_targ, &get_edge_property(*this->base()));
+ }
+ VertexDescriptor m_src, m_targ;
+ VerticesSizeType m_n;
+ };
+
+ //=======================================================================
+ // Directed In Edge Iterator
+
+ template < typename VertexDescriptor, typename MatrixIter,
+ typename VerticesSizeType, typename EdgeDescriptor >
+ struct dir_adj_matrix_in_edge_iter
+ : iterator_adaptor< dir_adj_matrix_in_edge_iter< VertexDescriptor,
+ MatrixIter, VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ {
+ typedef iterator_adaptor<
+ dir_adj_matrix_in_edge_iter< VertexDescriptor, MatrixIter,
+ VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ super_t;
+
+ dir_adj_matrix_in_edge_iter() {}
+
+ dir_adj_matrix_in_edge_iter(const MatrixIter& i, const MatrixIter& last,
+ const VertexDescriptor& tgt, const VerticesSizeType& n)
+ : super_t(i), m_last(last), m_src(0), m_targ(tgt), m_n(n)
+ {
+ }
+
+ void increment()
+ {
+ if (VerticesSizeType(m_last - this->base_reference()) >= m_n)
+ {
+ this->base_reference() += m_n;
+ ++m_src;
+ }
+ else
+ {
+ this->base_reference() = m_last;
+ }
+ }
+
+ inline EdgeDescriptor dereference() const
+ {
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
+ m_targ, &get_edge_property(*this->base()));
+ }
+ MatrixIter m_last;
+ VertexDescriptor m_src, m_targ;
+ VerticesSizeType m_n;
+ };
+
+ //=======================================================================
+ // Undirected Out Edge Iterator
+
+ template < typename VertexDescriptor, typename MatrixIter,
+ typename VerticesSizeType, typename EdgeDescriptor >
+ struct undir_adj_matrix_out_edge_iter
+ : iterator_adaptor< undir_adj_matrix_out_edge_iter< VertexDescriptor,
+ MatrixIter, VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ {
+ typedef iterator_adaptor<
+ undir_adj_matrix_out_edge_iter< VertexDescriptor, MatrixIter,
+ VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ super_t;
+
+ undir_adj_matrix_out_edge_iter() {}
+
+ undir_adj_matrix_out_edge_iter(const MatrixIter& i,
+ const VertexDescriptor& src, const VerticesSizeType& n)
+ : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
+ {
+ }
+
+ void increment()
+ {
+ if (m_targ < m_src) // first half
+ {
+ ++this->base_reference();
+ }
+ else if (m_targ < m_n - 1)
+ { // second half
+ ++m_inc;
+ this->base_reference() += m_inc;
+ }
+ else
+ { // past-the-end
+ this->base_reference() += m_n - m_src;
+ }
+ ++m_targ;
+ }
+
+ inline EdgeDescriptor dereference() const
+ {
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
+ m_targ, &get_edge_property(*this->base()));
+ }
+
+ VertexDescriptor m_src, m_inc, m_targ;
+ VerticesSizeType m_n;
+ };
+
+ //=======================================================================
+ // Undirected In Edge Iterator
+
+ template < typename VertexDescriptor, typename MatrixIter,
+ typename VerticesSizeType, typename EdgeDescriptor >
+ struct undir_adj_matrix_in_edge_iter
+ : iterator_adaptor< undir_adj_matrix_in_edge_iter< VertexDescriptor,
+ MatrixIter, VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ {
+ typedef iterator_adaptor<
+ undir_adj_matrix_in_edge_iter< VertexDescriptor, MatrixIter,
+ VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ super_t;
+
+ undir_adj_matrix_in_edge_iter() {}
+
+ undir_adj_matrix_in_edge_iter(const MatrixIter& i,
+ const VertexDescriptor& src, const VerticesSizeType& n)
+ : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
+ {
+ }
+
+ void increment()
+ {
+ if (m_targ < m_src) // first half
+ {
+ ++this->base_reference();
+ }
+ else if (m_targ < m_n - 1)
+ { // second half
+ ++m_inc;
+ this->base_reference() += m_inc;
+ }
+ else
+ { // past-the-end
+ this->base_reference() += m_n - m_src;
+ }
+ ++m_targ;
+ }
+
+ inline EdgeDescriptor dereference() const
+ {
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_targ,
+ m_src, &get_edge_property(*this->base()));
+ }
+
+ VertexDescriptor m_src, m_inc, m_targ;
+ VerticesSizeType m_n;
+ };
+
+ //=======================================================================
+ // Edge Iterator
+
+ template < typename Directed, typename MatrixIter,
+ typename VerticesSizeType, typename EdgeDescriptor >
+ struct adj_matrix_edge_iter
+ : iterator_adaptor< adj_matrix_edge_iter< Directed, MatrixIter,
+ VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ {
+ typedef iterator_adaptor< adj_matrix_edge_iter< Directed, MatrixIter,
+ VerticesSizeType, EdgeDescriptor >,
+ MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
+ std::ptrdiff_t >
+ super_t;
+
+ adj_matrix_edge_iter() {}
+
+ adj_matrix_edge_iter(const MatrixIter& i, const MatrixIter& start,
+ const VerticesSizeType& n)
+ : super_t(i), m_start(start), m_src(0), m_targ(0), m_n(n)
+ {
+ }
+
+ void increment()
+ {
+ increment_dispatch(this->base_reference(), Directed());
+ }
+
+ void increment_dispatch(MatrixIter& i, directedS)
+ {
+ ++i;
+ if (m_targ == m_n - 1)
+ {
+ m_targ = 0;
+ ++m_src;
+ }
+ else
+ {
+ ++m_targ;
+ }
+ }
+
+ void increment_dispatch(MatrixIter& i, undirectedS)
+ {
+ ++i;
+ if (m_targ == m_src)
+ {
+ m_targ = 0;
+ ++m_src;
+ }
+ else
+ {
+ ++m_targ;
+ }
+ }
+
+ inline EdgeDescriptor dereference() const
+ {
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
+ m_targ, &get_edge_property(*this->base()));
+ }
+
+ MatrixIter m_start;
+ VerticesSizeType m_src, m_targ, m_n;
+ };
+
+} // namespace detail
+
+//=========================================================================
+// Adjacency Matrix Traits
+template < typename Directed = directedS > class adjacency_matrix_traits
+{
+ typedef typename Directed::is_directed_t is_directed;
+
+public:
+ // The bidirectionalS tag is not allowed with the adjacency_matrix
+ // graph type. Instead, use directedS, which also provides the
+ // functionality required for a Bidirectional Graph (in_edges,
+ // in_degree, etc.).
+ BOOST_STATIC_ASSERT(!(is_same< Directed, bidirectionalS >::value));
+
+ typedef typename mpl::if_< is_directed, bidirectional_tag,
+ undirected_tag >::type directed_category;
+
+ typedef disallow_parallel_edge_tag edge_parallel_category;
+
+ typedef std::size_t vertex_descriptor;
+
+ typedef detail::matrix_edge_desc_impl< directed_category,
+ vertex_descriptor >
+ edge_descriptor;
+};
+
+struct adjacency_matrix_class_tag
+{
+};
+
+struct adj_matrix_traversal_tag : public virtual adjacency_matrix_tag,
+ public virtual vertex_list_graph_tag,
+ public virtual incidence_graph_tag,
+ public virtual adjacency_graph_tag,
+ public virtual edge_list_graph_tag
+{
+};
+
+//=========================================================================
+// Adjacency Matrix Class
+template < typename Directed = directedS, typename VertexProperty = no_property,
+ typename EdgeProperty = no_property, typename GraphProperty = no_property,
+ typename Allocator = std::allocator< bool > >
+class adjacency_matrix
+{
+ typedef adjacency_matrix self;
+ typedef adjacency_matrix_traits< Directed > Traits;
+
+public:
+ // The bidirectionalS tag is not allowed with the adjacency_matrix
+ // graph type. Instead, use directedS, which also provides the
+ // functionality required for a Bidirectional Graph (in_edges,
+ // in_degree, etc.).
+ BOOST_STATIC_ASSERT(!(is_same< Directed, bidirectionalS >::value));
+
+ typedef GraphProperty graph_property_type;
+ typedef typename lookup_one_property< GraphProperty, graph_bundle_t >::type
+ graph_bundled;
+
+ typedef VertexProperty vertex_property_type;
+ typedef
+ typename lookup_one_property< VertexProperty, vertex_bundle_t >::type
+ vertex_bundled;
+
+ typedef EdgeProperty edge_property_type;
+ typedef typename lookup_one_property< EdgeProperty, edge_bundle_t >::type
+ edge_bundled;
+
+public: // should be private
+ typedef
+ typename mpl::if_< typename has_property< edge_property_type >::type,
+ std::pair< bool, edge_property_type >, char >::type StoredEdge;
+#if defined(BOOST_NO_STD_ALLOCATOR)
+ typedef std::vector< StoredEdge > Matrix;
+#else
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+ typedef typename Allocator::template rebind< StoredEdge >::other Alloc;
+#else
+ typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
+ StoredEdge >
+ Alloc;
+#endif
+ typedef std::vector< StoredEdge, Alloc > Matrix;
+#endif
+ typedef typename Matrix::iterator MatrixIter;
+ typedef typename Matrix::size_type size_type;
+
+public:
+ // Graph concept required types
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::edge_descriptor edge_descriptor;
+ typedef typename Traits::directed_category directed_category;
+ typedef typename Traits::edge_parallel_category edge_parallel_category;
+ typedef adj_matrix_traversal_tag traversal_category;
+
+ static vertex_descriptor null_vertex()
+ {
+ return (std::numeric_limits< vertex_descriptor >::max)();
+ }
+
+ // private: if friends worked, these would be private
+
+ typedef detail::dir_adj_matrix_out_edge_iter< vertex_descriptor, MatrixIter,
+ size_type, edge_descriptor >
+ DirOutEdgeIter;
+
+ typedef detail::undir_adj_matrix_out_edge_iter< vertex_descriptor,
+ MatrixIter, size_type, edge_descriptor >
+ UnDirOutEdgeIter;
+
+ typedef typename mpl::if_< typename Directed::is_directed_t, DirOutEdgeIter,
+ UnDirOutEdgeIter >::type unfiltered_out_edge_iter;
+
+ typedef detail::dir_adj_matrix_in_edge_iter< vertex_descriptor, MatrixIter,
+ size_type, edge_descriptor >
+ DirInEdgeIter;
+
+ typedef detail::undir_adj_matrix_in_edge_iter< vertex_descriptor,
+ MatrixIter, size_type, edge_descriptor >
+ UnDirInEdgeIter;
+
+ typedef typename mpl::if_< typename Directed::is_directed_t, DirInEdgeIter,
+ UnDirInEdgeIter >::type unfiltered_in_edge_iter;
+
+ typedef detail::adj_matrix_edge_iter< Directed, MatrixIter, size_type,
+ edge_descriptor >
+ unfiltered_edge_iter;
+
+public:
+ // IncidenceGraph concept required types
+ typedef filter_iterator< detail::does_edge_exist, unfiltered_out_edge_iter >
+ out_edge_iterator;
+
+ typedef size_type degree_size_type;
+
+ // BidirectionalGraph required types
+ typedef filter_iterator< detail::does_edge_exist, unfiltered_in_edge_iter >
+ in_edge_iterator;
+
+ // AdjacencyGraph required types
+ typedef typename adjacency_iterator_generator< self, vertex_descriptor,
+ out_edge_iterator >::type adjacency_iterator;
+
+ // VertexListGraph required types
+ typedef size_type vertices_size_type;
+ typedef integer_range< vertex_descriptor > VertexList;
+ typedef typename VertexList::iterator vertex_iterator;
+
+ // EdgeListGraph required types
+ typedef size_type edges_size_type;
+ typedef filter_iterator< detail::does_edge_exist, unfiltered_edge_iter >
+ edge_iterator;
+
+ // PropertyGraph required types
+ typedef adjacency_matrix_class_tag graph_tag;
+
+ // Constructor required by MutableGraph
+ adjacency_matrix(
+ vertices_size_type n_vertices, const GraphProperty& p = GraphProperty())
+ : m_matrix(Directed::is_directed ? (n_vertices * n_vertices)
+ : (n_vertices * (n_vertices + 1) / 2))
+ , m_vertex_set(0, n_vertices)
+ , m_vertex_properties(n_vertices)
+ , m_num_edges(0)
+ , m_property(p)
+ {
+ }
+
+ template < typename EdgeIterator >
+ adjacency_matrix(EdgeIterator first, EdgeIterator last,
+ vertices_size_type n_vertices, const GraphProperty& p = GraphProperty())
+ : m_matrix(Directed::is_directed ? (n_vertices * n_vertices)
+ : (n_vertices * (n_vertices + 1) / 2))
+ , m_vertex_set(0, n_vertices)
+ , m_vertex_properties(n_vertices)
+ , m_num_edges(0)
+ , m_property(p)
+ {
+ for (; first != last; ++first)
+ {
+ add_edge(first->first, first->second, *this);
+ }
+ }
+
+ template < typename EdgeIterator, typename EdgePropertyIterator >
+ adjacency_matrix(EdgeIterator first, EdgeIterator last,
+ EdgePropertyIterator ep_iter, vertices_size_type n_vertices,
+ const GraphProperty& p = GraphProperty())
+ : m_matrix(Directed::is_directed ? (n_vertices * n_vertices)
+ : (n_vertices * (n_vertices + 1) / 2))
+ , m_vertex_set(0, n_vertices)
+ , m_vertex_properties(n_vertices)
+ , m_num_edges(0)
+ , m_property(p)
+ {
+ for (; first != last; ++first, ++ep_iter)
+ {
+ add_edge(first->first, first->second, *ep_iter, *this);
+ }
+ }
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ // Directly access a vertex or edge bundle
+ vertex_bundled& operator[](vertex_descriptor v)
+ {
+ return get(vertex_bundle, *this, v);
+ }
+
+ const vertex_bundled& operator[](vertex_descriptor v) const
+ {
+ return get(vertex_bundle, *this, v);
+ }
+
+ edge_bundled& operator[](edge_descriptor e)
+ {
+ return get(edge_bundle, *this, e);
+ }
+
+ const edge_bundled& operator[](edge_descriptor e) const
+ {
+ return get(edge_bundle, *this, e);
+ }
+
+ graph_bundled& operator[](graph_bundle_t) { return get_property(*this); }
+
+ const graph_bundled& operator[](graph_bundle_t) const
+ {
+ return get_property(*this);
+ }
+#endif
+
+ // private: if friends worked, these would be private
+
+ typename Matrix::const_reference get_edge(
+ vertex_descriptor u, vertex_descriptor v) const
+ {
+ if (Directed::is_directed)
+ return m_matrix[u * m_vertex_set.size() + v];
+ else
+ {
+ if (v > u)
+ std::swap(u, v);
+ return m_matrix[u * (u + 1) / 2 + v];
+ }
+ }
+ typename Matrix::reference get_edge(
+ vertex_descriptor u, vertex_descriptor v)
+ {
+ if (Directed::is_directed)
+ return m_matrix[u * m_vertex_set.size() + v];
+ else
+ {
+ if (v > u)
+ std::swap(u, v);
+ return m_matrix[u * (u + 1) / 2 + v];
+ }
+ }
+
+ Matrix m_matrix;
+ VertexList m_vertex_set;
+ std::vector< vertex_property_type > m_vertex_properties;
+ size_type m_num_edges;
+ graph_property_type m_property;
+};
+
+//=========================================================================
+// Functions required by the AdjacencyMatrix concept
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor,
+ bool >
+edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
+ const adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ bool exists = detail::get_edge_exists(g.get_edge(u, v), 0);
+ typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor e(
+ exists, u, v, &detail::get_edge_property(g.get_edge(u, v)));
+ return std::make_pair(e, exists);
+}
+
+//=========================================================================
+// Functions required by the IncidenceGraph concept
+
+// O(1)
+template < typename VP, typename EP, typename GP, typename A >
+std::pair<
+ typename adjacency_matrix< directedS, VP, EP, GP, A >::out_edge_iterator,
+ typename adjacency_matrix< directedS, VP, EP, GP, A >::out_edge_iterator >
+out_edges(
+ typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u,
+ const adjacency_matrix< directedS, VP, EP, GP, A >& g_)
+{
+ typedef adjacency_matrix< directedS, VP, EP, GP, A > Graph;
+ Graph& g = const_cast< Graph& >(g_);
+ typename Graph::vertices_size_type offset = u * g.m_vertex_set.size();
+ typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
+ typename Graph::MatrixIter l = f + g.m_vertex_set.size();
+ typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()),
+ last(l, u, g.m_vertex_set.size());
+ detail::does_edge_exist pred;
+ typedef typename Graph::out_edge_iterator out_edge_iterator;
+ return std::make_pair(out_edge_iterator(pred, first, last),
+ out_edge_iterator(pred, last, last));
+}
+
+// O(1)
+template < typename VP, typename EP, typename GP, typename A >
+std::pair<
+ typename adjacency_matrix< undirectedS, VP, EP, GP, A >::out_edge_iterator,
+ typename adjacency_matrix< undirectedS, VP, EP, GP, A >::out_edge_iterator >
+out_edges(
+ typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor
+ u,
+ const adjacency_matrix< undirectedS, VP, EP, GP, A >& g_)
+{
+ typedef adjacency_matrix< undirectedS, VP, EP, GP, A > Graph;
+ Graph& g = const_cast< Graph& >(g_);
+ typename Graph::vertices_size_type offset = u * (u + 1) / 2;
+ typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
+ typename Graph::MatrixIter l = g.m_matrix.end();
+
+ typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()),
+ last(l, u, g.m_vertex_set.size());
+
+ detail::does_edge_exist pred;
+ typedef typename Graph::out_edge_iterator out_edge_iterator;
+ return std::make_pair(out_edge_iterator(pred, first, last),
+ out_edge_iterator(pred, last, last));
+}
+
+// O(N)
+template < typename D, typename VP, typename EP, typename GP, typename A >
+typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type out_degree(
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
+ const adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type n = 0;
+ typename adjacency_matrix< D, VP, EP, GP, A >::out_edge_iterator f, l;
+ for (boost::tie(f, l) = out_edges(u, g); f != l; ++f)
+ ++n;
+ return n;
+}
+
+// O(1)
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Dir, typename Vertex >
+typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor source(
+ const detail::matrix_edge_desc_impl< Dir, Vertex >& e,
+ const adjacency_matrix< D, VP, EP, GP, A >&)
+{
+ return e.m_source;
+}
+
+// O(1)
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Dir, typename Vertex >
+typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor target(
+ const detail::matrix_edge_desc_impl< Dir, Vertex >& e,
+ const adjacency_matrix< D, VP, EP, GP, A >&)
+{
+ return e.m_target;
+}
+
+//=========================================================================
+// Functions required by the BidirectionalGraph concept
+
+// O(1)
+template < typename VP, typename EP, typename GP, typename A >
+std::pair<
+ typename adjacency_matrix< directedS, VP, EP, GP, A >::in_edge_iterator,
+ typename adjacency_matrix< directedS, VP, EP, GP, A >::in_edge_iterator >
+in_edges(
+ typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u,
+ const adjacency_matrix< directedS, VP, EP, GP, A >& g_)
+{
+ typedef adjacency_matrix< directedS, VP, EP, GP, A > Graph;
+ Graph& g = const_cast< Graph& >(g_);
+ typename Graph::MatrixIter f = g.m_matrix.begin() + u;
+ typename Graph::MatrixIter l = g.m_matrix.end();
+ typename Graph::unfiltered_in_edge_iter first(
+ f, l, u, g.m_vertex_set.size()),
+ last(l, l, u, g.m_vertex_set.size());
+ detail::does_edge_exist pred;
+ typedef typename Graph::in_edge_iterator in_edge_iterator;
+ return std::make_pair(in_edge_iterator(pred, first, last),
+ in_edge_iterator(pred, last, last));
+}
+
+// O(1)
+template < typename VP, typename EP, typename GP, typename A >
+std::pair<
+ typename adjacency_matrix< undirectedS, VP, EP, GP, A >::in_edge_iterator,
+ typename adjacency_matrix< undirectedS, VP, EP, GP, A >::in_edge_iterator >
+in_edges(
+ typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor
+ u,
+ const adjacency_matrix< undirectedS, VP, EP, GP, A >& g_)
+{
+ typedef adjacency_matrix< undirectedS, VP, EP, GP, A > Graph;
+ Graph& g = const_cast< Graph& >(g_);
+ typename Graph::vertices_size_type offset = u * (u + 1) / 2;
+ typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
+ typename Graph::MatrixIter l = g.m_matrix.end();
+
+ typename Graph::unfiltered_in_edge_iter first(f, u, g.m_vertex_set.size()),
+ last(l, u, g.m_vertex_set.size());
+
+ detail::does_edge_exist pred;
+ typedef typename Graph::in_edge_iterator in_edge_iterator;
+ return std::make_pair(in_edge_iterator(pred, first, last),
+ in_edge_iterator(pred, last, last));
+}
+
+// O(N)
+template < typename D, typename VP, typename EP, typename GP, typename A >
+typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type in_degree(
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
+ const adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type n = 0;
+ typename adjacency_matrix< D, VP, EP, GP, A >::in_edge_iterator f, l;
+ for (boost::tie(f, l) = in_edges(u, g); f != l; ++f)
+ ++n;
+ return n;
+}
+
+//=========================================================================
+// Functions required by the AdjacencyGraph concept
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::adjacency_iterator,
+ typename adjacency_matrix< D, VP, EP, GP, A >::adjacency_iterator >
+adjacent_vertices(
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
+ const adjacency_matrix< D, VP, EP, GP, A >& g_)
+{
+ typedef adjacency_matrix< D, VP, EP, GP, A > Graph;
+ const Graph& cg = static_cast< const Graph& >(g_);
+ Graph& g = const_cast< Graph& >(cg);
+ typedef typename Graph::adjacency_iterator adjacency_iterator;
+ typename Graph::out_edge_iterator first, last;
+ boost::tie(first, last) = out_edges(u, g);
+ return std::make_pair(
+ adjacency_iterator(first, &g), adjacency_iterator(last, &g));
+}
+
+//=========================================================================
+// Functions required by the VertexListGraph concept
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::vertex_iterator,
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_iterator >
+vertices(const adjacency_matrix< D, VP, EP, GP, A >& g_)
+{
+ typedef adjacency_matrix< D, VP, EP, GP, A > Graph;
+ Graph& g = const_cast< Graph& >(g_);
+ return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end());
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+typename adjacency_matrix< D, VP, EP, GP, A >::vertices_size_type num_vertices(
+ const adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ return g.m_vertex_set.size();
+}
+
+//=========================================================================
+// Functions required by the EdgeListGraph concept
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_iterator,
+ typename adjacency_matrix< D, VP, EP, GP, A >::edge_iterator >
+edges(const adjacency_matrix< D, VP, EP, GP, A >& g_)
+{
+ typedef adjacency_matrix< D, VP, EP, GP, A > Graph;
+ Graph& g = const_cast< Graph& >(g_);
+
+ typename Graph::unfiltered_edge_iter first(
+ g.m_matrix.begin(), g.m_matrix.begin(), g.m_vertex_set.size()),
+ last(g.m_matrix.end(), g.m_matrix.begin(), g.m_vertex_set.size());
+ detail::does_edge_exist pred;
+ typedef typename Graph::edge_iterator edge_iterator;
+ return std::make_pair(
+ edge_iterator(pred, first, last), edge_iterator(pred, last, last));
+}
+
+// O(1)
+template < typename D, typename VP, typename EP, typename GP, typename A >
+typename adjacency_matrix< D, VP, EP, GP, A >::edges_size_type num_edges(
+ const adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ return g.m_num_edges;
+}
+
+//=========================================================================
+// Functions required by the MutableGraph concept
+
+// O(1)
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename EP2 >
+std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor,
+ bool >
+add_edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
+ const EP2& ep, adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ typedef typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor
+ edge_descriptor;
+ if (detail::get_edge_exists(g.get_edge(u, v), 0) == false)
+ {
+ ++(g.m_num_edges);
+ detail::set_edge_property(g.get_edge(u, v), EP(ep), 0);
+ detail::set_edge_exists(g.get_edge(u, v), true, 0);
+ return std::make_pair(edge_descriptor(true, u, v,
+ &detail::get_edge_property(g.get_edge(u, v))),
+ true);
+ }
+ else
+ return std::make_pair(edge_descriptor(true, u, v,
+ &detail::get_edge_property(g.get_edge(u, v))),
+ false);
+}
+// O(1)
+template < typename D, typename VP, typename EP, typename GP, typename A >
+std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor,
+ bool >
+add_edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
+ adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ EP ep;
+ return add_edge(u, v, ep, g);
+}
+
+// O(1)
+template < typename D, typename VP, typename EP, typename GP, typename A >
+void remove_edge(
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
+ adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ // Don'remove the edge unless it already exists.
+ if (detail::get_edge_exists(g.get_edge(u, v), 0))
+ {
+ --(g.m_num_edges);
+ detail::set_edge_exists(g.get_edge(u, v), false, 0);
+ }
+}
+
+// O(1)
+template < typename D, typename VP, typename EP, typename GP, typename A >
+void remove_edge(
+ typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor e,
+ adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ remove_edge(source(e, g), target(e, g), g);
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+inline typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor
+add_vertex(adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ // UNDER CONSTRUCTION
+ BOOST_ASSERT(false);
+ return *vertices(g).first;
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename VP2 >
+inline typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor
+add_vertex(const VP2& /*vp*/, adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ // UNDER CONSTRUCTION
+ BOOST_ASSERT(false);
+ return *vertices(g).first;
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+inline void remove_vertex(
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor /*u*/,
+ adjacency_matrix< D, VP, EP, GP, A >& /*g*/)
+{
+ // UNDER CONSTRUCTION
+ BOOST_ASSERT(false);
+}
+
+// O(V)
+template < typename VP, typename EP, typename GP, typename A >
+void clear_vertex(
+ typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u,
+ adjacency_matrix< directedS, VP, EP, GP, A >& g)
+{
+ typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_iterator vi,
+ vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ remove_edge(u, *vi, g);
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ remove_edge(*vi, u, g);
+}
+
+// O(V)
+template < typename VP, typename EP, typename GP, typename A >
+void clear_vertex(
+ typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor
+ u,
+ adjacency_matrix< undirectedS, VP, EP, GP, A >& g)
+{
+ typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_iterator vi,
+ vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ remove_edge(u, *vi, g);
+}
+
+//=========================================================================
+// Functions required by the PropertyGraph concept
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Prop, typename Kind >
+struct adj_mat_pm_helper;
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Prop >
+struct adj_mat_pm_helper< D, VP, EP, GP, A, Prop, vertex_property_tag >
+{
+ typedef typename graph_traits<
+ adjacency_matrix< D, VP, EP, GP, A > >::vertex_descriptor arg_type;
+ typedef typed_identity_property_map< arg_type > vi_map_type;
+ typedef iterator_property_map< typename std::vector< VP >::iterator,
+ vi_map_type >
+ all_map_type;
+ typedef iterator_property_map< typename std::vector< VP >::const_iterator,
+ vi_map_type >
+ all_map_const_type;
+ typedef transform_value_property_map<
+ detail::lookup_one_property_f< VP, Prop >, all_map_type >
+ type;
+ typedef transform_value_property_map<
+ detail::lookup_one_property_f< const VP, Prop >, all_map_const_type >
+ const_type;
+ typedef typename property_traits< type >::reference single_nonconst_type;
+ typedef typename property_traits< const_type >::reference single_const_type;
+
+ static type get_nonconst(adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop)
+ {
+ return type(
+ prop, all_map_type(g.m_vertex_properties.begin(), vi_map_type()));
+ }
+
+ static const_type get_const(
+ const adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop)
+ {
+ return const_type(prop,
+ all_map_const_type(g.m_vertex_properties.begin(), vi_map_type()));
+ }
+
+ static single_nonconst_type get_nonconst_one(
+ adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop, arg_type v)
+ {
+ return lookup_one_property< VP, Prop >::lookup(
+ g.m_vertex_properties[v], prop);
+ }
+
+ static single_const_type get_const_one(
+ const adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop, arg_type v)
+ {
+ return lookup_one_property< const VP, Prop >::lookup(
+ g.m_vertex_properties[v], prop);
+ }
+};
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag >
+struct adj_mat_pm_helper< D, VP, EP, GP, A, Tag, edge_property_tag >
+{
+ typedef typename graph_traits<
+ adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor edge_descriptor;
+
+ template < typename IsConst > struct lookup_property_from_edge
+ {
+ Tag tag;
+ lookup_property_from_edge(Tag tag) : tag(tag) {}
+ typedef typename boost::mpl::if_< IsConst, const EP, EP >::type
+ ep_type_nonref;
+ typedef ep_type_nonref& ep_type;
+ typedef typename lookup_one_property< ep_type_nonref, Tag >::type&
+ result_type;
+ result_type operator()(edge_descriptor e) const
+ {
+ return lookup_one_property< ep_type_nonref, Tag >::lookup(
+ *static_cast< ep_type_nonref* >(e.get_property()), tag);
+ }
+ };
+
+ typedef function_property_map<
+ lookup_property_from_edge< boost::mpl::false_ >,
+ typename graph_traits<
+ adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor >
+ type;
+ typedef function_property_map<
+ lookup_property_from_edge< boost::mpl::true_ >,
+ typename graph_traits<
+ adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor >
+ const_type;
+ typedef edge_descriptor arg_type;
+ typedef
+ typename lookup_property_from_edge< boost::mpl::false_ >::result_type
+ single_nonconst_type;
+ typedef typename lookup_property_from_edge< boost::mpl::true_ >::result_type
+ single_const_type;
+
+ static type get_nonconst(adjacency_matrix< D, VP, EP, GP, A >& /* g */, Tag tag)
+ {
+ return type(tag);
+ }
+
+ static const_type get_const(
+ const adjacency_matrix< D, VP, EP, GP, A >& /* g */, Tag tag)
+ {
+ return const_type(tag);
+ }
+
+ static single_nonconst_type get_nonconst_one(
+ adjacency_matrix< D, VP, EP, GP, A >& /* g */, Tag tag, edge_descriptor e)
+ {
+ return lookup_one_property< EP, Tag >::lookup(
+ *static_cast< EP* >(e.get_property()), tag);
+ }
+
+ static single_const_type get_const_one(
+ const adjacency_matrix< D, VP, EP, GP, A >& /* g */, Tag tag,
+ edge_descriptor e)
+ {
+ return lookup_one_property< const EP, Tag >::lookup(
+ *static_cast< const EP* >(e.get_property()), tag);
+ }
+};
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag >
+struct property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >
+: adj_mat_pm_helper< D, VP, EP, GP, A, Tag,
+ typename detail::property_kind_from_graph<
+ adjacency_matrix< D, VP, EP, GP, A >, Tag >::type >
+{
+};
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag >
+typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::type get(
+ Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ return property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ Tag >::get_nonconst(g, tag);
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag >
+typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::const_type
+get(Tag tag, const adjacency_matrix< D, VP, EP, GP, A >& g)
+{
+ return property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::get_const(
+ g, tag);
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag >
+typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ Tag >::single_nonconst_type
+get(Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g,
+ typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type
+ a)
+{
+ return property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ Tag >::get_nonconst_one(g, tag, a);
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag >
+typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ Tag >::single_const_type
+get(Tag tag, const adjacency_matrix< D, VP, EP, GP, A >& g,
+ typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type
+ a)
+{
+ return property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ Tag >::get_const_one(g, tag, a);
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag >
+void put(Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g,
+ typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type
+ a,
+ typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ Tag >::single_const_type val)
+{
+ property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::get_nonconst_one(
+ g, tag, a)
+ = val;
+}
+
+// O(1)
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag, typename Value >
+inline void set_property(
+ adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag, const Value& value)
+{
+ get_property_value(g.m_property, tag) = value;
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag >
+inline
+ typename graph_property< adjacency_matrix< D, VP, EP, GP, A >, Tag >::type&
+ get_property(adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
+{
+ return get_property_value(g.m_property, tag);
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A,
+ typename Tag >
+inline const typename graph_property< adjacency_matrix< D, VP, EP, GP, A >,
+ Tag >::type&
+get_property(const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
+{
+ return get_property_value(g.m_property, tag);
+}
+
+//=========================================================================
+// Vertex Property Map
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+struct property_map< adjacency_matrix< D, VP, EP, GP, A >, vertex_index_t >
+{
+ typedef
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor Vertex;
+ typedef typed_identity_property_map< Vertex > type;
+ typedef type const_type;
+};
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ vertex_index_t >::const_type
+get(vertex_index_t, adjacency_matrix< D, VP, EP, GP, A >&)
+{
+ return typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ vertex_index_t >::const_type();
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor get(
+ vertex_index_t, adjacency_matrix< D, VP, EP, GP, A >&,
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v)
+{
+ return v;
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ vertex_index_t >::const_type
+get(vertex_index_t, const adjacency_matrix< D, VP, EP, GP, A >&)
+{
+ return typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
+ vertex_index_t >::const_type();
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor get(
+ vertex_index_t, const adjacency_matrix< D, VP, EP, GP, A >&,
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v)
+{
+ return v;
+}
+
+//=========================================================================
+// Other Functions
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor vertex(
+ typename adjacency_matrix< D, VP, EP, GP, A >::vertices_size_type n,
+ const adjacency_matrix< D, VP, EP, GP, A >&)
+{
+ return n;
+}
+
+template < typename D, typename VP, typename EP, typename GP, typename A >
+struct graph_mutability_traits< adjacency_matrix< D, VP, EP, GP, A > >
+{
+ typedef mutable_edge_property_graph_tag category;
+};
+
+} // namespace boost
+
+#endif // BOOST_ADJACENCY_MATRIX_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/astar_search.hpp b/contrib/restricted/boost/graph/include/boost/graph/astar_search.hpp
new file mode 100644
index 0000000000..02f4b1cb49
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/astar_search.hpp
@@ -0,0 +1,655 @@
+
+
+//
+//=======================================================================
+// Copyright (c) 2004 Kristopher Beevers
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+
+#ifndef BOOST_GRAPH_ASTAR_SEARCH_HPP
+#define BOOST_GRAPH_ASTAR_SEARCH_HPP
+
+#include <functional>
+#include <vector>
+#include <boost/limits.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/relax.hpp>
+#include <boost/graph/exception.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/detail/d_ary_heap.hpp>
+#include <boost/graph/property_maps/constant_property_map.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/property_map/vector_property_map.hpp>
+#include <boost/property_map/function_property_map.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+
+template < class Heuristic, class Graph > struct AStarHeuristicConcept
+{
+ void constraints()
+ {
+ BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Heuristic >));
+ h(u);
+ }
+ Heuristic h;
+ typename graph_traits< Graph >::vertex_descriptor u;
+};
+
+template < class Graph, class CostType > class astar_heuristic
+{
+public:
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef Vertex argument_type;
+ typedef CostType result_type;
+ astar_heuristic() {}
+ CostType operator()(Vertex u) { return static_cast< CostType >(0); }
+};
+
+template < class Visitor, class Graph > struct AStarVisitorConcept
+{
+ void constraints()
+ {
+ BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >));
+ vis.initialize_vertex(u, g);
+ vis.discover_vertex(u, g);
+ vis.examine_vertex(u, g);
+ vis.examine_edge(e, g);
+ vis.edge_relaxed(e, g);
+ vis.edge_not_relaxed(e, g);
+ vis.black_target(e, g);
+ vis.finish_vertex(u, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename graph_traits< Graph >::vertex_descriptor u;
+ typename graph_traits< Graph >::edge_descriptor e;
+};
+
+template < class Visitors = null_visitor >
+class astar_visitor : public bfs_visitor< Visitors >
+{
+public:
+ astar_visitor() {}
+ astar_visitor(Visitors vis) : bfs_visitor< Visitors >(vis) {}
+
+ template < class Edge, class Graph >
+ void edge_relaxed(Edge e, const Graph& g)
+ {
+ invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
+ }
+ template < class Edge, class Graph >
+ void edge_not_relaxed(Edge e, const Graph& g)
+ {
+ invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
+ }
+
+private:
+ template < class Edge, class Graph > void tree_edge(Edge e, const Graph& g)
+ {
+ }
+ template < class Edge, class Graph >
+ void non_tree_edge(Edge e, const Graph& g)
+ {
+ }
+};
+template < class Visitors >
+astar_visitor< Visitors > make_astar_visitor(Visitors vis)
+{
+ return astar_visitor< Visitors >(vis);
+}
+typedef astar_visitor<> default_astar_visitor;
+
+namespace detail
+{
+
+ template < class AStarHeuristic, class UniformCostVisitor,
+ class UpdatableQueue, class PredecessorMap, class CostMap,
+ class DistanceMap, class WeightMap, class ColorMap,
+ class BinaryFunction, class BinaryPredicate >
+ struct astar_bfs_visitor
+ {
+
+ typedef typename property_traits< CostMap >::value_type C;
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+ typedef
+ typename property_traits< DistanceMap >::value_type distance_type;
+
+ astar_bfs_visitor(AStarHeuristic h, UniformCostVisitor vis,
+ UpdatableQueue& Q, PredecessorMap p, CostMap c, DistanceMap d,
+ WeightMap w, ColorMap col, BinaryFunction combine,
+ BinaryPredicate compare, C zero)
+ : m_h(h)
+ , m_vis(vis)
+ , m_Q(Q)
+ , m_predecessor(p)
+ , m_cost(c)
+ , m_distance(d)
+ , m_weight(w)
+ , m_color(col)
+ , m_combine(combine)
+ , m_compare(compare)
+ , m_zero(zero)
+ {
+ }
+
+ template < class Vertex, class Graph >
+ void initialize_vertex(Vertex u, const Graph& g)
+ {
+ m_vis.initialize_vertex(u, g);
+ }
+ template < class Vertex, class Graph >
+ void discover_vertex(Vertex u, const Graph& g)
+ {
+ m_vis.discover_vertex(u, g);
+ }
+ template < class Vertex, class Graph >
+ void examine_vertex(Vertex u, const Graph& g)
+ {
+ m_vis.examine_vertex(u, g);
+ }
+ template < class Vertex, class Graph >
+ void finish_vertex(Vertex u, const Graph& g)
+ {
+ m_vis.finish_vertex(u, g);
+ }
+ template < class Edge, class Graph >
+ void examine_edge(Edge e, const Graph& g)
+ {
+ if (m_compare(get(m_weight, e), m_zero))
+ BOOST_THROW_EXCEPTION(negative_edge());
+ m_vis.examine_edge(e, g);
+ }
+ template < class Edge, class Graph >
+ void non_tree_edge(Edge, const Graph&)
+ {
+ }
+
+ template < class Edge, class Graph >
+ void tree_edge(Edge e, const Graph& g)
+ {
+ using boost::get;
+ bool m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
+ m_combine, m_compare);
+
+ if (m_decreased)
+ {
+ m_vis.edge_relaxed(e, g);
+ put(m_cost, target(e, g),
+ m_combine(
+ get(m_distance, target(e, g)), m_h(target(e, g))));
+ }
+ else
+ m_vis.edge_not_relaxed(e, g);
+ }
+
+ template < class Edge, class Graph >
+ void gray_target(Edge e, const Graph& g)
+ {
+ using boost::get;
+ bool m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
+ m_combine, m_compare);
+
+ if (m_decreased)
+ {
+ put(m_cost, target(e, g),
+ m_combine(
+ get(m_distance, target(e, g)), m_h(target(e, g))));
+ m_Q.update(target(e, g));
+ m_vis.edge_relaxed(e, g);
+ }
+ else
+ m_vis.edge_not_relaxed(e, g);
+ }
+
+ template < class Edge, class Graph >
+ void black_target(Edge e, const Graph& g)
+ {
+ using boost::get;
+ bool m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
+ m_combine, m_compare);
+
+ if (m_decreased)
+ {
+ m_vis.edge_relaxed(e, g);
+ put(m_cost, target(e, g),
+ m_combine(
+ get(m_distance, target(e, g)), m_h(target(e, g))));
+ m_Q.push(target(e, g));
+ put(m_color, target(e, g), Color::gray());
+ m_vis.black_target(e, g);
+ }
+ else
+ m_vis.edge_not_relaxed(e, g);
+ }
+
+ AStarHeuristic m_h;
+ UniformCostVisitor m_vis;
+ UpdatableQueue& m_Q;
+ PredecessorMap m_predecessor;
+ CostMap m_cost;
+ DistanceMap m_distance;
+ WeightMap m_weight;
+ ColorMap m_color;
+ BinaryFunction m_combine;
+ BinaryPredicate m_compare;
+ C m_zero;
+ };
+
+} // namespace detail
+
+template < typename VertexListGraph, typename AStarHeuristic,
+ typename AStarVisitor, typename PredecessorMap, typename CostMap,
+ typename DistanceMap, typename WeightMap, typename ColorMap,
+ typename VertexIndexMap, typename CompareFunction, typename CombineFunction,
+ typename CostInf, typename CostZero >
+inline void astar_search_no_init(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor,
+ CostMap cost, DistanceMap distance, WeightMap weight, ColorMap color,
+ VertexIndexMap index_map, CompareFunction compare, CombineFunction combine,
+ CostInf /*inf*/, CostZero zero)
+{
+ typedef typename graph_traits< VertexListGraph >::vertex_descriptor Vertex;
+ typedef boost::vector_property_map< std::size_t, VertexIndexMap >
+ IndexInHeapMap;
+ IndexInHeapMap index_in_heap(index_map);
+ typedef d_ary_heap_indirect< Vertex, 4, IndexInHeapMap, CostMap,
+ CompareFunction >
+ MutableQueue;
+ MutableQueue Q(cost, index_in_heap, compare);
+
+ detail::astar_bfs_visitor< AStarHeuristic, AStarVisitor, MutableQueue,
+ PredecessorMap, CostMap, DistanceMap, WeightMap, ColorMap,
+ CombineFunction, CompareFunction >
+ bfs_vis(h, vis, Q, predecessor, cost, distance, weight, color, combine,
+ compare, zero);
+
+ breadth_first_visit(g, s, Q, bfs_vis, color);
+}
+
+namespace graph_detail
+{
+ template < typename A, typename B > struct select1st
+ {
+ typedef std::pair< A, B > argument_type;
+ typedef A result_type;
+ A operator()(const std::pair< A, B >& p) const { return p.first; }
+ };
+}
+
+template < typename VertexListGraph, typename AStarHeuristic,
+ typename AStarVisitor, typename PredecessorMap, typename CostMap,
+ typename DistanceMap, typename WeightMap, typename CompareFunction,
+ typename CombineFunction, typename CostInf, typename CostZero >
+inline void astar_search_no_init_tree(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor,
+ CostMap cost, DistanceMap distance, WeightMap weight,
+ CompareFunction compare, CombineFunction combine, CostInf /*inf*/,
+ CostZero zero)
+{
+ typedef typename graph_traits< VertexListGraph >::vertex_descriptor Vertex;
+ typedef typename property_traits< DistanceMap >::value_type Distance;
+ typedef d_ary_heap_indirect< std::pair< Distance, Vertex >, 4,
+ null_property_map< std::pair< Distance, Vertex >, std::size_t >,
+ function_property_map< graph_detail::select1st< Distance, Vertex >,
+ std::pair< Distance, Vertex > >,
+ CompareFunction >
+ MutableQueue;
+ MutableQueue Q(make_function_property_map< std::pair< Distance, Vertex > >(
+ graph_detail::select1st< Distance, Vertex >()),
+ null_property_map< std::pair< Distance, Vertex >, std::size_t >(),
+ compare);
+
+ vis.discover_vertex(s, g);
+ Q.push(std::make_pair(get(cost, s), s));
+ while (!Q.empty())
+ {
+ Vertex v;
+ Distance v_rank;
+ boost::tie(v_rank, v) = Q.top();
+ Q.pop();
+ vis.examine_vertex(v, g);
+ BGL_FORALL_OUTEDGES_T(v, e, g, VertexListGraph)
+ {
+ Vertex w = target(e, g);
+ vis.examine_edge(e, g);
+ Distance e_weight = get(weight, e);
+ if (compare(e_weight, zero))
+ BOOST_THROW_EXCEPTION(negative_edge());
+ bool decreased
+ = relax(e, g, weight, predecessor, distance, combine, compare);
+ if (decreased)
+ {
+ vis.edge_relaxed(e, g);
+ Distance w_rank = combine(get(distance, w), h(w));
+ put(cost, w, w_rank);
+ vis.discover_vertex(w, g);
+ Q.push(std::make_pair(w_rank, w));
+ }
+ else
+ {
+ vis.edge_not_relaxed(e, g);
+ }
+ }
+ vis.finish_vertex(v, g);
+ }
+}
+
+// Non-named parameter interface
+template < typename VertexListGraph, typename AStarHeuristic,
+ typename AStarVisitor, typename PredecessorMap, typename CostMap,
+ typename DistanceMap, typename WeightMap, typename VertexIndexMap,
+ typename ColorMap, typename CompareFunction, typename CombineFunction,
+ typename CostInf, typename CostZero >
+inline void astar_search(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor,
+ CostMap cost, DistanceMap distance, WeightMap weight,
+ VertexIndexMap index_map, ColorMap color, CompareFunction compare,
+ CombineFunction combine, CostInf inf, CostZero zero)
+{
+
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+ typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ put(color, *ui, Color::white());
+ put(distance, *ui, inf);
+ put(cost, *ui, inf);
+ put(predecessor, *ui, *ui);
+ vis.initialize_vertex(*ui, g);
+ }
+ put(distance, s, zero);
+ put(cost, s, h(s));
+
+ astar_search_no_init(g, s, h, vis, predecessor, cost, distance, weight,
+ color, index_map, compare, combine, inf, zero);
+}
+
+// Non-named parameter interface
+template < typename VertexListGraph, typename AStarHeuristic,
+ typename AStarVisitor, typename PredecessorMap, typename CostMap,
+ typename DistanceMap, typename WeightMap, typename CompareFunction,
+ typename CombineFunction, typename CostInf, typename CostZero >
+inline void astar_search_tree(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor,
+ CostMap cost, DistanceMap distance, WeightMap weight,
+ CompareFunction compare, CombineFunction combine, CostInf inf,
+ CostZero zero)
+{
+
+ typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ put(distance, *ui, inf);
+ put(cost, *ui, inf);
+ put(predecessor, *ui, *ui);
+ vis.initialize_vertex(*ui, g);
+ }
+ put(distance, s, zero);
+ put(cost, s, h(s));
+
+ astar_search_no_init_tree(g, s, h, vis, predecessor, cost, distance, weight,
+ compare, combine, inf, zero);
+}
+
+// Named parameter interfaces
+template < typename VertexListGraph, typename AStarHeuristic, typename P,
+ typename T, typename R >
+void astar_search(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ AStarHeuristic h, const bgl_named_params< P, T, R >& params)
+{
+ using namespace boost::graph::keywords;
+ typedef bgl_named_params< P, T, R > params_type;
+ BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params)
+
+ // Distance type is the value type of the distance map if there is one,
+ // otherwise the value type of the weight map.
+ typedef
+ typename boost::detail::override_const_property_result< arg_pack_type,
+ boost::graph::keywords::tag::weight_map, edge_weight_t,
+ VertexListGraph >::type weight_map_type;
+ typedef typename boost::property_traits< weight_map_type >::value_type D;
+ const D inf = arg_pack[_distance_inf || detail::get_max< D >()];
+ const D zero_actual = D();
+ const D zero_d = arg_pack[_distance_zero | zero_actual];
+ null_visitor null_vis;
+ astar_visitor< null_visitor > default_visitor(null_vis);
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::visitor, dummy_property_map& >::type vis
+ = arg_pack[_visitor | default_visitor];
+ dummy_property_map dummy_prop;
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::predecessor_map,
+ dummy_property_map& >::type pred_map
+ = arg_pack[_predecessor_map | dummy_prop];
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::rank_map, D >
+ rank_map_gen(zero_actual);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::rank_map, D >::map_type r_map
+ = rank_map_gen(g, arg_pack);
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::distance_map, D >
+ dist_map_gen(zero_actual);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::distance_map, D >::map_type dist_map
+ = dist_map_gen(g, arg_pack);
+ weight_map_type w_map = detail::override_const_property(
+ arg_pack, _weight_map, g, edge_weight);
+ typename boost::detail::override_const_property_result< arg_pack_type,
+ boost::graph::keywords::tag::vertex_index_map, vertex_index_t,
+ VertexListGraph >::type v_i_map
+ = detail::override_const_property(
+ arg_pack, _vertex_index_map, g, vertex_index);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::color_map,
+ boost::default_color_type >::map_type c_map
+ = boost::detail::make_color_map_from_arg_pack(g, arg_pack);
+ std::less< D > default_compare;
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::distance_compare, std::less< D >& >::type
+ dist_comp
+ = arg_pack[_distance_compare | default_compare];
+ closed_plus< D > default_combine(inf);
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::distance_combine, closed_plus< D >& >::type
+ dist_comb
+ = arg_pack[_distance_combine | default_combine];
+ astar_search(g, s, h, vis, pred_map, r_map, dist_map, w_map, v_i_map, c_map,
+ dist_comp, dist_comb, inf, zero_d);
+}
+
+template < typename VertexListGraph, typename AStarHeuristic, typename P,
+ typename T, typename R >
+void astar_search_tree(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ AStarHeuristic h, const bgl_named_params< P, T, R >& params)
+{
+ using namespace boost::graph::keywords;
+ typedef bgl_named_params< P, T, R > params_type;
+ BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params)
+
+ // Distance type is the value type of the distance map if there is one,
+ // otherwise the value type of the weight map.
+ typedef
+ typename boost::detail::override_const_property_result< arg_pack_type,
+ boost::graph::keywords::tag::weight_map, edge_weight_t,
+ VertexListGraph >::type weight_map_type;
+ typedef typename boost::property_traits< weight_map_type >::value_type D;
+ const D inf = arg_pack[_distance_inf || detail::get_max< D >()];
+ const D zero_actual = D();
+ const D zero_d = arg_pack[_distance_zero | zero_actual];
+ null_visitor null_vis;
+ astar_visitor< null_visitor > default_visitor(null_vis);
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::visitor, dummy_property_map& >::type vis
+ = arg_pack[_visitor | default_visitor];
+ dummy_property_map dummy_prop;
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::predecessor_map,
+ dummy_property_map& >::type pred_map
+ = arg_pack[_predecessor_map | dummy_prop];
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::rank_map, D >
+ rank_map_gen(zero_actual);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::rank_map, D >::map_type r_map
+ = rank_map_gen(g, arg_pack);
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::distance_map, D >
+ dist_map_gen(zero_actual);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::distance_map, D >::map_type dist_map
+ = dist_map_gen(g, arg_pack);
+ weight_map_type w_map = detail::override_const_property(
+ arg_pack, _weight_map, g, edge_weight);
+ std::less< D > default_compare;
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::distance_compare, std::less< D >& >::type
+ dist_comp
+ = arg_pack[_distance_compare | default_compare];
+ closed_plus< D > default_combine(inf);
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::distance_combine, closed_plus< D >& >::type
+ dist_comb
+ = arg_pack[_distance_combine | default_combine];
+ astar_search_tree(g, s, h, vis, pred_map, r_map, dist_map, w_map, dist_comp,
+ dist_comb, inf, zero_d);
+}
+
+template < typename VertexListGraph, typename AStarHeuristic, typename P,
+ typename T, typename R >
+void astar_search_no_init(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ AStarHeuristic h, const bgl_named_params< P, T, R >& params)
+{
+ using namespace boost::graph::keywords;
+ typedef bgl_named_params< P, T, R > params_type;
+ BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params)
+ typedef
+ typename boost::detail::override_const_property_result< arg_pack_type,
+ boost::graph::keywords::tag::weight_map, edge_weight_t,
+ VertexListGraph >::type weight_map_type;
+ typedef typename boost::property_traits< weight_map_type >::value_type D;
+ const D inf = arg_pack[_distance_inf || detail::get_max< D >()];
+ const D zero_actual = D();
+ const D zero_d = arg_pack[_distance_zero | zero_actual];
+ null_visitor null_vis;
+ astar_visitor< null_visitor > default_visitor(null_vis);
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::visitor, dummy_property_map& >::type vis
+ = arg_pack[_visitor | default_visitor];
+ dummy_property_map dummy_prop;
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::predecessor_map,
+ dummy_property_map& >::type pred_map
+ = arg_pack[_predecessor_map | dummy_prop];
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::rank_map, D >
+ rank_map_gen(zero_actual);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::rank_map, D >::map_type r_map
+ = rank_map_gen(g, arg_pack);
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::distance_map, D >
+ dist_map_gen(zero_actual);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::distance_map, D >::map_type dist_map
+ = dist_map_gen(g, arg_pack);
+ weight_map_type w_map = detail::override_const_property(
+ arg_pack, _weight_map, g, edge_weight);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::color_map,
+ boost::default_color_type >::map_type c_map
+ = boost::detail::make_color_map_from_arg_pack(g, arg_pack);
+ typename boost::detail::override_const_property_result< arg_pack_type,
+ boost::graph::keywords::tag::vertex_index_map, vertex_index_t,
+ VertexListGraph >::type v_i_map
+ = detail::override_const_property(
+ arg_pack, _vertex_index_map, g, vertex_index);
+ std::less< D > default_compare;
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::distance_compare, std::less< D >& >::type
+ dist_comp
+ = arg_pack[_distance_compare | default_compare];
+ closed_plus< D > default_combine(inf);
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::distance_combine, closed_plus< D >& >::type
+ dist_comb
+ = arg_pack[_distance_combine | default_combine];
+ astar_search_no_init(g, s, h, vis, pred_map, r_map, dist_map, w_map, c_map,
+ v_i_map, dist_comp, dist_comb, inf, zero_d);
+}
+
+template < typename VertexListGraph, typename AStarHeuristic, typename P,
+ typename T, typename R >
+void astar_search_no_init_tree(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ AStarHeuristic h, const bgl_named_params< P, T, R >& params)
+{
+ using namespace boost::graph::keywords;
+ typedef bgl_named_params< P, T, R > params_type;
+ BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params)
+ typedef
+ typename boost::detail::override_const_property_result< arg_pack_type,
+ boost::graph::keywords::tag::weight_map, edge_weight_t,
+ VertexListGraph >::type weight_map_type;
+ typedef typename boost::property_traits< weight_map_type >::value_type D;
+ const D inf = arg_pack[_distance_inf || detail::get_max< D >()];
+ const D zero_actual = D();
+ const D zero_d = arg_pack[_distance_zero | zero_actual];
+ null_visitor null_vis;
+ astar_visitor< null_visitor > default_visitor(null_vis);
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::visitor, dummy_property_map& >::type vis
+ = arg_pack[_visitor | default_visitor];
+ dummy_property_map dummy_prop;
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::predecessor_map,
+ dummy_property_map& >::type pred_map
+ = arg_pack[_predecessor_map | dummy_prop];
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::rank_map, D >
+ rank_map_gen(zero_actual);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::rank_map, D >::map_type r_map
+ = rank_map_gen(g, arg_pack);
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::distance_map, D >
+ dist_map_gen(zero_actual);
+ typename boost::detail::map_maker< VertexListGraph, arg_pack_type,
+ boost::graph::keywords::tag::distance_map, D >::map_type dist_map
+ = dist_map_gen(g, arg_pack);
+ weight_map_type w_map = detail::override_const_property(
+ arg_pack, _weight_map, g, edge_weight);
+ std::less< D > default_compare;
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::distance_compare, std::less< D >& >::type
+ dist_comp
+ = arg_pack[_distance_compare | default_compare];
+ closed_plus< D > default_combine(inf);
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::distance_combine, closed_plus< D >& >::type
+ dist_comb
+ = arg_pack[_distance_combine | default_combine];
+ astar_search_no_init_tree(g, s, h, vis, pred_map, r_map, dist_map, w_map,
+ dist_comp, dist_comb, inf, zero_d);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_ASTAR_SEARCH_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/bandwidth.hpp b/contrib/restricted/boost/graph/include/boost/graph/bandwidth.hpp
new file mode 100644
index 0000000000..e3f99adf51
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/bandwidth.hpp
@@ -0,0 +1,94 @@
+// Copyright (c) Jeremy Siek 2001, Marc Wintermantel 2002
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_BANDWIDTH_HPP
+#define BOOST_GRAPH_BANDWIDTH_HPP
+
+#include <algorithm> // for std::min and std::max
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/detail/numeric_traits.hpp>
+
+namespace boost
+{
+
+template < typename Graph, typename VertexIndexMap >
+typename graph_traits< Graph >::vertices_size_type ith_bandwidth(
+ typename graph_traits< Graph >::vertex_descriptor i, const Graph& g,
+ VertexIndexMap index)
+{
+ BOOST_USING_STD_MAX();
+ using std::abs;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+ vertices_size_type b = 0;
+ typename graph_traits< Graph >::out_edge_iterator e, end;
+ for (boost::tie(e, end) = out_edges(i, g); e != end; ++e)
+ {
+ int f_i = get(index, i);
+ int f_j = get(index, target(*e, g));
+ b = max BOOST_PREVENT_MACRO_SUBSTITUTION(
+ b, vertices_size_type(abs(f_i - f_j)));
+ }
+ return b;
+}
+
+template < typename Graph >
+typename graph_traits< Graph >::vertices_size_type ith_bandwidth(
+ typename graph_traits< Graph >::vertex_descriptor i, const Graph& g)
+{
+ return ith_bandwidth(i, g, get(vertex_index, g));
+}
+
+template < typename Graph, typename VertexIndexMap >
+typename graph_traits< Graph >::vertices_size_type bandwidth(
+ const Graph& g, VertexIndexMap index)
+{
+ BOOST_USING_STD_MAX();
+ using std::abs;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+ vertices_size_type b = 0;
+ typename graph_traits< Graph >::edge_iterator i, end;
+ for (boost::tie(i, end) = edges(g); i != end; ++i)
+ {
+ int f_i = get(index, source(*i, g));
+ int f_j = get(index, target(*i, g));
+ b = max BOOST_PREVENT_MACRO_SUBSTITUTION(
+ b, vertices_size_type(abs(f_i - f_j)));
+ }
+ return b;
+}
+
+template < typename Graph >
+typename graph_traits< Graph >::vertices_size_type bandwidth(const Graph& g)
+{
+ return bandwidth(g, get(vertex_index, g));
+}
+
+template < typename Graph, typename VertexIndexMap >
+typename graph_traits< Graph >::vertices_size_type edgesum(
+ const Graph& g, VertexIndexMap index_map)
+{
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+ typedef
+ typename detail::numeric_traits< size_type >::difference_type diff_t;
+ size_type sum = 0;
+ typename graph_traits< Graph >::edge_iterator i, end;
+ for (boost::tie(i, end) = edges(g); i != end; ++i)
+ {
+ diff_t f_u = get(index_map, source(*i, g));
+ diff_t f_v = get(index_map, target(*i, g));
+ using namespace std; // to call abs() unqualified
+ sum += abs(f_u - f_v);
+ }
+ return sum;
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_BANDWIDTH_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/bc_clustering.hpp b/contrib/restricted/boost/graph/include/boost/graph/bc_clustering.hpp
new file mode 100644
index 0000000000..dd26bdf397
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/bc_clustering.hpp
@@ -0,0 +1,169 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP
+#define BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP
+
+#include <boost/algorithm/minmax_element.hpp>
+#include <boost/graph/betweenness_centrality.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_utility.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <vector>
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+
+/** Threshold termination function for the betweenness centrality
+ * clustering algorithm.
+ */
+template < typename T > struct bc_clustering_threshold
+{
+ typedef T centrality_type;
+
+ /// Terminate clustering when maximum absolute edge centrality is
+ /// below the given threshold.
+ explicit bc_clustering_threshold(T threshold)
+ : threshold(threshold), dividend(1.0)
+ {
+ }
+
+ /**
+ * Terminate clustering when the maximum edge centrality is below
+ * the given threshold.
+ *
+ * @param threshold the threshold value
+ *
+ * @param g the graph on which the threshold will be calculated
+ *
+ * @param normalize when true, the threshold is compared against the
+ * normalized edge centrality based on the input graph; otherwise,
+ * the threshold is compared against the absolute edge centrality.
+ */
+ template < typename Graph >
+ bc_clustering_threshold(T threshold, const Graph& g, bool normalize = true)
+ : threshold(threshold), dividend(1.0)
+ {
+ if (normalize)
+ {
+ typename graph_traits< Graph >::vertices_size_type n
+ = num_vertices(g);
+ dividend = T((n - 1) * (n - 2)) / T(2);
+ }
+ }
+
+ /** Returns true when the given maximum edge centrality (potentially
+ * normalized) falls below the threshold.
+ */
+ template < typename Graph, typename Edge >
+ bool operator()(T max_centrality, Edge, const Graph&)
+ {
+ return (max_centrality / dividend) < threshold;
+ }
+
+protected:
+ T threshold;
+ T dividend;
+};
+
+/** Graph clustering based on edge betweenness centrality.
+ *
+ * This algorithm implements graph clustering based on edge
+ * betweenness centrality. It is an iterative algorithm, where in each
+ * step it compute the edge betweenness centrality (via @ref
+ * brandes_betweenness_centrality) and removes the edge with the
+ * maximum betweenness centrality. The @p done function object
+ * determines when the algorithm terminates (the edge found when the
+ * algorithm terminates will not be removed).
+ *
+ * @param g The graph on which clustering will be performed. The type
+ * of this parameter (@c MutableGraph) must be a model of the
+ * VertexListGraph, IncidenceGraph, EdgeListGraph, and Mutable Graph
+ * concepts.
+ *
+ * @param done The function object that indicates termination of the
+ * algorithm. It must be a ternary function object thats accepts the
+ * maximum centrality, the descriptor of the edge that will be
+ * removed, and the graph @p g.
+ *
+ * @param edge_centrality (UTIL/OUT) The property map that will store
+ * the betweenness centrality for each edge. When the algorithm
+ * terminates, it will contain the edge centralities for the
+ * graph. The type of this property map must model the
+ * ReadWritePropertyMap concept. Defaults to an @c
+ * iterator_property_map whose value type is
+ * @c Done::centrality_type and using @c get(edge_index, g) for the
+ * index map.
+ *
+ * @param vertex_index (IN) The property map that maps vertices to
+ * indices in the range @c [0, num_vertices(g)). This type of this
+ * property map must model the ReadablePropertyMap concept and its
+ * value type must be an integral type. Defaults to
+ * @c get(vertex_index, g).
+ */
+template < typename MutableGraph, typename Done, typename EdgeCentralityMap,
+ typename VertexIndexMap >
+void betweenness_centrality_clustering(MutableGraph& g, Done done,
+ EdgeCentralityMap edge_centrality, VertexIndexMap vertex_index)
+{
+ typedef typename property_traits< EdgeCentralityMap >::value_type
+ centrality_type;
+ typedef typename graph_traits< MutableGraph >::edge_iterator edge_iterator;
+ typedef
+ typename graph_traits< MutableGraph >::edge_descriptor edge_descriptor;
+
+ if (has_no_edges(g))
+ return;
+
+ // Function object that compares the centrality of edges
+ indirect_cmp< EdgeCentralityMap, std::less< centrality_type > > cmp(
+ edge_centrality);
+
+ bool is_done;
+ do
+ {
+ brandes_betweenness_centrality(g,
+ edge_centrality_map(edge_centrality)
+ .vertex_index_map(vertex_index));
+ std::pair< edge_iterator, edge_iterator > edges_iters = edges(g);
+ edge_descriptor e
+ = *boost::first_max_element(edges_iters.first, edges_iters.second, cmp);
+ is_done = done(get(edge_centrality, e), e, g);
+ if (!is_done)
+ remove_edge(e, g);
+ } while (!is_done && !has_no_edges(g));
+}
+
+/**
+ * \overload
+ */
+template < typename MutableGraph, typename Done, typename EdgeCentralityMap >
+void betweenness_centrality_clustering(
+ MutableGraph& g, Done done, EdgeCentralityMap edge_centrality)
+{
+ betweenness_centrality_clustering(
+ g, done, edge_centrality, get(vertex_index, g));
+}
+
+/**
+ * \overload
+ */
+template < typename MutableGraph, typename Done >
+void betweenness_centrality_clustering(MutableGraph& g, Done done)
+{
+ typedef typename Done::centrality_type centrality_type;
+ std::vector< centrality_type > edge_centrality(num_edges(g));
+ betweenness_centrality_clustering(g, done,
+ make_iterator_property_map(edge_centrality.begin(), get(edge_index, g)),
+ get(vertex_index, g));
+}
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/bellman_ford_shortest_paths.hpp b/contrib/restricted/boost/graph/include/boost/graph/bellman_ford_shortest_paths.hpp
new file mode 100644
index 0000000000..2aa4e80833
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/bellman_ford_shortest_paths.hpp
@@ -0,0 +1,226 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+
+/*
+ This file implements the function
+
+ template <class EdgeListGraph, class Size, class P, class T, class R>
+ bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N,
+ const bgl_named_params<P, T, R>& params)
+
+ */
+
+#ifndef BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP
+#define BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/relax.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+
+template < class Visitor, class Graph > struct BellmanFordVisitorConcept
+{
+ void constraints()
+ {
+ BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >));
+ vis.examine_edge(e, g);
+ vis.edge_relaxed(e, g);
+ vis.edge_not_relaxed(e, g);
+ vis.edge_minimized(e, g);
+ vis.edge_not_minimized(e, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename graph_traits< Graph >::edge_descriptor e;
+};
+
+template < class Visitors = null_visitor > class bellman_visitor
+{
+public:
+ bellman_visitor() {}
+ bellman_visitor(Visitors vis) : m_vis(vis) {}
+
+ template < class Edge, class Graph > void examine_edge(Edge u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, on_examine_edge());
+ }
+ template < class Edge, class Graph > void edge_relaxed(Edge u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, on_edge_relaxed());
+ }
+ template < class Edge, class Graph > void edge_not_relaxed(Edge u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, on_edge_not_relaxed());
+ }
+ template < class Edge, class Graph > void edge_minimized(Edge u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, on_edge_minimized());
+ }
+ template < class Edge, class Graph >
+ void edge_not_minimized(Edge u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, on_edge_not_minimized());
+ }
+
+protected:
+ Visitors m_vis;
+};
+template < class Visitors >
+bellman_visitor< Visitors > make_bellman_visitor(Visitors vis)
+{
+ return bellman_visitor< Visitors >(vis);
+}
+typedef bellman_visitor<> default_bellman_visitor;
+
+template < class EdgeListGraph, class Size, class WeightMap,
+ class PredecessorMap, class DistanceMap, class BinaryFunction,
+ class BinaryPredicate, class BellmanFordVisitor >
+bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N, WeightMap weight,
+ PredecessorMap pred, DistanceMap distance, BinaryFunction combine,
+ BinaryPredicate compare, BellmanFordVisitor v)
+{
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< EdgeListGraph >));
+ typedef graph_traits< EdgeListGraph > GTraits;
+ typedef typename GTraits::edge_descriptor Edge;
+ typedef typename GTraits::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< DistanceMap, Vertex >));
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< WeightMap, Edge >));
+
+ typename GTraits::edge_iterator i, end;
+
+ for (Size k = 0; k < N; ++k)
+ {
+ bool at_least_one_edge_relaxed = false;
+ for (boost::tie(i, end) = edges(g); i != end; ++i)
+ {
+ v.examine_edge(*i, g);
+ if (relax(*i, g, weight, pred, distance, combine, compare))
+ {
+ at_least_one_edge_relaxed = true;
+ v.edge_relaxed(*i, g);
+ }
+ else
+ v.edge_not_relaxed(*i, g);
+ }
+ if (!at_least_one_edge_relaxed)
+ break;
+ }
+
+ for (boost::tie(i, end) = edges(g); i != end; ++i)
+ if (compare(combine(get(distance, source(*i, g)), get(weight, *i)),
+ get(distance, target(*i, g))))
+ {
+ v.edge_not_minimized(*i, g);
+ return false;
+ }
+ else
+ v.edge_minimized(*i, g);
+
+ return true;
+}
+
+namespace detail
+{
+
+ template < typename VertexAndEdgeListGraph, typename Size,
+ typename WeightMap, typename PredecessorMap, typename DistanceMap,
+ typename P, typename T, typename R >
+ bool bellman_dispatch2(VertexAndEdgeListGraph& g,
+ typename graph_traits< VertexAndEdgeListGraph >::vertex_descriptor s,
+ Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance,
+ const bgl_named_params< P, T, R >& params)
+ {
+ typedef typename property_traits< DistanceMap >::value_type D;
+ bellman_visitor<> null_vis;
+ typedef typename property_traits< WeightMap >::value_type weight_type;
+ typename graph_traits< VertexAndEdgeListGraph >::vertex_iterator v,
+ v_end;
+ for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v)
+ {
+ put(distance, *v, (std::numeric_limits< weight_type >::max)());
+ put(pred, *v, *v);
+ }
+ put(distance, s, weight_type(0));
+ return bellman_ford_shortest_paths(g, N, weight, pred, distance,
+ choose_param(
+ get_param(params, distance_combine_t()), closed_plus< D >()),
+ choose_param(
+ get_param(params, distance_compare_t()), std::less< D >()),
+ choose_param(get_param(params, graph_visitor), null_vis));
+ }
+
+ template < typename VertexAndEdgeListGraph, typename Size,
+ typename WeightMap, typename PredecessorMap, typename DistanceMap,
+ typename P, typename T, typename R >
+ bool bellman_dispatch2(VertexAndEdgeListGraph& g, param_not_found, Size N,
+ WeightMap weight, PredecessorMap pred, DistanceMap distance,
+ const bgl_named_params< P, T, R >& params)
+ {
+ typedef typename property_traits< DistanceMap >::value_type D;
+ bellman_visitor<> null_vis;
+ return bellman_ford_shortest_paths(g, N, weight, pred, distance,
+ choose_param(
+ get_param(params, distance_combine_t()), closed_plus< D >()),
+ choose_param(
+ get_param(params, distance_compare_t()), std::less< D >()),
+ choose_param(get_param(params, graph_visitor), null_vis));
+ }
+
+ template < class EdgeListGraph, class Size, class WeightMap,
+ class DistanceMap, class P, class T, class R >
+ bool bellman_dispatch(EdgeListGraph& g, Size N, WeightMap weight,
+ DistanceMap distance, const bgl_named_params< P, T, R >& params)
+ {
+ dummy_property_map dummy_pred;
+ return detail::bellman_dispatch2(g, get_param(params, root_vertex_t()),
+ N, weight,
+ choose_param(get_param(params, vertex_predecessor), dummy_pred),
+ distance, params);
+ }
+} // namespace detail
+
+template < class EdgeListGraph, class Size, class P, class T, class R >
+bool bellman_ford_shortest_paths(
+ EdgeListGraph& g, Size N, const bgl_named_params< P, T, R >& params)
+{
+ return detail::bellman_dispatch(g, N,
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_pmap(get_param(params, vertex_distance), g, vertex_distance),
+ params);
+}
+
+template < class EdgeListGraph, class Size >
+bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N)
+{
+ bgl_named_params< int, int > params(0);
+ return bellman_ford_shortest_paths(g, N, params);
+}
+
+template < class VertexAndEdgeListGraph, class P, class T, class R >
+bool bellman_ford_shortest_paths(
+ VertexAndEdgeListGraph& g, const bgl_named_params< P, T, R >& params)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexAndEdgeListGraph >));
+ return detail::bellman_dispatch(g, num_vertices(g),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_pmap(get_param(params, vertex_distance), g, vertex_distance),
+ params);
+}
+} // namespace boost
+
+#endif // BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/betweenness_centrality.hpp b/contrib/restricted/boost/graph/include/boost/graph/betweenness_centrality.hpp
new file mode 100644
index 0000000000..b6148e46ab
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/betweenness_centrality.hpp
@@ -0,0 +1,645 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP
+#define BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP
+
+#include <stack>
+#include <vector>
+#include <boost/graph/overloading.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/relax.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <algorithm>
+
+namespace boost
+{
+
+namespace detail
+{
+ namespace graph
+ {
+
+ /**
+ * Customized visitor passed to Dijkstra's algorithm by Brandes'
+ * betweenness centrality algorithm. This visitor is responsible for
+ * keeping track of the order in which vertices are discovered, the
+ * predecessors on the shortest path(s) to a vertex, and the number
+ * of shortest paths.
+ */
+ template < typename Graph, typename WeightMap, typename IncomingMap,
+ typename DistanceMap, typename PathCountMap >
+ struct brandes_dijkstra_visitor : public bfs_visitor<>
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+ typedef
+ typename graph_traits< Graph >::edge_descriptor edge_descriptor;
+
+ brandes_dijkstra_visitor(
+ std::stack< vertex_descriptor >& ordered_vertices,
+ WeightMap weight, IncomingMap incoming, DistanceMap distance,
+ PathCountMap path_count)
+ : ordered_vertices(ordered_vertices)
+ , weight(weight)
+ , incoming(incoming)
+ , distance(distance)
+ , path_count(path_count)
+ {
+ }
+
+ /**
+ * Whenever an edge e = (v, w) is relaxed, the incoming edge list
+ * for w is set to {(v, w)} and the shortest path count of w is set
+ * to the number of paths that reach {v}.
+ */
+ void edge_relaxed(edge_descriptor e, const Graph& g)
+ {
+ vertex_descriptor v = source(e, g), w = target(e, g);
+ incoming[w].clear();
+ incoming[w].push_back(e);
+ put(path_count, w, get(path_count, v));
+ }
+
+ /**
+ * If an edge e = (v, w) was not relaxed, it may still be the case
+ * that we've found more equally-short paths, so include {(v, w)} in
+ * the incoming edges of w and add all of the shortest paths to v to
+ * the shortest path count of w.
+ */
+ void edge_not_relaxed(edge_descriptor e, const Graph& g)
+ {
+ typedef typename property_traits< WeightMap >::value_type
+ weight_type;
+ typedef typename property_traits< DistanceMap >::value_type
+ distance_type;
+ vertex_descriptor v = source(e, g), w = target(e, g);
+ distance_type d_v = get(distance, v), d_w = get(distance, w);
+ weight_type w_e = get(weight, e);
+
+ closed_plus< distance_type > combine;
+ if (d_w == combine(d_v, w_e))
+ {
+ put(path_count, w, get(path_count, w) + get(path_count, v));
+ incoming[w].push_back(e);
+ }
+ }
+
+ /// Keep track of vertices as they are reached
+ void examine_vertex(vertex_descriptor w, const Graph&)
+ {
+ ordered_vertices.push(w);
+ }
+
+ private:
+ std::stack< vertex_descriptor >& ordered_vertices;
+ WeightMap weight;
+ IncomingMap incoming;
+ DistanceMap distance;
+ PathCountMap path_count;
+ };
+
+ /**
+ * Function object that calls Dijkstra's shortest paths algorithm
+ * using the Dijkstra visitor for the Brandes betweenness centrality
+ * algorithm.
+ */
+ template < typename WeightMap > struct brandes_dijkstra_shortest_paths
+ {
+ brandes_dijkstra_shortest_paths(WeightMap weight_map)
+ : weight_map(weight_map)
+ {
+ }
+
+ template < typename Graph, typename IncomingMap,
+ typename DistanceMap, typename PathCountMap,
+ typename VertexIndexMap >
+ void operator()(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ std::stack< typename graph_traits< Graph >::vertex_descriptor >&
+ ov,
+ IncomingMap incoming, DistanceMap distance,
+ PathCountMap path_count, VertexIndexMap vertex_index)
+ {
+ typedef brandes_dijkstra_visitor< Graph, WeightMap, IncomingMap,
+ DistanceMap, PathCountMap >
+ visitor_type;
+ visitor_type visitor(
+ ov, weight_map, incoming, distance, path_count);
+
+ dijkstra_shortest_paths(g, s,
+ boost::weight_map(weight_map)
+ .vertex_index_map(vertex_index)
+ .distance_map(distance)
+ .visitor(visitor));
+ }
+
+ private:
+ WeightMap weight_map;
+ };
+
+ /**
+ * Function object that invokes breadth-first search for the
+ * unweighted form of the Brandes betweenness centrality algorithm.
+ */
+ struct brandes_unweighted_shortest_paths
+ {
+ /**
+ * Customized visitor passed to breadth-first search, which
+ * records predecessor and the number of shortest paths to each
+ * vertex.
+ */
+ template < typename Graph, typename IncomingMap,
+ typename DistanceMap, typename PathCountMap >
+ struct visitor_type : public bfs_visitor<>
+ {
+ typedef typename graph_traits< Graph >::edge_descriptor
+ edge_descriptor;
+ typedef typename graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+
+ visitor_type(IncomingMap incoming, DistanceMap distance,
+ PathCountMap path_count,
+ std::stack< vertex_descriptor >& ordered_vertices)
+ : incoming(incoming)
+ , distance(distance)
+ , path_count(path_count)
+ , ordered_vertices(ordered_vertices)
+ {
+ }
+
+ /// Keep track of vertices as they are reached
+ void examine_vertex(vertex_descriptor v, Graph&)
+ {
+ ordered_vertices.push(v);
+ }
+
+ /**
+ * Whenever an edge e = (v, w) is labelled a tree edge, the
+ * incoming edge list for w is set to {(v, w)} and the shortest
+ * path count of w is set to the number of paths that reach {v}.
+ */
+ void tree_edge(edge_descriptor e, Graph& g)
+ {
+ vertex_descriptor v = source(e, g);
+ vertex_descriptor w = target(e, g);
+ put(distance, w, get(distance, v) + 1);
+
+ put(path_count, w, get(path_count, v));
+ incoming[w].push_back(e);
+ }
+
+ /**
+ * If an edge e = (v, w) is not a tree edge, it may still be the
+ * case that we've found more equally-short paths, so include
+ * (v, w) in the incoming edge list of w and add all of the
+ * shortest paths to v to the shortest path count of w.
+ */
+ void non_tree_edge(edge_descriptor e, Graph& g)
+ {
+ vertex_descriptor v = source(e, g);
+ vertex_descriptor w = target(e, g);
+ if (get(distance, w) == get(distance, v) + 1)
+ {
+ put(path_count, w,
+ get(path_count, w) + get(path_count, v));
+ incoming[w].push_back(e);
+ }
+ }
+
+ private:
+ IncomingMap incoming;
+ DistanceMap distance;
+ PathCountMap path_count;
+ std::stack< vertex_descriptor >& ordered_vertices;
+ };
+
+ template < typename Graph, typename IncomingMap,
+ typename DistanceMap, typename PathCountMap,
+ typename VertexIndexMap >
+ void operator()(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ std::stack< typename graph_traits< Graph >::vertex_descriptor >&
+ ov,
+ IncomingMap incoming, DistanceMap distance,
+ PathCountMap path_count, VertexIndexMap vertex_index)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+
+ visitor_type< Graph, IncomingMap, DistanceMap, PathCountMap >
+ visitor(incoming, distance, path_count, ov);
+
+ std::vector< default_color_type > colors(num_vertices(g),
+ color_traits< default_color_type >::white());
+ boost::queue< vertex_descriptor > Q;
+ breadth_first_visit(g, s, Q, visitor,
+ make_iterator_property_map(colors.begin(), vertex_index));
+ }
+ };
+
+ // When the edge centrality map is a dummy property map, no
+ // initialization is needed.
+ template < typename Iter >
+ inline void init_centrality_map(
+ std::pair< Iter, Iter >, dummy_property_map)
+ {
+ }
+
+ // When we have a real edge centrality map, initialize all of the
+ // centralities to zero.
+ template < typename Iter, typename Centrality >
+ void init_centrality_map(
+ std::pair< Iter, Iter > keys, Centrality centrality_map)
+ {
+ typedef typename property_traits< Centrality >::value_type
+ centrality_type;
+ while (keys.first != keys.second)
+ {
+ put(centrality_map, *keys.first, centrality_type(0));
+ ++keys.first;
+ }
+ }
+
+ // When the edge centrality map is a dummy property map, no update
+ // is performed.
+ template < typename Key, typename T >
+ inline void update_centrality(dummy_property_map, const Key&, const T&)
+ {
+ }
+
+ // When we have a real edge centrality map, add the value to the map
+ template < typename CentralityMap, typename Key, typename T >
+ inline void update_centrality(
+ CentralityMap centrality_map, Key k, const T& x)
+ {
+ put(centrality_map, k, get(centrality_map, k) + x);
+ }
+
+ template < typename Iter >
+ inline void divide_centrality_by_two(
+ std::pair< Iter, Iter >, dummy_property_map)
+ {
+ }
+
+ template < typename Iter, typename CentralityMap >
+ inline void divide_centrality_by_two(
+ std::pair< Iter, Iter > keys, CentralityMap centrality_map)
+ {
+ typename property_traits< CentralityMap >::value_type two(2);
+ while (keys.first != keys.second)
+ {
+ put(centrality_map, *keys.first,
+ get(centrality_map, *keys.first) / two);
+ ++keys.first;
+ }
+ }
+
+ template < typename Graph, typename CentralityMap,
+ typename EdgeCentralityMap, typename IncomingMap,
+ typename DistanceMap, typename DependencyMap, typename PathCountMap,
+ typename VertexIndexMap, typename ShortestPaths >
+ void brandes_betweenness_centrality_impl(const Graph& g,
+ CentralityMap centrality, // C_B
+ EdgeCentralityMap edge_centrality_map,
+ IncomingMap incoming, // P
+ DistanceMap distance, // d
+ DependencyMap dependency, // delta
+ PathCountMap path_count, // sigma
+ VertexIndexMap vertex_index, ShortestPaths shortest_paths)
+ {
+ typedef
+ typename graph_traits< Graph >::vertex_iterator vertex_iterator;
+ typedef typename graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+
+ // Initialize centrality
+ init_centrality_map(vertices(g), centrality);
+ init_centrality_map(edges(g), edge_centrality_map);
+
+ std::stack< vertex_descriptor > ordered_vertices;
+ vertex_iterator s, s_end;
+ for (boost::tie(s, s_end) = vertices(g); s != s_end; ++s)
+ {
+ // Initialize for this iteration
+ vertex_iterator w, w_end;
+ for (boost::tie(w, w_end) = vertices(g); w != w_end; ++w)
+ {
+ incoming[*w].clear();
+ put(path_count, *w, 0);
+ put(dependency, *w, 0);
+ }
+ put(path_count, *s, 1);
+
+ // Execute the shortest paths algorithm. This will be either
+ // Dijkstra's algorithm or a customized breadth-first search,
+ // depending on whether the graph is weighted or unweighted.
+ shortest_paths(g, *s, ordered_vertices, incoming, distance,
+ path_count, vertex_index);
+
+ while (!ordered_vertices.empty())
+ {
+ vertex_descriptor w = ordered_vertices.top();
+ ordered_vertices.pop();
+
+ typedef typename property_traits< IncomingMap >::value_type
+ incoming_type;
+ typedef typename incoming_type::iterator incoming_iterator;
+ typedef
+ typename property_traits< DependencyMap >::value_type
+ dependency_type;
+
+ for (incoming_iterator vw = incoming[w].begin();
+ vw != incoming[w].end(); ++vw)
+ {
+ vertex_descriptor v = source(*vw, g);
+ dependency_type factor
+ = dependency_type(get(path_count, v))
+ / dependency_type(get(path_count, w));
+ factor *= (dependency_type(1) + get(dependency, w));
+ put(dependency, v, get(dependency, v) + factor);
+ update_centrality(edge_centrality_map, *vw, factor);
+ }
+
+ if (w != *s)
+ {
+ update_centrality(centrality, w, get(dependency, w));
+ }
+ }
+ }
+
+ typedef typename graph_traits< Graph >::directed_category
+ directed_category;
+ const bool is_undirected
+ = is_convertible< directed_category*, undirected_tag* >::value;
+ if (is_undirected)
+ {
+ divide_centrality_by_two(vertices(g), centrality);
+ divide_centrality_by_two(edges(g), edge_centrality_map);
+ }
+ }
+
+ }
+} // end namespace detail::graph
+
+template < typename Graph, typename CentralityMap, typename EdgeCentralityMap,
+ typename IncomingMap, typename DistanceMap, typename DependencyMap,
+ typename PathCountMap, typename VertexIndexMap >
+void brandes_betweenness_centrality(const Graph& g,
+ CentralityMap centrality, // C_B
+ EdgeCentralityMap edge_centrality_map,
+ IncomingMap incoming, // P
+ DistanceMap distance, // d
+ DependencyMap dependency, // delta
+ PathCountMap path_count, // sigma
+ VertexIndexMap vertex_index BOOST_GRAPH_ENABLE_IF_MODELS_PARM(
+ Graph, vertex_list_graph_tag))
+{
+ detail::graph::brandes_unweighted_shortest_paths shortest_paths;
+
+ detail::graph::brandes_betweenness_centrality_impl(g, centrality,
+ edge_centrality_map, incoming, distance, dependency, path_count,
+ vertex_index, shortest_paths);
+}
+
+template < typename Graph, typename CentralityMap, typename EdgeCentralityMap,
+ typename IncomingMap, typename DistanceMap, typename DependencyMap,
+ typename PathCountMap, typename VertexIndexMap, typename WeightMap >
+void brandes_betweenness_centrality(const Graph& g,
+ CentralityMap centrality, // C_B
+ EdgeCentralityMap edge_centrality_map,
+ IncomingMap incoming, // P
+ DistanceMap distance, // d
+ DependencyMap dependency, // delta
+ PathCountMap path_count, // sigma
+ VertexIndexMap vertex_index,
+ WeightMap weight_map BOOST_GRAPH_ENABLE_IF_MODELS_PARM(
+ Graph, vertex_list_graph_tag))
+{
+ detail::graph::brandes_dijkstra_shortest_paths< WeightMap > shortest_paths(
+ weight_map);
+
+ detail::graph::brandes_betweenness_centrality_impl(g, centrality,
+ edge_centrality_map, incoming, distance, dependency, path_count,
+ vertex_index, shortest_paths);
+}
+
+namespace detail
+{
+ namespace graph
+ {
+ template < typename Graph, typename CentralityMap,
+ typename EdgeCentralityMap, typename WeightMap,
+ typename VertexIndexMap >
+ void brandes_betweenness_centrality_dispatch2(const Graph& g,
+ CentralityMap centrality, EdgeCentralityMap edge_centrality_map,
+ WeightMap weight_map, VertexIndexMap vertex_index)
+ {
+ typedef typename graph_traits< Graph >::degree_size_type
+ degree_size_type;
+ typedef
+ typename graph_traits< Graph >::edge_descriptor edge_descriptor;
+ typedef typename mpl::if_c<
+ (is_same< CentralityMap, dummy_property_map >::value),
+ EdgeCentralityMap, CentralityMap >::type a_centrality_map;
+ typedef typename property_traits< a_centrality_map >::value_type
+ centrality_type;
+
+ typename graph_traits< Graph >::vertices_size_type V
+ = num_vertices(g);
+
+ std::vector< std::vector< edge_descriptor > > incoming(V);
+ std::vector< centrality_type > distance(V);
+ std::vector< centrality_type > dependency(V);
+ std::vector< degree_size_type > path_count(V);
+
+ brandes_betweenness_centrality(g, centrality, edge_centrality_map,
+ make_iterator_property_map(incoming.begin(), vertex_index),
+ make_iterator_property_map(distance.begin(), vertex_index),
+ make_iterator_property_map(dependency.begin(), vertex_index),
+ make_iterator_property_map(path_count.begin(), vertex_index),
+ vertex_index, weight_map);
+ }
+
+ template < typename Graph, typename CentralityMap,
+ typename EdgeCentralityMap, typename VertexIndexMap >
+ void brandes_betweenness_centrality_dispatch2(const Graph& g,
+ CentralityMap centrality, EdgeCentralityMap edge_centrality_map,
+ VertexIndexMap vertex_index)
+ {
+ typedef typename graph_traits< Graph >::degree_size_type
+ degree_size_type;
+ typedef
+ typename graph_traits< Graph >::edge_descriptor edge_descriptor;
+ typedef typename mpl::if_c<
+ (is_same< CentralityMap, dummy_property_map >::value),
+ EdgeCentralityMap, CentralityMap >::type a_centrality_map;
+ typedef typename property_traits< a_centrality_map >::value_type
+ centrality_type;
+
+ typename graph_traits< Graph >::vertices_size_type V
+ = num_vertices(g);
+
+ std::vector< std::vector< edge_descriptor > > incoming(V);
+ std::vector< centrality_type > distance(V);
+ std::vector< centrality_type > dependency(V);
+ std::vector< degree_size_type > path_count(V);
+
+ brandes_betweenness_centrality(g, centrality, edge_centrality_map,
+ make_iterator_property_map(incoming.begin(), vertex_index),
+ make_iterator_property_map(distance.begin(), vertex_index),
+ make_iterator_property_map(dependency.begin(), vertex_index),
+ make_iterator_property_map(path_count.begin(), vertex_index),
+ vertex_index);
+ }
+
+ template < typename WeightMap >
+ struct brandes_betweenness_centrality_dispatch1
+ {
+ template < typename Graph, typename CentralityMap,
+ typename EdgeCentralityMap, typename VertexIndexMap >
+ static void run(const Graph& g, CentralityMap centrality,
+ EdgeCentralityMap edge_centrality_map,
+ VertexIndexMap vertex_index, WeightMap weight_map)
+ {
+ brandes_betweenness_centrality_dispatch2(g, centrality,
+ edge_centrality_map, weight_map, vertex_index);
+ }
+ };
+
+ template <>
+ struct brandes_betweenness_centrality_dispatch1< param_not_found >
+ {
+ template < typename Graph, typename CentralityMap,
+ typename EdgeCentralityMap, typename VertexIndexMap >
+ static void run(const Graph& g, CentralityMap centrality,
+ EdgeCentralityMap edge_centrality_map,
+ VertexIndexMap vertex_index, param_not_found)
+ {
+ brandes_betweenness_centrality_dispatch2(
+ g, centrality, edge_centrality_map, vertex_index);
+ }
+ };
+
+ template < typename T > struct is_bgl_named_params
+ {
+ BOOST_STATIC_CONSTANT(bool, value = false);
+ };
+
+ template < typename Param, typename Tag, typename Rest >
+ struct is_bgl_named_params< bgl_named_params< Param, Tag, Rest > >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+
+ }
+} // end namespace detail::graph
+
+template < typename Graph, typename Param, typename Tag, typename Rest >
+void brandes_betweenness_centrality(const Graph& g,
+ const bgl_named_params< Param, Tag, Rest >& params
+ BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, vertex_list_graph_tag))
+{
+ typedef bgl_named_params< Param, Tag, Rest > named_params;
+
+ typedef typename get_param_type< edge_weight_t, named_params >::type ew;
+ detail::graph::brandes_betweenness_centrality_dispatch1< ew >::run(g,
+ choose_param(
+ get_param(params, vertex_centrality), dummy_property_map()),
+ choose_param(get_param(params, edge_centrality), dummy_property_map()),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ get_param(params, edge_weight));
+}
+
+// disable_if is required to work around problem with MSVC 7.1 (it seems to not
+// get partial ordering getween this overload and the previous one correct)
+template < typename Graph, typename CentralityMap >
+typename disable_if< detail::graph::is_bgl_named_params< CentralityMap >,
+ void >::type
+brandes_betweenness_centrality(const Graph& g,
+ CentralityMap centrality BOOST_GRAPH_ENABLE_IF_MODELS_PARM(
+ Graph, vertex_list_graph_tag))
+{
+ detail::graph::brandes_betweenness_centrality_dispatch2(
+ g, centrality, dummy_property_map(), get(vertex_index, g));
+}
+
+template < typename Graph, typename CentralityMap, typename EdgeCentralityMap >
+void brandes_betweenness_centrality(const Graph& g, CentralityMap centrality,
+ EdgeCentralityMap edge_centrality_map BOOST_GRAPH_ENABLE_IF_MODELS_PARM(
+ Graph, vertex_list_graph_tag))
+{
+ detail::graph::brandes_betweenness_centrality_dispatch2(
+ g, centrality, edge_centrality_map, get(vertex_index, g));
+}
+
+/**
+ * Converts "absolute" betweenness centrality (as computed by the
+ * brandes_betweenness_centrality algorithm) in the centrality map
+ * into "relative" centrality. The result is placed back into the
+ * given centrality map.
+ */
+template < typename Graph, typename CentralityMap >
+void relative_betweenness_centrality(const Graph& g, CentralityMap centrality)
+{
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator;
+ typedef
+ typename property_traits< CentralityMap >::value_type centrality_type;
+
+ typename graph_traits< Graph >::vertices_size_type n = num_vertices(g);
+ centrality_type factor
+ = centrality_type(2) / centrality_type(n * n - 3 * n + 2);
+ vertex_iterator v, v_end;
+ for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v)
+ {
+ put(centrality, *v, factor * get(centrality, *v));
+ }
+}
+
+// Compute the central point dominance of a graph.
+template < typename Graph, typename CentralityMap >
+typename property_traits< CentralityMap >::value_type central_point_dominance(
+ const Graph& g,
+ CentralityMap centrality BOOST_GRAPH_ENABLE_IF_MODELS_PARM(
+ Graph, vertex_list_graph_tag))
+{
+ using std::max;
+
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator;
+ typedef
+ typename property_traits< CentralityMap >::value_type centrality_type;
+
+ typename graph_traits< Graph >::vertices_size_type n = num_vertices(g);
+
+ // Find max centrality
+ centrality_type max_centrality(0);
+ vertex_iterator v, v_end;
+ for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v)
+ {
+ max_centrality = (max)(max_centrality, get(centrality, *v));
+ }
+
+ // Compute central point dominance
+ centrality_type sum(0);
+ for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v)
+ {
+ sum += (max_centrality - get(centrality, *v));
+ }
+ return sum / (n - 1);
+}
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/biconnected_components.hpp b/contrib/restricted/boost/graph/include/boost/graph/biconnected_components.hpp
new file mode 100644
index 0000000000..9b70e0eb48
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/biconnected_components.hpp
@@ -0,0 +1,440 @@
+// Copyright (c) Jeremy Siek 2001
+// Copyright (c) Douglas Gregor 2004
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// NOTE: this final is generated by libs/graph/doc/biconnected_components.w
+
+#ifndef BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
+#define BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
+
+#include <stack>
+#include <vector>
+#include <algorithm> // for std::min and std::max
+#include <boost/config.hpp>
+#include <boost/limits.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/graph_utility.hpp>
+#include <boost/concept/assert.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+namespace detail
+{
+ template < typename ComponentMap, typename DiscoverTimeMap,
+ typename LowPointMap, typename PredecessorMap, typename OutputIterator,
+ typename Stack, typename ArticulationVector, typename IndexMap,
+ typename DFSVisitor >
+ struct biconnected_components_visitor : public dfs_visitor<>
+ {
+ biconnected_components_visitor(ComponentMap comp, std::size_t& c,
+ std::size_t& children_of_root, DiscoverTimeMap dtm,
+ std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred,
+ OutputIterator out, Stack& S,
+ ArticulationVector& is_articulation_point, IndexMap index_map,
+ DFSVisitor vis)
+ : comp(comp)
+ , c(c)
+ , children_of_root(children_of_root)
+ , dtm(dtm)
+ , dfs_time(dfs_time)
+ , lowpt(lowpt)
+ , pred(pred)
+ , out(out)
+ , S(S)
+ , is_articulation_point(is_articulation_point)
+ , index_map(index_map)
+ , vis(vis)
+ {
+ }
+
+ template < typename Vertex, typename Graph >
+ void initialize_vertex(const Vertex& u, Graph& g)
+ {
+ put(pred, u, u);
+ vis.initialize_vertex(u, g);
+ }
+
+ template < typename Vertex, typename Graph >
+ void start_vertex(const Vertex& u, Graph& g)
+ {
+ children_of_root = 0;
+ vis.start_vertex(u, g);
+ }
+
+ template < typename Vertex, typename Graph >
+ void discover_vertex(const Vertex& u, Graph& g)
+ {
+ put(dtm, u, ++dfs_time);
+ put(lowpt, u, get(dtm, u));
+ vis.discover_vertex(u, g);
+ }
+
+ template < typename Edge, typename Graph >
+ void examine_edge(const Edge& e, Graph& g)
+ {
+ vis.examine_edge(e, g);
+ }
+
+ template < typename Edge, typename Graph >
+ void tree_edge(const Edge& e, Graph& g)
+ {
+ typename boost::graph_traits< Graph >::vertex_descriptor src
+ = source(e, g);
+ typename boost::graph_traits< Graph >::vertex_descriptor tgt
+ = target(e, g);
+
+ S.push(e);
+ put(pred, tgt, src);
+ if (get(pred, src) == src)
+ {
+ ++children_of_root;
+ }
+ vis.tree_edge(e, g);
+ }
+
+ template < typename Edge, typename Graph >
+ void back_edge(const Edge& e, Graph& g)
+ {
+ BOOST_USING_STD_MIN();
+
+ typename boost::graph_traits< Graph >::vertex_descriptor src
+ = source(e, g);
+ typename boost::graph_traits< Graph >::vertex_descriptor tgt
+ = target(e, g);
+ if (tgt != get(pred, src))
+ {
+ S.push(e);
+ put(lowpt, src,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ get(lowpt, src), get(dtm, tgt)));
+ }
+ vis.back_edge(e, g);
+ }
+
+ template < typename Edge, typename Graph >
+ void forward_or_cross_edge(const Edge& e, Graph& g)
+ {
+ vis.forward_or_cross_edge(e, g);
+ }
+
+ template < typename Vertex, typename Graph >
+ void finish_vertex(const Vertex& u, Graph& g)
+ {
+ BOOST_USING_STD_MIN();
+ Vertex parent = get(pred, u);
+ if (parent == u)
+ { // Root of tree is special
+ is_articulation_point[get(index_map, u)]
+ = (children_of_root > 1);
+ }
+ else
+ {
+ put(lowpt, parent,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ get(lowpt, parent), get(lowpt, u)));
+ if (get(lowpt, u) >= get(dtm, parent))
+ {
+ is_articulation_point[get(index_map, parent)] = true;
+ while (get(dtm, source(S.top(), g)) >= get(dtm, u))
+ {
+ put(comp, S.top(), c);
+ S.pop();
+ }
+ BOOST_ASSERT(source(S.top(), g) == parent);
+ BOOST_ASSERT(target(S.top(), g) == u);
+ put(comp, S.top(), c);
+ S.pop();
+ ++c;
+ }
+ }
+ if (is_articulation_point[get(index_map, u)])
+ {
+ *out++ = u;
+ }
+ vis.finish_vertex(u, g);
+ }
+
+ ComponentMap comp;
+ std::size_t& c;
+ std::size_t& children_of_root;
+ DiscoverTimeMap dtm;
+ std::size_t& dfs_time;
+ LowPointMap lowpt;
+ PredecessorMap pred;
+ OutputIterator out;
+ Stack& S;
+ ArticulationVector& is_articulation_point;
+ IndexMap index_map;
+ DFSVisitor vis;
+ };
+
+ template < typename Graph, typename ComponentMap, typename OutputIterator,
+ typename VertexIndexMap, typename DiscoverTimeMap, typename LowPointMap,
+ typename PredecessorMap, typename DFSVisitor >
+ std::pair< std::size_t, OutputIterator > biconnected_components_impl(
+ const Graph& g, ComponentMap comp, OutputIterator out,
+ VertexIndexMap index_map, DiscoverTimeMap dtm, LowPointMap lowpt,
+ PredecessorMap pred, DFSVisitor dfs_vis)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT(
+ (WritablePropertyMapConcept< ComponentMap, edge_t >));
+ BOOST_CONCEPT_ASSERT(
+ (ReadWritePropertyMapConcept< DiscoverTimeMap, vertex_t >));
+ BOOST_CONCEPT_ASSERT(
+ (ReadWritePropertyMapConcept< LowPointMap, vertex_t >));
+ BOOST_CONCEPT_ASSERT(
+ (ReadWritePropertyMapConcept< PredecessorMap, vertex_t >));
+
+ std::size_t num_components = 0;
+ std::size_t children_of_root;
+ std::size_t dfs_time = 0;
+ std::stack< edge_t > S;
+ std::vector< char > is_articulation_point(num_vertices(g));
+
+ biconnected_components_visitor< ComponentMap, DiscoverTimeMap,
+ LowPointMap, PredecessorMap, OutputIterator, std::stack< edge_t >,
+ std::vector< char >, VertexIndexMap, DFSVisitor >
+ vis(comp, num_components, children_of_root, dtm, dfs_time, lowpt,
+ pred, out, S, is_articulation_point, index_map, dfs_vis);
+
+ depth_first_search(g, visitor(vis).vertex_index_map(index_map));
+
+ return std::pair< std::size_t, OutputIterator >(
+ num_components, vis.out);
+ }
+
+ template < typename PredecessorMap > struct bicomp_dispatch3
+ {
+ template < typename Graph, typename ComponentMap,
+ typename OutputIterator, typename VertexIndexMap,
+ typename DiscoverTimeMap, typename LowPointMap, class P, class T,
+ class R >
+ static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ DiscoverTimeMap dtm, LowPointMap lowpt,
+ const bgl_named_params< P, T, R >& params, PredecessorMap pred)
+ {
+ return biconnected_components_impl(g, comp, out, index_map, dtm,
+ lowpt, pred,
+ choose_param(get_param(params, graph_visitor),
+ make_dfs_visitor(null_visitor())));
+ }
+ };
+
+ template <> struct bicomp_dispatch3< param_not_found >
+ {
+ template < typename Graph, typename ComponentMap,
+ typename OutputIterator, typename VertexIndexMap,
+ typename DiscoverTimeMap, typename LowPointMap, class P, class T,
+ class R >
+ static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ DiscoverTimeMap dtm, LowPointMap lowpt,
+ const bgl_named_params< P, T, R >& params, param_not_found)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ std::vector< vertex_t > pred(num_vertices(g));
+ vertex_t vert = graph_traits< Graph >::null_vertex();
+
+ return biconnected_components_impl(g, comp, out, index_map, dtm,
+ lowpt,
+ make_iterator_property_map(pred.begin(), index_map, vert),
+ choose_param(get_param(params, graph_visitor),
+ make_dfs_visitor(null_visitor())));
+ }
+ };
+
+ template < typename LowPointMap > struct bicomp_dispatch2
+ {
+ template < typename Graph, typename ComponentMap,
+ typename OutputIterator, typename VertexIndexMap,
+ typename DiscoverTimeMap, typename P, typename T, typename R >
+ static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ DiscoverTimeMap dtm, const bgl_named_params< P, T, R >& params,
+ LowPointMap lowpt)
+ {
+ typedef typename get_param_type< vertex_predecessor_t,
+ bgl_named_params< P, T, R > >::type dispatch_type;
+
+ return bicomp_dispatch3< dispatch_type >::apply(g, comp, out,
+ index_map, dtm, lowpt, params,
+ get_param(params, vertex_predecessor));
+ }
+ };
+
+ template <> struct bicomp_dispatch2< param_not_found >
+ {
+ template < typename Graph, typename ComponentMap,
+ typename OutputIterator, typename VertexIndexMap,
+ typename DiscoverTimeMap, typename P, typename T, typename R >
+ static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ DiscoverTimeMap dtm, const bgl_named_params< P, T, R >& params,
+ param_not_found)
+ {
+ typedef typename graph_traits< Graph >::vertices_size_type
+ vertices_size_type;
+ std::vector< vertices_size_type > lowpt(num_vertices(g));
+ vertices_size_type vst(0);
+
+ typedef typename get_param_type< vertex_predecessor_t,
+ bgl_named_params< P, T, R > >::type dispatch_type;
+
+ return bicomp_dispatch3< dispatch_type >::apply(g, comp, out,
+ index_map, dtm,
+ make_iterator_property_map(lowpt.begin(), index_map, vst),
+ params, get_param(params, vertex_predecessor));
+ }
+ };
+
+ template < typename DiscoverTimeMap > struct bicomp_dispatch1
+ {
+ template < typename Graph, typename ComponentMap,
+ typename OutputIterator, typename VertexIndexMap, class P, class T,
+ class R >
+ static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ const bgl_named_params< P, T, R >& params, DiscoverTimeMap dtm)
+ {
+ typedef typename get_param_type< vertex_lowpoint_t,
+ bgl_named_params< P, T, R > >::type dispatch_type;
+
+ return bicomp_dispatch2< dispatch_type >::apply(g, comp, out,
+ index_map, dtm, params, get_param(params, vertex_lowpoint));
+ }
+ };
+
+ template <> struct bicomp_dispatch1< param_not_found >
+ {
+ template < typename Graph, typename ComponentMap,
+ typename OutputIterator, typename VertexIndexMap, class P, class T,
+ class R >
+ static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ const bgl_named_params< P, T, R >& params, param_not_found)
+ {
+ typedef typename graph_traits< Graph >::vertices_size_type
+ vertices_size_type;
+ std::vector< vertices_size_type > discover_time(num_vertices(g));
+ vertices_size_type vst(0);
+
+ typedef typename get_param_type< vertex_lowpoint_t,
+ bgl_named_params< P, T, R > >::type dispatch_type;
+
+ return bicomp_dispatch2< dispatch_type >::apply(g, comp, out,
+ index_map,
+ make_iterator_property_map(
+ discover_time.begin(), index_map, vst),
+ params, get_param(params, vertex_lowpoint));
+ }
+ };
+
+}
+
+template < typename Graph, typename ComponentMap, typename OutputIterator,
+ typename DiscoverTimeMap, typename LowPointMap >
+std::pair< std::size_t, OutputIterator > biconnected_components(const Graph& g,
+ ComponentMap comp, OutputIterator out, DiscoverTimeMap dtm,
+ LowPointMap lowpt)
+{
+ typedef param_not_found dispatch_type;
+
+ return detail::bicomp_dispatch3< dispatch_type >::apply(g, comp, out,
+ get(vertex_index, g), dtm, lowpt,
+ bgl_named_params< int, buffer_param_t >(0), param_not_found());
+}
+
+template < typename Graph, typename ComponentMap, typename OutputIterator,
+ typename P, typename T, typename R >
+std::pair< std::size_t, OutputIterator > biconnected_components(const Graph& g,
+ ComponentMap comp, OutputIterator out,
+ const bgl_named_params< P, T, R >& params)
+{
+ typedef typename get_param_type< vertex_discover_time_t,
+ bgl_named_params< P, T, R > >::type dispatch_type;
+
+ return detail::bicomp_dispatch1< dispatch_type >::apply(g, comp, out,
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ params, get_param(params, vertex_discover_time));
+}
+
+template < typename Graph, typename ComponentMap, typename OutputIterator >
+std::pair< std::size_t, OutputIterator > biconnected_components(
+ const Graph& g, ComponentMap comp, OutputIterator out)
+{
+ return biconnected_components(
+ g, comp, out, bgl_named_params< int, buffer_param_t >(0));
+}
+
+namespace graph_detail
+{
+ struct dummy_output_iterator
+ {
+ typedef std::output_iterator_tag iterator_category;
+ typedef void value_type;
+ typedef void pointer;
+ typedef void difference_type;
+
+ struct reference
+ {
+ template < typename T > reference& operator=(const T&)
+ {
+ return *this;
+ }
+ };
+
+ reference operator*() const { return reference(); }
+ dummy_output_iterator& operator++() { return *this; }
+ dummy_output_iterator operator++(int) { return *this; }
+ };
+} // end namespace graph_detail
+
+template < typename Graph, typename ComponentMap, typename P, typename T,
+ typename R >
+std::size_t biconnected_components(const Graph& g, ComponentMap comp,
+ const bgl_named_params< P, T, R >& params)
+{
+ return biconnected_components(
+ g, comp, graph_detail::dummy_output_iterator(), params)
+ .first;
+}
+
+template < typename Graph, typename ComponentMap >
+std::size_t biconnected_components(const Graph& g, ComponentMap comp)
+{
+ return biconnected_components(
+ g, comp, graph_detail::dummy_output_iterator())
+ .first;
+}
+
+template < typename Graph, typename OutputIterator, typename P, typename T,
+ typename R >
+OutputIterator articulation_points(const Graph& g, OutputIterator out,
+ const bgl_named_params< P, T, R >& params)
+{
+ return biconnected_components(g, dummy_property_map(), out, params).second;
+}
+
+template < typename Graph, typename OutputIterator >
+OutputIterator articulation_points(const Graph& g, OutputIterator out)
+{
+ return biconnected_components(g, dummy_property_map(), out,
+ bgl_named_params< int, buffer_param_t >(0))
+ .second;
+}
+
+} // namespace boost
+
+#endif /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */
diff --git a/contrib/restricted/boost/graph/include/boost/graph/bipartite.hpp b/contrib/restricted/boost/graph/include/boost/graph/bipartite.hpp
new file mode 100644
index 0000000000..21382840c3
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/bipartite.hpp
@@ -0,0 +1,403 @@
+/**
+ *
+ * Copyright (c) 2010 Matthias Walter (xammy@xammy.homelinux.net)
+ *
+ * Authors: Matthias Walter
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+#ifndef BOOST_GRAPH_BIPARTITE_HPP
+#define BOOST_GRAPH_BIPARTITE_HPP
+
+#include <utility>
+#include <vector>
+#include <exception>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/one_bit_color_map.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ /**
+ * The bipartite_visitor_error is thrown if an edge cannot be colored.
+ * The witnesses are the edges incident vertices.
+ */
+
+ template < typename Vertex >
+ struct BOOST_SYMBOL_VISIBLE bipartite_visitor_error : std::exception
+ {
+ std::pair< Vertex, Vertex > witnesses;
+
+ bipartite_visitor_error(Vertex a, Vertex b) : witnesses(a, b) {}
+
+ const char* what() const noexcept { return "Graph is not bipartite."; }
+ };
+
+ /**
+ * Functor which colors edges to be non-monochromatic.
+ */
+
+ template < typename PartitionMap > struct bipartition_colorize
+ {
+ typedef on_tree_edge event_filter;
+
+ bipartition_colorize(PartitionMap partition_map)
+ : partition_map_(partition_map)
+ {
+ }
+
+ template < typename Edge, typename Graph >
+ void operator()(Edge e, const Graph& g)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor_t;
+ typedef color_traits<
+ typename property_traits< PartitionMap >::value_type >
+ color_traits;
+
+ vertex_descriptor_t source_vertex = source(e, g);
+ vertex_descriptor_t target_vertex = target(e, g);
+ if (get(partition_map_, source_vertex) == color_traits::white())
+ put(partition_map_, target_vertex, color_traits::black());
+ else
+ put(partition_map_, target_vertex, color_traits::white());
+ }
+
+ private:
+ PartitionMap partition_map_;
+ };
+
+ /**
+ * Creates a bipartition_colorize functor which colors edges
+ * to be non-monochromatic.
+ *
+ * @param partition_map Color map for the bipartition
+ * @return The functor.
+ */
+
+ template < typename PartitionMap >
+ inline bipartition_colorize< PartitionMap > colorize_bipartition(
+ PartitionMap partition_map)
+ {
+ return bipartition_colorize< PartitionMap >(partition_map);
+ }
+
+ /**
+ * Functor which tests an edge to be monochromatic.
+ */
+
+ template < typename PartitionMap > struct bipartition_check
+ {
+ typedef on_back_edge event_filter;
+
+ bipartition_check(PartitionMap partition_map)
+ : partition_map_(partition_map)
+ {
+ }
+
+ template < typename Edge, typename Graph >
+ void operator()(Edge e, const Graph& g)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor_t;
+
+ vertex_descriptor_t source_vertex = source(e, g);
+ vertex_descriptor_t target_vertex = target(e, g);
+ if (get(partition_map_, source_vertex)
+ == get(partition_map_, target_vertex))
+ throw bipartite_visitor_error< vertex_descriptor_t >(
+ source_vertex, target_vertex);
+ }
+
+ private:
+ PartitionMap partition_map_;
+ };
+
+ /**
+ * Creates a bipartition_check functor which raises an error if a
+ * monochromatic edge is found.
+ *
+ * @param partition_map The map for a bipartition.
+ * @return The functor.
+ */
+
+ template < typename PartitionMap >
+ inline bipartition_check< PartitionMap > check_bipartition(
+ PartitionMap partition_map)
+ {
+ return bipartition_check< PartitionMap >(partition_map);
+ }
+
+ /**
+ * Find the beginning of a common suffix of two sequences
+ *
+ * @param sequence1 Pair of bidirectional iterators defining the first
+ * sequence.
+ * @param sequence2 Pair of bidirectional iterators defining the second
+ * sequence.
+ * @return Pair of iterators pointing to the beginning of the common suffix.
+ */
+
+ template < typename BiDirectionalIterator1,
+ typename BiDirectionalIterator2 >
+ inline std::pair< BiDirectionalIterator1, BiDirectionalIterator2 >
+ reverse_mismatch(
+ std::pair< BiDirectionalIterator1, BiDirectionalIterator1 > sequence1,
+ std::pair< BiDirectionalIterator2, BiDirectionalIterator2 > sequence2)
+ {
+ if (sequence1.first == sequence1.second
+ || sequence2.first == sequence2.second)
+ return std::make_pair(sequence1.first, sequence2.first);
+
+ BiDirectionalIterator1 iter1 = sequence1.second;
+ BiDirectionalIterator2 iter2 = sequence2.second;
+
+ while (true)
+ {
+ --iter1;
+ --iter2;
+ if (*iter1 != *iter2)
+ {
+ ++iter1;
+ ++iter2;
+ break;
+ }
+ if (iter1 == sequence1.first)
+ break;
+ if (iter2 == sequence2.first)
+ break;
+ }
+
+ return std::make_pair(iter1, iter2);
+ }
+
+}
+
+/**
+ * Checks a given graph for bipartiteness and fills the given color map with
+ * white and black according to the bipartition. If the graph is not
+ * bipartite, the contents of the color map are undefined. Runs in linear
+ * time in the size of the graph, if access to the property maps is in
+ * constant time.
+ *
+ * @param graph The given graph.
+ * @param index_map An index map associating vertices with an index.
+ * @param partition_map A color map to fill with the bipartition.
+ * @return true if and only if the given graph is bipartite.
+ */
+
+template < typename Graph, typename IndexMap, typename PartitionMap >
+bool is_bipartite(
+ const Graph& graph, const IndexMap index_map, PartitionMap partition_map)
+{
+ /// General types and variables
+ typedef
+ typename property_traits< PartitionMap >::value_type partition_color_t;
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+
+ /// Declare dfs visitor
+ // detail::empty_recorder recorder;
+ // typedef detail::bipartite_visitor <PartitionMap,
+ // detail::empty_recorder> dfs_visitor_t; dfs_visitor_t dfs_visitor
+ // (partition_map, recorder);
+
+ /// Call dfs
+ try
+ {
+ depth_first_search(graph,
+ vertex_index_map(index_map).visitor(make_dfs_visitor(
+ std::make_pair(detail::colorize_bipartition(partition_map),
+ std::make_pair(detail::check_bipartition(partition_map),
+ put_property(partition_map,
+ color_traits< partition_color_t >::white(),
+ on_start_vertex()))))));
+ }
+ catch (const detail::bipartite_visitor_error< vertex_descriptor_t >&)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Checks a given graph for bipartiteness.
+ *
+ * @param graph The given graph.
+ * @param index_map An index map associating vertices with an index.
+ * @return true if and only if the given graph is bipartite.
+ */
+
+template < typename Graph, typename IndexMap >
+bool is_bipartite(const Graph& graph, const IndexMap index_map)
+{
+ typedef one_bit_color_map< IndexMap > partition_map_t;
+ partition_map_t partition_map(num_vertices(graph), index_map);
+
+ return is_bipartite(graph, index_map, partition_map);
+}
+
+/**
+ * Checks a given graph for bipartiteness. The graph must
+ * have an internal vertex_index property. Runs in linear time in the
+ * size of the graph, if access to the property maps is in constant time.
+ *
+ * @param graph The given graph.
+ * @return true if and only if the given graph is bipartite.
+ */
+
+template < typename Graph > bool is_bipartite(const Graph& graph)
+{
+ return is_bipartite(graph, get(vertex_index, graph));
+}
+
+/**
+ * Checks a given graph for bipartiteness and fills a given color map with
+ * white and black according to the bipartition. If the graph is not
+ * bipartite, a sequence of vertices, producing an odd-cycle, is written to
+ * the output iterator. The final iterator value is returned. Runs in linear
+ * time in the size of the graph, if access to the property maps is in
+ * constant time.
+ *
+ * @param graph The given graph.
+ * @param index_map An index map associating vertices with an index.
+ * @param partition_map A color map to fill with the bipartition.
+ * @param result An iterator to write the odd-cycle vertices to.
+ * @return The final iterator value after writing.
+ */
+
+template < typename Graph, typename IndexMap, typename PartitionMap,
+ typename OutputIterator >
+OutputIterator find_odd_cycle(const Graph& graph, const IndexMap index_map,
+ PartitionMap partition_map, OutputIterator result)
+{
+ /// General types and variables
+ typedef
+ typename property_traits< PartitionMap >::value_type partition_color_t;
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ vertex_iterator_t vertex_iter, vertex_end;
+
+ /// Declare predecessor map
+ typedef std::vector< vertex_descriptor_t > predecessors_t;
+ typedef iterator_property_map< typename predecessors_t::iterator, IndexMap,
+ vertex_descriptor_t, vertex_descriptor_t& >
+ predecessor_map_t;
+
+ predecessors_t predecessors(
+ num_vertices(graph), graph_traits< Graph >::null_vertex());
+ predecessor_map_t predecessor_map(predecessors.begin(), index_map);
+
+ /// Initialize predecessor map
+ for (boost::tie(vertex_iter, vertex_end) = vertices(graph);
+ vertex_iter != vertex_end; ++vertex_iter)
+ {
+ put(predecessor_map, *vertex_iter, *vertex_iter);
+ }
+
+ /// Call dfs
+ try
+ {
+ depth_first_search(graph,
+ vertex_index_map(index_map).visitor(make_dfs_visitor(
+ std::make_pair(detail::colorize_bipartition(partition_map),
+ std::make_pair(detail::check_bipartition(partition_map),
+ std::make_pair(
+ put_property(partition_map,
+ color_traits< partition_color_t >::white(),
+ on_start_vertex()),
+ record_predecessors(
+ predecessor_map, on_tree_edge())))))));
+ }
+ catch (const detail::bipartite_visitor_error< vertex_descriptor_t >& error)
+ {
+ typedef std::vector< vertex_descriptor_t > path_t;
+
+ path_t path1, path2;
+ vertex_descriptor_t next, current;
+
+ /// First path
+ next = error.witnesses.first;
+ do
+ {
+ current = next;
+ path1.push_back(current);
+ next = predecessor_map[current];
+ } while (current != next);
+
+ /// Second path
+ next = error.witnesses.second;
+ do
+ {
+ current = next;
+ path2.push_back(current);
+ next = predecessor_map[current];
+ } while (current != next);
+
+ /// Find beginning of common suffix
+ std::pair< typename path_t::iterator, typename path_t::iterator >
+ mismatch = detail::reverse_mismatch(
+ std::make_pair(path1.begin(), path1.end()),
+ std::make_pair(path2.begin(), path2.end()));
+
+ /// Copy the odd-length cycle
+ result = std::copy(path1.begin(), mismatch.first + 1, result);
+ return std::reverse_copy(path2.begin(), mismatch.second, result);
+ }
+
+ return result;
+}
+
+/**
+ * Checks a given graph for bipartiteness. If the graph is not bipartite, a
+ * sequence of vertices, producing an odd-cycle, is written to the output
+ * iterator. The final iterator value is returned. Runs in linear time in the
+ * size of the graph, if access to the property maps is in constant time.
+ *
+ * @param graph The given graph.
+ * @param index_map An index map associating vertices with an index.
+ * @param result An iterator to write the odd-cycle vertices to.
+ * @return The final iterator value after writing.
+ */
+
+template < typename Graph, typename IndexMap, typename OutputIterator >
+OutputIterator find_odd_cycle(
+ const Graph& graph, const IndexMap index_map, OutputIterator result)
+{
+ typedef one_bit_color_map< IndexMap > partition_map_t;
+ partition_map_t partition_map(num_vertices(graph), index_map);
+
+ return find_odd_cycle(graph, index_map, partition_map, result);
+}
+
+/**
+ * Checks a given graph for bipartiteness. If the graph is not bipartite, a
+ * sequence of vertices, producing an odd-cycle, is written to the output
+ * iterator. The final iterator value is returned. The graph must have an
+ * internal vertex_index property. Runs in linear time in the size of the
+ * graph, if access to the property maps is in constant time.
+ *
+ * @param graph The given graph.
+ * @param result An iterator to write the odd-cycle vertices to.
+ * @return The final iterator value after writing.
+ */
+
+template < typename Graph, typename OutputIterator >
+OutputIterator find_odd_cycle(const Graph& graph, OutputIterator result)
+{
+ return find_odd_cycle(graph, get(vertex_index, graph), result);
+}
+}
+
+#endif /// BOOST_GRAPH_BIPARTITE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/boyer_myrvold_planar_test.hpp b/contrib/restricted/boost/graph/include/boost/graph/boyer_myrvold_planar_test.hpp
new file mode 100644
index 0000000000..34a476b50e
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/boyer_myrvold_planar_test.hpp
@@ -0,0 +1,262 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef __BOYER_MYRVOLD_PLANAR_TEST_HPP__
+#define __BOYER_MYRVOLD_PLANAR_TEST_HPP__
+
+#include <boost/graph/planar_detail/boyer_myrvold_impl.hpp>
+#include <boost/parameter.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost
+{
+
+struct no_kuratowski_subgraph_isolation
+{
+};
+struct no_planar_embedding
+{
+};
+
+namespace boyer_myrvold_params
+{
+
+ BOOST_PARAMETER_KEYWORD(tag, graph)
+ BOOST_PARAMETER_KEYWORD(tag, embedding)
+ BOOST_PARAMETER_KEYWORD(tag, kuratowski_subgraph)
+ BOOST_PARAMETER_KEYWORD(tag, vertex_index_map)
+ BOOST_PARAMETER_KEYWORD(tag, edge_index_map)
+
+ typedef parameter::parameters< parameter::required< tag::graph >,
+ tag::embedding, tag::kuratowski_subgraph, tag::vertex_index_map,
+ tag::edge_index_map >
+ boyer_myrvold_params_t;
+
+ namespace core
+ {
+
+ template < typename ArgumentPack >
+ bool dispatched_boyer_myrvold(
+ ArgumentPack const& args, mpl::true_, mpl::true_)
+ {
+ // Dispatch for no planar embedding, no kuratowski subgraph
+ // isolation
+
+ typedef typename remove_const< typename parameter::value_type<
+ ArgumentPack, tag::graph >::type >::type graph_t;
+
+ typedef typename property_map< graph_t, vertex_index_t >::const_type
+ vertex_default_index_map_t;
+
+ typedef typename parameter::value_type< ArgumentPack,
+ tag::vertex_index_map, vertex_default_index_map_t >::type
+ vertex_index_map_t;
+
+ graph_t const& g = args[graph];
+ vertex_default_index_map_t v_d_map = get(vertex_index, g);
+ vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map];
+ boyer_myrvold_impl< graph_t, vertex_index_map_t,
+ graph::detail::no_old_handles, graph::detail::no_embedding >
+ planarity_tester(g, v_i_map);
+
+ return planarity_tester.is_planar() ? true : false;
+ }
+
+ template < typename ArgumentPack >
+ bool dispatched_boyer_myrvold(
+ ArgumentPack const& args, mpl::true_, mpl::false_)
+ {
+ // Dispatch for no planar embedding, kuratowski subgraph isolation
+ typedef typename remove_const< typename parameter::value_type<
+ ArgumentPack, tag::graph >::type >::type graph_t;
+
+ typedef typename property_map< graph_t, vertex_index_t >::const_type
+ vertex_default_index_map_t;
+
+ typedef typename parameter::value_type< ArgumentPack,
+ tag::vertex_index_map, vertex_default_index_map_t >::type
+ vertex_index_map_t;
+
+ typedef typename property_map< graph_t, edge_index_t >::const_type
+ edge_default_index_map_t;
+
+ typedef typename parameter::value_type< ArgumentPack,
+ tag::edge_index_map, edge_default_index_map_t >::type
+ edge_index_map_t;
+
+ graph_t const& g = args[graph];
+ vertex_default_index_map_t v_d_map = get(vertex_index, g);
+ vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map];
+ edge_default_index_map_t e_d_map = get(edge_index, g);
+ edge_index_map_t e_i_map = args[edge_index_map | e_d_map];
+ boyer_myrvold_impl< graph_t, vertex_index_map_t,
+ graph::detail::store_old_handles, graph::detail::no_embedding >
+ planarity_tester(g, v_i_map);
+
+ if (planarity_tester.is_planar())
+ return true;
+ else
+ {
+ planarity_tester.extract_kuratowski_subgraph(
+ args[kuratowski_subgraph], e_i_map);
+ return false;
+ }
+ }
+
+ template < typename ArgumentPack >
+ bool dispatched_boyer_myrvold(
+ ArgumentPack const& args, mpl::false_, mpl::true_)
+ {
+ // Dispatch for planar embedding, no kuratowski subgraph isolation
+ typedef typename remove_const< typename parameter::value_type<
+ ArgumentPack, tag::graph >::type >::type graph_t;
+
+ typedef typename property_map< graph_t, vertex_index_t >::const_type
+ vertex_default_index_map_t;
+
+ typedef typename parameter::value_type< ArgumentPack,
+ tag::vertex_index_map, vertex_default_index_map_t >::type
+ vertex_index_map_t;
+
+ graph_t const& g = args[graph];
+ vertex_default_index_map_t v_d_map = get(vertex_index, g);
+ vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map];
+ boyer_myrvold_impl< graph_t, vertex_index_map_t,
+ graph::detail::no_old_handles,
+#ifdef BOOST_GRAPH_PREFER_STD_LIB
+ graph::detail::std_list
+#else
+ graph::detail::recursive_lazy_list
+#endif
+ >
+ planarity_tester(g, v_i_map);
+
+ if (planarity_tester.is_planar())
+ {
+ planarity_tester.make_edge_permutation(args[embedding]);
+ return true;
+ }
+ else
+ return false;
+ }
+
+ template < typename ArgumentPack >
+ bool dispatched_boyer_myrvold(
+ ArgumentPack const& args, mpl::false_, mpl::false_)
+ {
+ // Dispatch for planar embedding, kuratowski subgraph isolation
+ typedef typename remove_const< typename parameter::value_type<
+ ArgumentPack, tag::graph >::type >::type graph_t;
+
+ typedef typename property_map< graph_t, vertex_index_t >::const_type
+ vertex_default_index_map_t;
+
+ typedef typename parameter::value_type< ArgumentPack,
+ tag::vertex_index_map, vertex_default_index_map_t >::type
+ vertex_index_map_t;
+
+ typedef typename property_map< graph_t, edge_index_t >::const_type
+ edge_default_index_map_t;
+
+ typedef typename parameter::value_type< ArgumentPack,
+ tag::edge_index_map, edge_default_index_map_t >::type
+ edge_index_map_t;
+
+ graph_t const& g = args[graph];
+ vertex_default_index_map_t v_d_map = get(vertex_index, g);
+ vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map];
+ edge_default_index_map_t e_d_map = get(edge_index, g);
+ edge_index_map_t e_i_map = args[edge_index_map | e_d_map];
+ boyer_myrvold_impl< graph_t, vertex_index_map_t,
+ graph::detail::store_old_handles,
+#ifdef BOOST_BGL_PREFER_STD_LIB
+ graph::detail::std_list
+#else
+ graph::detail::recursive_lazy_list
+#endif
+ >
+ planarity_tester(g, v_i_map);
+
+ if (planarity_tester.is_planar())
+ {
+ planarity_tester.make_edge_permutation(args[embedding]);
+ return true;
+ }
+ else
+ {
+ planarity_tester.extract_kuratowski_subgraph(
+ args[kuratowski_subgraph], e_i_map);
+ return false;
+ }
+ }
+
+ template < typename ArgumentPack >
+ bool boyer_myrvold_planarity_test(ArgumentPack const& args)
+ {
+
+ typedef typename parameter::binding< ArgumentPack,
+ tag::kuratowski_subgraph,
+ const no_kuratowski_subgraph_isolation& >::type
+ kuratowski_arg_t;
+
+ typedef typename parameter::binding< ArgumentPack, tag::embedding,
+ const no_planar_embedding& >::type embedding_arg_t;
+
+ return dispatched_boyer_myrvold(args,
+ boost::is_same< embedding_arg_t, const no_planar_embedding& >(),
+ boost::is_same< kuratowski_arg_t,
+ const no_kuratowski_subgraph_isolation& >());
+ }
+
+ } // namespace core
+
+} // namespace boyer_myrvold_params
+
+template < typename A0 > bool boyer_myrvold_planarity_test(A0 const& arg0)
+{
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test(
+ boyer_myrvold_params::boyer_myrvold_params_t()(arg0));
+}
+
+template < typename A0, typename A1 >
+// bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1)
+bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1)
+{
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test(
+ boyer_myrvold_params::boyer_myrvold_params_t()(arg0, arg1));
+}
+
+template < typename A0, typename A1, typename A2 >
+bool boyer_myrvold_planarity_test(
+ A0 const& arg0, A1 const& arg1, A2 const& arg2)
+{
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test(
+ boyer_myrvold_params::boyer_myrvold_params_t()(arg0, arg1, arg2));
+}
+
+template < typename A0, typename A1, typename A2, typename A3 >
+bool boyer_myrvold_planarity_test(
+ A0 const& arg0, A1 const& arg1, A2 const& arg2, A3 const& arg3)
+{
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test(
+ boyer_myrvold_params::boyer_myrvold_params_t()(arg0, arg1, arg2, arg3));
+}
+
+template < typename A0, typename A1, typename A2, typename A3, typename A4 >
+bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1,
+ A2 const& arg2, A3 const& arg3, A4 const& arg4)
+{
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test(
+ boyer_myrvold_params::boyer_myrvold_params_t()(
+ arg0, arg1, arg2, arg3, arg4));
+}
+
+}
+
+#endif //__BOYER_MYRVOLD_PLANAR_TEST_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/bron_kerbosch_all_cliques.hpp b/contrib/restricted/boost/graph/include/boost/graph/bron_kerbosch_all_cliques.hpp
new file mode 100644
index 0000000000..e0f862e837
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/bron_kerbosch_all_cliques.hpp
@@ -0,0 +1,312 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_CLIQUE_HPP
+#define BOOST_GRAPH_CLIQUE_HPP
+
+#include <vector>
+#include <deque>
+#include <boost/config.hpp>
+
+#include <boost/concept/assert.hpp>
+
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/lookup_edge.hpp>
+
+#include <boost/concept/detail/concept_def.hpp>
+namespace boost
+{
+namespace concepts
+{
+ BOOST_concept(CliqueVisitor, (Visitor)(Clique)(Graph))
+ {
+ BOOST_CONCEPT_USAGE(CliqueVisitor) { vis.clique(k, g); }
+
+ private:
+ Visitor vis;
+ Graph g;
+ Clique k;
+ };
+} /* namespace concepts */
+using concepts::CliqueVisitorConcept;
+} /* namespace boost */
+#include <boost/concept/detail/concept_undef.hpp>
+
+namespace boost
+{
+// The algorithm implemented in this paper is based on the so-called
+// Algorithm 457, published as:
+//
+// @article{362367,
+// author = {Coen Bron and Joep Kerbosch},
+// title = {Algorithm 457: finding all cliques of an undirected graph},
+// journal = {Communications of the ACM},
+// volume = {16},
+// number = {9},
+// year = {1973},
+// issn = {0001-0782},
+// pages = {575--577},
+// doi = {http://doi.acm.org/10.1145/362342.362367},
+// publisher = {ACM Press},
+// address = {New York, NY, USA},
+// }
+//
+// Sort of. This implementation is adapted from the 1st version of the
+// algorithm and does not implement the candidate selection optimization
+// described as published - it could, it just doesn't yet.
+//
+// The algorithm is given as proportional to (3.14)^(n/3) power. This is
+// not the same as O(...), but based on time measures and approximation.
+//
+// Unfortunately, this implementation may be less efficient on non-
+// AdjacencyMatrix modeled graphs due to the non-constant implementation
+// of the edge(u,v,g) functions.
+//
+// TODO: It might be worthwhile to provide functionality for passing
+// a connectivity matrix to improve the efficiency of those lookups
+// when needed. This could simply be passed as a BooleanMatrix
+// s.t. edge(u,v,B) returns true or false. This could easily be
+// abstracted for adjacency matricies.
+//
+// The following paper is interesting for a number of reasons. First,
+// it lists a number of other such algorithms and second, it describes
+// a new algorithm (that does not appear to require the edge(u,v,g)
+// function and appears fairly efficient. It is probably worth investigating.
+//
+// @article{DBLP:journals/tcs/TomitaTT06,
+// author = {Etsuji Tomita and Akira Tanaka and Haruhisa Takahashi},
+// title = {The worst-case time complexity for generating all maximal
+// cliques and computational experiments}, journal = {Theor. Comput.
+// Sci.}, volume = {363}, number = {1}, year = {2006}, pages = {28-42}
+// ee = {https://doi.org/10.1016/j.tcs.2006.06.015}
+// }
+
+/**
+ * The default clique_visitor supplies an empty visitation function.
+ */
+struct clique_visitor
+{
+ template < typename VertexSet, typename Graph >
+ void clique(const VertexSet&, Graph&)
+ {
+ }
+};
+
+/**
+ * The max_clique_visitor records the size of the maximum clique (but not the
+ * clique itself).
+ */
+struct max_clique_visitor
+{
+ max_clique_visitor(std::size_t& max) : maximum(max) {}
+
+ template < typename Clique, typename Graph >
+ inline void clique(const Clique& p, const Graph& g)
+ {
+ BOOST_USING_STD_MAX();
+ maximum = max BOOST_PREVENT_MACRO_SUBSTITUTION(maximum, p.size());
+ }
+ std::size_t& maximum;
+};
+
+inline max_clique_visitor find_max_clique(std::size_t& max)
+{
+ return max_clique_visitor(max);
+}
+
+namespace detail
+{
+ template < typename Graph >
+ inline bool is_connected_to_clique(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor u,
+ typename graph_traits< Graph >::vertex_descriptor v,
+ typename graph_traits< Graph >::undirected_category)
+ {
+ return lookup_edge(u, v, g).second;
+ }
+
+ template < typename Graph >
+ inline bool is_connected_to_clique(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor u,
+ typename graph_traits< Graph >::vertex_descriptor v,
+ typename graph_traits< Graph >::directed_category)
+ {
+ // Note that this could alternate between using an || to determine
+ // full connectivity. I believe that this should produce strongly
+ // connected components. Note that using && instead of || will
+ // change the results to a fully connected subgraph (i.e., symmetric
+ // edges between all vertices s.t., if a->b, then b->a.
+ return lookup_edge(u, v, g).second && lookup_edge(v, u, g).second;
+ }
+
+ template < typename Graph, typename Container >
+ inline void filter_unconnected_vertices(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor v,
+ const Container& in, Container& out)
+ {
+ BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+
+ typename graph_traits< Graph >::directed_category cat;
+ typename Container::const_iterator i, end = in.end();
+ for (i = in.begin(); i != end; ++i)
+ {
+ if (is_connected_to_clique(g, v, *i, cat))
+ {
+ out.push_back(*i);
+ }
+ }
+ }
+
+ template < typename Graph,
+ typename Clique, // compsub type
+ typename Container, // candidates/not type
+ typename Visitor >
+ void extend_clique(const Graph& g, Clique& clique, Container& cands,
+ Container& nots, Visitor vis, std::size_t min)
+ {
+ BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((CliqueVisitorConcept< Visitor, Clique, Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+
+ // Is there vertex in nots that is connected to all vertices
+ // in the candidate set? If so, no clique can ever be found.
+ // This could be broken out into a separate function.
+ {
+ typename Container::iterator ni, nend = nots.end();
+ typename Container::iterator ci, cend = cands.end();
+ for (ni = nots.begin(); ni != nend; ++ni)
+ {
+ for (ci = cands.begin(); ci != cend; ++ci)
+ {
+ // if we don't find an edge, then we're okay.
+ if (!lookup_edge(*ni, *ci, g).second)
+ break;
+ }
+ // if we iterated all the way to the end, then *ni
+ // is connected to all *ci
+ if (ci == cend)
+ break;
+ }
+ // if we broke early, we found *ni connected to all *ci
+ if (ni != nend)
+ return;
+ }
+
+ // TODO: the original algorithm 457 describes an alternative
+ // (albeit really complicated) mechanism for selecting candidates.
+ // The given optimizaiton seeks to bring about the above
+ // condition sooner (i.e., there is a vertex in the not set
+ // that is connected to all candidates). unfortunately, the
+ // method they give for doing this is fairly unclear.
+
+ // basically, for every vertex in not, we should know how many
+ // vertices it is disconnected from in the candidate set. if
+ // we fix some vertex in the not set, then we want to keep
+ // choosing vertices that are not connected to that fixed vertex.
+ // apparently, by selecting fix point with the minimum number
+ // of disconnections (i.e., the maximum number of connections
+ // within the candidate set), then the previous condition wil
+ // be reached sooner.
+
+ // there's some other stuff about using the number of disconnects
+ // as a counter, but i'm jot really sure i followed it.
+
+ // TODO: If we min-sized cliques to visit, then theoretically, we
+ // should be able to stop recursing if the clique falls below that
+ // size - maybe?
+
+ // otherwise, iterate over candidates and and test
+ // for maxmimal cliquiness.
+ typename Container::iterator i, j;
+ for (i = cands.begin(); i != cands.end();)
+ {
+ Vertex candidate = *i;
+
+ // add the candidate to the clique (keeping the iterator!)
+ // typename Clique::iterator ci = clique.insert(clique.end(),
+ // candidate);
+ clique.push_back(candidate);
+
+ // remove it from the candidate set
+ i = cands.erase(i);
+
+ // build new candidate and not sets by removing all vertices
+ // that are not connected to the current candidate vertex.
+ // these actually invert the operation, adding them to the new
+ // sets if the vertices are connected. its semantically the same.
+ Container new_cands, new_nots;
+ filter_unconnected_vertices(g, candidate, cands, new_cands);
+ filter_unconnected_vertices(g, candidate, nots, new_nots);
+
+ if (new_cands.empty() && new_nots.empty())
+ {
+ // our current clique is maximal since there's nothing
+ // that's connected that we haven't already visited. If
+ // the clique is below our radar, then we won't visit it.
+ if (clique.size() >= min)
+ {
+ vis.clique(clique, g);
+ }
+ }
+ else
+ {
+ // recurse to explore the new candidates
+ extend_clique(g, clique, new_cands, new_nots, vis, min);
+ }
+
+ // we're done with this vertex, so we need to move it
+ // to the nots, and remove the candidate from the clique.
+ nots.push_back(candidate);
+ clique.pop_back();
+ }
+ }
+} /* namespace detail */
+
+template < typename Graph, typename Visitor >
+inline void bron_kerbosch_all_cliques(
+ const Graph& g, Visitor vis, std::size_t min)
+{
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT(
+ (AdjacencyMatrixConcept< Graph >)); // Structural requirement only
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+ typedef std::vector< Vertex > VertexSet;
+ typedef std::deque< Vertex > Clique;
+ BOOST_CONCEPT_ASSERT((CliqueVisitorConcept< Visitor, Clique, Graph >));
+
+ // NOTE: We're using a deque to implement the clique, because it provides
+ // constant inserts and removals at the end and also a constant size.
+
+ VertexIterator i, end;
+ boost::tie(i, end) = vertices(g);
+ VertexSet cands(i, end); // start with all vertices as candidates
+ VertexSet nots; // start with no vertices visited
+
+ Clique clique; // the first clique is an empty vertex set
+ detail::extend_clique(g, clique, cands, nots, vis, min);
+}
+
+// NOTE: By default the minimum number of vertices per clique is set at 2
+// because singleton cliques aren't really very interesting.
+template < typename Graph, typename Visitor >
+inline void bron_kerbosch_all_cliques(const Graph& g, Visitor vis)
+{
+ bron_kerbosch_all_cliques(g, vis, 2);
+}
+
+template < typename Graph >
+inline std::size_t bron_kerbosch_clique_number(const Graph& g)
+{
+ std::size_t ret = 0;
+ bron_kerbosch_all_cliques(g, find_max_clique(ret));
+ return ret;
+}
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/chrobak_payne_drawing.hpp b/contrib/restricted/boost/graph/include/boost/graph/chrobak_payne_drawing.hpp
new file mode 100644
index 0000000000..68106267ce
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/chrobak_payne_drawing.hpp
@@ -0,0 +1,251 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef __CHROBAK_PAYNE_DRAWING_HPP__
+#define __CHROBAK_PAYNE_DRAWING_HPP__
+
+#include <vector>
+#include <list>
+#include <stack>
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+
+namespace graph
+{
+ namespace detail
+ {
+
+ template < typename Graph, typename VertexToVertexMap,
+ typename VertexTo1DCoordMap >
+ void accumulate_offsets(
+ typename graph_traits< Graph >::vertex_descriptor v,
+ std::size_t offset, const Graph& g, VertexTo1DCoordMap x,
+ VertexTo1DCoordMap delta_x, VertexToVertexMap left,
+ VertexToVertexMap right)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+ // Suggestion of explicit stack from Aaron Windsor to avoid system
+ // stack overflows.
+ typedef std::pair< vertex_descriptor, std::size_t > stack_entry;
+ std::stack< stack_entry > st;
+ st.push(stack_entry(v, offset));
+ while (!st.empty())
+ {
+ vertex_descriptor v = st.top().first;
+ std::size_t offset = st.top().second;
+ st.pop();
+ if (v != graph_traits< Graph >::null_vertex())
+ {
+ x[v] += delta_x[v] + offset;
+ st.push(stack_entry(left[v], x[v]));
+ st.push(stack_entry(right[v], x[v]));
+ }
+ }
+ }
+
+ } /*namespace detail*/
+} /*namespace graph*/
+
+template < typename Graph, typename PlanarEmbedding, typename ForwardIterator,
+ typename GridPositionMap, typename VertexIndexMap >
+void chrobak_payne_straight_line_drawing(const Graph& g,
+ PlanarEmbedding embedding, ForwardIterator ordering_begin,
+ ForwardIterator ordering_end, GridPositionMap drawing, VertexIndexMap vm)
+{
+
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename PlanarEmbedding::value_type::const_iterator
+ edge_permutation_iterator_t;
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+ typedef std::vector< vertex_t > vertex_vector_t;
+ typedef std::vector< v_size_t > vsize_vector_t;
+ typedef std::vector< bool > bool_vector_t;
+ typedef boost::iterator_property_map< typename vertex_vector_t::iterator,
+ VertexIndexMap >
+ vertex_to_vertex_map_t;
+ typedef boost::iterator_property_map< typename vsize_vector_t::iterator,
+ VertexIndexMap >
+ vertex_to_vsize_map_t;
+ typedef boost::iterator_property_map< typename bool_vector_t::iterator,
+ VertexIndexMap >
+ vertex_to_bool_map_t;
+
+ vertex_vector_t left_vector(
+ num_vertices(g), graph_traits< Graph >::null_vertex());
+ vertex_vector_t right_vector(
+ num_vertices(g), graph_traits< Graph >::null_vertex());
+ vsize_vector_t seen_as_right_vector(num_vertices(g), 0);
+ vsize_vector_t seen_vector(num_vertices(g), 0);
+ vsize_vector_t delta_x_vector(num_vertices(g), 0);
+ vsize_vector_t y_vector(num_vertices(g));
+ vsize_vector_t x_vector(num_vertices(g), 0);
+ bool_vector_t installed_vector(num_vertices(g), false);
+
+ vertex_to_vertex_map_t left(left_vector.begin(), vm);
+ vertex_to_vertex_map_t right(right_vector.begin(), vm);
+ vertex_to_vsize_map_t seen_as_right(seen_as_right_vector.begin(), vm);
+ vertex_to_vsize_map_t seen(seen_vector.begin(), vm);
+ vertex_to_vsize_map_t delta_x(delta_x_vector.begin(), vm);
+ vertex_to_vsize_map_t y(y_vector.begin(), vm);
+ vertex_to_vsize_map_t x(x_vector.begin(), vm);
+ vertex_to_bool_map_t installed(installed_vector.begin(), vm);
+
+ v_size_t timestamp = 1;
+ vertex_vector_t installed_neighbors;
+
+ ForwardIterator itr = ordering_begin;
+ vertex_t v1 = *itr;
+ ++itr;
+ vertex_t v2 = *itr;
+ ++itr;
+ vertex_t v3 = *itr;
+ ++itr;
+
+ delta_x[v2] = 1;
+ delta_x[v3] = 1;
+
+ y[v1] = 0;
+ y[v2] = 0;
+ y[v3] = 1;
+
+ right[v1] = v3;
+ right[v3] = v2;
+
+ installed[v1] = installed[v2] = installed[v3] = true;
+
+ for (ForwardIterator itr_end = ordering_end; itr != itr_end; ++itr)
+ {
+ vertex_t v = *itr;
+
+ // First, find the leftmost and rightmost neighbor of v on the outer
+ // cycle of the embedding.
+ // Note: since we're moving clockwise through the edges adjacent to v,
+ // we're actually moving from right to left among v's neighbors on the
+ // outer face (since v will be installed above them all) looking for
+ // the leftmost and rightmost installed neigbhors
+
+ vertex_t leftmost = graph_traits< Graph >::null_vertex();
+ vertex_t rightmost = graph_traits< Graph >::null_vertex();
+
+ installed_neighbors.clear();
+
+ vertex_t prev_vertex = graph_traits< Graph >::null_vertex();
+ edge_permutation_iterator_t pi, pi_end;
+ pi_end = embedding[v].end();
+ for (pi = embedding[v].begin(); pi != pi_end; ++pi)
+ {
+ vertex_t curr_vertex
+ = source(*pi, g) == v ? target(*pi, g) : source(*pi, g);
+
+ // Skip any self-loops or parallel edges
+ if (curr_vertex == v || curr_vertex == prev_vertex)
+ continue;
+
+ if (installed[curr_vertex])
+ {
+ seen[curr_vertex] = timestamp;
+
+ if (right[curr_vertex] != graph_traits< Graph >::null_vertex())
+ {
+ seen_as_right[right[curr_vertex]] = timestamp;
+ }
+ installed_neighbors.push_back(curr_vertex);
+ }
+
+ prev_vertex = curr_vertex;
+ }
+
+ typename vertex_vector_t::iterator vi, vi_end;
+ vi_end = installed_neighbors.end();
+ for (vi = installed_neighbors.begin(); vi != vi_end; ++vi)
+ {
+ if (right[*vi] == graph_traits< Graph >::null_vertex()
+ || seen[right[*vi]] != timestamp)
+ rightmost = *vi;
+ if (seen_as_right[*vi] != timestamp)
+ leftmost = *vi;
+ }
+
+ ++timestamp;
+
+ // stretch gaps
+ ++delta_x[right[leftmost]];
+ ++delta_x[rightmost];
+
+ // adjust offsets
+ std::size_t delta_p_q = 0;
+ vertex_t stopping_vertex = right[rightmost];
+ for (vertex_t temp = right[leftmost]; temp != stopping_vertex;
+ temp = right[temp])
+ {
+ delta_p_q += delta_x[temp];
+ }
+
+ delta_x[v] = ((y[rightmost] + delta_p_q) - y[leftmost]) / 2;
+ y[v] = y[leftmost] + delta_x[v];
+ delta_x[rightmost] = delta_p_q - delta_x[v];
+
+ bool leftmost_and_rightmost_adjacent = right[leftmost] == rightmost;
+ if (!leftmost_and_rightmost_adjacent)
+ delta_x[right[leftmost]] -= delta_x[v];
+
+ // install v
+ if (!leftmost_and_rightmost_adjacent)
+ {
+ left[v] = right[leftmost];
+ vertex_t next_to_rightmost;
+ for (vertex_t temp = leftmost; temp != rightmost;
+ temp = right[temp])
+ {
+ next_to_rightmost = temp;
+ }
+
+ right[next_to_rightmost] = graph_traits< Graph >::null_vertex();
+ }
+ else
+ {
+ left[v] = graph_traits< Graph >::null_vertex();
+ }
+
+ right[leftmost] = v;
+ right[v] = rightmost;
+ installed[v] = true;
+ }
+
+ graph::detail::accumulate_offsets(
+ *ordering_begin, 0, g, x, delta_x, left, right);
+
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+ drawing[v].x = x[v];
+ drawing[v].y = y[v];
+ }
+}
+
+template < typename Graph, typename PlanarEmbedding, typename ForwardIterator,
+ typename GridPositionMap >
+inline void chrobak_payne_straight_line_drawing(const Graph& g,
+ PlanarEmbedding embedding, ForwardIterator ord_begin,
+ ForwardIterator ord_end, GridPositionMap drawing)
+{
+ chrobak_payne_straight_line_drawing(
+ g, embedding, ord_begin, ord_end, drawing, get(vertex_index, g));
+}
+
+} // namespace boost
+
+#endif //__CHROBAK_PAYNE_DRAWING_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/circle_layout.hpp b/contrib/restricted/boost/graph/include/boost/graph/circle_layout.hpp
new file mode 100644
index 0000000000..f295bd20b5
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/circle_layout.hpp
@@ -0,0 +1,61 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_CIRCLE_LAYOUT_HPP
+#define BOOST_GRAPH_CIRCLE_LAYOUT_HPP
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <utility>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/topology.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost
+{
+/**
+ * \brief Layout the graph with the vertices at the points of a regular
+ * n-polygon.
+ *
+ * The distance from the center of the polygon to each point is
+ * determined by the @p radius parameter. The @p position parameter
+ * must be an Lvalue Property Map whose value type is a class type
+ * containing @c x and @c y members that will be set to the @c x and
+ * @c y coordinates.
+ */
+template < typename VertexListGraph, typename PositionMap, typename Radius >
+void circle_graph_layout(
+ const VertexListGraph& g, PositionMap position, Radius radius)
+{
+ BOOST_STATIC_ASSERT(
+ property_traits< PositionMap >::value_type::dimensions >= 2);
+ const double pi = boost::math::constants::pi< double >();
+
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::cos;
+ using std::sin;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ typedef typename graph_traits< VertexListGraph >::vertices_size_type
+ vertices_size_type;
+
+ vertices_size_type n = num_vertices(g);
+
+ vertices_size_type i = 0;
+ double two_pi_over_n = 2. * pi / n;
+ BGL_FORALL_VERTICES_T(v, g, VertexListGraph)
+ {
+ position[v][0] = radius * cos(i * two_pi_over_n);
+ position[v][1] = radius * sin(i * two_pi_over_n);
+ ++i;
+ }
+}
+} // end namespace boost
+
+#endif // BOOST_GRAPH_CIRCLE_LAYOUT_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/closeness_centrality.hpp b/contrib/restricted/boost/graph/include/boost/graph/closeness_centrality.hpp
new file mode 100644
index 0000000000..d28123cad5
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/closeness_centrality.hpp
@@ -0,0 +1,151 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_CLOSENESS_CENTRALITY_HPP
+#define BOOST_GRAPH_CLOSENESS_CENTRALITY_HPP
+
+#include <boost/graph/detail/geodesic.hpp>
+#include <boost/graph/exterior_property.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+template < typename Graph, typename DistanceType, typename ResultType,
+ typename Reciprocal = detail::reciprocal< ResultType > >
+struct closeness_measure
+: public geodesic_measure< Graph, DistanceType, ResultType >
+{
+ typedef geodesic_measure< Graph, DistanceType, ResultType > base_type;
+ typedef typename base_type::distance_type distance_type;
+ typedef typename base_type::result_type result_type;
+
+ result_type operator()(distance_type d, const Graph&)
+ {
+ BOOST_CONCEPT_ASSERT((NumericValueConcept< DistanceType >));
+ BOOST_CONCEPT_ASSERT((NumericValueConcept< ResultType >));
+ BOOST_CONCEPT_ASSERT((AdaptableUnaryFunctionConcept< Reciprocal,
+ ResultType, ResultType >));
+ return (d == base_type::infinite_distance()) ? base_type::zero_result()
+ : rec(result_type(d));
+ }
+ Reciprocal rec;
+};
+
+template < typename Graph, typename DistanceMap >
+inline closeness_measure< Graph,
+ typename property_traits< DistanceMap >::value_type, double,
+ detail::reciprocal< double > >
+measure_closeness(const Graph&, DistanceMap)
+{
+ typedef typename property_traits< DistanceMap >::value_type Distance;
+ return closeness_measure< Graph, Distance, double,
+ detail::reciprocal< double > >();
+}
+
+template < typename T, typename Graph, typename DistanceMap >
+inline closeness_measure< Graph,
+ typename property_traits< DistanceMap >::value_type, T,
+ detail::reciprocal< T > >
+measure_closeness(const Graph&, DistanceMap)
+{
+ typedef typename property_traits< DistanceMap >::value_type Distance;
+ return closeness_measure< Graph, Distance, T, detail::reciprocal< T > >();
+}
+
+template < typename T, typename Graph, typename DistanceMap,
+ typename Reciprocal >
+inline closeness_measure< Graph,
+ typename property_traits< DistanceMap >::value_type, T, Reciprocal >
+measure_closeness(const Graph&, DistanceMap)
+{
+ typedef typename property_traits< DistanceMap >::value_type Distance;
+ return closeness_measure< Graph, Distance, T, Reciprocal >();
+}
+
+template < typename Graph, typename DistanceMap, typename Measure,
+ typename Combinator >
+inline typename Measure::result_type closeness_centrality(
+ const Graph& g, DistanceMap dist, Measure measure, Combinator combine)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >));
+ typedef typename property_traits< DistanceMap >::value_type Distance;
+ BOOST_CONCEPT_ASSERT((NumericValueConcept< Distance >));
+ BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >));
+
+ Distance n = detail::combine_distances(g, dist, combine, Distance(0));
+ return measure(n, g);
+}
+
+template < typename Graph, typename DistanceMap, typename Measure >
+inline typename Measure::result_type closeness_centrality(
+ const Graph& g, DistanceMap dist, Measure measure)
+{
+ BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >));
+ typedef typename property_traits< DistanceMap >::value_type Distance;
+
+ return closeness_centrality(g, dist, measure, std::plus< Distance >());
+}
+
+template < typename Graph, typename DistanceMap >
+inline double closeness_centrality(const Graph& g, DistanceMap dist)
+{
+ return closeness_centrality(g, dist, measure_closeness(g, dist));
+}
+
+template < typename T, typename Graph, typename DistanceMap >
+inline T closeness_centrality(const Graph& g, DistanceMap dist)
+{
+ return closeness_centrality(g, dist, measure_closeness< T >(g, dist));
+}
+
+template < typename Graph, typename DistanceMatrixMap, typename CentralityMap,
+ typename Measure >
+inline void all_closeness_centralities(
+ const Graph& g, DistanceMatrixMap dist, CentralityMap cent, Measure measure)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< DistanceMatrixMap, Vertex >));
+ typedef
+ typename property_traits< DistanceMatrixMap >::value_type DistanceMap;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >));
+ BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< CentralityMap, Vertex >));
+ typedef typename property_traits< CentralityMap >::value_type Centrality;
+
+ typename graph_traits< Graph >::vertex_iterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ {
+ DistanceMap dm = get(dist, *i);
+ Centrality c = closeness_centrality(g, dm, measure);
+ put(cent, *i, c);
+ }
+}
+
+template < typename Graph, typename DistanceMatrixMap, typename CentralityMap >
+inline void all_closeness_centralities(
+ const Graph& g, DistanceMatrixMap dist, CentralityMap cent)
+{
+ BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< DistanceMatrixMap, Vertex >));
+ typedef
+ typename property_traits< DistanceMatrixMap >::value_type DistanceMap;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >));
+ typedef typename property_traits< CentralityMap >::value_type Result;
+
+ all_closeness_centralities(
+ g, dist, cent, measure_closeness< Result >(g, DistanceMap()));
+}
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/clustering_coefficient.hpp b/contrib/restricted/boost/graph/include/boost/graph/clustering_coefficient.hpp
new file mode 100644
index 0000000000..e275dd7e32
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/clustering_coefficient.hpp
@@ -0,0 +1,160 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_CLUSTERING_COEFFICIENT_HPP
+#define BOOST_GRAPH_CLUSTERING_COEFFICIENT_HPP
+
+#include <boost/next_prior.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/lookup_edge.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+namespace detail
+{
+ template < class Graph >
+ inline typename graph_traits< Graph >::degree_size_type possible_edges(
+ const Graph& g, std::size_t k, directed_tag)
+ {
+ BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::degree_size_type T;
+ return T(k) * (T(k) - 1);
+ }
+
+ template < class Graph >
+ inline typename graph_traits< Graph >::degree_size_type possible_edges(
+ const Graph& g, size_t k, undirected_tag)
+ {
+ // dirty little trick...
+ return possible_edges(g, k, directed_tag()) / 2;
+ }
+
+ // This template matches directedS and bidirectionalS.
+ template < class Graph >
+ inline typename graph_traits< Graph >::degree_size_type count_edges(
+ const Graph& g, typename graph_traits< Graph >::vertex_descriptor u,
+ typename graph_traits< Graph >::vertex_descriptor v, directed_tag)
+
+ {
+ BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >));
+ return (lookup_edge(u, v, g).second ? 1 : 0)
+ + (lookup_edge(v, u, g).second ? 1 : 0);
+ }
+
+ // This template matches undirectedS
+ template < class Graph >
+ inline typename graph_traits< Graph >::degree_size_type count_edges(
+ const Graph& g, typename graph_traits< Graph >::vertex_descriptor u,
+ typename graph_traits< Graph >::vertex_descriptor v, undirected_tag)
+ {
+ BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph >));
+ return lookup_edge(u, v, g).second ? 1 : 0;
+ }
+}
+
+template < typename Graph, typename Vertex >
+inline typename graph_traits< Graph >::degree_size_type
+num_paths_through_vertex(const Graph& g, Vertex v)
+{
+ BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::directed_category Directed;
+ typedef
+ typename graph_traits< Graph >::adjacency_iterator AdjacencyIterator;
+
+ // TODO: There should actually be a set of neighborhood functions
+ // for things like this (num_neighbors() would be great).
+
+ AdjacencyIterator i, end;
+ boost::tie(i, end) = adjacent_vertices(v, g);
+ std::size_t k = std::distance(i, end);
+ return detail::possible_edges(g, k, Directed());
+}
+
+template < typename Graph, typename Vertex >
+inline typename graph_traits< Graph >::degree_size_type num_triangles_on_vertex(
+ const Graph& g, Vertex v)
+{
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::degree_size_type Degree;
+ typedef typename graph_traits< Graph >::directed_category Directed;
+ typedef
+ typename graph_traits< Graph >::adjacency_iterator AdjacencyIterator;
+
+ // TODO: I might be able to reduce the requirement from adjacency graph
+ // to incidence graph by using out edges.
+
+ Degree count(0);
+ AdjacencyIterator i, j, end;
+ for (boost::tie(i, end) = adjacent_vertices(v, g); i != end; ++i)
+ {
+ for (j = boost::next(i); j != end; ++j)
+ {
+ count += detail::count_edges(g, *i, *j, Directed());
+ }
+ }
+ return count;
+} /* namespace detail */
+
+template < typename T, typename Graph, typename Vertex >
+inline T clustering_coefficient(const Graph& g, Vertex v)
+{
+ T zero(0);
+ T routes = T(num_paths_through_vertex(g, v));
+ return (routes > zero) ? T(num_triangles_on_vertex(g, v)) / routes : zero;
+}
+
+template < typename Graph, typename Vertex >
+inline double clustering_coefficient(const Graph& g, Vertex v)
+{
+ return clustering_coefficient< double >(g, v);
+}
+
+template < typename Graph, typename ClusteringMap >
+inline typename property_traits< ClusteringMap >::value_type
+all_clustering_coefficients(const Graph& g, ClusteringMap cm)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+ BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< ClusteringMap, Vertex >));
+ typedef typename property_traits< ClusteringMap >::value_type Coefficient;
+
+ Coefficient sum(0);
+ VertexIterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ {
+ Coefficient cc = clustering_coefficient< Coefficient >(g, *i);
+ put(cm, *i, cc);
+ sum += cc;
+ }
+ return sum / Coefficient(num_vertices(g));
+}
+
+template < typename Graph, typename ClusteringMap >
+inline typename property_traits< ClusteringMap >::value_type
+mean_clustering_coefficient(const Graph& g, ClusteringMap cm)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< ClusteringMap, Vertex >));
+ typedef typename property_traits< ClusteringMap >::value_type Coefficient;
+
+ Coefficient cc(0);
+ VertexIterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ {
+ cc += get(cm, *i);
+ }
+ return cc / Coefficient(num_vertices(g));
+}
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/core_numbers.hpp b/contrib/restricted/boost/graph/include/boost/graph/core_numbers.hpp
new file mode 100644
index 0000000000..95053caf1f
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/core_numbers.hpp
@@ -0,0 +1,375 @@
+//
+//=======================================================================
+// Copyright 2007 Stanford University
+// Authors: David Gleich
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_CORE_NUMBERS_HPP
+#define BOOST_GRAPH_CORE_NUMBERS_HPP
+
+#include <boost/graph/detail/d_ary_heap.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+#include <boost/concept/assert.hpp>
+
+/*
+ * core_numbers
+ *
+ * Requirement: IncidenceGraph
+ */
+
+// History
+//
+// 30 July 2007
+// Added visitors to the implementation
+//
+// 8 February 2008
+// Fixed headers and missing typename
+
+namespace boost
+{
+
+// A linear time O(m) algorithm to compute the indegree core number
+// of a graph for unweighted graphs.
+//
+// and a O((n+m) log n) algorithm to compute the in-edge-weight core
+// numbers of a weighted graph.
+//
+// The linear algorithm comes from:
+// Vladimir Batagelj and Matjaz Zaversnik, "An O(m) Algorithm for Cores
+// Decomposition of Networks." Sept. 1 2002.
+
+template < typename Visitor, typename Graph > struct CoreNumbersVisitorConcept
+{
+ void constraints()
+ {
+ BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >));
+ vis.examine_vertex(u, g);
+ vis.finish_vertex(u, g);
+ vis.examine_edge(e, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename graph_traits< Graph >::vertex_descriptor u;
+ typename graph_traits< Graph >::edge_descriptor e;
+};
+
+template < class Visitors = null_visitor >
+class core_numbers_visitor : public bfs_visitor< Visitors >
+{
+public:
+ core_numbers_visitor() {}
+ core_numbers_visitor(Visitors vis) : bfs_visitor< Visitors >(vis) {}
+
+private:
+ template < class Vertex, class Graph >
+ void initialize_vertex(Vertex, Graph&)
+ {
+ }
+
+ template < class Vertex, class Graph > void discover_vertex(Vertex, Graph&)
+ {
+ }
+
+ template < class Vertex, class Graph > void gray_target(Vertex, Graph&) {}
+
+ template < class Vertex, class Graph > void black_target(Vertex, Graph&) {}
+
+ template < class Edge, class Graph > void tree_edge(Edge, Graph&) {}
+
+ template < class Edge, class Graph > void non_tree_edge(Edge, Graph&) {}
+};
+
+template < class Visitors >
+core_numbers_visitor< Visitors > make_core_numbers_visitor(Visitors vis)
+{
+ return core_numbers_visitor< Visitors >(vis);
+}
+
+typedef core_numbers_visitor<> default_core_numbers_visitor;
+
+namespace detail
+{
+
+ // implement a constant_property_map to simplify compute_in_degree
+ // for the weighted and unweighted case
+ // this is based on dummy property map
+ template < typename ValueType >
+ class constant_value_property_map
+ : public boost::put_get_helper< ValueType,
+ constant_value_property_map< ValueType > >
+ {
+ public:
+ typedef void key_type;
+ typedef ValueType value_type;
+ typedef const ValueType& reference;
+ typedef boost::readable_property_map_tag category;
+ inline constant_value_property_map(ValueType cc) : c(cc) {}
+ inline constant_value_property_map(
+ const constant_value_property_map< ValueType >& x)
+ : c(x.c)
+ {
+ }
+ template < class Vertex > inline reference operator[](Vertex) const
+ {
+ return c;
+ }
+
+ protected:
+ ValueType c;
+ };
+
+ // the core numbers start as the indegree or inweight. This function
+ // will initialize these values
+ template < typename Graph, typename CoreMap, typename EdgeWeightMap >
+ void compute_in_degree_map(Graph& g, CoreMap d, EdgeWeightMap wm)
+ {
+ typename graph_traits< Graph >::vertex_iterator vi, vi_end;
+ typename graph_traits< Graph >::out_edge_iterator ei, ei_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ put(d, *vi, 0);
+ }
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ for (boost::tie(ei, ei_end) = out_edges(*vi, g); ei != ei_end; ++ei)
+ {
+ put(d, target(*ei, g), get(d, target(*ei, g)) + get(wm, *ei));
+ }
+ }
+ }
+
+ // the version for weighted graphs is a little different
+ template < typename Graph, typename CoreMap, typename EdgeWeightMap,
+ typename MutableQueue, typename Visitor >
+ typename property_traits< CoreMap >::value_type core_numbers_impl(
+ Graph& g, CoreMap c, EdgeWeightMap wm, MutableQueue& Q, Visitor vis)
+ {
+ typename property_traits< CoreMap >::value_type v_cn = 0;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex;
+ while (!Q.empty())
+ {
+ // remove v from the Q, and then decrease the core numbers
+ // of its successors
+ vertex v = Q.top();
+ vis.examine_vertex(v, g);
+ Q.pop();
+ v_cn = get(c, v);
+ typename graph_traits< Graph >::out_edge_iterator oi, oi_end;
+ for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi)
+ {
+ vis.examine_edge(*oi, g);
+ vertex u = target(*oi, g);
+ // if c[u] > c[v], then u is still in the graph,
+ if (get(c, u) > v_cn)
+ {
+ // remove the edge
+ put(c, u, get(c, u) - get(wm, *oi));
+ if (Q.contains(u))
+ Q.update(u);
+ }
+ }
+ vis.finish_vertex(v, g);
+ }
+ return (v_cn);
+ }
+
+ template < typename Graph, typename CoreMap, typename EdgeWeightMap,
+ typename IndexMap, typename CoreNumVisitor >
+ typename property_traits< CoreMap >::value_type core_numbers_dispatch(
+ Graph& g, CoreMap c, EdgeWeightMap wm, IndexMap im, CoreNumVisitor vis)
+ {
+ typedef typename property_traits< CoreMap >::value_type D;
+ typedef std::less< D > Cmp;
+ // build the mutable queue
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex;
+ std::vector< std::size_t > index_in_heap_data(num_vertices(g));
+ typedef iterator_property_map< std::vector< std::size_t >::iterator,
+ IndexMap >
+ index_in_heap_map_type;
+ index_in_heap_map_type index_in_heap_map(
+ index_in_heap_data.begin(), im);
+ typedef d_ary_heap_indirect< vertex, 4, index_in_heap_map_type, CoreMap,
+ Cmp >
+ MutableQueue;
+ MutableQueue Q(c, index_in_heap_map, Cmp());
+ typename graph_traits< Graph >::vertex_iterator vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ Q.push(*vi);
+ }
+ return core_numbers_impl(g, c, wm, Q, vis);
+ }
+
+ // the version for the unweighted case
+ // for this functions CoreMap must be initialized
+ // with the in degree of each vertex
+ template < typename Graph, typename CoreMap, typename PositionMap,
+ typename Visitor >
+ typename property_traits< CoreMap >::value_type core_numbers_impl(
+ Graph& g, CoreMap c, PositionMap pos, Visitor vis)
+ {
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+ typedef typename graph_traits< Graph >::degree_size_type degree_type;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex;
+ typename graph_traits< Graph >::vertex_iterator vi, vi_end;
+
+ // store the vertex core numbers
+ typename property_traits< CoreMap >::value_type v_cn = 0;
+
+ // compute the maximum degree (degrees are in the coremap)
+ typename graph_traits< Graph >::degree_size_type max_deg = 0;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ max_deg = (std::max<
+ typename graph_traits< Graph >::degree_size_type >)(max_deg,
+ get(c, *vi));
+ }
+
+ // store the vertices in bins by their degree
+ // allocate two extra locations to ease boundary cases
+ std::vector< size_type > bin(max_deg + 2);
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ ++bin[get(c, *vi)];
+ }
+
+ // this loop sets bin[d] to the starting position of vertices
+ // with degree d in the vert array for the bucket sort
+ size_type cur_pos = 0;
+ for (degree_type cur_deg = 0; cur_deg < max_deg + 2; ++cur_deg)
+ {
+ degree_type tmp = bin[cur_deg];
+ bin[cur_deg] = cur_pos;
+ cur_pos += tmp;
+ }
+
+ // perform the bucket sort with pos and vert so that
+ // pos[0] is the vertex of smallest degree
+ std::vector< vertex > vert(num_vertices(g));
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex v = *vi;
+ size_type p = bin[get(c, v)];
+ put(pos, v, p);
+ vert[p] = v;
+ ++bin[get(c, v)];
+ }
+ // we ``abused'' bin while placing the vertices, now,
+ // we need to restore it
+ std::copy(boost::make_reverse_iterator(bin.end() - 2),
+ boost::make_reverse_iterator(bin.begin()),
+ boost::make_reverse_iterator(bin.end() - 1));
+ // now simulate removing the vertices
+ for (size_type i = 0; i < num_vertices(g); ++i)
+ {
+ vertex v = vert[i];
+ vis.examine_vertex(v, g);
+ v_cn = get(c, v);
+ typename graph_traits< Graph >::out_edge_iterator oi, oi_end;
+ for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi)
+ {
+ vis.examine_edge(*oi, g);
+ vertex u = target(*oi, g);
+ // if c[u] > c[v], then u is still in the graph,
+ if (get(c, u) > v_cn)
+ {
+ degree_type deg_u = get(c, u);
+ degree_type pos_u = get(pos, u);
+ // w is the first vertex with the same degree as u
+ // (this is the resort operation!)
+ degree_type pos_w = bin[deg_u];
+ vertex w = vert[pos_w];
+ if (u != v)
+ {
+ // swap u and w
+ put(pos, u, pos_w);
+ put(pos, w, pos_u);
+ vert[pos_w] = u;
+ vert[pos_u] = w;
+ }
+ // now, the vertices array is sorted assuming
+ // we perform the following step
+ // start the set of vertices with degree of u
+ // one into the future (this now points at vertex
+ // w which we swapped with u).
+ ++bin[deg_u];
+ // we are removing v from the graph, so u's degree
+ // decreases
+ put(c, u, get(c, u) - 1);
+ }
+ }
+ vis.finish_vertex(v, g);
+ }
+ return v_cn;
+ }
+
+} // namespace detail
+
+// non-named parameter version for the unweighted case
+template < typename Graph, typename CoreMap, typename CoreNumVisitor >
+typename property_traits< CoreMap >::value_type core_numbers(
+ Graph& g, CoreMap c, CoreNumVisitor vis)
+{
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+ detail::compute_in_degree_map(g, c,
+ detail::constant_value_property_map<
+ typename property_traits< CoreMap >::value_type >(1));
+ return detail::core_numbers_impl(g, c,
+ make_iterator_property_map(
+ std::vector< size_type >(num_vertices(g)).begin(),
+ get(vertex_index, g)),
+ vis);
+}
+
+// non-named paramter version for the unweighted case
+template < typename Graph, typename CoreMap >
+typename property_traits< CoreMap >::value_type core_numbers(
+ Graph& g, CoreMap c)
+{
+ return core_numbers(g, c, make_core_numbers_visitor(null_visitor()));
+}
+
+// non-named parameter version for the weighted case
+template < typename Graph, typename CoreMap, typename EdgeWeightMap,
+ typename VertexIndexMap, typename CoreNumVisitor >
+typename property_traits< CoreMap >::value_type core_numbers(Graph& g,
+ CoreMap c, EdgeWeightMap wm, VertexIndexMap vim, CoreNumVisitor vis)
+{
+ detail::compute_in_degree_map(g, c, wm);
+ return detail::core_numbers_dispatch(g, c, wm, vim, vis);
+}
+
+// non-named parameter version for the weighted case
+// template <typename Graph, typename CoreMap, typename EdgeWeightMap>
+// typename property_traits<CoreMap>::value_type
+// core_numbers(Graph& g, CoreMap c, EdgeWeightMap wm)
+// {
+// typedef typename graph_traits<Graph>::vertices_size_type size_type;
+// detail::compute_in_degree_map(g,c,wm);
+// return detail::core_numbers_dispatch(g,c,wm,get(vertex_index,g),
+// make_core_numbers_visitor(null_visitor()));
+// }
+
+template < typename Graph, typename CoreMap >
+typename property_traits< CoreMap >::value_type weighted_core_numbers(
+ Graph& g, CoreMap c)
+{
+ return weighted_core_numbers(
+ g, c, make_core_numbers_visitor(null_visitor()));
+}
+
+template < typename Graph, typename CoreMap, typename CoreNumVisitor >
+typename property_traits< CoreMap >::value_type weighted_core_numbers(
+ Graph& g, CoreMap c, CoreNumVisitor vis)
+{
+ return core_numbers(g, c, get(edge_weight, g), get(vertex_index, g), vis);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_CORE_NUMBERS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/create_condensation_graph.hpp b/contrib/restricted/boost/graph/include/boost/graph/create_condensation_graph.hpp
new file mode 100644
index 0000000000..1eb6fa2b60
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/create_condensation_graph.hpp
@@ -0,0 +1,86 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_CREATE_CONDENSATION_GRAPH_HPP
+#define BOOST_CREATE_CONDENSATION_GRAPH_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+
+template < typename Graph, typename ComponentLists, typename ComponentNumberMap,
+ typename CondensationGraph, typename EdgeMultiplicityMap >
+void create_condensation_graph(const Graph& g, const ComponentLists& components,
+ ComponentNumberMap component_number, CondensationGraph& cg,
+ EdgeMultiplicityMap edge_mult_map)
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex;
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+ typedef
+ typename graph_traits< CondensationGraph >::vertex_descriptor cg_vertex;
+ std::vector< cg_vertex > to_cg_vertex(components.size());
+ for (size_type s = 0; s < components.size(); ++s)
+ to_cg_vertex[s] = add_vertex(cg);
+
+ for (size_type si = 0; si < components.size(); ++si)
+ {
+ cg_vertex s = to_cg_vertex[si];
+ std::vector< cg_vertex > adj;
+ for (size_type i = 0; i < components[si].size(); ++i)
+ {
+ vertex u = components[s][i];
+ typename graph_traits< Graph >::adjacency_iterator v, v_end;
+ for (boost::tie(v, v_end) = adjacent_vertices(u, g); v != v_end;
+ ++v)
+ {
+ cg_vertex t = to_cg_vertex[component_number[*v]];
+ if (s != t) // Avoid loops in the condensation graph
+ adj.push_back(t);
+ }
+ }
+ std::sort(adj.begin(), adj.end());
+ if (!adj.empty())
+ {
+ size_type i = 0;
+ cg_vertex t = adj[i];
+ typename graph_traits< CondensationGraph >::edge_descriptor e;
+ bool inserted;
+ boost::tie(e, inserted) = add_edge(s, t, cg);
+ put(edge_mult_map, e, 1);
+ ++i;
+ while (i < adj.size())
+ {
+ if (adj[i] == t)
+ put(edge_mult_map, e, get(edge_mult_map, e) + 1);
+ else
+ {
+ t = adj[i];
+ boost::tie(e, inserted) = add_edge(s, t, cg);
+ put(edge_mult_map, e, 1);
+ }
+ ++i;
+ }
+ }
+ }
+}
+
+template < typename Graph, typename ComponentLists, typename ComponentNumberMap,
+ typename CondensationGraph >
+void create_condensation_graph(const Graph& g, const ComponentLists& components,
+ ComponentNumberMap component_number, CondensationGraph& cg)
+{
+ create_condensation_graph(
+ g, components, component_number, cg, dummy_property_map());
+}
+
+} // namespace boost
+
+#endif // BOOST_CREATE_CONDENSATION_GRAPH_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/cuthill_mckee_ordering.hpp b/contrib/restricted/boost/graph/include/boost/graph/cuthill_mckee_ordering.hpp
new file mode 100644
index 0000000000..75750bdf5b
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/cuthill_mckee_ordering.hpp
@@ -0,0 +1,181 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004, 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
+// Doug Gregor, D. Kevin McGrath
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_CUTHILL_MCKEE_HPP
+#define BOOST_GRAPH_CUTHILL_MCKEE_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/detail/sparse_ordering.hpp>
+#include <boost/graph/graph_utility.hpp>
+#include <algorithm>
+
+/*
+ (Reverse) Cuthill-McKee Algorithm for matrix reordering
+*/
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < typename OutputIterator, typename Buffer, typename DegreeMap >
+ class bfs_rcm_visitor : public default_bfs_visitor
+ {
+ public:
+ bfs_rcm_visitor(OutputIterator* iter, Buffer* b, DegreeMap deg)
+ : permutation(iter), Qptr(b), degree(deg)
+ {
+ }
+ template < class Vertex, class Graph >
+ void examine_vertex(Vertex u, Graph&)
+ {
+ *(*permutation)++ = u;
+ index_begin = Qptr->size();
+ }
+ template < class Vertex, class Graph >
+ void finish_vertex(Vertex, Graph&)
+ {
+ using std::sort;
+
+ typedef typename property_traits< DegreeMap >::value_type ds_type;
+
+ typedef indirect_cmp< DegreeMap, std::less< ds_type > > Compare;
+ Compare comp(degree);
+
+ sort(Qptr->begin() + index_begin, Qptr->end(), comp);
+ }
+
+ protected:
+ OutputIterator* permutation;
+ int index_begin;
+ Buffer* Qptr;
+ DegreeMap degree;
+ };
+
+} // namespace detail
+
+// Reverse Cuthill-McKee algorithm with a given starting Vertex.
+//
+// If user provides a reverse iterator, this will be a reverse-cuthill-mckee
+// algorithm, otherwise it will be a standard CM algorithm
+
+template < class Graph, class OutputIterator, class ColorMap, class DegreeMap >
+OutputIterator cuthill_mckee_ordering(const Graph& g,
+ std::deque< typename graph_traits< Graph >::vertex_descriptor >
+ vertex_queue,
+ OutputIterator permutation, ColorMap color, DegreeMap degree)
+{
+
+ // create queue, visitor...don't forget namespaces!
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename boost::sparse::sparse_ordering_queue< Vertex > queue;
+ typedef typename detail::bfs_rcm_visitor< OutputIterator, queue, DegreeMap >
+ Visitor;
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+
+ queue Q;
+
+ // create a bfs_rcm_visitor as defined above
+ Visitor vis(&permutation, &Q, degree);
+
+ typename graph_traits< Graph >::vertex_iterator ui, ui_end;
+
+ // Copy degree to pseudo_degree
+ // initialize the color map
+ for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ put(color, *ui, Color::white());
+ }
+
+ while (!vertex_queue.empty())
+ {
+ Vertex s = vertex_queue.front();
+ vertex_queue.pop_front();
+
+ // call BFS with visitor
+ breadth_first_visit(g, s, Q, vis, color);
+ }
+ return permutation;
+}
+
+// This is the case where only a single starting vertex is supplied.
+template < class Graph, class OutputIterator, class ColorMap, class DegreeMap >
+OutputIterator cuthill_mckee_ordering(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ OutputIterator permutation, ColorMap color, DegreeMap degree)
+{
+
+ std::deque< typename graph_traits< Graph >::vertex_descriptor >
+ vertex_queue;
+ vertex_queue.push_front(s);
+
+ return cuthill_mckee_ordering(g, vertex_queue, permutation, color, degree);
+}
+
+// This is the version of CM which selects its own starting vertex
+template < class Graph, class OutputIterator, class ColorMap, class DegreeMap >
+OutputIterator cuthill_mckee_ordering(const Graph& G,
+ OutputIterator permutation, ColorMap color, DegreeMap degree)
+{
+ if (boost::graph::has_no_vertices(G))
+ return permutation;
+
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+
+ std::deque< Vertex > vertex_queue;
+
+ // Mark everything white
+ BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white());
+
+ // Find one vertex from each connected component
+ BGL_FORALL_VERTICES_T(v, G, Graph)
+ {
+ if (get(color, v) == Color::white())
+ {
+ depth_first_visit(G, v, dfs_visitor<>(), color);
+ vertex_queue.push_back(v);
+ }
+ }
+
+ // Find starting nodes for all vertices
+ // TBD: How to do this with a directed graph?
+ for (typename std::deque< Vertex >::iterator i = vertex_queue.begin();
+ i != vertex_queue.end(); ++i)
+ *i = find_starting_node(G, *i, color, degree);
+
+ return cuthill_mckee_ordering(G, vertex_queue, permutation, color, degree);
+}
+
+template < typename Graph, typename OutputIterator, typename VertexIndexMap >
+OutputIterator cuthill_mckee_ordering(
+ const Graph& G, OutputIterator permutation, VertexIndexMap index_map)
+{
+ if (boost::graph::has_no_vertices(G))
+ return permutation;
+
+ std::vector< default_color_type > colors(num_vertices(G));
+ return cuthill_mckee_ordering(G, permutation,
+ make_iterator_property_map(&colors[0], index_map, colors[0]),
+ make_out_degree_map(G));
+}
+
+template < typename Graph, typename OutputIterator >
+inline OutputIterator cuthill_mckee_ordering(
+ const Graph& G, OutputIterator permutation)
+{
+ return cuthill_mckee_ordering(G, permutation, get(vertex_index, G));
+}
+} // namespace boost
+
+#endif // BOOST_GRAPH_CUTHILL_MCKEE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/cycle_canceling.hpp b/contrib/restricted/boost/graph/include/boost/graph/cycle_canceling.hpp
new file mode 100644
index 0000000000..5aaa25e752
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/cycle_canceling.hpp
@@ -0,0 +1,191 @@
+//=======================================================================
+// Copyright 2013 University of Warsaw.
+// Authors: Piotr Wygocki
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+//
+// This algorithm is described in "Network Flows: Theory, Algorithms, and
+// Applications"
+// by Ahuja, Magnanti, Orlin.
+
+#ifndef BOOST_GRAPH_CYCLE_CANCELING_HPP
+#define BOOST_GRAPH_CYCLE_CANCELING_HPP
+
+#include <numeric>
+
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/graph/bellman_ford_shortest_paths.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/detail/augment.hpp>
+#include <boost/graph/find_flow_cost.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < typename PredEdgeMap, typename Vertex >
+ class RecordEdgeMapAndCycleVertex
+ : public bellman_visitor<
+ edge_predecessor_recorder< PredEdgeMap, on_edge_relaxed > >
+ {
+ typedef edge_predecessor_recorder< PredEdgeMap, on_edge_relaxed >
+ PredRec;
+
+ public:
+ RecordEdgeMapAndCycleVertex(PredEdgeMap pred, Vertex& v)
+ : bellman_visitor< PredRec >(PredRec(pred)), m_v(v), m_pred(pred)
+ {
+ }
+
+ template < typename Graph, typename Edge >
+ void edge_not_minimized(Edge e, const Graph& g) const
+ {
+ typename graph_traits< Graph >::vertices_size_type n
+ = num_vertices(g) + 1;
+
+ // edge e is not minimized but does not have to be on the negative
+ // weight cycle to find vertex on negative wieight cycle we move n+1
+ // times backword in the PredEdgeMap graph.
+ while (n > 0)
+ {
+ e = get(m_pred, source(e, g));
+ --n;
+ }
+ m_v = source(e, g);
+ }
+
+ private:
+ Vertex& m_v;
+ PredEdgeMap m_pred;
+ };
+
+} // detail
+
+template < class Graph, class Pred, class Distance, class Reversed,
+ class ResidualCapacity, class Weight >
+void cycle_canceling(const Graph& g, Weight weight, Reversed rev,
+ ResidualCapacity residual_capacity, Pred pred, Distance distance)
+{
+ typedef filtered_graph< const Graph, is_residual_edge< ResidualCapacity > >
+ ResGraph;
+ ResGraph gres = detail::residual_graph(g, residual_capacity);
+
+ typedef graph_traits< ResGraph > ResGTraits;
+ typedef graph_traits< Graph > GTraits;
+ typedef typename ResGTraits::edge_descriptor edge_descriptor;
+ typedef typename ResGTraits::vertex_descriptor vertex_descriptor;
+
+ typename GTraits::vertices_size_type N = num_vertices(g);
+
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ put(pred, v, edge_descriptor());
+ put(distance, v, 0);
+ }
+
+ vertex_descriptor cycleStart;
+ while (!bellman_ford_shortest_paths(gres, N,
+ weight_map(weight).distance_map(distance).visitor(
+ detail::RecordEdgeMapAndCycleVertex< Pred, vertex_descriptor >(
+ pred, cycleStart))))
+ {
+
+ detail::augment(
+ g, cycleStart, cycleStart, pred, residual_capacity, rev);
+
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ put(pred, v, edge_descriptor());
+ put(distance, v, 0);
+ }
+ }
+}
+
+// in this namespace argument dispatching takes place
+namespace detail
+{
+
+ template < class Graph, class P, class T, class R, class ResidualCapacity,
+ class Weight, class Reversed, class Pred, class Distance >
+ void cycle_canceling_dispatch2(const Graph& g, Weight weight, Reversed rev,
+ ResidualCapacity residual_capacity, Pred pred, Distance dist,
+ const bgl_named_params< P, T, R >& params)
+ {
+ cycle_canceling(g, weight, rev, residual_capacity, pred, dist);
+ }
+
+ // setting default distance map
+ template < class Graph, class P, class T, class R, class Pred,
+ class ResidualCapacity, class Weight, class Reversed >
+ void cycle_canceling_dispatch2(Graph& g, Weight weight, Reversed rev,
+ ResidualCapacity residual_capacity, Pred pred, param_not_found,
+ const bgl_named_params< P, T, R >& params)
+ {
+ typedef typename property_traits< Weight >::value_type D;
+
+ std::vector< D > d_map(num_vertices(g));
+
+ cycle_canceling(g, weight, rev, residual_capacity, pred,
+ make_iterator_property_map(d_map.begin(),
+ choose_const_pmap(
+ get_param(params, vertex_index), g, vertex_index)));
+ }
+
+ template < class Graph, class P, class T, class R, class ResidualCapacity,
+ class Weight, class Reversed, class Pred >
+ void cycle_canceling_dispatch1(Graph& g, Weight weight, Reversed rev,
+ ResidualCapacity residual_capacity, Pred pred,
+ const bgl_named_params< P, T, R >& params)
+ {
+ cycle_canceling_dispatch2(g, weight, rev, residual_capacity, pred,
+ get_param(params, vertex_distance), params);
+ }
+
+ // setting default predecessors map
+ template < class Graph, class P, class T, class R, class ResidualCapacity,
+ class Weight, class Reversed >
+ void cycle_canceling_dispatch1(Graph& g, Weight weight, Reversed rev,
+ ResidualCapacity residual_capacity, param_not_found,
+ const bgl_named_params< P, T, R >& params)
+ {
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor;
+ std::vector< edge_descriptor > p_map(num_vertices(g));
+
+ cycle_canceling_dispatch2(g, weight, rev, residual_capacity,
+ make_iterator_property_map(p_map.begin(),
+ choose_const_pmap(
+ get_param(params, vertex_index), g, vertex_index)),
+ get_param(params, vertex_distance), params);
+ }
+
+} // detail
+
+template < class Graph, class P, class T, class R >
+void cycle_canceling(Graph& g, const bgl_named_params< P, T, R >& params)
+{
+ cycle_canceling_dispatch1(g,
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
+ choose_pmap(get_param(params, edge_residual_capacity), g,
+ edge_residual_capacity),
+ get_param(params, vertex_predecessor), params);
+}
+
+template < class Graph > void cycle_canceling(Graph& g)
+{
+ bgl_named_params< int, buffer_param_t > params(0);
+ cycle_canceling(g, params);
+}
+
+}
+
+#endif /* BOOST_GRAPH_CYCLE_CANCELING_HPP */
diff --git a/contrib/restricted/boost/graph/include/boost/graph/degree_centrality.hpp b/contrib/restricted/boost/graph/include/boost/graph/degree_centrality.hpp
new file mode 100644
index 0000000000..6db11b95eb
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/degree_centrality.hpp
@@ -0,0 +1,135 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_DEGREE_CENTRALITY_HPP
+#define BOOST_GRAPH_DEGREE_CENTRALITY_HPP
+
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+
+template < typename Graph > struct degree_centrality_measure
+{
+ typedef typename graph_traits< Graph >::degree_size_type degree_type;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_type;
+};
+
+template < typename Graph >
+struct influence_measure : public degree_centrality_measure< Graph >
+{
+ typedef degree_centrality_measure< Graph > base_type;
+ typedef typename base_type::degree_type degree_type;
+ typedef typename base_type::vertex_type vertex_type;
+
+ inline degree_type operator()(vertex_type v, const Graph& g)
+ {
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+ return out_degree(v, g);
+ }
+};
+
+template < typename Graph >
+inline influence_measure< Graph > measure_influence(const Graph&)
+{
+ return influence_measure< Graph >();
+}
+
+template < typename Graph >
+struct prestige_measure : public degree_centrality_measure< Graph >
+{
+ typedef degree_centrality_measure< Graph > base_type;
+ typedef typename base_type::degree_type degree_type;
+ typedef typename base_type::vertex_type vertex_type;
+
+ inline degree_type operator()(vertex_type v, const Graph& g)
+ {
+ BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >));
+ return in_degree(v, g);
+ }
+};
+
+template < typename Graph >
+inline prestige_measure< Graph > measure_prestige(const Graph&)
+{
+ return prestige_measure< Graph >();
+}
+
+template < typename Graph, typename Vertex, typename Measure >
+inline typename Measure::degree_type degree_centrality(
+ const Graph& g, Vertex v, Measure measure)
+{
+ BOOST_CONCEPT_ASSERT((DegreeMeasureConcept< Measure, Graph >));
+ return measure(v, g);
+}
+
+template < typename Graph, typename Vertex >
+inline typename graph_traits< Graph >::degree_size_type degree_centrality(
+ const Graph& g, Vertex v)
+{
+ return degree_centrality(g, v, measure_influence(g));
+}
+
+// These are alias functions, intended to provide a more expressive interface.
+
+template < typename Graph, typename Vertex >
+inline typename graph_traits< Graph >::degree_size_type influence(
+ const Graph& g, Vertex v)
+{
+ return degree_centrality(g, v, measure_influence(g));
+}
+
+template < typename Graph, typename Vertex >
+inline typename graph_traits< Graph >::degree_size_type prestige(
+ const Graph& g, Vertex v)
+{
+ return degree_centrality(g, v, measure_prestige(g));
+}
+
+template < typename Graph, typename CentralityMap, typename Measure >
+inline void all_degree_centralities(
+ const Graph& g, CentralityMap cent, Measure measure)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+ BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< CentralityMap, Vertex >));
+ typedef typename property_traits< CentralityMap >::value_type Centrality;
+
+ VertexIterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ {
+ Centrality c = degree_centrality(g, *i, measure);
+ put(cent, *i, c);
+ }
+}
+
+template < typename Graph, typename CentralityMap >
+inline void all_degree_centralities(const Graph& g, CentralityMap cent)
+{
+ all_degree_centralities(g, cent, measure_influence(g));
+}
+
+// More helper functions for computing influence and prestige.
+// I hate the names of these functions, but influence and prestige
+// don't pluralize too well.
+
+template < typename Graph, typename CentralityMap >
+inline void all_influence_values(const Graph& g, CentralityMap cent)
+{
+ all_degree_centralities(g, cent, measure_influence(g));
+}
+
+template < typename Graph, typename CentralityMap >
+inline void all_prestige_values(const Graph& g, CentralityMap cent)
+{
+ all_degree_centralities(g, cent, measure_prestige(g));
+}
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/augment.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/augment.hpp
new file mode 100644
index 0000000000..956f274cb4
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/augment.hpp
@@ -0,0 +1,66 @@
+//=======================================================================
+// Copyright 2013 University of Warsaw.
+// Authors: Piotr Wygocki
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_AUGMENT_HPP
+#define BOOST_GRAPH_AUGMENT_HPP
+
+#include <boost/graph/filtered_graph.hpp>
+
+namespace boost
+{
+namespace detail
+{
+
+ template < class Graph, class ResCapMap >
+ filtered_graph< const Graph, is_residual_edge< ResCapMap > > residual_graph(
+ const Graph& g, ResCapMap residual_capacity)
+ {
+ return filtered_graph< const Graph, is_residual_edge< ResCapMap > >(
+ g, is_residual_edge< ResCapMap >(residual_capacity));
+ }
+
+ template < class Graph, class PredEdgeMap, class ResCapMap,
+ class RevEdgeMap >
+ inline void augment(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink, PredEdgeMap p,
+ ResCapMap residual_capacity, RevEdgeMap reverse_edge)
+ {
+ typename graph_traits< Graph >::edge_descriptor e;
+ typename graph_traits< Graph >::vertex_descriptor u;
+ typedef typename property_traits< ResCapMap >::value_type FlowValue;
+
+ // find minimum residual capacity along the augmenting path
+ FlowValue delta = (std::numeric_limits< FlowValue >::max)();
+ e = get(p, sink);
+ do
+ {
+ BOOST_USING_STD_MIN();
+ delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ delta, get(residual_capacity, e));
+ u = source(e, g);
+ e = get(p, u);
+ } while (u != src);
+
+ // push delta units of flow along the augmenting path
+ e = get(p, sink);
+ do
+ {
+ put(residual_capacity, e, get(residual_capacity, e) - delta);
+ put(residual_capacity, get(reverse_edge, e),
+ get(residual_capacity, get(reverse_edge, e)) + delta);
+ u = source(e, g);
+ e = get(p, u);
+ } while (u != src);
+ }
+
+} // namespace detail
+} // namespace boost
+
+#endif /* BOOST_GRAPH_AUGMENT_HPP */
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/connected_components.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/connected_components.hpp
new file mode 100644
index 0000000000..a97159118d
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/connected_components.hpp
@@ -0,0 +1,206 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
+#define BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
+
+#if defined(__sgi) && !defined(__GNUC__)
+#pragma set woff 1234
+#endif
+
+#include <boost/operators.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ //=========================================================================
+ // Implementation details of connected_components
+
+ // This is used both in the connected_components algorithm and in
+ // the kosaraju strong components algorithm during the second DFS
+ // traversal.
+ template < class ComponentsPA, class DFSVisitor >
+ class components_recorder : public DFSVisitor
+ {
+ typedef typename property_traits< ComponentsPA >::value_type comp_type;
+
+ public:
+ components_recorder(ComponentsPA c, comp_type& c_count, DFSVisitor v)
+ : DFSVisitor(v), m_component(c), m_count(c_count)
+ {
+ }
+
+ template < class Vertex, class Graph >
+ void start_vertex(Vertex u, Graph& g)
+ {
+ ++m_count;
+ DFSVisitor::start_vertex(u, g);
+ }
+ template < class Vertex, class Graph >
+ void discover_vertex(Vertex u, Graph& g)
+ {
+ put(m_component, u, m_count);
+ DFSVisitor::discover_vertex(u, g);
+ }
+
+ protected:
+ ComponentsPA m_component;
+ comp_type& m_count;
+ };
+
+ template < class DiscoverTimeMap, class FinishTimeMap, class TimeT,
+ class DFSVisitor >
+ class time_recorder : public DFSVisitor
+ {
+ public:
+ time_recorder(
+ DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor v)
+ : DFSVisitor(v), m_discover_time(d), m_finish_time(f), m_t(t)
+ {
+ }
+
+ template < class Vertex, class Graph >
+ void discover_vertex(Vertex u, Graph& g)
+ {
+ put(m_discover_time, u, ++m_t);
+ DFSVisitor::discover_vertex(u, g);
+ }
+ template < class Vertex, class Graph >
+ void finish_vertex(Vertex u, Graph& g)
+ {
+ put(m_finish_time, u, ++m_t);
+ DFSVisitor::discover_vertex(u, g);
+ }
+
+ protected:
+ DiscoverTimeMap m_discover_time;
+ FinishTimeMap m_finish_time;
+ TimeT m_t;
+ };
+ template < class DiscoverTimeMap, class FinishTimeMap, class TimeT,
+ class DFSVisitor >
+ time_recorder< DiscoverTimeMap, FinishTimeMap, TimeT, DFSVisitor >
+ record_times(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor vis)
+ {
+ return time_recorder< DiscoverTimeMap, FinishTimeMap, TimeT,
+ DFSVisitor >(d, f, t, vis);
+ }
+
+ //=========================================================================
+ // Implementation detail of dynamic_components
+
+ //-------------------------------------------------------------------------
+ // Helper functions for the component_index class
+
+ // Record the representative vertices in the header array.
+ // Representative vertices now point to the component number.
+
+ template < class Parent, class OutputIterator, class Integer >
+ inline void build_components_header(
+ Parent p, OutputIterator header, Integer num_nodes)
+ {
+ Parent component = p;
+ Integer component_num = 0;
+ for (Integer v = 0; v != num_nodes; ++v)
+ if (p[v] == v)
+ {
+ *header++ = v;
+ component[v] = component_num++;
+ }
+ }
+
+ // Pushes x onto the front of the list. The list is represented in
+ // an array.
+ template < class Next, class T, class V >
+ inline void push_front(Next next, T& head, V x)
+ {
+ T tmp = head;
+ head = x;
+ next[x] = tmp;
+ }
+
+ // Create a linked list of the vertices in each component
+ // by reusing the representative array.
+ template < class Parent1, class Parent2, class Integer >
+ void link_components(Parent1 component, Parent2 header, Integer num_nodes,
+ Integer num_components)
+ {
+ // Make the non-representative vertices point to their component
+ Parent1 representative = component;
+ for (Integer v = 0; v != num_nodes; ++v)
+ if (component[v] >= num_components || header[component[v]] != v)
+ component[v] = component[representative[v]];
+
+ // initialize the "head" of the lists to "NULL"
+ std::fill_n(header, num_components, num_nodes);
+
+ // Add each vertex to the linked list for its component
+ Parent1 next = component;
+ for (Integer k = 0; k != num_nodes; ++k)
+ push_front(next, header[component[k]], k);
+ }
+
+ template < class IndexContainer, class HeaderContainer >
+ void construct_component_index(
+ IndexContainer& index, HeaderContainer& header)
+ {
+ build_components_header(index.begin(), std::back_inserter(header),
+ index.end() - index.begin());
+
+ link_components(index.begin(), header.begin(),
+ index.end() - index.begin(), header.end() - header.begin());
+ }
+
+ template < class IndexIterator, class Integer, class Distance >
+ class component_iterator
+ : boost::forward_iterator_helper<
+ component_iterator< IndexIterator, Integer, Distance >, Integer,
+ Distance, Integer*, Integer& >
+ {
+ public:
+ typedef component_iterator self;
+
+ IndexIterator next;
+ Integer node;
+
+ typedef std::forward_iterator_tag iterator_category;
+ typedef Integer value_type;
+ typedef Integer& reference;
+ typedef Integer* pointer;
+ typedef Distance difference_type;
+
+ component_iterator() {}
+ component_iterator(IndexIterator x, Integer i) : next(x), node(i) {}
+ Integer operator*() const { return node; }
+ self& operator++()
+ {
+ node = next[node];
+ return *this;
+ }
+ };
+
+ template < class IndexIterator, class Integer, class Distance >
+ inline bool operator==(
+ const component_iterator< IndexIterator, Integer, Distance >& x,
+ const component_iterator< IndexIterator, Integer, Distance >& y)
+ {
+ return x.node == y.node;
+ }
+
+} // namespace detail
+
+} // namespace detail
+
+#if defined(__sgi) && !defined(__GNUC__)
+#pragma reset woff 1234
+#endif
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/empty_header.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/empty_header.hpp
new file mode 100644
index 0000000000..fde3672551
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/empty_header.hpp
@@ -0,0 +1,10 @@
+#ifndef BOOST_GRAPH_DETAIL_EMPTY_HEADER_HPP_INCLUDED
+#define BOOST_GRAPH_DETAIL_EMPTY_HEADER_HPP_INCLUDED
+
+// Copyright 2018 Peter Dimov
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#endif // #ifndef BOOST_GRAPH_DETAIL_EMPTY_HEADER_HPP_INCLUDED
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/geodesic.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/geodesic.hpp
new file mode 100644
index 0000000000..84805fb647
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/geodesic.hpp
@@ -0,0 +1,138 @@
+// (C) Copyright 2007 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_DETAIL_GEODESIC_HPP
+#define BOOST_GRAPH_DETAIL_GEODESIC_HPP
+
+#include <functional>
+#include <boost/config.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/numeric_values.hpp>
+#include <boost/concept/assert.hpp>
+
+// TODO: Should this really be in detail?
+
+namespace boost
+{
+// This is a very good discussion on centrality measures. While I can't
+// say that this has been the motivating factor for the design and
+// implementation of ths centrality framework, it does provide a single
+// point of reference for defining things like degree and closeness
+// centrality. Plus, the bibliography seems fairly complete.
+//
+// @article{citeulike:1144245,
+// author = {Borgatti, Stephen P. and Everett, Martin G.},
+// citeulike-article-id = {1144245},
+// doi = {10.1016/j.socnet.2005.11.005},
+// journal = {Social Networks},
+// month = {October},
+// number = {4},
+// pages = {466--484},
+// priority = {0},
+// title = {A Graph-theoretic perspective on centrality},
+// url = {https://doi.org/10.1016/j.socnet.2005.11.005},
+// volume = {28},
+// year = {2006}
+// }
+// }
+
+namespace detail
+{
+ // Note that this assumes T == property_traits<DistanceMap>::value_type
+ // and that the args and return of combine are also T.
+ template < typename Graph, typename DistanceMap, typename Combinator,
+ typename Distance >
+ inline Distance combine_distances(
+ const Graph& g, DistanceMap dist, Combinator combine, Distance init)
+ {
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< DistanceMap, Vertex >));
+ BOOST_CONCEPT_ASSERT((NumericValueConcept< Distance >));
+ typedef numeric_values< Distance > DistanceNumbers;
+// NOTE: Disabled until this concept assert is fixed in Boost.ConceptCheck.
+// BOOST_CONCEPT_ASSERT((AdaptableBinaryFunction< Combinator, Distance,
+// Distance, Distance >));
+
+ // If there's ever an infinite distance, then we simply return
+ // infinity. Note that this /will/ include the a non-zero
+ // distance-to-self in the combined values. However, this is usually
+ // zero, so it shouldn't be too problematic.
+ Distance ret = init;
+ VertexIterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ {
+ Vertex v = *i;
+ if (get(dist, v) != DistanceNumbers::infinity())
+ {
+ ret = combine(ret, get(dist, v));
+ }
+ else
+ {
+ ret = DistanceNumbers::infinity();
+ break;
+ }
+ }
+ return ret;
+ }
+
+ // Similar to std::plus<T>, but maximizes parameters
+ // rather than adding them.
+ template < typename T > struct maximize
+ {
+ typedef T result_type;
+ typedef T first_argument_type;
+ typedef T second_argument_type;
+ T operator()(T x, T y) const
+ {
+ BOOST_USING_STD_MAX();
+ return max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y);
+ }
+ };
+
+ // Another helper, like maximize() to help abstract functional
+ // concepts. This is trivially instantiated for builtin numeric
+ // types, but should be specialized for those types that have
+ // discrete notions of reciprocals.
+ template < typename T > struct reciprocal
+ {
+ typedef T result_type;
+ typedef T argument_type;
+ T operator()(T t) { return T(1) / t; }
+ };
+} /* namespace detail */
+
+// This type defines the basic facilities used for computing values
+// based on the geodesic distances between vertices. Examples include
+// closeness centrality and mean geodesic distance.
+template < typename Graph, typename DistanceType, typename ResultType >
+struct geodesic_measure
+{
+ typedef DistanceType distance_type;
+ typedef ResultType result_type;
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+
+ typedef numeric_values< distance_type > distance_values;
+ typedef numeric_values< result_type > result_values;
+
+ static inline distance_type infinite_distance()
+ {
+ return distance_values::infinity();
+ }
+
+ static inline result_type infinite_result()
+ {
+ return result_values::infinity();
+ }
+
+ static inline result_type zero_result() { return result_values::zero(); }
+};
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/incidence_iterator.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/incidence_iterator.hpp
new file mode 100644
index 0000000000..2da4874ac7
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/incidence_iterator.hpp
@@ -0,0 +1,98 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP
+#define BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP
+
+#include <utility>
+#include <iterator>
+
+// OBSOLETE
+
+namespace boost
+{
+
+namespace detail
+{
+ // EdgeDir tags
+ struct in_edge_tag
+ {
+ };
+ struct out_edge_tag
+ {
+ };
+
+ template < class Vertex, class Edge, class Iterator1D, class EdgeDir >
+ struct bidir_incidence_iterator
+ {
+ typedef bidir_incidence_iterator self;
+ typedef Edge edge_type;
+ typedef typename Edge::property_type EdgeProperty;
+
+ public:
+ typedef int difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef edge_type reference;
+ typedef edge_type value_type;
+ typedef value_type* pointer;
+ inline bidir_incidence_iterator() {}
+ inline bidir_incidence_iterator(Iterator1D ii, Vertex src)
+ : i(ii), _src(src)
+ {
+ }
+
+ inline self& operator++()
+ {
+ ++i;
+ return *this;
+ }
+ inline self operator++(int)
+ {
+ self tmp = *this;
+ ++(*this);
+ return tmp;
+ }
+
+ inline reference operator*() const { return deref_helper(EdgeDir()); }
+ inline self* operator->() { return this; }
+
+ Iterator1D& iter() { return i; }
+ const Iterator1D& iter() const { return i; }
+
+ Iterator1D i;
+ Vertex _src;
+
+ protected:
+ inline reference deref_helper(out_edge_tag) const
+ {
+ return edge_type(_src, (*i).get_target(), &(*i).get_property());
+ }
+ inline reference deref_helper(in_edge_tag) const
+ {
+ return edge_type((*i).get_target(), _src, &(*i).get_property());
+ }
+ };
+
+ template < class V, class E, class Iter, class Dir >
+ inline bool operator==(const bidir_incidence_iterator< V, E, Iter, Dir >& x,
+ const bidir_incidence_iterator< V, E, Iter, Dir >& y)
+ {
+ return x.i == y.i;
+ }
+ template < class V, class E, class Iter, class Dir >
+ inline bool operator!=(const bidir_incidence_iterator< V, E, Iter, Dir >& x,
+ const bidir_incidence_iterator< V, E, Iter, Dir >& y)
+ {
+ return x.i != y.i;
+ }
+
+}
+}
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/incremental_components.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/incremental_components.hpp
new file mode 100644
index 0000000000..8941f67283
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/incremental_components.hpp
@@ -0,0 +1,92 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Copyright 2009 Trustees of Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Michael Hansen
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
+#define BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
+
+#include <boost/operators.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ // Iterator for a component index linked list. The contents of
+ // each array element represent the next index in the list. A
+ // special value (the maximum index + 1) is used to terminate a
+ // list.
+ template < typename IndexRandomAccessIterator >
+ class component_index_iterator
+ : boost::forward_iterator_helper<
+ component_index_iterator< IndexRandomAccessIterator >,
+ typename std::iterator_traits<
+ IndexRandomAccessIterator >::value_type,
+ typename std::iterator_traits<
+ IndexRandomAccessIterator >::difference_type,
+ typename std::iterator_traits< IndexRandomAccessIterator >::pointer,
+ typename std::iterator_traits<
+ IndexRandomAccessIterator >::reference >
+ {
+
+ private:
+ typedef component_index_iterator< IndexRandomAccessIterator > self;
+
+ public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef typename std::iterator_traits<
+ IndexRandomAccessIterator >::value_type value_type;
+ typedef typename std::iterator_traits<
+ IndexRandomAccessIterator >::difference_type reference;
+ typedef
+ typename std::iterator_traits< IndexRandomAccessIterator >::pointer
+ pointer;
+ typedef typename std::iterator_traits<
+ IndexRandomAccessIterator >::reference difference_type;
+
+ // Constructor for "begin" iterator
+ component_index_iterator(
+ IndexRandomAccessIterator index_iterator, value_type begin_index)
+ : m_index_iterator(index_iterator), m_current_index(begin_index)
+ {
+ }
+
+ // Constructor for "end" iterator (end_index should be the linked
+ // list terminator).
+ component_index_iterator(value_type end_index)
+ : m_current_index(end_index)
+ {
+ }
+
+ inline value_type operator*() const { return (m_current_index); }
+
+ self& operator++()
+ {
+ // Move to the next element in the linked list
+ m_current_index = m_index_iterator[m_current_index];
+ return (*this);
+ }
+
+ bool operator==(const self& other_iterator) const
+ {
+ return (m_current_index == *other_iterator);
+ }
+
+ protected:
+ IndexRandomAccessIterator m_index_iterator;
+ value_type m_current_index;
+
+ }; // class component_index_iterator
+
+} // namespace detail
+
+} // namespace detail
+
+#endif // BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/index.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/index.hpp
new file mode 100644
index 0000000000..7ffc843fc2
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/index.hpp
@@ -0,0 +1,78 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_DETAIL_INDEX_HPP
+#define BOOST_GRAPH_DETAIL_INDEX_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+
+// The structures in this module are responsible for selecting and defining
+// types for accessing a builting index map. Note that the selection of these
+// types requires the Graph parameter to model either VertexIndexGraph or
+// EdgeIndexGraph.
+
+namespace boost
+{
+namespace detail
+{
+ template < typename Graph > struct vertex_indexer
+ {
+ typedef vertex_index_t index_type;
+ typedef typename property_map< Graph, vertex_index_t >::type map_type;
+ typedef typename property_map< Graph, vertex_index_t >::const_type
+ const_map_type;
+ typedef typename property_traits< map_type >::value_type value_type;
+ typedef typename graph_traits< Graph >::vertex_descriptor key_type;
+
+ static const_map_type index_map(const Graph& g)
+ {
+ return get(vertex_index, g);
+ }
+
+ static map_type index_map(Graph& g) { return get(vertex_index, g); }
+
+ static value_type index(key_type k, const Graph& g)
+ {
+ return get(vertex_index, g, k);
+ }
+ };
+
+ template < typename Graph > struct edge_indexer
+ {
+ typedef edge_index_t index_type;
+ typedef typename property_map< Graph, edge_index_t >::type map_type;
+ typedef typename property_map< Graph, edge_index_t >::const_type
+ const_map_type;
+ typedef typename property_traits< map_type >::value_type value_type;
+ typedef typename graph_traits< Graph >::edge_descriptor key_type;
+
+ static const_map_type index_map(const Graph& g)
+ {
+ return get(edge_index, g);
+ }
+
+ static map_type index_map(Graph& g) { return get(edge_index, g); }
+
+ static value_type index(key_type k, const Graph& g)
+ {
+ return get(edge_index, g, k);
+ }
+ };
+
+ // NOTE: The Graph parameter MUST be a model of VertexIndexGraph or
+ // VertexEdgeGraph - whichever type Key is selecting.
+ template < typename Graph, typename Key > struct choose_indexer
+ {
+ typedef typename mpl::if_<
+ is_same< Key, typename graph_traits< Graph >::vertex_descriptor >,
+ vertex_indexer< Graph >, edge_indexer< Graph > >::type indexer_type;
+ typedef typename indexer_type::index_type index_type;
+ };
+}
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/labeled_graph_traits.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/labeled_graph_traits.hpp
new file mode 100644
index 0000000000..b6600dbb02
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/labeled_graph_traits.hpp
@@ -0,0 +1,232 @@
+// Copyright (C) 2009 Andrew Sutton
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_LABELED_GRAPH_TRAITS_HPP
+#define BOOST_GRAPH_LABELED_GRAPH_TRAITS_HPP
+
+#include <boost/graph/graph_mutability_traits.hpp>
+
+namespace boost
+{
+
+// Extend the graph mutability traits (and metafunctions) to include options
+// for labeled graphs.
+
+// NOTE: the label_vertex tag denotes the fact that you can basically assign
+// arbitrary labels to vertices without modifying the actual graph.
+
+// TODO: We might also overlay the uniqueness/multiplicity of labels in this
+// hierarchy also. For now, we just assumed that labels are unique.
+
+struct label_vertex_tag
+{
+};
+struct labeled_add_vertex_tag : virtual label_vertex_tag
+{
+};
+struct labeled_add_vertex_property_tag : virtual labeled_add_vertex_tag
+{
+};
+struct labeled_remove_vertex_tag
+{
+};
+struct labeled_add_edge_tag : virtual label_vertex_tag
+{
+};
+struct labeled_add_edge_property_tag : virtual labeled_add_edge_tag
+{
+};
+struct labeled_remove_edge_tag
+{
+};
+
+struct labeled_mutable_vertex_graph_tag : virtual labeled_add_vertex_tag,
+ virtual labeled_remove_vertex_tag
+{
+};
+struct labeled_mutable_vertex_property_graph_tag
+: virtual labeled_add_vertex_property_tag,
+ virtual labeled_remove_vertex_tag
+{
+};
+struct labeled_mutable_edge_graph_tag : virtual labeled_add_edge_tag,
+ virtual labeled_remove_edge_tag
+{
+};
+struct labeled_mutable_edge_property_graph_tag
+: virtual labeled_add_edge_property_tag,
+ virtual labeled_remove_edge_tag
+{
+};
+
+struct labeled_graph_tag : virtual label_vertex_tag
+{
+};
+struct labeled_mutable_graph_tag : virtual labeled_mutable_vertex_graph_tag,
+ virtual labeled_mutable_edge_graph_tag
+{
+};
+struct labeled_mutable_property_graph_tag
+: virtual labeled_mutable_vertex_property_graph_tag,
+ virtual labeled_mutable_edge_property_graph_tag
+{
+};
+struct labeled_add_only_property_graph_tag
+: virtual labeled_add_vertex_property_tag,
+ virtual labeled_mutable_edge_property_graph_tag
+{
+};
+
+// Metafunctions
+
+template < typename Graph >
+struct graph_has_add_vertex_by_label
+: mpl::bool_<
+ is_convertible< typename graph_mutability_traits< Graph >::category,
+ labeled_add_vertex_tag >::value >
+{
+};
+
+template < typename Graph >
+struct graph_has_add_vertex_by_label_with_property
+: mpl::bool_<
+ is_convertible< typename graph_mutability_traits< Graph >::category,
+ labeled_add_vertex_property_tag >::value >
+{
+};
+
+template < typename Graph >
+struct graph_has_remove_vertex_by_label
+: mpl::bool_<
+ is_convertible< typename graph_mutability_traits< Graph >::category,
+ labeled_remove_vertex_tag >::value >
+{
+};
+
+template < typename Graph >
+struct graph_has_add_edge_by_label
+: mpl::bool_<
+ is_convertible< typename graph_mutability_traits< Graph >::category,
+ labeled_add_edge_tag >::value >
+{
+};
+
+template < typename Graph >
+struct graph_has_add_edge_by_label_with_property
+: mpl::bool_<
+ is_convertible< typename graph_mutability_traits< Graph >::category,
+ labeled_add_edge_property_tag >::value >
+{
+};
+
+template < typename Graph >
+struct graph_has_remove_edge_by_label
+: mpl::bool_<
+ is_convertible< typename graph_mutability_traits< Graph >::category,
+ labeled_remove_edge_tag >::value >
+{
+};
+
+template < typename Graph >
+struct is_labeled_mutable_vertex_graph
+: mpl::and_< graph_has_add_vertex_by_label< Graph >,
+ graph_has_remove_vertex_by_label< Graph > >
+{
+};
+
+template < typename Graph >
+struct is_labeled_mutable_vertex_property_graph
+: mpl::and_< graph_has_add_vertex_by_label< Graph >,
+ graph_has_remove_vertex_by_label< Graph > >
+{
+};
+
+template < typename Graph >
+struct is_labeled_mutable_edge_graph
+: mpl::and_< graph_has_add_edge_by_label< Graph >,
+ graph_has_remove_edge_by_label< Graph > >
+{
+};
+
+template < typename Graph >
+struct is_labeled_mutable_edge_property_graph
+: mpl::and_< graph_has_add_edge_by_label< Graph >,
+ graph_has_remove_edge_by_label< Graph > >
+{
+};
+
+template < typename Graph >
+struct is_labeled_mutable_graph
+: mpl::and_< is_labeled_mutable_vertex_graph< Graph >,
+ is_labeled_mutable_edge_graph< Graph > >
+{
+};
+
+template < typename Graph >
+struct is_labeled_mutable_property_graph
+: mpl::and_< is_labeled_mutable_vertex_property_graph< Graph >,
+ is_labeled_mutable_edge_property_graph< Graph > >
+{
+};
+
+template < typename Graph >
+struct is_labeled_add_only_property_graph
+: mpl::bool_<
+ is_convertible< typename graph_mutability_traits< Graph >::category,
+ labeled_add_only_property_graph_tag >::value >
+{
+};
+
+template < typename Graph >
+struct is_labeled_graph
+: mpl::bool_<
+ is_convertible< typename graph_mutability_traits< Graph >::category,
+ label_vertex_tag >::value >
+{
+};
+
+template < typename > struct graph_mutability_traits;
+
+namespace graph_detail
+{
+ // The determine mutability metafunction computes a labeled mutability tag
+ // based on the mutability of the given graph type. This is used by the
+ // graph_mutability_traits specialization below.
+ template < typename Graph > struct determine_mutability
+ {
+ typedef typename mpl::if_< is_add_only_property_graph< Graph >,
+ labeled_add_only_property_graph_tag,
+ typename mpl::if_< is_mutable_property_graph< Graph >,
+ labeled_mutable_property_graph_tag,
+ typename mpl::if_< is_mutable_graph< Graph >,
+ labeled_mutable_graph_tag,
+ typename mpl::if_< is_mutable_edge_graph< Graph >,
+ labeled_graph_tag,
+ typename graph_mutability_traits< Graph >::category >::
+ type >::type >::type >::type type;
+ };
+} // namespace graph_detail
+
+#define LABELED_GRAPH_PARAMS typename G, typename L, typename S
+#define LABELED_GRAPH labeled_graph< G, L, S >
+
+// Specialize mutability traits for the labeled graph.
+// This specialization depends on the mutability of the underlying graph type.
+// If the underlying graph is fully mutable, this is also fully mutable.
+// Otherwise, it's different.
+template < LABELED_GRAPH_PARAMS >
+struct graph_mutability_traits< LABELED_GRAPH >
+{
+ typedef typename graph_detail::determine_mutability<
+ typename LABELED_GRAPH::graph_type >::type category;
+};
+
+#undef LABELED_GRAPH_PARAMS
+#undef LABELED_GRAPH
+
+} // namespace boost
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/list_base.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/list_base.hpp
new file mode 100644
index 0000000000..bd1fc17119
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/list_base.hpp
@@ -0,0 +1,206 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_LIST_BASE_HPP
+#define BOOST_LIST_BASE_HPP
+
+#include <boost/iterator_adaptors.hpp>
+
+// Perhaps this should go through formal review, and move to <boost/>.
+
+/*
+ An alternate interface idea:
+ Extend the std::list functionality by creating remove/insert
+ functions that do not require the container object!
+ */
+
+namespace boost
+{
+namespace detail
+{
+
+ //=========================================================================
+ // Linked-List Generic Implementation Functions
+
+ template < class Node, class Next >
+ inline Node slist_insert_after(Node pos, Node x, Next next)
+ {
+ next(x) = next(pos);
+ next(pos) = x;
+ return x;
+ }
+
+ // return next(pos) or next(next(pos)) ?
+ template < class Node, class Next >
+ inline Node slist_remove_after(Node pos, Next next)
+ {
+ Node n = next(pos);
+ next(pos) = next(n);
+ return n;
+ }
+
+ template < class Node, class Next >
+ inline Node slist_remove_range(Node before_first, Node last, Next next)
+ {
+ next(before_first) = last;
+ return last;
+ }
+
+ template < class Node, class Next >
+ inline Node slist_previous(Node head, Node x, Node empty, Next next)
+ {
+ while (head != empty && next(head) != x)
+ head = next(head);
+ return head;
+ }
+
+ template < class Node, class Next >
+ inline void slist_splice_after(
+ Node pos, Node before_first, Node before_last, Next next)
+ {
+ if (pos != before_first && pos != before_last)
+ {
+ Node first = next(before_first);
+ Node after = next(pos);
+ next(before_first) = next(before_last);
+ next(pos) = first;
+ next(before_last) = after;
+ }
+ }
+
+ template < class Node, class Next >
+ inline Node slist_reverse(Node node, Node empty, Next next)
+ {
+ Node result = node;
+ node = next(node);
+ next(result) = empty;
+ while (node)
+ {
+ Node next = next(node);
+ next(node) = result;
+ result = node;
+ node = next;
+ }
+ return result;
+ }
+
+ template < class Node, class Next >
+ inline std::size_t slist_size(Node head, Node empty, Next next)
+ {
+ std::size_t s = 0;
+ for (; head != empty; head = next(head))
+ ++s;
+ return s;
+ }
+
+ template < class Next, class Data > class slist_iterator_policies
+ {
+ public:
+ explicit slist_iterator_policies(const Next& n, const Data& d)
+ : m_next(n), m_data(d)
+ {
+ }
+
+ template < class Reference, class Node >
+ Reference dereference(type< Reference >, const Node& x) const
+ {
+ return m_data(x);
+ }
+
+ template < class Node > void increment(Node& x) const { x = m_next(x); }
+
+ template < class Node > bool equal(Node& x, Node& y) const
+ {
+ return x == y;
+ }
+
+ protected:
+ Next m_next;
+ Data m_data;
+ };
+
+ //===========================================================================
+ // Doubly-Linked List Generic Implementation Functions
+
+ template < class Node, class Next, class Prev >
+ inline void dlist_insert_before(Node pos, Node x, Next next, Prev prev)
+ {
+ next(x) = pos;
+ prev(x) = prev(pos);
+ next(prev(pos)) = x;
+ prev(pos) = x;
+ }
+
+ template < class Node, class Next, class Prev >
+ void dlist_remove(Node pos, Next next, Prev prev)
+ {
+ Node next_node = next(pos);
+ Node prev_node = prev(pos);
+ next(prev_node) = next_node;
+ prev(next_node) = prev_node;
+ }
+
+ // This deletes every node in the list except the
+ // sentinel node.
+ template < class Node, class Delete >
+ inline void dlist_clear(Node sentinel, Delete del)
+ {
+ Node i, tmp;
+ i = next(sentinel);
+ while (i != sentinel)
+ {
+ tmp = i;
+ i = next(i);
+ del(tmp);
+ }
+ }
+
+ template < class Node > inline bool dlist_empty(Node dummy)
+ {
+ return next(dummy) == dummy;
+ }
+
+ template < class Node, class Next, class Prev >
+ void dlist_transfer(Node pos, Node first, Node last, Next next, Prev prev)
+ {
+ if (pos != last)
+ {
+ // Remove [first,last) from its old position
+ next(prev(last)) = pos;
+ next(prev(first)) = last;
+ next(prev(pos)) = first;
+
+ // Splice [first,last) into its new position
+ Node tmp = prev(pos);
+ prev(pos) = prev(last);
+ prev(last) = prev(first);
+ prev(first) = tmp;
+ }
+ }
+
+ template < class Next, class Prev, class Data >
+ class dlist_iterator_policies : public slist_iterator_policies< Next, Data >
+ {
+ typedef slist_iterator_policies< Next, Data > Base;
+
+ public:
+ template < class Node > void decrement(Node& x) const { x = m_prev(x); }
+
+ dlist_iterator_policies(Next n, Prev p, Data d) : Base(n, d), m_prev(p)
+ {
+ }
+
+ protected:
+ Prev m_prev;
+ };
+
+} // namespace detail
+} // namespace boost
+
+#endif // BOOST_LIST_BASE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/permutation.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/permutation.hpp
new file mode 100644
index 0000000000..31ced8e79b
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/permutation.hpp
@@ -0,0 +1,211 @@
+// (C) Copyright Jeremy Siek 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PERMUTATION_HPP
+#define BOOST_PERMUTATION_HPP
+
+#include <vector>
+#include <memory>
+#include <functional>
+#include <algorithm>
+#include <boost/graph/detail/shadow_iterator.hpp>
+
+namespace boost
+{
+
+template < class Iter1, class Iter2 >
+void permute_serial(Iter1 permuter, Iter1 last, Iter2 result)
+{
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ typedef std::ptrdiff_t D :
+#else
+ typedef typename std::iterator_traits< Iter1 >::difference_type D;
+#endif
+
+ D n
+ = 0;
+ while (permuter != last)
+ {
+ std::swap(result[n], result[*permuter]);
+ ++n;
+ ++permuter;
+ }
+}
+
+template < class InIter, class RandIterP, class RandIterR >
+void permute_copy(InIter first, InIter last, RandIterP p, RandIterR result)
+{
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ typedef std::ptrdiff_t i = 0;
+#else
+ typename std::iterator_traits< RandIterP >::difference_type i = 0;
+#endif
+ for (; first != last; ++first, ++i)
+ result[p[i]] = *first;
+}
+
+namespace detail
+{
+
+ template < class RandIter, class RandIterPerm, class D, class T >
+ void permute_helper(RandIter first, RandIter last, RandIterPerm p, D, T)
+ {
+ D i = 0, pi, n = last - first, cycle_start;
+ T tmp;
+ std::vector< int > visited(n, false);
+
+ while (i != n)
+ { // continue until all elements have been processed
+ cycle_start = i;
+ tmp = first[i];
+ do
+ { // walk around a cycle
+ pi = p[i];
+ visited[pi] = true;
+ std::swap(tmp, first[pi]);
+ i = pi;
+ } while (i != cycle_start);
+
+ // find the next cycle
+ for (i = 0; i < n; ++i)
+ if (visited[i] == false)
+ break;
+ }
+ }
+
+} // namespace detail
+
+template < class RandIter, class RandIterPerm >
+void permute(RandIter first, RandIter last, RandIterPerm p)
+{
+ detail::permute_helper(first, last, p, last - first, *first);
+}
+
+// Knuth 1.3.3, Vol. 1 p 176
+// modified for zero-based arrays
+// time complexity?
+//
+// WARNING: T must be a signed integer!
+template < class PermIter > void invert_permutation(PermIter X, PermIter Xend)
+{
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ typedef std::ptrdiff_t T :
+#else
+ typedef typename std::iterator_traits< PermIter >::value_type T;
+#endif
+ T n
+ = Xend - X;
+ T m = n;
+ T j = -1;
+
+ while (m > 0)
+ {
+ T i = X[m - 1] + 1;
+ if (i > 0)
+ {
+ do
+ {
+ X[m - 1] = j - 1;
+ j = -m;
+ m = i;
+ i = X[m - 1] + 1;
+ } while (i > 0);
+ i = j;
+ }
+ X[m - 1] = -i - 1;
+ --m;
+ }
+}
+
+// Takes a "normal" permutation array (and its inverse), and turns it
+// into a BLAS-style permutation array (which can be thought of as a
+// serialized permutation).
+template < class Iter1, class Iter2, class Iter3 >
+inline void serialize_permutation(Iter1 q, Iter1 q_end, Iter2 q_inv, Iter3 p)
+{
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ typedef std::ptrdiff_t P1;
+ typedef std::ptrdiff_t P2;
+ typedef std::ptrdiff_t D;
+#else
+ typedef typename std::iterator_traits< Iter1 >::value_type P1;
+ typedef typename std::iterator_traits< Iter2 >::value_type P2;
+ typedef typename std::iterator_traits< Iter1 >::difference_type D;
+#endif
+ D n = q_end - q;
+ for (D i = 0; i < n; ++i)
+ {
+ P1 qi = q[i];
+ P2 qii = q_inv[i];
+ *p++ = qii;
+ std::swap(q[i], q[qii]);
+ std::swap(q_inv[i], q_inv[qi]);
+ }
+}
+
+// Not used anymore, leaving it here for future reference.
+template < typename Iter, typename Compare >
+void merge_sort(Iter first, Iter last, Compare cmp)
+{
+ if (first + 1 < last)
+ {
+ Iter mid = first + (last - first) / 2;
+ merge_sort(first, mid, cmp);
+ merge_sort(mid, last, cmp);
+ std::inplace_merge(first, mid, last, cmp);
+ }
+}
+
+// time: N log N + 3N + ?
+// space: 2N
+template < class Iter, class IterP, class Cmp, class Alloc >
+inline void sortp(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
+{
+ typedef typename std::iterator_traits< IterP >::value_type P;
+ typedef typename std::iterator_traits< IterP >::difference_type D;
+ D n = last - first;
+ std::vector< P, Alloc > q(n);
+ for (D i = 0; i < n; ++i)
+ q[i] = i;
+ std::sort(make_shadow_iter(first, q.begin()),
+ make_shadow_iter(last, q.end()), shadow_cmp< Cmp >(cmp));
+ invert_permutation(q.begin(), q.end());
+ std::copy(q.begin(), q.end(), p);
+}
+
+template < class Iter, class IterP, class Cmp >
+inline void sortp(Iter first, Iter last, IterP p, Cmp cmp)
+{
+ typedef typename std::iterator_traits< IterP >::value_type P;
+ sortp(first, last, p, cmp, std::allocator< P >());
+}
+
+template < class Iter, class IterP >
+inline void sortp(Iter first, Iter last, IterP p)
+{
+ typedef typename std::iterator_traits< Iter >::value_type T;
+ typedef typename std::iterator_traits< IterP >::value_type P;
+ sortp(first, last, p, std::less< T >(), std::allocator< P >());
+}
+
+template < class Iter, class IterP, class Cmp, class Alloc >
+inline void sortv(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
+{
+ typedef typename std::iterator_traits< IterP >::value_type P;
+ typedef typename std::iterator_traits< IterP >::difference_type D;
+ D n = last - first;
+ std::vector< P, Alloc > q(n), q_inv(n);
+ for (D i = 0; i < n; ++i)
+ q_inv[i] = i;
+ std::sort(make_shadow_iter(first, q_inv.begin()),
+ make_shadow_iter(last, q_inv.end()), shadow_cmp< Cmp >(cmp));
+ std::copy(q_inv, q_inv.end(), q.begin());
+ invert_permutation(q.begin(), q.end());
+ serialize_permutation(q.begin(), q.end(), q_inv.end(), p);
+}
+
+} // namespace boost
+
+#endif // BOOST_PERMUTATION_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/self_avoiding_walk.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/self_avoiding_walk.hpp
new file mode 100644
index 0000000000..52ad1cbb92
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/self_avoiding_walk.hpp
@@ -0,0 +1,483 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_SELF_AVOIDING_WALK_HPP
+#define BOOST_SELF_AVOIDING_WALK_HPP
+
+/*
+ This file defines necessary components for SAW.
+
+ mesh language: (defined by myself to clearify what is what)
+ A triangle in mesh is called an triangle.
+ An edge in mesh is called an line.
+ A vertex in mesh is called a point.
+
+ A triangular mesh corresponds to a graph in which a vertex is a
+ triangle and an edge(u, v) stands for triangle u and triangle v
+ share an line.
+
+ After this point, a vertex always refers to vertex in graph,
+ therefore it is a traingle in mesh.
+
+ */
+
+#include <utility>
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map/property_map.hpp>
+
+#define SAW_SENTINAL -1
+
+namespace boost
+{
+
+template < class T1, class T2, class T3 > struct triple
+{
+ T1 first;
+ T2 second;
+ T3 third;
+ triple(const T1& a, const T2& b, const T3& c)
+ : first(a), second(b), third(c)
+ {
+ }
+ triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {}
+};
+
+typedef triple< int, int, int > Triple;
+
+/* Define a vertex property which has a triangle inside. Triangle is
+ represented by a triple. */
+struct triangle_tag
+{
+ enum
+ {
+ num = 100
+ };
+};
+typedef property< triangle_tag, Triple > triangle_property;
+
+/* Define an edge property with a line. A line is represented by a
+ pair. This is not required for SAW though.
+*/
+struct line_tag
+{
+ enum
+ {
+ num = 101
+ };
+};
+template < class T >
+struct line_property : public property< line_tag, std::pair< T, T > >
+{
+};
+
+/*Precondition: Points in a Triangle are in order */
+template < class Triangle, class Line >
+inline void get_sharing(const Triangle& a, const Triangle& b, Line& l)
+{
+ l.first = SAW_SENTINAL;
+ l.second = SAW_SENTINAL;
+
+ if (a.first == b.first)
+ {
+ l.first = a.first;
+ if (a.second == b.second || a.second == b.third)
+ l.second = a.second;
+ else if (a.third == b.second || a.third == b.third)
+ l.second = a.third;
+ }
+ else if (a.first == b.second)
+ {
+ l.first = a.first;
+ if (a.second == b.third)
+ l.second = a.second;
+ else if (a.third == b.third)
+ l.second = a.third;
+ }
+ else if (a.first == b.third)
+ {
+ l.first = a.first;
+ }
+ else if (a.second == b.first)
+ {
+ l.first = a.second;
+ if (a.third == b.second || a.third == b.third)
+ l.second = a.third;
+ }
+ else if (a.second == b.second)
+ {
+ l.first = a.second;
+ if (a.third == b.third)
+ l.second = a.third;
+ }
+ else if (a.second == b.third)
+ {
+ l.first = a.second;
+ }
+ else if (a.third == b.first || a.third == b.second || a.third == b.third)
+ l.first = a.third;
+
+ /*Make it in order*/
+ if (l.first > l.second)
+ {
+ typename Line::first_type i = l.first;
+ l.first = l.second;
+ l.second = i;
+ }
+}
+
+template < class TriangleDecorator, class Vertex, class Line >
+struct get_vertex_sharing
+{
+ typedef std::pair< Vertex, Line > Pair;
+ get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {}
+ inline Line operator()(const Vertex& u, const Vertex& v) const
+ {
+ Line l;
+ get_sharing(td[u], td[v], l);
+ return l;
+ }
+ inline Line operator()(const Pair& u, const Vertex& v) const
+ {
+ Line l;
+ get_sharing(td[u.first], td[v], l);
+ return l;
+ }
+ inline Line operator()(const Pair& u, const Pair& v) const
+ {
+ Line l;
+ get_sharing(td[u.first], td[v.first], l);
+ return l;
+ }
+ TriangleDecorator td;
+};
+
+/* HList has to be a handle of data holder so that pass-by-value is
+ * in right logic.
+ *
+ * The element of HList is a pair of vertex and line. (remember a
+ * line is a pair of two ints.). That indicates the walk w from
+ * current vertex is across line. (If the first of line is -1, it is
+ * a point though.
+ */
+template < class TriangleDecorator, class HList, class IteratorD >
+class SAW_visitor : public bfs_visitor<>, public dfs_visitor<>
+{
+ typedef typename boost::property_traits< IteratorD >::value_type iter;
+ /*use boost shared_ptr*/
+ typedef typename HList::element_type::value_type::second_type Line;
+
+public:
+ typedef tree_edge_tag category;
+
+ inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia)
+ : td(_td), hlist(_hlist), iter_d(ia)
+ {
+ }
+
+ template < class Vertex, class Graph >
+ inline void start_vertex(Vertex v, Graph&)
+ {
+ Line l1;
+ l1.first = SAW_SENTINAL;
+ l1.second = SAW_SENTINAL;
+ hlist->push_front(std::make_pair(v, l1));
+ iter_d[v] = hlist->begin();
+ }
+
+ /*Several symbols:
+ w(i): i-th triangle in walk w
+ w(i) |- w(i+1): w enter w(i+1) from w(i) over a line
+ w(i) ~> w(i+1): w enter w(i+1) from w(i) over a point
+ w(i) -> w(i+1): w enter w(i+1) from w(i)
+ w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1)
+ */
+ template < class Edge, class Graph > bool tree_edge(Edge e, Graph& G)
+ {
+ using std::make_pair;
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex;
+ Vertex tau = target(e, G);
+ Vertex i = source(e, G);
+
+ get_vertex_sharing< TriangleDecorator, Vertex, Line > get_sharing_line(
+ td);
+
+ Line tau_i = get_sharing_line(tau, i);
+
+ iter w_end = hlist->end();
+
+ iter w_i = iter_d[i];
+
+ iter w_i_m_1 = w_i;
+ iter w_i_p_1 = w_i;
+
+ /*----------------------------------------------------------
+ * true false
+ *==========================================================
+ *a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null
+ *----------------------------------------------------------
+ *b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet
+ *----------------------------------------------------------
+ */
+
+ bool a = false, b = false;
+
+ --w_i_m_1;
+ ++w_i_p_1;
+ b = (w_i->second.first != SAW_SENTINAL);
+
+ if (w_i_m_1 != w_end)
+ {
+ a = (w_i_m_1->second.first != SAW_SENTINAL);
+ }
+
+ if (a)
+ {
+
+ if (b)
+ {
+ /*Case 1:
+
+ w(i-1) |- w(i) |- w(i+1)
+ */
+ Line l1 = get_sharing_line(*w_i_m_1, tau);
+
+ iter w_i_m_2 = w_i_m_1;
+ --w_i_m_2;
+
+ bool c = true;
+
+ if (w_i_m_2 != w_end)
+ {
+ c = w_i_m_2->second != l1;
+ }
+
+ if (c)
+ { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */
+ /*extension: w(i-1) -> tau |- w(i) */
+ w_i_m_1->second = l1;
+ /*insert(pos, const T&) is to insert before pos*/
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ }
+ else
+ { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */
+ /*must be w(i-2) ~> w(i-1) */
+
+ bool d = true;
+ // need to handle the case when w_i_p_1 is null
+ Line l3 = get_sharing_line(*w_i_p_1, tau);
+ if (w_i_p_1 != w_end)
+ d = w_i_p_1->second != l3;
+ if (d)
+ { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */
+ /*extension: w(i) |- tau -> w(i+1) */
+ w_i->second = tau_i;
+ iter_d[tau]
+ = hlist->insert(w_i_p_1, make_pair(tau, l3));
+ }
+ else
+ { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */
+ /*must be w(1+1) ~> w(i+2) */
+ Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1);
+ if (l5 != w_i_p_1->second)
+ { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */
+ /*extension: w(i-2) -> tau |- w(i) |- w(i-1) ->
+ * w(i+1) */
+ w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
+ iter_d[tau]
+ = hlist->insert(w_i, make_pair(tau, tau_i));
+ w_i->second = w_i_m_1->second;
+ w_i_m_1->second = l5;
+ iter_d[w_i_m_1->first]
+ = hlist->insert(w_i_p_1, *w_i_m_1);
+ hlist->erase(w_i_m_1);
+ }
+ else
+ {
+ /*mesh is tetrahedral*/
+ // dont know what that means.
+ ;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*Case 2:
+
+ w(i-1) |- w(i) ~> w(1+1)
+ */
+
+ if (w_i->second.second == tau_i.first
+ || w_i->second.second == tau_i.second)
+ { /*w(i) ^ w(i+1) < w(i) ^ tau*/
+ /*extension: w(i) |- tau -> w(i+1) */
+ w_i->second = tau_i;
+ Line l1 = get_sharing_line(*w_i_p_1, tau);
+ iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
+ }
+ else
+ { /*w(i) ^ w(i+1) !< w(i) ^ tau*/
+ Line l1 = get_sharing_line(*w_i_m_1, tau);
+ bool c = true;
+ iter w_i_m_2 = w_i_m_1;
+ --w_i_m_2;
+ if (w_i_m_2 != w_end)
+ c = l1 != w_i_m_2->second;
+ if (c)
+ { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/
+ /*extension: w(i-1) -> tau |- w(i)*/
+ w_i_m_1->second = l1;
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ }
+ else
+ { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/
+ /*must be w(i-2)~>w(i-1)*/
+ /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/
+ w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ w_i->second = w_i_m_1->second;
+ w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1);
+ iter_d[w_i_m_1->first]
+ = hlist->insert(w_i_p_1, *w_i_m_1);
+ hlist->erase(w_i_m_1);
+ }
+ }
+ }
+ }
+ else
+ {
+
+ if (b)
+ {
+ /*Case 3:
+
+ w(i-1) ~> w(i) |- w(i+1)
+ */
+ bool c = false;
+ if (w_i_m_1 != w_end)
+ c = (w_i_m_1->second.second == tau_i.first)
+ || (w_i_m_1->second.second == tau_i.second);
+
+ if (c)
+ { /*w(i-1) ^ w(i) < w(i) ^ tau*/
+ /* extension: w(i-1) -> tau |- w(i) */
+ if (w_i_m_1 != w_end)
+ w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ }
+ else
+ {
+ bool d = true;
+ Line l1;
+ l1.first = SAW_SENTINAL;
+ l1.second = SAW_SENTINAL;
+ if (w_i_p_1 != w_end)
+ {
+ l1 = get_sharing_line(*w_i_p_1, tau);
+ d = l1 != w_i_p_1->second;
+ }
+ if (d)
+ { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/
+ /*extension: w(i) |- tau -> w(i+1) */
+ w_i->second = tau_i;
+ iter_d[tau]
+ = hlist->insert(w_i_p_1, make_pair(tau, l1));
+ }
+ else
+ {
+ /*must be w(i+1) ~> w(i+2)*/
+ /*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2)
+ */
+ iter w_i_p_2 = w_i_p_1;
+ ++w_i_p_2;
+
+ w_i_p_1->second = w_i->second;
+ iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i));
+ hlist->erase(w_i);
+ Line l2 = get_sharing_line(*w_i_p_2, tau);
+ iter_d[tau]
+ = hlist->insert(w_i_p_2, make_pair(tau, l2));
+ }
+ }
+ }
+ else
+ {
+ /*Case 4:
+
+ w(i-1) ~> w(i) ~> w(i+1)
+
+ */
+ bool c = false;
+ if (w_i_m_1 != w_end)
+ {
+ c = (w_i_m_1->second.second == tau_i.first)
+ || (w_i_m_1->second.second == tau_i.second);
+ }
+ if (c)
+ { /*w(i-1) ^ w(i) < w(i) ^ tau */
+ /*extension: w(i-1) -> tau |- w(i) */
+ if (w_i_m_1 != w_end)
+ w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ }
+ else
+ {
+ /*extension: w(i) |- tau -> w(i+1) */
+ w_i->second = tau_i;
+ Line l1;
+ l1.first = SAW_SENTINAL;
+ l1.second = SAW_SENTINAL;
+ if (w_i_p_1 != w_end)
+ l1 = get_sharing_line(*w_i_p_1, tau);
+ iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
+ }
+ }
+ }
+
+ return true;
+ }
+
+protected:
+ TriangleDecorator td; /*a decorator for vertex*/
+ HList hlist;
+ /*This must be a handle of list to record the SAW
+ The element type of the list is pair<Vertex, Line>
+ */
+
+ IteratorD iter_d;
+ /*Problem statement: Need a fast access to w for triangle i.
+ *Possible solution: mantain an array to record.
+ iter_d[i] will return an iterator
+ which points to w(i), where i is a vertex
+ representing triangle i.
+ */
+};
+
+template < class Triangle, class HList, class Iterator >
+inline SAW_visitor< Triangle, HList, Iterator > visit_SAW(
+ Triangle t, HList hl, Iterator i)
+{
+ return SAW_visitor< Triangle, HList, Iterator >(t, hl, i);
+}
+
+template < class Tri, class HList, class Iter >
+inline SAW_visitor< random_access_iterator_property_map< Tri*, Tri, Tri& >,
+ HList, random_access_iterator_property_map< Iter*, Iter, Iter& > >
+visit_SAW_ptr(Tri* t, HList hl, Iter* i)
+{
+ typedef random_access_iterator_property_map< Tri*, Tri, Tri& > TriD;
+ typedef random_access_iterator_property_map< Iter*, Iter, Iter& > IterD;
+ return SAW_visitor< TriD, HList, IterD >(t, hl, i);
+}
+
+// should also have combo's of pointers, and also const :(
+
+}
+
+#endif /*BOOST_SAW_H*/
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/shadow_iterator.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/shadow_iterator.hpp
new file mode 100644
index 0000000000..060d13fcc9
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/shadow_iterator.hpp
@@ -0,0 +1,183 @@
+// (C) Copyright Jeremy Siek 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_SHADOW_ITERATOR_HPP
+#define BOOST_SHADOW_ITERATOR_HPP
+
+#include <boost/iterator_adaptors.hpp>
+#include <boost/operators.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < class A, class B, class D >
+ class shadow_proxy : boost::operators< shadow_proxy< A, B, D > >
+ {
+ typedef shadow_proxy self;
+
+ public:
+ inline shadow_proxy(A aa, B bb) : a(aa), b(bb) {}
+ inline shadow_proxy(const self& x) : a(x.a), b(x.b) {}
+ template < class Self > inline shadow_proxy(Self x) : a(x.a), b(x.b) {}
+ inline self& operator=(const self& x)
+ {
+ a = x.a;
+ b = x.b;
+ return *this;
+ }
+ inline self& operator++()
+ {
+ ++a;
+ return *this;
+ }
+ inline self& operator--()
+ {
+ --a;
+ return *this;
+ }
+ inline self& operator+=(const self& x)
+ {
+ a += x.a;
+ return *this;
+ }
+ inline self& operator-=(const self& x)
+ {
+ a -= x.a;
+ return *this;
+ }
+ inline self& operator*=(const self& x)
+ {
+ a *= x.a;
+ return *this;
+ }
+ inline self& operator/=(const self& x)
+ {
+ a /= x.a;
+ return *this;
+ }
+ inline self& operator%=(const self& x) { return *this; } // JGS
+ inline self& operator&=(const self& x) { return *this; } // JGS
+ inline self& operator|=(const self& x) { return *this; } // JGS
+ inline self& operator^=(const self& x) { return *this; } // JGS
+ inline friend D operator-(const self& x, const self& y)
+ {
+ return x.a - y.a;
+ }
+ inline bool operator==(const self& x) const { return a == x.a; }
+ inline bool operator<(const self& x) const { return a < x.a; }
+ // protected:
+ A a;
+ B b;
+ };
+
+ struct shadow_iterator_policies
+ {
+ template < typename iter_pair > void initialize(const iter_pair&) {}
+
+ template < typename Iter >
+ typename Iter::reference dereference(const Iter& i) const
+ {
+ typedef typename Iter::reference R;
+ return R(*i.base().first, *i.base().second);
+ }
+ template < typename Iter >
+ bool equal(const Iter& p1, const Iter& p2) const
+ {
+ return p1.base().first == p2.base().first;
+ }
+ template < typename Iter > void increment(Iter& i)
+ {
+ ++i.base().first;
+ ++i.base().second;
+ }
+
+ template < typename Iter > void decrement(Iter& i)
+ {
+ --i.base().first;
+ --i.base().second;
+ }
+
+ template < typename Iter > bool less(const Iter& x, const Iter& y) const
+ {
+ return x.base().first < y.base().first;
+ }
+ template < typename Iter >
+ typename Iter::difference_type distance(
+ const Iter& x, const Iter& y) const
+ {
+ return y.base().first - x.base().first;
+ }
+ template < typename D, typename Iter > void advance(Iter& p, D n)
+ {
+ p.base().first += n;
+ p.base().second += n;
+ }
+ };
+
+} // namespace detail
+
+template < typename IterA, typename IterB > struct shadow_iterator_generator
+{
+
+ // To use the iterator_adaptor we can't derive from
+ // random_access_iterator because we don't have a real reference.
+ // However, we want the STL algorithms to treat the shadow
+ // iterator like a random access iterator.
+ struct shadow_iterator_tag : public std::input_iterator_tag
+ {
+ operator std::random_access_iterator_tag()
+ {
+ return std::random_access_iterator_tag();
+ };
+ };
+ typedef typename std::iterator_traits< IterA >::value_type Aval;
+ typedef typename std::iterator_traits< IterB >::value_type Bval;
+ typedef typename std::iterator_traits< IterA >::reference Aref;
+ typedef typename std::iterator_traits< IterB >::reference Bref;
+ typedef typename std::iterator_traits< IterA >::difference_type D;
+ typedef detail::shadow_proxy< Aval, Bval, Aval > V;
+ typedef detail::shadow_proxy< Aref, Bref, Aval > R;
+ typedef iterator_adaptor< std::pair< IterA, IterB >,
+ detail::shadow_iterator_policies, V, R, V*, shadow_iterator_tag, D >
+ type;
+};
+
+// short cut for creating a shadow iterator
+template < class IterA, class IterB >
+inline typename shadow_iterator_generator< IterA, IterB >::type
+make_shadow_iter(IterA a, IterB b)
+{
+ typedef typename shadow_iterator_generator< IterA, IterB >::type Iter;
+ return Iter(std::make_pair(a, b));
+}
+
+template < class Cmp > struct shadow_cmp
+{
+ inline shadow_cmp(const Cmp& c) : cmp(c) {}
+ template < class ShadowProxy1, class ShadowProxy2 >
+ inline bool operator()(const ShadowProxy1& x, const ShadowProxy2& y) const
+ {
+ return cmp(x.a, y.a);
+ }
+ Cmp cmp;
+};
+
+} // namespace boost
+
+namespace std
+{
+template < class A1, class B1, class D1, class A2, class B2, class D2 >
+void swap(boost::detail::shadow_proxy< A1&, B1&, D1 > x,
+ boost::detail::shadow_proxy< A2&, B2&, D2 > y)
+{
+ std::swap(x.a, y.a);
+ std::swap(x.b, y.b);
+}
+}
+
+#endif // BOOST_SHADOW_ITERATOR_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/detail/sparse_ordering.hpp b/contrib/restricted/boost/graph/include/boost/graph/detail/sparse_ordering.hpp
new file mode 100644
index 0000000000..b7bf470db0
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/detail/sparse_ordering.hpp
@@ -0,0 +1,210 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004, 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
+// Doug Gregor, D. Kevin McGrath
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================//
+#ifndef BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP
+#define BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP
+
+#include <boost/config.hpp>
+#include <vector>
+#include <queue>
+#include <boost/pending/queue.hpp>
+#include <boost/pending/mutable_queue.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/depth_first_search.hpp>
+
+namespace boost
+{
+
+namespace sparse
+{
+
+ // rcm_queue
+ //
+ // This is a custom queue type used in the
+ // *_ordering algorithms.
+ // In addition to the normal queue operations, the
+ // rcm_queue provides:
+ //
+ // int eccentricity() const;
+ // value_type spouse() const;
+ //
+
+ // yes, it's a bad name...but it works, so use it
+ template < class Vertex, class DegreeMap,
+ class Container = std::deque< Vertex > >
+ class rcm_queue : public std::queue< Vertex, Container >
+ {
+ typedef std::queue< Vertex > base;
+
+ public:
+ typedef typename base::value_type value_type;
+ typedef typename base::size_type size_type;
+
+ /* SGI queue has not had a contructor queue(const Container&) */
+ inline rcm_queue(DegreeMap deg)
+ : _size(0), Qsize(1), eccen(-1), degree(deg)
+ {
+ }
+
+ inline void pop()
+ {
+ if (!_size)
+ Qsize = base::size();
+
+ base::pop();
+ if (_size == Qsize - 1)
+ {
+ _size = 0;
+ ++eccen;
+ }
+ else
+ ++_size;
+ }
+
+ inline value_type& front()
+ {
+ value_type& u = base::front();
+ if (_size == 0)
+ w = u;
+ else if (get(degree, u) < get(degree, w))
+ w = u;
+ return u;
+ }
+
+ inline const value_type& front() const
+ {
+ const value_type& u = base::front();
+ if (_size == 0)
+ w = u;
+ else if (get(degree, u) < get(degree, w))
+ w = u;
+ return u;
+ }
+
+ inline value_type& top() { return front(); }
+ inline const value_type& top() const { return front(); }
+
+ inline size_type size() const { return base::size(); }
+
+ inline size_type eccentricity() const { return eccen; }
+ inline value_type spouse() const { return w; }
+
+ protected:
+ size_type _size;
+ size_type Qsize;
+ int eccen;
+ mutable value_type w;
+ DegreeMap degree;
+ };
+
+ template < typename Tp, typename Sequence = std::deque< Tp > >
+ class sparse_ordering_queue : public boost::queue< Tp, Sequence >
+ {
+ public:
+ typedef typename Sequence::iterator iterator;
+ typedef typename Sequence::reverse_iterator reverse_iterator;
+ typedef queue< Tp, Sequence > base;
+ typedef typename Sequence::size_type size_type;
+
+ inline iterator begin() { return this->c.begin(); }
+ inline reverse_iterator rbegin() { return this->c.rbegin(); }
+ inline iterator end() { return this->c.end(); }
+ inline reverse_iterator rend() { return this->c.rend(); }
+ inline Tp& operator[](int n) { return this->c[n]; }
+ inline size_type size() { return this->c.size(); }
+
+ protected:
+ // nothing
+ };
+
+} // namespace sparse
+
+// Compute Pseudo peripheral
+//
+// To compute an approximated peripheral for a given vertex.
+// Used in <tt>king_ordering</tt> algorithm.
+//
+template < class Graph, class Vertex, class ColorMap, class DegreeMap >
+Vertex pseudo_peripheral_pair(
+ Graph const& G, const Vertex& u, int& ecc, ColorMap color, DegreeMap degree)
+{
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+
+ sparse::rcm_queue< Vertex, DegreeMap > Q(degree);
+
+ typename boost::graph_traits< Graph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
+ if (get(color, *ui) != Color::red())
+ put(color, *ui, Color::white());
+ breadth_first_visit(G, u, buffer(Q).color_map(color));
+
+ ecc = Q.eccentricity();
+ return Q.spouse();
+}
+
+// Find a good starting node
+//
+// This is to find a good starting node for the
+// king_ordering algorithm. "good" is in the sense
+// of the ordering generated by RCM.
+//
+template < class Graph, class Vertex, class Color, class Degree >
+Vertex find_starting_node(Graph const& G, Vertex r, Color color, Degree degree)
+{
+ Vertex x, y;
+ int eccen_r, eccen_x;
+
+ x = pseudo_peripheral_pair(G, r, eccen_r, color, degree);
+ y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
+
+ while (eccen_x > eccen_r)
+ {
+ r = x;
+ eccen_r = eccen_x;
+ x = y;
+ y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
+ }
+ return x;
+}
+
+template < typename Graph >
+class out_degree_property_map
+: public put_get_helper< typename graph_traits< Graph >::degree_size_type,
+ out_degree_property_map< Graph > >
+{
+public:
+ typedef typename graph_traits< Graph >::vertex_descriptor key_type;
+ typedef typename graph_traits< Graph >::degree_size_type value_type;
+ typedef value_type reference;
+ typedef readable_property_map_tag category;
+ out_degree_property_map(const Graph& g) : m_g(g) {}
+ value_type operator[](const key_type& v) const
+ {
+ return out_degree(v, m_g);
+ }
+
+private:
+ const Graph& m_g;
+};
+template < typename Graph >
+inline out_degree_property_map< Graph > make_out_degree_map(const Graph& g)
+{
+ return out_degree_property_map< Graph >(g);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_KING_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp b/contrib/restricted/boost/graph/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp
new file mode 100644
index 0000000000..09607c49a3
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp
@@ -0,0 +1,235 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2009 Trustees of Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Michael Hansen
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_DIJKSTRA_NO_COLOR_MAP_HPP
+#define BOOST_GRAPH_DIJKSTRA_NO_COLOR_MAP_HPP
+
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/graph/relax.hpp>
+#include <boost/graph/detail/d_ary_heap.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/iteration_macros.hpp>
+
+namespace boost
+{
+
+// No init version
+template < typename Graph, typename DijkstraVisitor, typename PredecessorMap,
+ typename DistanceMap, typename WeightMap, typename VertexIndexMap,
+ typename DistanceCompare, typename DistanceWeightCombine,
+ typename DistanceInfinity, typename DistanceZero >
+void dijkstra_shortest_paths_no_color_map_no_init(const Graph& graph,
+ typename graph_traits< Graph >::vertex_descriptor start_vertex,
+ PredecessorMap predecessor_map, DistanceMap distance_map,
+ WeightMap weight_map, VertexIndexMap index_map,
+ DistanceCompare distance_compare,
+ DistanceWeightCombine distance_weight_combine,
+ DistanceInfinity distance_infinity, DistanceZero distance_zero,
+ DijkstraVisitor visitor)
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename property_traits< DistanceMap >::value_type Distance;
+
+ typedef indirect_cmp< DistanceMap, DistanceCompare >
+ DistanceIndirectCompare;
+ DistanceIndirectCompare distance_indirect_compare(
+ distance_map, distance_compare);
+
+ // Default - use d-ary heap (d = 4)
+ typedef detail::vertex_property_map_generator< Graph, VertexIndexMap,
+ std::size_t >
+ IndexInHeapMapHelper;
+ typedef typename IndexInHeapMapHelper::type IndexInHeapMap;
+ typedef d_ary_heap_indirect< Vertex, 4, IndexInHeapMap, DistanceMap,
+ DistanceCompare >
+ VertexQueue;
+
+ boost::scoped_array< std::size_t > index_in_heap_map_holder;
+ IndexInHeapMap index_in_heap = IndexInHeapMapHelper::build(
+ graph, index_map, index_in_heap_map_holder);
+ VertexQueue vertex_queue(distance_map, index_in_heap, distance_compare);
+
+ // Add vertex to the queue
+ vertex_queue.push(start_vertex);
+
+ // Starting vertex will always be the first discovered vertex
+ visitor.discover_vertex(start_vertex, graph);
+
+ while (!vertex_queue.empty())
+ {
+ Vertex min_vertex = vertex_queue.top();
+ vertex_queue.pop();
+
+ visitor.examine_vertex(min_vertex, graph);
+
+ // Check if any other vertices can be reached
+ Distance min_vertex_distance = get(distance_map, min_vertex);
+
+ if (!distance_compare(min_vertex_distance, distance_infinity))
+ {
+ // This is the minimum vertex, so all other vertices are unreachable
+ return;
+ }
+
+ // Examine neighbors of min_vertex
+ BGL_FORALL_OUTEDGES_T(min_vertex, current_edge, graph, Graph)
+ {
+ visitor.examine_edge(current_edge, graph);
+
+ // Check if the edge has a negative weight
+ if (distance_compare(get(weight_map, current_edge), distance_zero))
+ {
+ boost::throw_exception(negative_edge());
+ }
+
+ // Extract the neighboring vertex and get its distance
+ Vertex neighbor_vertex = target(current_edge, graph);
+ Distance neighbor_vertex_distance
+ = get(distance_map, neighbor_vertex);
+ bool is_neighbor_undiscovered = !distance_compare(
+ neighbor_vertex_distance, distance_infinity);
+
+ // Attempt to relax the edge
+ bool was_edge_relaxed
+ = relax_target(current_edge, graph, weight_map, predecessor_map,
+ distance_map, distance_weight_combine, distance_compare);
+
+ if (was_edge_relaxed)
+ {
+ visitor.edge_relaxed(current_edge, graph);
+ if (is_neighbor_undiscovered)
+ {
+ visitor.discover_vertex(neighbor_vertex, graph);
+ vertex_queue.push(neighbor_vertex);
+ }
+ else
+ {
+ vertex_queue.update(neighbor_vertex);
+ }
+ }
+ else
+ {
+ visitor.edge_not_relaxed(current_edge, graph);
+ }
+
+ } // end out edge iteration
+
+ visitor.finish_vertex(min_vertex, graph);
+ } // end while queue not empty
+}
+
+// Full init version
+template < typename Graph, typename DijkstraVisitor, typename PredecessorMap,
+ typename DistanceMap, typename WeightMap, typename VertexIndexMap,
+ typename DistanceCompare, typename DistanceWeightCombine,
+ typename DistanceInfinity, typename DistanceZero >
+void dijkstra_shortest_paths_no_color_map(const Graph& graph,
+ typename graph_traits< Graph >::vertex_descriptor start_vertex,
+ PredecessorMap predecessor_map, DistanceMap distance_map,
+ WeightMap weight_map, VertexIndexMap index_map,
+ DistanceCompare distance_compare,
+ DistanceWeightCombine distance_weight_combine,
+ DistanceInfinity distance_infinity, DistanceZero distance_zero,
+ DijkstraVisitor visitor)
+{
+ // Initialize vertices
+ BGL_FORALL_VERTICES_T(current_vertex, graph, Graph)
+ {
+ visitor.initialize_vertex(current_vertex, graph);
+
+ // Default all distances to infinity
+ put(distance_map, current_vertex, distance_infinity);
+
+ // Default all vertex predecessors to the vertex itself
+ put(predecessor_map, current_vertex, current_vertex);
+ }
+
+ // Set distance for start_vertex to zero
+ put(distance_map, start_vertex, distance_zero);
+
+ // Pass everything on to the no_init version
+ dijkstra_shortest_paths_no_color_map_no_init(graph, start_vertex,
+ predecessor_map, distance_map, weight_map, index_map, distance_compare,
+ distance_weight_combine, distance_infinity, distance_zero, visitor);
+}
+
+namespace detail
+{
+
+ // Handle defaults for PredecessorMap, DistanceCompare,
+ // DistanceWeightCombine, DistanceInfinity and DistanceZero
+ template < typename Graph, typename DistanceMap, typename WeightMap,
+ typename VertexIndexMap, typename Params >
+ inline void dijkstra_no_color_map_dispatch2(const Graph& graph,
+ typename graph_traits< Graph >::vertex_descriptor start_vertex,
+ DistanceMap distance_map, WeightMap weight_map,
+ VertexIndexMap index_map, const Params& params)
+ {
+ // Default for predecessor map
+ dummy_property_map predecessor_map;
+
+ typedef
+ typename property_traits< DistanceMap >::value_type DistanceType;
+ DistanceType inf = choose_param(get_param(params, distance_inf_t()),
+ (std::numeric_limits< DistanceType >::max)());
+ dijkstra_shortest_paths_no_color_map(graph, start_vertex,
+ choose_param(
+ get_param(params, vertex_predecessor), predecessor_map),
+ distance_map, weight_map, index_map,
+ choose_param(get_param(params, distance_compare_t()),
+ std::less< DistanceType >()),
+ choose_param(get_param(params, distance_combine_t()),
+ std::plus< DistanceType >()),
+ inf,
+ choose_param(get_param(params, distance_zero_t()), DistanceType()),
+ choose_param(get_param(params, graph_visitor),
+ make_dijkstra_visitor(null_visitor())));
+ }
+
+ template < typename Graph, typename DistanceMap, typename WeightMap,
+ typename IndexMap, typename Params >
+ inline void dijkstra_no_color_map_dispatch1(const Graph& graph,
+ typename graph_traits< Graph >::vertex_descriptor start_vertex,
+ DistanceMap distance_map, WeightMap weight_map, IndexMap index_map,
+ const Params& params)
+ {
+ // Default for distance map
+ typedef typename property_traits< WeightMap >::value_type DistanceType;
+ typename std::vector< DistanceType >::size_type vertex_count
+ = is_default_param(distance_map) ? num_vertices(graph) : 1;
+
+ std::vector< DistanceType > default_distance_map(vertex_count);
+
+ detail::dijkstra_no_color_map_dispatch2(graph, start_vertex,
+ choose_param(distance_map,
+ make_iterator_property_map(default_distance_map.begin(),
+ index_map, default_distance_map[0])),
+ weight_map, index_map, params);
+ }
+} // namespace detail
+
+// Named parameter version
+template < typename Graph, typename Param, typename Tag, typename Rest >
+inline void dijkstra_shortest_paths_no_color_map(const Graph& graph,
+ typename graph_traits< Graph >::vertex_descriptor start_vertex,
+ const bgl_named_params< Param, Tag, Rest >& params)
+{
+ // Default for edge weight and vertex index map is to ask for them
+ // from the graph. Default for the visitor is null_visitor.
+ detail::dijkstra_no_color_map_dispatch1(graph, start_vertex,
+ get_param(params, vertex_distance),
+ choose_const_pmap(get_param(params, edge_weight), graph, edge_weight),
+ choose_const_pmap(get_param(params, vertex_index), graph, vertex_index),
+ params);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_DIJKSTRA_NO_COLOR_MAP_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/dimacs.hpp b/contrib/restricted/boost/graph/include/boost/graph/dimacs.hpp
new file mode 100644
index 0000000000..d6171d2438
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/dimacs.hpp
@@ -0,0 +1,375 @@
+// Copyright 2005 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Alex Breuer
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_DIMACS_HPP
+#define BOOST_GRAPH_DIMACS_HPP
+
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <iterator>
+#include <exception>
+#include <vector>
+#include <queue>
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+
+namespace boost
+{
+namespace graph
+{
+
+ class BOOST_SYMBOL_VISIBLE dimacs_exception : public std::exception
+ {
+ };
+
+ class dimacs_basic_reader
+ {
+ public:
+ typedef std::size_t vertices_size_type;
+ typedef std::size_t edges_size_type;
+ typedef double vertex_weight_type;
+ typedef double edge_weight_type;
+ typedef std::pair< vertices_size_type, vertices_size_type > edge_type;
+ enum incr_mode
+ {
+ edge,
+ edge_weight
+ };
+
+ dimacs_basic_reader(std::istream& in, bool want_weights = true)
+ : inpt(in), seen_edges(0), want_weights(want_weights)
+ {
+ while (getline(inpt, buf) && !buf.empty() && buf[0] == 'c')
+ ;
+
+ if (buf[0] != 'p')
+ {
+ boost::throw_exception(dimacs_exception());
+ }
+
+ std::stringstream instr(buf);
+ std::string junk;
+
+ instr >> junk >> junk >> num_vertices >> num_edges;
+ read_edge_weights.push(-1);
+ incr(edge_weight);
+ }
+
+ // for a past the end iterator
+ dimacs_basic_reader()
+ : inpt(std::cin)
+ , num_vertices(0)
+ , num_edges(0)
+ , seen_edges(0)
+ , want_weights(false)
+ {
+ }
+
+ edge_type edge_deref()
+ {
+ BOOST_ASSERT(!read_edges.empty());
+ return read_edges.front();
+ }
+
+ inline edge_type* edge_ref()
+ {
+ BOOST_ASSERT(!read_edges.empty());
+ return &read_edges.front();
+ }
+
+ inline edge_weight_type edge_weight_deref()
+ {
+ BOOST_ASSERT(!read_edge_weights.empty());
+ return read_edge_weights.front();
+ }
+
+ inline dimacs_basic_reader incr(incr_mode mode)
+ {
+ if (mode == edge)
+ {
+ BOOST_ASSERT(!read_edges.empty());
+ read_edges.pop();
+ }
+ else if (mode == edge_weight)
+ {
+ BOOST_ASSERT(!read_edge_weights.empty());
+ read_edge_weights.pop();
+ }
+
+ if ((mode == edge && read_edges.empty())
+ || (mode == edge_weight && read_edge_weights.empty()))
+ {
+
+ if (seen_edges > num_edges)
+ {
+ boost::throw_exception(dimacs_exception());
+ }
+
+ while (getline(inpt, buf) && !buf.empty() && buf[0] == 'c')
+ ;
+
+ if (!inpt.eof())
+ {
+ int source, dest, weight;
+ read_edge_line((char*)buf.c_str(), source, dest, weight);
+
+ seen_edges++;
+ source--;
+ dest--;
+
+ read_edges.push(edge_type(source, dest));
+ if (want_weights)
+ {
+ read_edge_weights.push(weight);
+ }
+ }
+ BOOST_ASSERT(read_edges.size() < 100);
+ BOOST_ASSERT(read_edge_weights.size() < 100);
+ }
+
+ // the 1000000 just happens to be about how many edges can be read
+ // in 10s
+ // if( !(seen_edges % 1000000) && !process_id( pg ) && mode ==
+ // edge ) {
+ // std::cout << "read " << seen_edges << " edges" <<
+ // std::endl;
+ // }
+ return *this;
+ }
+
+ inline bool done_edges()
+ {
+ return inpt.eof() && read_edges.size() == 0;
+ }
+
+ inline bool done_edge_weights()
+ {
+ return inpt.eof() && read_edge_weights.size() == 0;
+ }
+
+ inline vertices_size_type n_vertices() { return num_vertices; }
+
+ inline vertices_size_type processed_edges()
+ {
+ return seen_edges - read_edges.size();
+ }
+
+ inline vertices_size_type processed_edge_weights()
+ {
+ return seen_edges - read_edge_weights.size();
+ }
+
+ inline vertices_size_type n_edges() { return num_edges; }
+
+ protected:
+ bool read_edge_line(char* linebuf, int& from, int& to, int& weight)
+ {
+ char *fs = NULL, *ts = NULL, *ws = NULL;
+ char* tmp = linebuf + 2;
+
+ fs = tmp;
+ if ('e' == linebuf[0])
+ {
+ while (*tmp != '\n' && *tmp != '\0')
+ {
+ if (*tmp == ' ')
+ {
+ *tmp = '\0';
+ ts = ++tmp;
+ break;
+ }
+ tmp++;
+ }
+ *tmp = '\0';
+ if (NULL == fs || NULL == ts)
+ return false;
+ from = atoi(fs);
+ to = atoi(ts);
+ weight = 0;
+ }
+ else if ('a' == linebuf[0])
+ {
+ while (*tmp != '\n' && *tmp != '\0')
+ {
+ if (*tmp == ' ')
+ {
+ *tmp = '\0';
+ ts = ++tmp;
+ break;
+ }
+ tmp++;
+ }
+ while (*tmp != '\n' && *tmp != '\0')
+ {
+ if (*tmp == ' ')
+ {
+ *tmp = '\0';
+ ws = ++tmp;
+ break;
+ }
+ tmp++;
+ }
+ while (*tmp != '\n' && *tmp != '\0')
+ tmp++;
+ *tmp = '\0';
+ if (fs == NULL || ts == NULL || ws == NULL)
+ return false;
+ from = atoi(fs);
+ to = atoi(ts);
+ if (want_weights)
+ weight = atoi(ws);
+ else
+ weight = 0;
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ std::queue< edge_type > read_edges;
+ std::queue< edge_weight_type > read_edge_weights;
+
+ std::istream& inpt;
+ std::string buf;
+ vertices_size_type num_vertices, num_edges, seen_edges;
+ bool want_weights;
+ };
+
+ template < typename T > class dimacs_edge_iterator
+ {
+ public:
+ typedef dimacs_basic_reader::edge_type edge_type;
+ typedef dimacs_basic_reader::incr_mode incr_mode;
+
+ typedef std::input_iterator_tag iterator_category;
+ typedef edge_type value_type;
+ typedef value_type reference;
+ typedef edge_type* pointer;
+ typedef std::ptrdiff_t difference_type;
+
+ dimacs_edge_iterator(T& reader) : reader(reader) {}
+
+ inline dimacs_edge_iterator& operator++()
+ {
+ reader.incr(dimacs_basic_reader::edge);
+ return *this;
+ }
+
+ inline edge_type operator*() { return reader.edge_deref(); }
+
+ inline edge_type* operator->() { return reader.edge_ref(); }
+
+ // don't expect this to do the right thing if you're not comparing
+ // against a general past-the-end-iterator made with the default
+ // constructor for dimacs_basic_reader
+ inline bool operator==(dimacs_edge_iterator arg)
+ {
+ if (reader.n_vertices() == 0)
+ {
+ return arg.reader.done_edges();
+ }
+ else if (arg.reader.n_vertices() == 0)
+ {
+ return reader.done_edges();
+ }
+ else
+ {
+ return false;
+ }
+ return false;
+ }
+
+ inline bool operator!=(dimacs_edge_iterator arg)
+ {
+ if (reader.n_vertices() == 0)
+ {
+ return !arg.reader.done_edges();
+ }
+ else if (arg.reader.n_vertices() == 0)
+ {
+ return !reader.done_edges();
+ }
+ else
+ {
+ return true;
+ }
+ return true;
+ }
+
+ private:
+ T& reader;
+ };
+
+ template < typename T > class dimacs_edge_weight_iterator
+ {
+ public:
+ typedef dimacs_basic_reader::edge_weight_type edge_weight_type;
+ typedef dimacs_basic_reader::incr_mode incr_mode;
+
+ dimacs_edge_weight_iterator(T& reader) : reader(reader) {}
+
+ inline dimacs_edge_weight_iterator& operator++()
+ {
+ reader.incr(dimacs_basic_reader::edge_weight);
+ return *this;
+ }
+
+ inline edge_weight_type operator*()
+ {
+ return reader.edge_weight_deref();
+ }
+
+ // don't expect this to do the right thing if you're not comparing
+ // against a general past-the-end-iterator made with the default
+ // constructor for dimacs_basic_reader
+ inline bool operator==(dimacs_edge_weight_iterator arg)
+ {
+ if (reader.n_vertices() == 0)
+ {
+ return arg.reader.done_edge_weights();
+ }
+ else if (arg.reader.n_vertices() == 0)
+ {
+ return reader.done_edge_weights();
+ }
+ else
+ {
+ return false;
+ }
+ return false;
+ }
+
+ inline bool operator!=(dimacs_edge_weight_iterator arg)
+ {
+ if (reader.n_vertices() == 0)
+ {
+ return !arg.reader.done_edge_weights();
+ }
+ else if (arg.reader.n_vertices() == 0)
+ {
+ return !reader.done_edge_weights();
+ }
+ else
+ {
+ return true;
+ }
+ return true;
+ }
+
+ private:
+ T& reader;
+ };
+
+}
+} // end namespace boost::graph
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/directed_graph.hpp b/contrib/restricted/boost/graph/include/boost/graph/directed_graph.hpp
new file mode 100644
index 0000000000..f40c1beb1b
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/directed_graph.hpp
@@ -0,0 +1,795 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_DIRECTED_GRAPH_HPP
+#define BOOST_GRAPH_DIRECTED_GRAPH_HPP
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/property.hpp>
+#include <boost/property_map/transform_value_property_map.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/mpl/if.hpp>
+
+namespace boost
+{
+struct directed_graph_tag
+{
+};
+
+/**
+ * The directed_graph class template is a simplified version of the BGL
+ * adjacency list. This class is provided for ease of use, but may not
+ * perform as well as custom-defined adjacency list classes. Instances of
+ * this template model the BidirectionalGraph, VertexIndexGraph, and
+ * EdgeIndexGraph concepts. The graph is also fully mutable, supporting
+ * both insertions and removals of vertices and edges.
+ *
+ * @note Special care must be taken when removing vertices or edges since
+ * those operations can invalidate the numbering of vertices.
+ */
+template < typename VertexProp = no_property, typename EdgeProp = no_property,
+ typename GraphProp = no_property >
+class directed_graph
+{
+public:
+ typedef GraphProp graph_property_type;
+ typedef VertexProp vertex_property_type;
+ typedef EdgeProp edge_property_type;
+ typedef typename lookup_one_property< GraphProp, graph_bundle_t >::type
+ graph_bundled;
+ typedef typename lookup_one_property< VertexProp, vertex_bundle_t >::type
+ vertex_bundled;
+ typedef typename lookup_one_property< EdgeProp, edge_bundle_t >::type
+ edge_bundled;
+
+public:
+ // Embed indices into the vertex type.
+ typedef property< vertex_index_t, unsigned, vertex_property_type >
+ internal_vertex_property;
+ typedef property< edge_index_t, unsigned, edge_property_type >
+ internal_edge_property;
+
+public:
+ typedef adjacency_list< listS, listS, bidirectionalS,
+ internal_vertex_property, internal_edge_property, GraphProp, listS >
+ graph_type;
+
+private:
+ // storage selectors
+ typedef typename graph_type::vertex_list_selector vertex_list_selector;
+ typedef typename graph_type::edge_list_selector edge_list_selector;
+ typedef typename graph_type::out_edge_list_selector out_edge_list_selector;
+ typedef typename graph_type::directed_selector directed_selector;
+
+public:
+ // more commonly used graph types
+ typedef typename graph_type::stored_vertex stored_vertex;
+ typedef typename graph_type::vertices_size_type vertices_size_type;
+ typedef typename graph_type::edges_size_type edges_size_type;
+ typedef typename graph_type::degree_size_type degree_size_type;
+ typedef typename graph_type::vertex_descriptor vertex_descriptor;
+ typedef typename graph_type::edge_descriptor edge_descriptor;
+
+ // iterator types
+ typedef typename graph_type::vertex_iterator vertex_iterator;
+ typedef typename graph_type::edge_iterator edge_iterator;
+ typedef typename graph_type::out_edge_iterator out_edge_iterator;
+ typedef typename graph_type::in_edge_iterator in_edge_iterator;
+ typedef typename graph_type::adjacency_iterator adjacency_iterator;
+
+ // miscellaneous types
+ typedef directed_graph_tag graph_tag;
+ typedef typename graph_type::directed_category directed_category;
+ typedef typename graph_type::edge_parallel_category edge_parallel_category;
+ typedef typename graph_type::traversal_category traversal_category;
+
+ typedef std::size_t vertex_index_type;
+ typedef std::size_t edge_index_type;
+
+ directed_graph(GraphProp const& p = GraphProp())
+ : m_graph(p)
+ , m_num_vertices(0)
+ , m_num_edges(0)
+ , m_max_vertex_index(0)
+ , m_max_edge_index(0)
+ {
+ }
+
+ directed_graph(directed_graph const& x)
+ : m_graph(x.m_graph)
+ , m_num_vertices(x.m_num_vertices)
+ , m_num_edges(x.m_num_edges)
+ , m_max_vertex_index(x.m_max_vertex_index)
+ , m_max_edge_index(x.m_max_edge_index)
+ {
+ }
+
+ directed_graph(vertices_size_type n, GraphProp const& p = GraphProp())
+ : m_graph(n, p)
+ , m_num_vertices(n)
+ , m_num_edges(0)
+ , m_max_vertex_index(n)
+ , m_max_edge_index(0)
+ {
+ renumber_vertex_indices();
+ }
+
+ template < typename EdgeIterator >
+ directed_graph(EdgeIterator f, EdgeIterator l, vertices_size_type n,
+ edges_size_type m = 0, GraphProp const& p = GraphProp())
+ : m_graph(f, l, n, m, p)
+ , m_num_vertices(n)
+ , m_num_edges(0)
+ , m_max_vertex_index(n)
+ , m_max_edge_index(0)
+ {
+ // Unfortunately, we have to renumber the entire graph.
+ renumber_indices();
+
+ // Can't always guarantee that the number of edges is actually
+ // m if distance(f, l) != m (or is undefined).
+ m_num_edges = m_max_edge_index = boost::num_edges(m_graph);
+ }
+
+ directed_graph& operator=(directed_graph const& g)
+ {
+ if (&g != this)
+ {
+ m_graph = g.m_graph;
+ m_num_vertices = g.m_num_vertices;
+ m_num_edges = g.m_num_edges;
+ m_max_vertex_index = g.m_max_vertex_index;
+ m_max_edge_index = g.m_max_edge_index;
+ }
+ return *this;
+ }
+
+ // The impl_() methods are not part of the public interface.
+ graph_type& impl() { return m_graph; }
+
+ graph_type const& impl() const { return m_graph; }
+
+ // The following methods are not part of the public interface
+ vertices_size_type num_vertices() const { return m_num_vertices; }
+
+private:
+ // This helper function manages the attribution of vertex indices.
+ vertex_descriptor make_index(vertex_descriptor v)
+ {
+ boost::put(vertex_index, m_graph, v, m_max_vertex_index);
+ m_num_vertices++;
+ m_max_vertex_index++;
+ return v;
+ }
+
+public:
+ vertex_descriptor add_vertex()
+ {
+ return make_index(boost::add_vertex(m_graph));
+ }
+
+ vertex_descriptor add_vertex(vertex_property_type const& p)
+ {
+ return make_index(
+ boost::add_vertex(internal_vertex_property(0u, p), m_graph));
+ }
+
+ void clear_vertex(vertex_descriptor v)
+ {
+ m_num_edges -= boost::degree(v, m_graph);
+ boost::clear_vertex(v, m_graph);
+ }
+
+ void remove_vertex(vertex_descriptor v)
+ {
+ boost::remove_vertex(v, m_graph);
+ --m_num_vertices;
+ }
+
+ edges_size_type num_edges() const { return m_num_edges; }
+
+private:
+ // A helper function for managing edge index attributes.
+ std::pair< edge_descriptor, bool > const& make_index(
+ std::pair< edge_descriptor, bool > const& x)
+ {
+ if (x.second)
+ {
+ boost::put(edge_index, m_graph, x.first, m_max_edge_index);
+ ++m_num_edges;
+ ++m_max_edge_index;
+ }
+ return x;
+ }
+
+public:
+ std::pair< edge_descriptor, bool > add_edge(
+ vertex_descriptor u, vertex_descriptor v)
+ {
+ return make_index(boost::add_edge(u, v, m_graph));
+ }
+
+ std::pair< edge_descriptor, bool > add_edge(
+ vertex_descriptor u, vertex_descriptor v, edge_property_type const& p)
+ {
+ return make_index(
+ boost::add_edge(u, v, internal_edge_property(0u, p), m_graph));
+ }
+
+ void remove_edge(vertex_descriptor u, vertex_descriptor v)
+ {
+ // find all edges, (u, v)
+ std::vector< edge_descriptor > edges;
+ out_edge_iterator i, i_end;
+ for (boost::tie(i, i_end) = boost::out_edges(u, m_graph); i != i_end;
+ ++i)
+ {
+ if (boost::target(*i, m_graph) == v)
+ {
+ edges.push_back(*i);
+ }
+ }
+ // remove all edges, (u, v)
+ typename std::vector< edge_descriptor >::iterator j = edges.begin(),
+ j_end = edges.end();
+ for (; j != j_end; ++j)
+ {
+ remove_edge(*j);
+ }
+ }
+
+ void remove_edge(edge_iterator i) { remove_edge(*i); }
+
+ void remove_edge(edge_descriptor e)
+ {
+ boost::remove_edge(e, m_graph);
+ --m_num_edges;
+ }
+
+ vertex_index_type max_vertex_index() const { return m_max_vertex_index; }
+
+ void renumber_vertex_indices()
+ {
+ vertex_iterator i, end;
+ boost::tie(i, end) = vertices(m_graph);
+ m_max_vertex_index = renumber_vertex_indices(i, end, 0);
+ }
+
+ void remove_vertex_and_renumber_indices(vertex_iterator i)
+ {
+ vertex_iterator j = next(i), end = vertices(m_graph).second;
+ vertex_index_type n = get(vertex_index, m_graph, *i);
+
+ // remove the offending vertex and renumber everything after
+ remove_vertex(*i);
+ m_max_vertex_index = renumber_vertex_indices(j, end, n);
+ }
+
+ edge_index_type max_edge_index() const { return m_max_edge_index; }
+
+ void renumber_edge_indices()
+ {
+ edge_iterator i, end;
+ boost::tie(i, end) = edges(m_graph);
+ m_max_edge_index = renumber_edge_indices(i, end, 0);
+ }
+
+ void remove_edge_and_renumber_indices(edge_iterator i)
+ {
+ edge_iterator j = next(i), end = edges(m_graph).second;
+ edge_index_type n = get(edge_index, m_graph, *i);
+
+ // remove the offending edge and renumber everything after
+ remove_edge(*i);
+ m_max_edge_index = renumber_edge_indices(j, end, n);
+ }
+
+ void renumber_indices()
+ {
+ renumber_vertex_indices();
+ renumber_edge_indices();
+ }
+
+ // bundled property support
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ vertex_bundled& operator[](vertex_descriptor v) { return m_graph[v]; }
+
+ vertex_bundled const& operator[](vertex_descriptor v) const
+ {
+ return m_graph[v];
+ }
+
+ edge_bundled& operator[](edge_descriptor e) { return m_graph[e]; }
+
+ edge_bundled const& operator[](edge_descriptor e) const
+ {
+ return m_graph[e];
+ }
+
+ graph_bundled& operator[](graph_bundle_t) { return get_property(*this); }
+
+ graph_bundled const& operator[](graph_bundle_t) const
+ {
+ return get_property(*this);
+ }
+#endif
+
+ // Graph concepts
+ static vertex_descriptor null_vertex() { return graph_type::null_vertex(); }
+
+ void clear()
+ {
+ m_graph.clear();
+ m_num_vertices = m_max_vertex_index = 0;
+ m_num_edges = m_max_edge_index = 0;
+ }
+
+ void swap(directed_graph& g)
+ {
+ m_graph.swap(g.m_graph);
+ std::swap(m_num_vertices, g.m_num_vertices);
+ std::swap(m_max_vertex_index, g.m_max_vertex_index);
+ std::swap(m_num_edges, g.m_num_edges);
+ std::swap(m_max_edge_index, g.m_max_edge_index);
+ }
+
+private:
+ vertices_size_type renumber_vertex_indices(
+ vertex_iterator i, vertex_iterator end, vertices_size_type n)
+ {
+ typedef
+ typename property_map< graph_type, vertex_index_t >::type IndexMap;
+ IndexMap indices = get(vertex_index, m_graph);
+ for (; i != end; ++i)
+ {
+ indices[*i] = n++;
+ }
+ return n;
+ }
+
+ vertices_size_type renumber_edge_indices(
+ edge_iterator i, edge_iterator end, vertices_size_type n)
+ {
+ typedef
+ typename property_map< graph_type, edge_index_t >::type IndexMap;
+ IndexMap indices = get(edge_index, m_graph);
+ for (; i != end; ++i)
+ {
+ indices[*i] = n++;
+ }
+ return n;
+ }
+
+ graph_type m_graph;
+ vertices_size_type m_num_vertices;
+ edges_size_type m_num_edges;
+ vertex_index_type m_max_vertex_index;
+ edge_index_type m_max_edge_index;
+};
+
+#define DIRECTED_GRAPH_PARAMS typename VP, typename EP, typename GP
+#define DIRECTED_GRAPH directed_graph< VP, EP, GP >
+
+// IncidenceGraph concepts
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::vertex_descriptor source(
+ typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH const& g)
+{
+ return source(e, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::vertex_descriptor target(
+ typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH const& g)
+{
+ return target(e, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::degree_size_type out_degree(
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g)
+{
+ return out_degree(v, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline std::pair< typename DIRECTED_GRAPH::out_edge_iterator,
+ typename DIRECTED_GRAPH::out_edge_iterator >
+out_edges(typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g)
+{
+ return out_edges(v, g.impl());
+}
+
+// BidirectionalGraph concepts
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::degree_size_type in_degree(
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g)
+{
+ return in_degree(v, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline std::pair< typename DIRECTED_GRAPH::in_edge_iterator,
+ typename DIRECTED_GRAPH::in_edge_iterator >
+in_edges(typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g)
+{
+ return in_edges(v, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::degree_size_type degree(
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g)
+{
+ return degree(v, g.impl());
+}
+
+// AdjacencyGraph concepts
+template < DIRECTED_GRAPH_PARAMS >
+inline std::pair< typename DIRECTED_GRAPH::adjacency_iterator,
+ typename DIRECTED_GRAPH::adjacency_iterator >
+adjacent_vertices(
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g)
+{
+ return adjacent_vertices(v, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+typename DIRECTED_GRAPH::vertex_descriptor vertex(
+ typename DIRECTED_GRAPH::vertices_size_type n, DIRECTED_GRAPH const& g)
+{
+ return vertex(n, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+std::pair< typename DIRECTED_GRAPH::edge_descriptor, bool > edge(
+ typename DIRECTED_GRAPH::vertex_descriptor u,
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g)
+{
+ return edge(u, v, g.impl());
+}
+
+// VertexListGraph concepts
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::vertices_size_type num_vertices(
+ DIRECTED_GRAPH const& g)
+{
+ return g.num_vertices();
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline std::pair< typename DIRECTED_GRAPH::vertex_iterator,
+ typename DIRECTED_GRAPH::vertex_iterator >
+vertices(DIRECTED_GRAPH const& g)
+{
+ return vertices(g.impl());
+}
+
+// EdgeListGraph concepts
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::edges_size_type num_edges(
+ DIRECTED_GRAPH const& g)
+{
+ return g.num_edges();
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline std::pair< typename DIRECTED_GRAPH::edge_iterator,
+ typename DIRECTED_GRAPH::edge_iterator >
+edges(DIRECTED_GRAPH const& g)
+{
+ return edges(g.impl());
+}
+
+// MutableGraph concepts
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::vertex_descriptor add_vertex(DIRECTED_GRAPH& g)
+{
+ return g.add_vertex();
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::vertex_descriptor add_vertex(
+ typename DIRECTED_GRAPH::vertex_property_type const& p, DIRECTED_GRAPH& g)
+{
+ return g.add_vertex(p);
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline void clear_vertex(
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH& g)
+{
+ return g.clear_vertex(v);
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline void remove_vertex(
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH& g)
+{
+ return g.remove_vertex(v);
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline std::pair< typename DIRECTED_GRAPH::edge_descriptor, bool > add_edge(
+ typename DIRECTED_GRAPH::vertex_descriptor u,
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH& g)
+{
+ return g.add_edge(u, v);
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline std::pair< typename DIRECTED_GRAPH::edge_descriptor, bool > add_edge(
+ typename DIRECTED_GRAPH::vertex_descriptor u,
+ typename DIRECTED_GRAPH::vertex_descriptor v,
+ typename DIRECTED_GRAPH::edge_property_type const& p, DIRECTED_GRAPH& g)
+{
+ return g.add_edge(u, v, p);
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline void remove_edge(typename DIRECTED_GRAPH::vertex_descriptor u,
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH& g)
+{
+ return g.remove_edge(u, v);
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline void remove_edge(
+ typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH& g)
+{
+ return g.remove_edge(e);
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline void remove_edge(
+ typename DIRECTED_GRAPH::edge_iterator i, DIRECTED_GRAPH& g)
+{
+ return g.remove_edge(i);
+}
+
+template < DIRECTED_GRAPH_PARAMS, class Predicate >
+inline void remove_edge_if(Predicate pred, DIRECTED_GRAPH& g)
+{
+ return remove_edge_if(pred, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS, class Predicate >
+inline void remove_out_edge_if(typename DIRECTED_GRAPH::vertex_descriptor v,
+ Predicate pred, DIRECTED_GRAPH& g)
+{
+ return remove_out_edge_if(v, pred, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS, class Predicate >
+inline void remove_in_edge_if(typename DIRECTED_GRAPH::vertex_descriptor v,
+ Predicate pred, DIRECTED_GRAPH& g)
+{
+ return remove_in_edge_if(v, pred, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS, typename Property >
+struct property_map< DIRECTED_GRAPH, Property >
+: property_map< typename DIRECTED_GRAPH::graph_type, Property >
+{
+};
+
+template < DIRECTED_GRAPH_PARAMS >
+struct property_map< DIRECTED_GRAPH, vertex_all_t >
+{
+ typedef transform_value_property_map< detail::remove_first_property,
+ typename property_map< typename DIRECTED_GRAPH::graph_type,
+ vertex_all_t >::const_type >
+ const_type;
+ typedef transform_value_property_map< detail::remove_first_property,
+ typename property_map< typename DIRECTED_GRAPH::graph_type,
+ vertex_all_t >::type >
+ type;
+};
+
+template < DIRECTED_GRAPH_PARAMS >
+struct property_map< DIRECTED_GRAPH, edge_all_t >
+{
+ typedef transform_value_property_map< detail::remove_first_property,
+ typename property_map< typename DIRECTED_GRAPH::graph_type,
+ edge_all_t >::const_type >
+ const_type;
+ typedef transform_value_property_map< detail::remove_first_property,
+ typename property_map< typename DIRECTED_GRAPH::graph_type,
+ edge_all_t >::type >
+ type;
+};
+
+// PropertyGraph concepts
+template < DIRECTED_GRAPH_PARAMS, typename Property >
+inline typename property_map< DIRECTED_GRAPH, Property >::type get(
+ Property p, DIRECTED_GRAPH& g)
+{
+ return get(p, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS, typename Property >
+inline typename property_map< DIRECTED_GRAPH, Property >::const_type get(
+ Property p, DIRECTED_GRAPH const& g)
+{
+ return get(p, g.impl());
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline typename property_map< DIRECTED_GRAPH, vertex_all_t >::type get(
+ vertex_all_t, DIRECTED_GRAPH& g)
+{
+ return typename property_map< DIRECTED_GRAPH, vertex_all_t >::type(
+ detail::remove_first_property(), get(vertex_all, g.impl()));
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline typename property_map< DIRECTED_GRAPH, vertex_all_t >::const_type get(
+ vertex_all_t, DIRECTED_GRAPH const& g)
+{
+ return typename property_map< DIRECTED_GRAPH, vertex_all_t >::const_type(
+ detail::remove_first_property(), get(vertex_all, g.impl()));
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline typename property_map< DIRECTED_GRAPH, edge_all_t >::type get(
+ edge_all_t, DIRECTED_GRAPH& g)
+{
+ return typename property_map< DIRECTED_GRAPH, edge_all_t >::type(
+ detail::remove_first_property(), get(edge_all, g.impl()));
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline typename property_map< DIRECTED_GRAPH, edge_all_t >::const_type get(
+ edge_all_t, DIRECTED_GRAPH const& g)
+{
+ return typename property_map< DIRECTED_GRAPH, edge_all_t >::const_type(
+ detail::remove_first_property(), get(edge_all, g.impl()));
+}
+
+template < DIRECTED_GRAPH_PARAMS, typename Property, typename Key >
+inline typename property_traits< typename property_map<
+ typename DIRECTED_GRAPH::graph_type, Property >::const_type >::value_type
+get(Property p, DIRECTED_GRAPH const& g, Key const& k)
+{
+ return get(p, g.impl(), k);
+}
+
+template < DIRECTED_GRAPH_PARAMS, typename Key >
+inline typename property_traits<
+ typename property_map< typename DIRECTED_GRAPH::graph_type,
+ vertex_all_t >::const_type >::value_type
+get(vertex_all_t, DIRECTED_GRAPH const& g, Key const& k)
+{
+ return get(vertex_all, g.impl(), k).m_base;
+}
+
+template < DIRECTED_GRAPH_PARAMS, typename Key >
+inline typename property_traits< typename property_map<
+ typename DIRECTED_GRAPH::graph_type, edge_all_t >::const_type >::value_type
+get(edge_all_t, DIRECTED_GRAPH const& g, Key const& k)
+{
+ return get(edge_all, g.impl(), k).m_base;
+}
+
+template < DIRECTED_GRAPH_PARAMS, typename Property, typename Key,
+ typename Value >
+inline void put(Property p, DIRECTED_GRAPH& g, Key const& k, Value const& v)
+{
+ put(p, g.impl(), k, v);
+}
+
+template < DIRECTED_GRAPH_PARAMS, typename Key, typename Value >
+inline void put(vertex_all_t, DIRECTED_GRAPH& g, Key const& k, Value const& v)
+{
+ put(vertex_all, g.impl(), k,
+ typename DIRECTED_GRAPH::internal_vertex_property(
+ get(vertex_index, g.impl(), k), v));
+}
+
+template < DIRECTED_GRAPH_PARAMS, typename Key, typename Value >
+inline void put(edge_all_t, DIRECTED_GRAPH& g, Key const& k, Value const& v)
+{
+ put(edge_all, g.impl(), k,
+ typename DIRECTED_GRAPH::internal_vertex_property(
+ get(edge_index, g.impl(), k), v));
+}
+
+template < DIRECTED_GRAPH_PARAMS, class Property >
+typename graph_property< DIRECTED_GRAPH, Property >::type& get_property(
+ DIRECTED_GRAPH& g, Property p)
+{
+ return get_property(g.impl(), p);
+}
+
+template < DIRECTED_GRAPH_PARAMS, class Property >
+typename graph_property< DIRECTED_GRAPH, Property >::type const& get_property(
+ DIRECTED_GRAPH const& g, Property p)
+{
+ return get_property(g.impl(), p);
+}
+
+template < DIRECTED_GRAPH_PARAMS, class Property, class Value >
+void set_property(DIRECTED_GRAPH& g, Property p, Value v)
+{
+ return set_property(g.impl(), p, v);
+}
+
+// Vertex index management
+
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::vertex_index_type get_vertex_index(
+ typename DIRECTED_GRAPH::vertex_descriptor v, DIRECTED_GRAPH const& g)
+{
+ return get(vertex_index, g, v);
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+typename DIRECTED_GRAPH::vertex_index_type max_vertex_index(
+ DIRECTED_GRAPH const& g)
+{
+ return g.max_vertex_index();
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline void renumber_vertex_indices(DIRECTED_GRAPH& g)
+{
+ g.renumber_vertex_indices();
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline void remove_vertex_and_renumber_indices(
+ typename DIRECTED_GRAPH::vertex_iterator i, DIRECTED_GRAPH& g)
+{
+ g.remove_vertex_and_renumber_indices(i);
+}
+
+// Edge index management
+template < DIRECTED_GRAPH_PARAMS >
+inline typename DIRECTED_GRAPH::edge_index_type get_edge_index(
+ typename DIRECTED_GRAPH::edge_descriptor v, DIRECTED_GRAPH const& g)
+{
+ return get(edge_index, g, v);
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+typename DIRECTED_GRAPH::edge_index_type max_edge_index(DIRECTED_GRAPH const& g)
+{
+ return g.max_edge_index();
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline void renumber_edge_indices(DIRECTED_GRAPH& g)
+{
+ g.renumber_edge_indices();
+}
+
+template < DIRECTED_GRAPH_PARAMS >
+inline void remove_edge_and_renumber_indices(
+ typename DIRECTED_GRAPH::edge_iterator i, DIRECTED_GRAPH& g)
+{
+ g.remove_edge_and_renumber_indices(i);
+}
+
+// Index management
+template < DIRECTED_GRAPH_PARAMS >
+inline void renumber_indices(DIRECTED_GRAPH& g)
+{
+ g.renumber_indices();
+}
+
+// Mutability Traits
+template < DIRECTED_GRAPH_PARAMS >
+struct graph_mutability_traits< DIRECTED_GRAPH >
+{
+ typedef mutable_property_graph_tag category;
+};
+
+#undef DIRECTED_GRAPH_PARAMS
+#undef DIRECTED_GRAPH
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/dominator_tree.hpp b/contrib/restricted/boost/graph/include/boost/graph/dominator_tree.hpp
new file mode 100644
index 0000000000..df9783b0b3
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/dominator_tree.hpp
@@ -0,0 +1,483 @@
+//=======================================================================
+// Copyright (C) 2005-2009 Jongsoo Park <jongsoo.park -at- gmail.com>
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_DOMINATOR_HPP
+#define BOOST_GRAPH_DOMINATOR_HPP
+
+#include <boost/config.hpp>
+#include <deque>
+#include <set>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/concept/assert.hpp>
+
+// Dominator tree computation
+
+namespace boost
+{
+namespace detail
+{
+ /**
+ * An extended time_stamper which also records vertices for each dfs number
+ */
+ template < class TimeMap, class VertexVector, class TimeT, class Tag >
+ class time_stamper_with_vertex_vector
+ : public base_visitor<
+ time_stamper_with_vertex_vector< TimeMap, VertexVector, TimeT, Tag > >
+ {
+ public:
+ typedef Tag event_filter;
+ time_stamper_with_vertex_vector(
+ TimeMap timeMap, VertexVector& v, TimeT& t)
+ : timeStamper_(timeMap, t), v_(v)
+ {
+ }
+
+ template < class Graph >
+ void operator()(const typename property_traits< TimeMap >::key_type& v,
+ const Graph& g)
+ {
+ timeStamper_(v, g);
+ v_[timeStamper_.m_time] = v;
+ }
+
+ private:
+ time_stamper< TimeMap, TimeT, Tag > timeStamper_;
+ VertexVector& v_;
+ };
+
+ /**
+ * A convenient way to create a time_stamper_with_vertex_vector
+ */
+ template < class TimeMap, class VertexVector, class TimeT, class Tag >
+ time_stamper_with_vertex_vector< TimeMap, VertexVector, TimeT, Tag >
+ stamp_times_with_vertex_vector(
+ TimeMap timeMap, VertexVector& v, TimeT& t, Tag)
+ {
+ return time_stamper_with_vertex_vector< TimeMap, VertexVector, TimeT,
+ Tag >(timeMap, v, t);
+ }
+
+ template < class Graph, class IndexMap, class TimeMap, class PredMap,
+ class DomTreePredMap >
+ class dominator_visitor
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
+
+ public:
+ /**
+ * @param g [in] the target graph of the dominator tree
+ * @param entry [in] the entry node of g
+ * @param indexMap [in] the vertex index map for g
+ * @param domTreePredMap [out] the immediate dominator map
+ * (parent map in dominator tree)
+ */
+ dominator_visitor(const Graph& g, const Vertex& entry,
+ const IndexMap& indexMap, DomTreePredMap domTreePredMap)
+ : semi_(num_vertices(g))
+ , ancestor_(num_vertices(g), graph_traits< Graph >::null_vertex())
+ , samedom_(ancestor_)
+ , best_(semi_)
+ , semiMap_(make_iterator_property_map(semi_.begin(), indexMap))
+ , ancestorMap_(make_iterator_property_map(ancestor_.begin(), indexMap))
+ , bestMap_(make_iterator_property_map(best_.begin(), indexMap))
+ , buckets_(num_vertices(g))
+ , bucketMap_(make_iterator_property_map(buckets_.begin(), indexMap))
+ , entry_(entry)
+ , domTreePredMap_(domTreePredMap)
+ , numOfVertices_(num_vertices(g))
+ , samedomMap(make_iterator_property_map(samedom_.begin(), indexMap))
+ {
+ }
+
+ void operator()(const Vertex& n, const TimeMap& dfnumMap,
+ const PredMap& parentMap, const Graph& g)
+ {
+ if (n == entry_)
+ return;
+
+ const Vertex p(get(parentMap, n));
+ Vertex s(p);
+
+ // 1. Calculate the semidominator of n,
+ // based on the semidominator thm.
+ // * Semidominator thm. : To find the semidominator of a node n,
+ // consider all predecessors v of n in the CFG (Control Flow
+ // Graph).
+ // - If v is a proper ancestor of n in the spanning tree
+ // (so dfnum(v) < dfnum(n)), then v is a candidate for semi(n)
+ // - If v is a non-ancestor of n (so dfnum(v) > dfnum(n))
+ // then for each u that is an ancestor of v (or u = v),
+ // Let semi(u) be a candidate for semi(n)
+ // of all these candidates, the one with lowest dfnum is
+ // the semidominator of n.
+
+ // For each predecessor of n
+ typename graph_traits< Graph >::in_edge_iterator inItr, inEnd;
+ for (boost::tie(inItr, inEnd) = in_edges(n, g); inItr != inEnd;
+ ++inItr)
+ {
+ const Vertex v = source(*inItr, g);
+ // To deal with unreachable nodes
+ if (get(dfnumMap, v) < 0 || get(dfnumMap, v) >= numOfVertices_)
+ continue;
+
+ Vertex s2;
+ if (get(dfnumMap, v) <= get(dfnumMap, n))
+ s2 = v;
+ else
+ s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap));
+
+ if (get(dfnumMap, s2) < get(dfnumMap, s))
+ s = s2;
+ }
+ put(semiMap_, n, s);
+
+ // 2. Calculation of n's dominator is deferred until
+ // the path from s to n has been linked into the forest
+ get(bucketMap_, s).push_back(n);
+ get(ancestorMap_, n) = p;
+ get(bestMap_, n) = n;
+
+ // 3. Now that the path from p to v has been linked into
+ // the spanning forest, these lines calculate the dominator of v,
+ // based on the dominator thm., or else defer the calculation
+ // until y's dominator is known
+ // * Dominator thm. : On the spanning-tree path below semi(n) and
+ // above or including n, let y be the node
+ // with the smallest-numbered semidominator. Then,
+ //
+ // idom(n) = semi(n) if semi(y)=semi(n) or
+ // idom(y) if semi(y) != semi(n)
+ typename std::deque< Vertex >::iterator buckItr;
+ for (buckItr = get(bucketMap_, p).begin();
+ buckItr != get(bucketMap_, p).end(); ++buckItr)
+ {
+ const Vertex v(*buckItr);
+ const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap));
+ if (get(semiMap_, y) == get(semiMap_, v))
+ put(domTreePredMap_, v, p);
+ else
+ put(samedomMap, v, y);
+ }
+
+ get(bucketMap_, p).clear();
+ }
+
+ protected:
+ /**
+ * Evaluate function in Tarjan's path compression
+ */
+ const Vertex ancestor_with_lowest_semi_(
+ const Vertex& v, const TimeMap& dfnumMap)
+ {
+ const Vertex a(get(ancestorMap_, v));
+
+ if (get(ancestorMap_, a) != graph_traits< Graph >::null_vertex())
+ {
+ const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap));
+
+ put(ancestorMap_, v, get(ancestorMap_, a));
+
+ if (get(dfnumMap, get(semiMap_, b))
+ < get(dfnumMap, get(semiMap_, get(bestMap_, v))))
+ put(bestMap_, v, b);
+ }
+
+ return get(bestMap_, v);
+ }
+
+ std::vector< Vertex > semi_, ancestor_, samedom_, best_;
+ PredMap semiMap_, ancestorMap_, bestMap_;
+ std::vector< std::deque< Vertex > > buckets_;
+
+ iterator_property_map<
+ typename std::vector< std::deque< Vertex > >::iterator, IndexMap >
+ bucketMap_;
+
+ const Vertex& entry_;
+ DomTreePredMap domTreePredMap_;
+ const VerticesSizeType numOfVertices_;
+
+ public:
+ PredMap samedomMap;
+ };
+
+} // namespace detail
+
+/**
+ * @brief Build dominator tree using Lengauer-Tarjan algorithm.
+ * It takes O((V+E)log(V+E)) time.
+ *
+ * @pre dfnumMap, parentMap and verticesByDFNum have dfs results corresponding
+ * indexMap.
+ * If dfs has already run before,
+ * this function would be good for saving computations.
+ * @pre Unreachable nodes must be masked as
+ * graph_traits<Graph>::null_vertex in parentMap.
+ * @pre Unreachable nodes must be masked as
+ * (std::numeric_limits<VerticesSizeType>::max)() in dfnumMap.
+ *
+ * @param domTreePredMap [out] : immediate dominator map (parent map
+ * in dom. tree)
+ *
+ * @note reference Appel. p. 452~453. algorithm 19.9, 19.10.
+ *
+ * @todo : Optimization in Finding Dominators in Practice, Loukas Georgiadis
+ */
+template < class Graph, class IndexMap, class TimeMap, class PredMap,
+ class VertexVector, class DomTreePredMap >
+void lengauer_tarjan_dominator_tree_without_dfs(const Graph& g,
+ const typename graph_traits< Graph >::vertex_descriptor& entry,
+ const IndexMap& indexMap, TimeMap dfnumMap, PredMap parentMap,
+ VertexVector& verticesByDFNum, DomTreePredMap domTreePredMap)
+{
+ // Typedefs and concept check
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
+
+ BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >));
+
+ const VerticesSizeType numOfVertices = num_vertices(g);
+ if (numOfVertices == 0)
+ return;
+
+ // 1. Visit each vertex in reverse post order and calculate sdom.
+ detail::dominator_visitor< Graph, IndexMap, TimeMap, PredMap,
+ DomTreePredMap >
+ visitor(g, entry, indexMap, domTreePredMap);
+
+ VerticesSizeType i;
+ for (i = 0; i < numOfVertices; ++i)
+ {
+ const Vertex u(verticesByDFNum[numOfVertices - 1 - i]);
+ if (u != graph_traits< Graph >::null_vertex())
+ visitor(u, dfnumMap, parentMap, g);
+ }
+
+ // 2. Now all the deferred dominator calculations,
+ // based on the second clause of the dominator thm., are performed
+ for (i = 0; i < numOfVertices; ++i)
+ {
+ const Vertex n(verticesByDFNum[i]);
+
+ if (n == entry || n == graph_traits< Graph >::null_vertex())
+ continue;
+
+ Vertex u = get(visitor.samedomMap, n);
+ if (u != graph_traits< Graph >::null_vertex())
+ {
+ put(domTreePredMap, n, get(domTreePredMap, u));
+ }
+ }
+}
+
+/**
+ * Unlike lengauer_tarjan_dominator_tree_without_dfs,
+ * dfs is run in this function and
+ * the result is written to dfnumMap, parentMap, vertices.
+ *
+ * If the result of dfs required after this algorithm,
+ * this function can eliminate the need of rerunning dfs.
+ */
+template < class Graph, class IndexMap, class TimeMap, class PredMap,
+ class VertexVector, class DomTreePredMap >
+void lengauer_tarjan_dominator_tree(const Graph& g,
+ const typename graph_traits< Graph >::vertex_descriptor& entry,
+ const IndexMap& indexMap, TimeMap dfnumMap, PredMap parentMap,
+ VertexVector& verticesByDFNum, DomTreePredMap domTreePredMap)
+{
+ // Typedefs and concept check
+ typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
+
+ BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >));
+
+ // 1. Depth first visit
+ const VerticesSizeType numOfVertices = num_vertices(g);
+ if (numOfVertices == 0)
+ return;
+
+ VerticesSizeType time = (std::numeric_limits< VerticesSizeType >::max)();
+ std::vector< default_color_type > colors(
+ numOfVertices, color_traits< default_color_type >::white());
+ depth_first_visit(g, entry,
+ make_dfs_visitor(
+ make_pair(record_predecessors(parentMap, on_tree_edge()),
+ detail::stamp_times_with_vertex_vector(
+ dfnumMap, verticesByDFNum, time, on_discover_vertex()))),
+ make_iterator_property_map(colors.begin(), indexMap));
+
+ // 2. Run main algorithm.
+ lengauer_tarjan_dominator_tree_without_dfs(g, entry, indexMap, dfnumMap,
+ parentMap, verticesByDFNum, domTreePredMap);
+}
+
+/**
+ * Use vertex_index as IndexMap and make dfnumMap, parentMap, verticesByDFNum
+ * internally.
+ * If we don't need the result of dfs (dfnumMap, parentMap, verticesByDFNum),
+ * this function would be more convenient one.
+ */
+template < class Graph, class DomTreePredMap >
+void lengauer_tarjan_dominator_tree(const Graph& g,
+ const typename graph_traits< Graph >::vertex_descriptor& entry,
+ DomTreePredMap domTreePredMap)
+{
+ // typedefs
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
+ typedef typename property_map< Graph, vertex_index_t >::const_type IndexMap;
+ typedef iterator_property_map<
+ typename std::vector< VerticesSizeType >::iterator, IndexMap >
+ TimeMap;
+ typedef iterator_property_map< typename std::vector< Vertex >::iterator,
+ IndexMap >
+ PredMap;
+
+ // Make property maps
+ const VerticesSizeType numOfVertices = num_vertices(g);
+ if (numOfVertices == 0)
+ return;
+
+ const IndexMap indexMap = get(vertex_index, g);
+
+ std::vector< VerticesSizeType > dfnum(numOfVertices, 0);
+ TimeMap dfnumMap(make_iterator_property_map(dfnum.begin(), indexMap));
+
+ std::vector< Vertex > parent(
+ numOfVertices, graph_traits< Graph >::null_vertex());
+ PredMap parentMap(make_iterator_property_map(parent.begin(), indexMap));
+
+ std::vector< Vertex > verticesByDFNum(parent);
+
+ // Run main algorithm
+ lengauer_tarjan_dominator_tree(g, entry, indexMap, dfnumMap, parentMap,
+ verticesByDFNum, domTreePredMap);
+}
+
+/**
+ * Muchnick. p. 182, 184
+ *
+ * using iterative bit vector analysis
+ */
+template < class Graph, class IndexMap, class DomTreePredMap >
+void iterative_bit_vector_dominator_tree(const Graph& g,
+ const typename graph_traits< Graph >::vertex_descriptor& entry,
+ const IndexMap& indexMap, DomTreePredMap domTreePredMap)
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator vertexItr;
+ typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
+ typedef iterator_property_map<
+ typename std::vector< std::set< Vertex > >::iterator, IndexMap >
+ vertexSetMap;
+
+ BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >));
+
+ // 1. Finding dominator
+ // 1.1. Initialize
+ const VerticesSizeType numOfVertices = num_vertices(g);
+ if (numOfVertices == 0)
+ return;
+
+ vertexItr vi, viend;
+ boost::tie(vi, viend) = vertices(g);
+ const std::set< Vertex > N(vi, viend);
+
+ bool change = true;
+
+ std::vector< std::set< Vertex > > dom(numOfVertices, N);
+ vertexSetMap domMap(make_iterator_property_map(dom.begin(), indexMap));
+ get(domMap, entry).clear();
+ get(domMap, entry).insert(entry);
+
+ while (change)
+ {
+ change = false;
+ for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
+ {
+ if (*vi == entry)
+ continue;
+
+ std::set< Vertex > T(N);
+
+ typename graph_traits< Graph >::in_edge_iterator inItr, inEnd;
+ for (boost::tie(inItr, inEnd) = in_edges(*vi, g); inItr != inEnd;
+ ++inItr)
+ {
+ const Vertex p = source(*inItr, g);
+
+ std::set< Vertex > tempSet;
+ std::set_intersection(T.begin(), T.end(),
+ get(domMap, p).begin(), get(domMap, p).end(),
+ std::inserter(tempSet, tempSet.begin()));
+ T.swap(tempSet);
+ }
+
+ T.insert(*vi);
+ if (T != get(domMap, *vi))
+ {
+ change = true;
+ get(domMap, *vi).swap(T);
+ }
+ } // end of for (boost::tie(vi, viend) = vertices(g)
+ } // end of while(change)
+
+ // 2. Build dominator tree
+ for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
+ get(domMap, *vi).erase(*vi);
+
+ Graph domTree(numOfVertices);
+
+ for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
+ {
+ if (*vi == entry)
+ continue;
+
+ // We have to iterate through copied dominator set
+ const std::set< Vertex > tempSet(get(domMap, *vi));
+ typename std::set< Vertex >::const_iterator s;
+ for (s = tempSet.begin(); s != tempSet.end(); ++s)
+ {
+ typename std::set< Vertex >::iterator t;
+ for (t = get(domMap, *vi).begin(); t != get(domMap, *vi).end();)
+ {
+ typename std::set< Vertex >::iterator old_t = t;
+ ++t; // Done early because t may become invalid
+ if (*old_t == *s)
+ continue;
+ if (get(domMap, *s).find(*old_t) != get(domMap, *s).end())
+ get(domMap, *vi).erase(old_t);
+ }
+ }
+ }
+
+ for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
+ {
+ if (*vi != entry && get(domMap, *vi).size() == 1)
+ {
+ Vertex temp = *get(domMap, *vi).begin();
+ put(domTreePredMap, *vi, temp);
+ }
+ }
+}
+
+template < class Graph, class DomTreePredMap >
+void iterative_bit_vector_dominator_tree(const Graph& g,
+ const typename graph_traits< Graph >::vertex_descriptor& entry,
+ DomTreePredMap domTreePredMap)
+{
+ typename property_map< Graph, vertex_index_t >::const_type indexMap
+ = get(vertex_index, g);
+
+ iterative_bit_vector_dominator_tree(g, entry, indexMap, domTreePredMap);
+}
+} // namespace boost
+
+#endif // BOOST_GRAPH_DOMINATOR_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/eccentricity.hpp b/contrib/restricted/boost/graph/include/boost/graph/eccentricity.hpp
new file mode 100644
index 0000000000..26480ced0e
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/eccentricity.hpp
@@ -0,0 +1,121 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_ECCENTRICITY_HPP
+#define BOOST_GRAPH_ECCENTRICITY_HPP
+
+#include <boost/next_prior.hpp>
+#include <boost/config.hpp>
+#include <boost/graph/detail/geodesic.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+template < typename Graph, typename DistanceMap, typename Combinator >
+inline typename property_traits< DistanceMap >::value_type eccentricity(
+ const Graph& g, DistanceMap dist, Combinator combine)
+{
+ BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >));
+ typedef typename property_traits< DistanceMap >::value_type Distance;
+
+ return detail::combine_distances(g, dist, combine, Distance(0));
+}
+
+template < typename Graph, typename DistanceMap >
+inline typename property_traits< DistanceMap >::value_type eccentricity(
+ const Graph& g, DistanceMap dist)
+{
+ BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< DistanceMap, Vertex >));
+ typedef typename property_traits< DistanceMap >::value_type Distance;
+
+ return eccentricity(g, dist, detail::maximize< Distance >());
+}
+
+template < typename Graph, typename DistanceMatrix, typename EccentricityMap >
+inline std::pair< typename property_traits< EccentricityMap >::value_type,
+ typename property_traits< EccentricityMap >::value_type >
+all_eccentricities(
+ const Graph& g, const DistanceMatrix& dist, EccentricityMap ecc)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< DistanceMatrix, Vertex >));
+ typedef typename property_traits< DistanceMatrix >::value_type DistanceMap;
+ BOOST_CONCEPT_ASSERT(
+ (WritablePropertyMapConcept< EccentricityMap, Vertex >));
+ typedef
+ typename property_traits< EccentricityMap >::value_type Eccentricity;
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+
+ Eccentricity r = numeric_values< Eccentricity >::infinity(),
+ d = numeric_values< Eccentricity >::zero();
+ VertexIterator i, end;
+ boost::tie(i, end) = vertices(g);
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ {
+ DistanceMap dm = get(dist, *i);
+ Eccentricity e = eccentricity(g, dm);
+ put(ecc, *i, e);
+
+ // track the radius and diameter at the same time
+ r = min BOOST_PREVENT_MACRO_SUBSTITUTION(r, e);
+ d = max BOOST_PREVENT_MACRO_SUBSTITUTION(d, e);
+ }
+ return std::make_pair(r, d);
+}
+
+template < typename Graph, typename EccentricityMap >
+inline std::pair< typename property_traits< EccentricityMap >::value_type,
+ typename property_traits< EccentricityMap >::value_type >
+radius_and_diameter(const Graph& g, EccentricityMap ecc)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< EccentricityMap, Vertex >));
+ typedef
+ typename property_traits< EccentricityMap >::value_type Eccentricity;
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+
+ VertexIterator i, end;
+ boost::tie(i, end) = vertices(g);
+ Eccentricity radius = get(ecc, *i);
+ Eccentricity diameter = get(ecc, *i);
+ for (i = boost::next(i); i != end; ++i)
+ {
+ Eccentricity cur = get(ecc, *i);
+ radius = min BOOST_PREVENT_MACRO_SUBSTITUTION(radius, cur);
+ diameter = max BOOST_PREVENT_MACRO_SUBSTITUTION(diameter, cur);
+ }
+ return std::make_pair(radius, diameter);
+}
+
+template < typename Graph, typename EccentricityMap >
+inline typename property_traits< EccentricityMap >::value_type radius(
+ const Graph& g, EccentricityMap ecc)
+{
+ return radius_and_diameter(g, ecc).first;
+}
+
+template < typename Graph, typename EccentricityMap >
+inline typename property_traits< EccentricityMap >::value_type diameter(
+ const Graph& g, EccentricityMap ecc)
+{
+ return radius_and_diameter(g, ecc).second;
+}
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/edge_coloring.hpp b/contrib/restricted/boost/graph/include/boost/graph/edge_coloring.hpp
new file mode 100644
index 0000000000..9de277658e
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/edge_coloring.hpp
@@ -0,0 +1,201 @@
+//=======================================================================
+// Copyright 2013 Maciej Piechotka
+// Authors: Maciej Piechotka
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_EDGE_COLORING_HPP
+#define BOOST_GRAPH_EDGE_COLORING_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/properties.hpp>
+#include <algorithm>
+#include <limits>
+#include <vector>
+
+/* This algorithm is to find coloring of an edges
+
+ Reference:
+
+ Misra, J., & Gries, D. (1992). A constructive proof of Vizing's
+ theorem. In Information Processing Letters.
+*/
+
+namespace boost
+{
+namespace detail
+{
+ template < typename Graph, typename ColorMap >
+ bool is_free(const Graph& g, ColorMap color,
+ typename boost::graph_traits< Graph >::vertex_descriptor u,
+ typename boost::property_traits< ColorMap >::value_type free_color)
+ {
+ typedef typename boost::property_traits< ColorMap >::value_type color_t;
+ if (free_color == (std::numeric_limits< color_t >::max)())
+ return false;
+ BGL_FORALL_OUTEDGES_T(u, e, g, Graph)
+ {
+ if (get(color, e) == free_color)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ template < typename Graph, typename ColorMap >
+ std::vector< typename boost::graph_traits< Graph >::vertex_descriptor >
+ maximal_fan(const Graph& g, ColorMap color,
+ typename boost::graph_traits< Graph >::vertex_descriptor x,
+ typename boost::graph_traits< Graph >::vertex_descriptor y)
+ {
+ typedef
+ typename boost::graph_traits< Graph >::vertex_descriptor vertex_t;
+ std::vector< vertex_t > fan;
+ fan.push_back(y);
+ bool extended;
+ do
+ {
+ extended = false;
+ BGL_FORALL_OUTEDGES_T(x, e, g, Graph)
+ {
+ vertex_t v = target(e, g);
+ if (is_free(g, color, fan.back(), get(color, e))
+ && std::find(fan.begin(), fan.end(), v) == fan.end())
+ {
+ fan.push_back(v);
+ extended = true;
+ }
+ }
+ } while (extended);
+ return fan;
+ }
+ template < typename Graph, typename ColorMap >
+ typename boost::property_traits< ColorMap >::value_type find_free_color(
+ const Graph& g, ColorMap color,
+ typename boost::graph_traits< Graph >::vertex_descriptor u)
+ {
+ typename boost::property_traits< ColorMap >::value_type c = 0;
+ while (!is_free(g, color, u, c))
+ c++;
+ return c;
+ }
+
+ template < typename Graph, typename ColorMap >
+ void invert_cd_path(const Graph& g, ColorMap color,
+ typename boost::graph_traits< Graph >::vertex_descriptor x,
+ typename boost::graph_traits< Graph >::edge_descriptor eold,
+ typename boost::property_traits< ColorMap >::value_type c,
+ typename boost::property_traits< ColorMap >::value_type d)
+ {
+ put(color, eold, d);
+ BGL_FORALL_OUTEDGES_T(x, e, g, Graph)
+ {
+ if (get(color, e) == d && e != eold)
+ {
+ invert_cd_path(g, color, target(e, g), e, d, c);
+ return;
+ }
+ }
+ }
+
+ template < typename Graph, typename ColorMap >
+ void invert_cd_path(const Graph& g, ColorMap color,
+ typename boost::graph_traits< Graph >::vertex_descriptor x,
+ typename boost::property_traits< ColorMap >::value_type c,
+ typename boost::property_traits< ColorMap >::value_type d)
+ {
+ BGL_FORALL_OUTEDGES_T(x, e, g, Graph)
+ {
+ if (get(color, e) == d)
+ {
+ invert_cd_path(g, color, target(e, g), e, d, c);
+ return;
+ }
+ }
+ }
+
+ template < typename Graph, typename ColorMap, typename ForwardIterator >
+ void rotate_fan(const Graph& g, ColorMap color,
+ typename boost::graph_traits< Graph >::vertex_descriptor x,
+ ForwardIterator begin, ForwardIterator end)
+ {
+ typedef typename boost::graph_traits< Graph >::edge_descriptor edge_t;
+ if (begin == end)
+ {
+ return;
+ }
+ edge_t previous = edge(x, *begin, g).first;
+ for (begin++; begin != end; begin++)
+ {
+ edge_t current = edge(x, *begin, g).first;
+ put(color, previous, get(color, current));
+ previous = current;
+ }
+ }
+
+ template < typename Graph, typename ColorMap > class find_free_in_fan
+ {
+ public:
+ find_free_in_fan(const Graph& graph, const ColorMap color,
+ typename boost::property_traits< ColorMap >::value_type d)
+ : graph(graph), color(color), d(d)
+ {
+ }
+ bool operator()(
+ const typename boost::graph_traits< Graph >::vertex_descriptor u)
+ const
+ {
+ return is_free(graph, color, u, d);
+ }
+
+ private:
+ const Graph& graph;
+ const ColorMap color;
+ const typename boost::property_traits< ColorMap >::value_type d;
+ };
+}
+
+template < typename Graph, typename ColorMap >
+typename boost::property_traits< ColorMap >::value_type color_edge(
+ const Graph& g, ColorMap color,
+ typename boost::graph_traits< Graph >::edge_descriptor e)
+{
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename boost::property_traits< ColorMap >::value_type color_t;
+ typedef typename std::vector< vertex_t >::iterator fan_iterator;
+ using namespace detail;
+ vertex_t x = source(e, g), y = target(e, g);
+ std::vector< vertex_t > fan = maximal_fan(g, color, x, y);
+ color_t c = find_free_color(g, color, x);
+ color_t d = find_free_color(g, color, fan.back());
+ invert_cd_path(g, color, x, c, d);
+ fan_iterator w = std::find_if(fan.begin(), fan.end(),
+ find_free_in_fan< Graph, ColorMap >(g, color, d));
+ rotate_fan(g, color, x, fan.begin(), w + 1);
+ put(color, edge(x, *w, g).first, d);
+ return (std::max)(c, d);
+}
+
+template < typename Graph, typename ColorMap >
+typename boost::property_traits< ColorMap >::value_type edge_coloring(
+ const Graph& g, ColorMap color)
+{
+ typedef typename boost::property_traits< ColorMap >::value_type color_t;
+ BGL_FORALL_EDGES_T(e, g, Graph)
+ {
+ put(color, e, (std::numeric_limits< color_t >::max)());
+ }
+ color_t colors = 0;
+ BGL_FORALL_EDGES_T(e, g, Graph)
+ {
+ colors = (std::max)(colors, color_edge(g, color, e) + 1);
+ }
+ return colors;
+}
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/edge_connectivity.hpp b/contrib/restricted/boost/graph/include/boost/graph/edge_connectivity.hpp
new file mode 100644
index 0000000000..25e7d85a52
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/edge_connectivity.hpp
@@ -0,0 +1,188 @@
+//=======================================================================
+// Copyright 2000 University of Notre Dame.
+// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_EDGE_CONNECTIVITY
+#define BOOST_EDGE_CONNECTIVITY
+
+// WARNING: not-yet fully tested!
+
+#include <boost/config.hpp>
+#include <vector>
+#include <set>
+#include <algorithm>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/edmonds_karp_max_flow.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < class Graph >
+ inline std::pair< typename graph_traits< Graph >::vertex_descriptor,
+ typename graph_traits< Graph >::degree_size_type >
+ min_degree_vertex(Graph& g)
+ {
+ typedef graph_traits< Graph > Traits;
+ typename Traits::vertex_descriptor p;
+ typedef typename Traits::degree_size_type size_type;
+ size_type delta = (std::numeric_limits< size_type >::max)();
+
+ typename Traits::vertex_iterator i, iend;
+ for (boost::tie(i, iend) = vertices(g); i != iend; ++i)
+ if (degree(*i, g) < delta)
+ {
+ delta = degree(*i, g);
+ p = *i;
+ }
+ return std::make_pair(p, delta);
+ }
+
+ template < class Graph, class OutputIterator >
+ void neighbors(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor u,
+ OutputIterator result)
+ {
+ typename graph_traits< Graph >::adjacency_iterator ai, aend;
+ for (boost::tie(ai, aend) = adjacent_vertices(u, g); ai != aend; ++ai)
+ *result++ = *ai;
+ }
+
+ template < class Graph, class VertexIterator, class OutputIterator >
+ void neighbors(const Graph& g, VertexIterator first, VertexIterator last,
+ OutputIterator result)
+ {
+ for (; first != last; ++first)
+ neighbors(g, *first, result);
+ }
+
+} // namespace detail
+
+// O(m n)
+template < class VertexListGraph, class OutputIterator >
+typename graph_traits< VertexListGraph >::degree_size_type edge_connectivity(
+ VertexListGraph& g, OutputIterator disconnecting_set)
+{
+ //-------------------------------------------------------------------------
+ // Type Definitions
+ typedef graph_traits< VertexListGraph > Traits;
+ typedef typename Traits::vertex_iterator vertex_iterator;
+ typedef typename Traits::edge_iterator edge_iterator;
+ typedef typename Traits::out_edge_iterator out_edge_iterator;
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::degree_size_type degree_size_type;
+ typedef color_traits< default_color_type > Color;
+
+ typedef adjacency_list_traits< vecS, vecS, directedS > Tr;
+ typedef typename Tr::edge_descriptor Tr_edge_desc;
+ typedef adjacency_list< vecS, vecS, directedS, no_property,
+ property< edge_capacity_t, degree_size_type,
+ property< edge_residual_capacity_t, degree_size_type,
+ property< edge_reverse_t, Tr_edge_desc > > > >
+ FlowGraph;
+ typedef typename graph_traits< FlowGraph >::edge_descriptor edge_descriptor;
+
+ //-------------------------------------------------------------------------
+ // Variable Declarations
+ vertex_descriptor u, v, p, k;
+ edge_descriptor e1, e2;
+ bool inserted;
+ vertex_iterator vi, vi_end;
+ edge_iterator ei, ei_end;
+ degree_size_type delta, alpha_star, alpha_S_k;
+ std::set< vertex_descriptor > S, neighbor_S;
+ std::vector< vertex_descriptor > S_star, non_neighbor_S;
+ std::vector< default_color_type > color(num_vertices(g));
+ std::vector< edge_descriptor > pred(num_vertices(g));
+
+ //-------------------------------------------------------------------------
+ // Create a network flow graph out of the undirected graph
+ FlowGraph flow_g(num_vertices(g));
+
+ typename property_map< FlowGraph, edge_capacity_t >::type cap
+ = get(edge_capacity, flow_g);
+ typename property_map< FlowGraph, edge_residual_capacity_t >::type res_cap
+ = get(edge_residual_capacity, flow_g);
+ typename property_map< FlowGraph, edge_reverse_t >::type rev_edge
+ = get(edge_reverse, flow_g);
+
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ u = source(*ei, g), v = target(*ei, g);
+ boost::tie(e1, inserted) = add_edge(u, v, flow_g);
+ cap[e1] = 1;
+ boost::tie(e2, inserted) = add_edge(v, u, flow_g);
+ cap[e2] = 1; // not sure about this
+ rev_edge[e1] = e2;
+ rev_edge[e2] = e1;
+ }
+
+ //-------------------------------------------------------------------------
+ // The Algorithm
+
+ boost::tie(p, delta) = detail::min_degree_vertex(g);
+ S_star.push_back(p);
+ alpha_star = delta;
+ S.insert(p);
+ neighbor_S.insert(p);
+ detail::neighbors(
+ g, S.begin(), S.end(), std::inserter(neighbor_S, neighbor_S.begin()));
+
+ boost::tie(vi, vi_end) = vertices(g);
+ std::set_difference(vi, vi_end, neighbor_S.begin(), neighbor_S.end(),
+ std::back_inserter(non_neighbor_S));
+
+ while (!non_neighbor_S.empty())
+ { // at most n - 1 times
+ k = non_neighbor_S.front();
+
+ alpha_S_k = edmonds_karp_max_flow(
+ flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]);
+
+ if (alpha_S_k < alpha_star)
+ {
+ alpha_star = alpha_S_k;
+ S_star.clear();
+ for (boost::tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi)
+ if (color[*vi] != Color::white())
+ S_star.push_back(*vi);
+ }
+ S.insert(k);
+ neighbor_S.insert(k);
+ detail::neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin()));
+ non_neighbor_S.clear();
+ boost::tie(vi, vi_end) = vertices(g);
+ std::set_difference(vi, vi_end, neighbor_S.begin(), neighbor_S.end(),
+ std::back_inserter(non_neighbor_S));
+ }
+ //-------------------------------------------------------------------------
+ // Compute edges of the cut [S*, ~S*]
+ std::vector< bool > in_S_star(num_vertices(g), false);
+ typename std::vector< vertex_descriptor >::iterator si;
+ for (si = S_star.begin(); si != S_star.end(); ++si)
+ in_S_star[*si] = true;
+
+ degree_size_type c = 0;
+ for (si = S_star.begin(); si != S_star.end(); ++si)
+ {
+ out_edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei)
+ if (!in_S_star[target(*ei, g)])
+ {
+ *disconnecting_set++ = *ei;
+ ++c;
+ }
+ }
+ return c;
+}
+
+} // namespace boost
+
+#endif // BOOST_EDGE_CONNECTIVITY
diff --git a/contrib/restricted/boost/graph/include/boost/graph/edge_list.hpp b/contrib/restricted/boost/graph/include/boost/graph/edge_list.hpp
new file mode 100644
index 0000000000..77c0c01ea4
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/edge_list.hpp
@@ -0,0 +1,330 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+
+#ifndef BOOST_GRAPH_EDGE_LIST_HPP
+#define BOOST_GRAPH_EDGE_LIST_HPP
+
+#include <iterator>
+#include <boost/config.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/range/irange.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+
+namespace boost
+{
+
+//
+// The edge_list class is an EdgeListGraph module that is constructed
+// from a pair of iterators whose value type is a pair of vertex
+// descriptors.
+//
+// For example:
+//
+// typedef std::pair<int,int> E;
+// list<E> elist;
+// ...
+// typedef edge_list<list<E>::iterator> Graph;
+// Graph g(elist.begin(), elist.end());
+//
+// If the iterators are random access, then Graph::edge_descriptor
+// is of Integral type, otherwise it is a struct, though it is
+// convertible to an Integral type.
+//
+
+struct edge_list_tag
+{
+};
+
+// The implementation class for edge_list.
+template < class G, class EdgeIter, class T, class D > class edge_list_impl
+{
+public:
+ typedef D edge_id;
+ typedef T Vpair;
+ typedef typename Vpair::first_type V;
+ typedef V vertex_descriptor;
+ typedef edge_list_tag graph_tag;
+ typedef void edge_property_type;
+
+ struct edge_descriptor
+ {
+ edge_descriptor() {}
+ edge_descriptor(EdgeIter p, edge_id id) : _ptr(p), _id(id) {}
+ operator edge_id() { return _id; }
+ EdgeIter _ptr;
+ edge_id _id;
+ };
+ typedef edge_descriptor E;
+
+ struct edge_iterator
+ {
+ typedef edge_iterator self;
+ typedef E value_type;
+ typedef E& reference;
+ typedef E* pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::input_iterator_tag iterator_category;
+ edge_iterator() {}
+ edge_iterator(EdgeIter iter) : _iter(iter), _i(0) {}
+ E operator*() { return E(_iter, _i); }
+ self& operator++()
+ {
+ ++_iter;
+ ++_i;
+ return *this;
+ }
+ self operator++(int)
+ {
+ self t = *this;
+ ++(*this);
+ return t;
+ }
+ bool operator==(const self& x) { return _iter == x._iter; }
+ bool operator!=(const self& x) { return _iter != x._iter; }
+ EdgeIter _iter;
+ edge_id _i;
+ };
+ typedef void out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef void adjacency_iterator;
+ typedef void vertex_iterator;
+};
+
+template < class G, class EI, class T, class D >
+std::pair< typename edge_list_impl< G, EI, T, D >::edge_iterator,
+ typename edge_list_impl< G, EI, T, D >::edge_iterator >
+edges(const edge_list_impl< G, EI, T, D >& g_)
+{
+ const G& g = static_cast< const G& >(g_);
+ typedef typename edge_list_impl< G, EI, T, D >::edge_iterator edge_iterator;
+ return std::make_pair(edge_iterator(g._first), edge_iterator(g._last));
+}
+template < class G, class EI, class T, class D >
+typename edge_list_impl< G, EI, T, D >::vertex_descriptor source(
+ typename edge_list_impl< G, EI, T, D >::edge_descriptor e,
+ const edge_list_impl< G, EI, T, D >&)
+{
+ return (*e._ptr).first;
+}
+template < class G, class EI, class T, class D >
+typename edge_list_impl< G, EI, T, D >::vertex_descriptor target(
+ typename edge_list_impl< G, EI, T, D >::edge_descriptor e,
+ const edge_list_impl< G, EI, T, D >&)
+{
+ return (*e._ptr).second;
+}
+
+template < class D, class E >
+class el_edge_property_map
+: public put_get_helper< D, el_edge_property_map< D, E > >
+{
+public:
+ typedef E key_type;
+ typedef D value_type;
+ typedef D reference;
+ typedef readable_property_map_tag category;
+
+ value_type operator[](key_type e) const { return e._i; }
+};
+struct edge_list_edge_property_selector
+{
+ template < class Graph, class Property, class Tag > struct bind_
+ {
+ typedef el_edge_property_map< typename Graph::edge_id,
+ typename Graph::edge_descriptor >
+ type;
+ typedef type const_type;
+ };
+};
+template <> struct edge_property_selector< edge_list_tag >
+{
+ typedef edge_list_edge_property_selector type;
+};
+
+template < class G, class EI, class T, class D >
+typename property_map< edge_list_impl< G, EI, T, D >, edge_index_t >::type get(
+ edge_index_t, const edge_list_impl< G, EI, T, D >&)
+{
+ typedef typename property_map< edge_list_impl< G, EI, T, D >,
+ edge_index_t >::type EdgeIndexMap;
+ return EdgeIndexMap();
+}
+
+template < class G, class EI, class T, class D >
+inline D get(edge_index_t, const edge_list_impl< G, EI, T, D >&,
+ typename edge_list_impl< G, EI, T, D >::edge_descriptor e)
+{
+ return e._i;
+}
+
+// A specialized implementation for when the iterators are random access.
+
+struct edge_list_ra_tag
+{
+};
+
+template < class G, class EdgeIter, class T, class D > class edge_list_impl_ra
+{
+public:
+ typedef D edge_id;
+ typedef T Vpair;
+ typedef typename Vpair::first_type V;
+ typedef edge_list_ra_tag graph_tag;
+ typedef void edge_property_type;
+
+ typedef edge_id edge_descriptor;
+ typedef V vertex_descriptor;
+ typedef typename boost::integer_range< edge_id >::iterator edge_iterator;
+ typedef void out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef void adjacency_iterator;
+ typedef void vertex_iterator;
+};
+
+template < class G, class EI, class T, class D >
+std::pair< typename edge_list_impl_ra< G, EI, T, D >::edge_iterator,
+ typename edge_list_impl_ra< G, EI, T, D >::edge_iterator >
+edges(const edge_list_impl_ra< G, EI, T, D >& g_)
+{
+ const G& g = static_cast< const G& >(g_);
+ typedef
+ typename edge_list_impl_ra< G, EI, T, D >::edge_iterator edge_iterator;
+ return std::make_pair(edge_iterator(0), edge_iterator(g._last - g._first));
+}
+template < class G, class EI, class T, class D >
+typename edge_list_impl_ra< G, EI, T, D >::vertex_descriptor source(
+ typename edge_list_impl_ra< G, EI, T, D >::edge_descriptor e,
+ const edge_list_impl_ra< G, EI, T, D >& g_)
+{
+ const G& g = static_cast< const G& >(g_);
+ return g._first[e].first;
+}
+template < class G, class EI, class T, class D >
+typename edge_list_impl_ra< G, EI, T, D >::vertex_descriptor target(
+ typename edge_list_impl_ra< G, EI, T, D >::edge_descriptor e,
+ const edge_list_impl_ra< G, EI, T, D >& g_)
+{
+ const G& g = static_cast< const G& >(g_);
+ return g._first[e].second;
+}
+template < class E >
+class el_ra_edge_property_map
+: public put_get_helper< E, el_ra_edge_property_map< E > >
+{
+public:
+ typedef E key_type;
+ typedef E value_type;
+ typedef E reference;
+ typedef readable_property_map_tag category;
+
+ value_type operator[](key_type e) const { return e; }
+};
+struct edge_list_ra_edge_property_selector
+{
+ template < class Graph, class Property, class Tag > struct bind_
+ {
+ typedef el_ra_edge_property_map< typename Graph::edge_descriptor > type;
+ typedef type const_type;
+ };
+};
+template <> struct edge_property_selector< edge_list_ra_tag >
+{
+ typedef edge_list_ra_edge_property_selector type;
+};
+template < class G, class EI, class T, class D >
+inline typename property_map< edge_list_impl_ra< G, EI, T, D >,
+ edge_index_t >::type
+get(edge_index_t, const edge_list_impl_ra< G, EI, T, D >&)
+{
+ typedef typename property_map< edge_list_impl_ra< G, EI, T, D >,
+ edge_index_t >::type EdgeIndexMap;
+ return EdgeIndexMap();
+}
+
+template < class G, class EI, class T, class D >
+inline D get(edge_index_t, const edge_list_impl_ra< G, EI, T, D >&,
+ typename edge_list_impl_ra< G, EI, T, D >::edge_descriptor e)
+{
+ return e;
+}
+
+// Some helper classes for determining if the iterators are random access
+template < class Cat > struct is_random
+{
+ enum
+ {
+ RET = false
+ };
+ typedef mpl::false_ type;
+};
+template <> struct is_random< std::random_access_iterator_tag >
+{
+ enum
+ {
+ RET = true
+ };
+ typedef mpl::true_ type;
+};
+
+// The edge_list class conditionally inherits from one of the
+// above two classes.
+
+template < class EdgeIter,
+#if !defined BOOST_NO_STD_ITERATOR_TRAITS
+ class T = typename std::iterator_traits< EdgeIter >::value_type,
+ class D = typename std::iterator_traits< EdgeIter >::difference_type,
+ class Cat = typename std::iterator_traits< EdgeIter >::iterator_category >
+#else
+ class T, class D, class Cat >
+#endif
+class edge_list
+: public mpl::if_< typename is_random< Cat >::type,
+ edge_list_impl_ra< edge_list< EdgeIter, T, D, Cat >, EdgeIter, T, D >,
+ edge_list_impl< edge_list< EdgeIter, T, D, Cat >, EdgeIter, T, D > >::type
+{
+public:
+ typedef directed_tag directed_category;
+ typedef allow_parallel_edge_tag edge_parallel_category;
+ typedef edge_list_graph_tag traversal_category;
+ typedef std::size_t edges_size_type;
+ typedef std::size_t vertices_size_type;
+ typedef std::size_t degree_size_type;
+ edge_list(EdgeIter first, EdgeIter last) : _first(first), _last(last)
+ {
+ m_num_edges = std::distance(first, last);
+ }
+ edge_list(EdgeIter first, EdgeIter last, edges_size_type E)
+ : _first(first), _last(last), m_num_edges(E)
+ {
+ }
+
+ EdgeIter _first, _last;
+ edges_size_type m_num_edges;
+};
+
+template < class EdgeIter, class T, class D, class Cat >
+std::size_t num_edges(const edge_list< EdgeIter, T, D, Cat >& el)
+{
+ return el.m_num_edges;
+}
+
+#ifndef BOOST_NO_STD_ITERATOR_TRAITS
+template < class EdgeIter >
+inline edge_list< EdgeIter > make_edge_list(EdgeIter first, EdgeIter last)
+{
+ return edge_list< EdgeIter >(first, last);
+}
+#endif
+
+} /* namespace boost */
+
+#endif /* BOOST_GRAPH_EDGE_LIST_HPP */
diff --git a/contrib/restricted/boost/graph/include/boost/graph/edmonds_karp_max_flow.hpp b/contrib/restricted/boost/graph/include/boost/graph/edmonds_karp_max_flow.hpp
new file mode 100644
index 0000000000..cd8aa99f63
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/edmonds_karp_max_flow.hpp
@@ -0,0 +1,245 @@
+//=======================================================================
+// Copyright 2000 University of Notre Dame.
+// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_EDMONDS_KARP_MAX_FLOW_HPP
+#define BOOST_GRAPH_EDMONDS_KARP_MAX_FLOW_HPP
+
+#include <boost/config.hpp>
+#include <vector>
+#include <algorithm> // for std::min and std::max
+#include <boost/config.hpp>
+#include <boost/pending/queue.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/filtered_graph.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+
+namespace boost
+{
+
+// The "labeling" algorithm from "Network Flows" by Ahuja, Magnanti,
+// Orlin. I think this is the same as or very similar to the original
+// Edmonds-Karp algorithm. This solves the maximum flow problem.
+
+namespace detail
+{
+
+ template < class Graph, class ResCapMap >
+ filtered_graph< Graph, is_residual_edge< ResCapMap > > residual_graph(
+ Graph& g, ResCapMap residual_capacity)
+ {
+ return filtered_graph< Graph, is_residual_edge< ResCapMap > >(
+ g, is_residual_edge< ResCapMap >(residual_capacity));
+ }
+
+ template < class Graph, class PredEdgeMap, class ResCapMap,
+ class RevEdgeMap >
+ inline void augment(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink, PredEdgeMap p,
+ ResCapMap residual_capacity, RevEdgeMap reverse_edge)
+ {
+ typename graph_traits< Graph >::edge_descriptor e;
+ typename graph_traits< Graph >::vertex_descriptor u;
+ typedef typename property_traits< ResCapMap >::value_type FlowValue;
+
+ // find minimum residual capacity along the augmenting path
+ FlowValue delta = (std::numeric_limits< FlowValue >::max)();
+ e = get(p, sink);
+ do
+ {
+ BOOST_USING_STD_MIN();
+ delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ delta, get(residual_capacity, e));
+ u = source(e, g);
+ e = get(p, u);
+ } while (u != src);
+
+ // push delta units of flow along the augmenting path
+ e = get(p, sink);
+ do
+ {
+ put(residual_capacity, e, get(residual_capacity, e) - delta);
+ put(residual_capacity, get(reverse_edge, e),
+ get(residual_capacity, get(reverse_edge, e)) + delta);
+ u = source(e, g);
+ e = get(p, u);
+ } while (u != src);
+ }
+
+} // namespace detail
+
+template < class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap,
+ class ReverseEdgeMap, class ColorMap, class PredEdgeMap >
+typename property_traits< CapacityEdgeMap >::value_type edmonds_karp_max_flow(
+ Graph& g, typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink, CapacityEdgeMap cap,
+ ResidualCapacityEdgeMap res, ReverseEdgeMap rev, ColorMap color,
+ PredEdgeMap pred)
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+
+ typename graph_traits< Graph >::vertex_iterator u_iter, u_end;
+ typename graph_traits< Graph >::out_edge_iterator ei, e_end;
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
+ for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
+ put(res, *ei, get(cap, *ei));
+
+ put(color, sink, Color::gray());
+ while (get(color, sink) != Color::white())
+ {
+ boost::queue< vertex_t > Q;
+ breadth_first_search(detail::residual_graph(g, res), src, Q,
+ make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())),
+ color);
+ if (get(color, sink) != Color::white())
+ detail::augment(g, src, sink, pred, res, rev);
+ } // while
+
+ typename property_traits< CapacityEdgeMap >::value_type flow = 0;
+ for (boost::tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei)
+ flow += (get(cap, *ei) - get(res, *ei));
+ return flow;
+} // edmonds_karp_max_flow()
+
+namespace detail
+{
+ //-------------------------------------------------------------------------
+ // Handle default for color property map
+
+ // use of class here is a VC++ workaround
+ template < class ColorMap > struct edmonds_karp_dispatch2
+ {
+ template < class Graph, class PredMap, class P, class T, class R >
+ static typename edge_capacity_value< Graph, P, T, R >::type apply(
+ Graph& g, typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink,
+ PredMap pred, const bgl_named_params< P, T, R >& params,
+ ColorMap color)
+ {
+ return edmonds_karp_max_flow(g, src, sink,
+ choose_const_pmap(
+ get_param(params, edge_capacity), g, edge_capacity),
+ choose_pmap(get_param(params, edge_residual_capacity), g,
+ edge_residual_capacity),
+ choose_const_pmap(
+ get_param(params, edge_reverse), g, edge_reverse),
+ color, pred);
+ }
+ };
+ template <> struct edmonds_karp_dispatch2< param_not_found >
+ {
+ template < class Graph, class PredMap, class P, class T, class R >
+ static typename edge_capacity_value< Graph, P, T, R >::type apply(
+ Graph& g, typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink,
+ PredMap pred, const bgl_named_params< P, T, R >& params,
+ param_not_found)
+ {
+ typedef
+ typename graph_traits< Graph >::vertices_size_type size_type;
+ size_type n = is_default_param(get_param(params, vertex_color))
+ ? num_vertices(g)
+ : 1;
+ std::vector< default_color_type > color_vec(n);
+ return edmonds_karp_max_flow(g, src, sink,
+ choose_const_pmap(
+ get_param(params, edge_capacity), g, edge_capacity),
+ choose_pmap(get_param(params, edge_residual_capacity), g,
+ edge_residual_capacity),
+ choose_const_pmap(
+ get_param(params, edge_reverse), g, edge_reverse),
+ make_iterator_property_map(color_vec.begin(),
+ choose_const_pmap(
+ get_param(params, vertex_index), g, vertex_index),
+ color_vec[0]),
+ pred);
+ }
+ };
+
+ //-------------------------------------------------------------------------
+ // Handle default for predecessor property map
+
+ // use of class here is a VC++ workaround
+ template < class PredMap > struct edmonds_karp_dispatch1
+ {
+ template < class Graph, class P, class T, class R >
+ static typename edge_capacity_value< Graph, P, T, R >::type apply(
+ Graph& g, typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink,
+ const bgl_named_params< P, T, R >& params, PredMap pred)
+ {
+ typedef typename get_param_type< vertex_color_t,
+ bgl_named_params< P, T, R > >::type C;
+ return edmonds_karp_dispatch2< C >::apply(
+ g, src, sink, pred, params, get_param(params, vertex_color));
+ }
+ };
+ template <> struct edmonds_karp_dispatch1< param_not_found >
+ {
+
+ template < class Graph, class P, class T, class R >
+ static typename edge_capacity_value< Graph, P, T, R >::type apply(
+ Graph& g, typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink,
+ const bgl_named_params< P, T, R >& params, param_not_found)
+ {
+ typedef
+ typename graph_traits< Graph >::edge_descriptor edge_descriptor;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type size_type;
+ size_type n
+ = is_default_param(get_param(params, vertex_predecessor))
+ ? num_vertices(g)
+ : 1;
+ std::vector< edge_descriptor > pred_vec(n);
+
+ typedef typename get_param_type< vertex_color_t,
+ bgl_named_params< P, T, R > >::type C;
+ return edmonds_karp_dispatch2< C >::apply(g, src, sink,
+ make_iterator_property_map(pred_vec.begin(),
+ choose_const_pmap(
+ get_param(params, vertex_index), g, vertex_index),
+ pred_vec[0]),
+ params, get_param(params, vertex_color));
+ }
+ };
+
+} // namespace detail
+
+template < class Graph, class P, class T, class R >
+typename detail::edge_capacity_value< Graph, P, T, R >::type
+edmonds_karp_max_flow(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink,
+ const bgl_named_params< P, T, R >& params)
+{
+ typedef typename get_param_type< vertex_predecessor_t,
+ bgl_named_params< P, T, R > >::type Pred;
+ return detail::edmonds_karp_dispatch1< Pred >::apply(
+ g, src, sink, params, get_param(params, vertex_predecessor));
+}
+
+template < class Graph >
+typename property_traits<
+ typename property_map< Graph, edge_capacity_t >::const_type >::value_type
+edmonds_karp_max_flow(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink)
+{
+ bgl_named_params< int, buffer_param_t > params(0);
+ return edmonds_karp_max_flow(g, src, sink, params);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_EDMONDS_KARP_MAX_FLOW_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/edmunds_karp_max_flow.hpp b/contrib/restricted/boost/graph/include/boost/graph/edmunds_karp_max_flow.hpp
new file mode 100644
index 0000000000..aee587acd9
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/edmunds_karp_max_flow.hpp
@@ -0,0 +1,22 @@
+//=======================================================================
+// (c) Copyright Juergen Hunold 2008
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_DEPRECATED_INCLUDE_EDMONDS_KARP_MAX_FLOW_HPP
+#define BOOST_DEPRECATED_INCLUDE_EDMONDS_KARP_MAX_FLOW_HPP
+
+#if defined(_MSC_VER) || defined(__BORLANDC__) && !defined(__clang__) || defined(__DMC__)
+#pragma message( \
+ "Warning: This header is deprecated. Please use: boost/graph/edmonds_karp_max_flow.hpp")
+#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) \
+ || defined(__IBMCPP__) || defined(__BORLANDC__)
+#warning \
+ "This header is deprecated. Please use: boost/graph/edmonds_karp_max_flow.hpp"
+#endif
+
+#include <boost/graph/edmonds_karp_max_flow.hpp>
+
+#endif // BOOST_DEPRECATED_INCLUDE_EDMONDS_KARP_MAX_FLOW_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/erdos_renyi_generator.hpp b/contrib/restricted/boost/graph/include/boost/graph/erdos_renyi_generator.hpp
new file mode 100644
index 0000000000..f5e33c9632
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/erdos_renyi_generator.hpp
@@ -0,0 +1,221 @@
+// Copyright 2004, 2005 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jeremiah Willcock
+// Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_ERDOS_RENYI_GENERATOR_HPP
+#define BOOST_GRAPH_ERDOS_RENYI_GENERATOR_HPP
+
+#include <boost/assert.hpp>
+#include <iterator>
+#include <utility>
+#include <boost/shared_ptr.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/random/geometric_distribution.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+
+namespace boost
+{
+
+template < typename RandomGenerator, typename Graph >
+class erdos_renyi_iterator
+: public iterator_facade< erdos_renyi_iterator< RandomGenerator, Graph >,
+ std::pair< typename graph_traits< Graph >::vertices_size_type,
+ typename graph_traits< Graph >::vertices_size_type >,
+ std::input_iterator_tag,
+ const std::pair< typename graph_traits< Graph >::vertices_size_type,
+ typename graph_traits< Graph >::vertices_size_type >& >
+{
+ typedef typename graph_traits< Graph >::directed_category directed_category;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+ typedef typename graph_traits< Graph >::edges_size_type edges_size_type;
+
+ BOOST_STATIC_CONSTANT(bool,
+ is_undirected
+ = (is_base_of< undirected_tag, directed_category >::value));
+
+public:
+ erdos_renyi_iterator() : gen(), n(0), edges(0), allow_self_loops(false) {}
+ erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n,
+ double fraction = 0.0, bool allow_self_loops = false)
+ : gen(&gen)
+ , n(n)
+ , edges(edges_size_type(fraction * n * n))
+ , allow_self_loops(allow_self_loops)
+ {
+ if (is_undirected)
+ edges = edges / 2;
+ next();
+ }
+
+ erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n,
+ edges_size_type m, bool allow_self_loops = false)
+ : gen(&gen), n(n), edges(m), allow_self_loops(allow_self_loops)
+ {
+ next();
+ }
+
+ const std::pair< vertices_size_type, vertices_size_type >&
+ dereference() const
+ {
+ return current;
+ }
+
+ void increment()
+ {
+ --edges;
+ next();
+ }
+
+ bool equal(const erdos_renyi_iterator& other) const
+ {
+ return edges == other.edges;
+ }
+
+private:
+ void next()
+ {
+ uniform_int< vertices_size_type > rand_vertex(0, n - 1);
+ current.first = rand_vertex(*gen);
+ do
+ {
+ current.second = rand_vertex(*gen);
+ } while (current.first == current.second && !allow_self_loops);
+ }
+
+ RandomGenerator* gen;
+ vertices_size_type n;
+ edges_size_type edges;
+ bool allow_self_loops;
+ std::pair< vertices_size_type, vertices_size_type > current;
+};
+
+template < typename RandomGenerator, typename Graph >
+class sorted_erdos_renyi_iterator
+: public iterator_facade< sorted_erdos_renyi_iterator< RandomGenerator, Graph >,
+ std::pair< typename graph_traits< Graph >::vertices_size_type,
+ typename graph_traits< Graph >::vertices_size_type >,
+ std::input_iterator_tag,
+ const std::pair< typename graph_traits< Graph >::vertices_size_type,
+ typename graph_traits< Graph >::vertices_size_type >& >
+{
+ typedef typename graph_traits< Graph >::directed_category directed_category;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+ typedef typename graph_traits< Graph >::edges_size_type edges_size_type;
+
+ BOOST_STATIC_CONSTANT(bool,
+ is_undirected
+ = (is_base_of< undirected_tag, directed_category >::value));
+
+public:
+ sorted_erdos_renyi_iterator()
+ : gen()
+ , rand_vertex(0.5)
+ , n(0)
+ , allow_self_loops(false)
+ , src((std::numeric_limits< vertices_size_type >::max)())
+ , tgt_index(vertices_size_type(-1))
+ , prob(.5)
+ {
+ }
+
+ // NOTE: The default probability has been changed to be the same as that
+ // used by the geometic distribution. It was previously 0.0, which would
+ // cause an assertion.
+ sorted_erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n,
+ double prob = 0.5, bool loops = false)
+ : gen()
+ , rand_vertex(1. - prob)
+ , n(n)
+ , allow_self_loops(loops)
+ , src(0)
+ , tgt_index(vertices_size_type(-1))
+ , prob(prob)
+ {
+ this->gen.reset(new uniform_01< RandomGenerator* >(&gen));
+
+ if (prob == 0.0)
+ {
+ src = (std::numeric_limits< vertices_size_type >::max)();
+ return;
+ }
+ next();
+ }
+
+ const std::pair< vertices_size_type, vertices_size_type >&
+ dereference() const
+ {
+ return current;
+ }
+
+ bool equal(const sorted_erdos_renyi_iterator& o) const
+ {
+ return src == o.src && tgt_index == o.tgt_index;
+ }
+
+ void increment() { next(); }
+
+private:
+ void next()
+ {
+ // In order to get the edges from the generator in sorted order, one
+ // effective (but slow) procedure would be to use a
+ // bernoulli_distribution for each legal (src, tgt_index) pair. Because
+ // of the O(|V|^2) cost of that, a geometric distribution is used. The
+ // geometric distribution tells how many times the
+ // bernoulli_distribution would need to be run until it returns true.
+ // Thus, this distribution can be used to step through the edges
+ // which are actually present.
+ BOOST_ASSERT(src != (std::numeric_limits< vertices_size_type >::max)()
+ && src != n);
+ while (src != n)
+ {
+ vertices_size_type increment = rand_vertex(*gen);
+ size_t tgt_index_limit
+ = (is_undirected ? src + 1 : n) + (allow_self_loops ? 0 : -1);
+ if (tgt_index + increment >= tgt_index_limit)
+ {
+ // Overflowed this source; go to the next one and try again.
+ ++src;
+ // This bias is because the geometric distribution always
+ // returns values >=1, and we want to allow 0 as a valid target.
+ tgt_index = vertices_size_type(-1);
+ continue;
+ }
+ else
+ {
+ tgt_index += increment;
+ current.first = src;
+ current.second = tgt_index
+ + (!allow_self_loops && !is_undirected && tgt_index >= src
+ ? 1
+ : 0);
+ break;
+ }
+ }
+ if (src == n)
+ src = (std::numeric_limits< vertices_size_type >::max)();
+ }
+
+ shared_ptr< uniform_01< RandomGenerator* > > gen;
+ geometric_distribution< vertices_size_type > rand_vertex;
+ vertices_size_type n;
+ bool allow_self_loops;
+ vertices_size_type src, tgt_index;
+ std::pair< vertices_size_type, vertices_size_type > current;
+ double prob;
+};
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_ERDOS_RENYI_GENERATOR_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/exterior_property.hpp b/contrib/restricted/boost/graph/include/boost/graph/exterior_property.hpp
new file mode 100644
index 0000000000..281b7bb2a9
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/exterior_property.hpp
@@ -0,0 +1,114 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_EXTERIOR_PROPERTY_HPP
+#define BOOST_GRAPH_EXTERIOR_PROPERTY_HPP
+
+#include <vector>
+#include <boost/graph/property_maps/container_property_map.hpp>
+#include <boost/graph/property_maps/matrix_property_map.hpp>
+
+namespace boost
+{
+namespace detail
+{
+ // The vector matrix provides a little abstraction over vector
+ // types that makes matrices easier to work with.
+ template < typename Value > struct vector_matrix
+ {
+ typedef std::vector< Value > container_type;
+ typedef std::vector< container_type > matrix_type;
+
+ typedef container_type value_type;
+ typedef container_type& reference;
+ typedef const container_type const_reference;
+ typedef container_type* pointer;
+ typedef typename matrix_type::size_type size_type;
+
+ // Instantiate the matrix over n elements (creates an n by n matrix).
+ // The graph has to be passed in order to ensure the index maps
+ // are constructed correctly when returning indexible elements.
+ inline vector_matrix(size_type n) : m_matrix(n, container_type(n)) {}
+
+ inline reference operator[](size_type n) { return m_matrix[n]; }
+
+ inline const_reference operator[](size_type n) const
+ {
+ return m_matrix[n];
+ }
+
+ matrix_type m_matrix;
+ };
+} /* namespace detail */
+
+/**
+ * The exterior_property metafunction defines an appropriate set of types for
+ * creating an exterior property. An exterior property is comprised of a both
+ * a container and a property map that acts as its abstraction. An extension
+ * of this metafunction will select an appropriate "matrix" property that
+ * records values for pairs of vertices.
+ *
+ * @todo This does not currently support the ability to define exterior
+ * properties for graph types that do not model the IndexGraph concepts. A
+ * solution should not be especially difficult, but will require an extension
+ * of type traits to affect the type selection.
+ */
+template < typename Graph, typename Key, typename Value >
+struct exterior_property
+{
+ typedef Key key_type;
+ typedef Value value_type;
+
+ typedef std::vector< Value > container_type;
+ typedef container_property_map< Graph, Key, container_type > map_type;
+
+ typedef detail::vector_matrix< Value > matrix_type;
+ typedef matrix_property_map< Graph, Key, matrix_type > matrix_map_type;
+
+private:
+ exterior_property() {}
+ exterior_property(const exterior_property&) {}
+};
+
+/**
+ * Define a the container and property map types requried to create an exterior
+ * vertex property for the given value type. The Graph parameter is required to
+ * model the VertexIndexGraph concept.
+ */
+template < typename Graph, typename Value > struct exterior_vertex_property
+{
+ typedef exterior_property< Graph,
+ typename graph_traits< Graph >::vertex_descriptor, Value >
+ property_type;
+ typedef typename property_type::key_type key_type;
+ typedef typename property_type::value_type value_type;
+ typedef typename property_type::container_type container_type;
+ typedef typename property_type::map_type map_type;
+ typedef typename property_type::matrix_type matrix_type;
+ typedef typename property_type::matrix_map_type matrix_map_type;
+};
+
+/**
+ * Define a the container and property map types requried to create an exterior
+ * edge property for the given value type. The Graph parameter is required to
+ * model the EdgeIndexGraph concept.
+ */
+template < typename Graph, typename Value > struct exterior_edge_property
+{
+ typedef exterior_property< Graph,
+ typename graph_traits< Graph >::edge_descriptor, Value >
+ property_type;
+ typedef typename property_type::key_type key_type;
+ typedef typename property_type::value_type value_type;
+ typedef typename property_type::container_type container_type;
+ typedef typename property_type::map_type map_type;
+ typedef typename property_type::matrix_type matrix_type;
+ typedef typename property_type::matrix_map_type matrix_map_type;
+};
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/find_flow_cost.hpp b/contrib/restricted/boost/graph/include/boost/graph/find_flow_cost.hpp
new file mode 100644
index 0000000000..78fd955d83
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/find_flow_cost.hpp
@@ -0,0 +1,57 @@
+//=======================================================================
+// Copyright 2013 University of Warsaw.
+// Authors: Piotr Wygocki
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_FIND_FLOW_COST_HPP
+#define BOOST_GRAPH_FIND_FLOW_COST_HPP
+
+#include <boost/graph/iteration_macros.hpp>
+
+namespace boost
+{
+
+template < class Graph, class Capacity, class ResidualCapacity, class Weight >
+typename property_traits< Weight >::value_type find_flow_cost(const Graph& g,
+ Capacity capacity, ResidualCapacity residual_capacity, Weight weight)
+{
+ typedef typename property_traits< Weight >::value_type Cost;
+
+ Cost cost = 0;
+ BGL_FORALL_EDGES_T(e, g, Graph)
+ {
+ if (get(capacity, e) > Cost(0))
+ {
+ cost += (get(capacity, e) - get(residual_capacity, e))
+ * get(weight, e);
+ }
+ }
+ return cost;
+}
+
+template < class Graph, class P, class T, class R >
+typename detail::edge_weight_value< Graph, P, T, R >::type find_flow_cost(
+ const Graph& g, const bgl_named_params< P, T, R >& params)
+{
+ return find_flow_cost(g,
+ choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
+ choose_const_pmap(get_param(params, edge_residual_capacity), g,
+ edge_residual_capacity),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight));
+}
+
+template < class Graph >
+typename property_traits<
+ typename property_map< Graph, edge_capacity_t >::type >::value_type
+find_flow_cost(const Graph& g)
+{
+ bgl_named_params< int, buffer_param_t > params(0);
+ return find_flow_cost(g, params);
+}
+
+} // boost
+
+#endif /* BOOST_GRAPH_FIND_FLOW_COST_HPP */
diff --git a/contrib/restricted/boost/graph/include/boost/graph/floyd_warshall_shortest.hpp b/contrib/restricted/boost/graph/include/boost/graph/floyd_warshall_shortest.hpp
new file mode 100644
index 0000000000..e8eeae5472
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/floyd_warshall_shortest.hpp
@@ -0,0 +1,223 @@
+// Copyright 2002 Rensselaer Polytechnic Institute
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Lauren Foutz
+// Scott Hill
+
+/*
+ This file implements the functions
+
+ template <class VertexListGraph, class DistanceMatrix,
+ class P, class T, class R>
+ bool floyd_warshall_initialized_all_pairs_shortest_paths(
+ const VertexListGraph& g, DistanceMatrix& d,
+ const bgl_named_params<P, T, R>& params)
+
+ AND
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class P, class T, class R>
+ bool floyd_warshall_all_pairs_shortest_paths(
+ const VertexAndEdgeListGraph& g, DistanceMatrix& d,
+ const bgl_named_params<P, T, R>& params)
+*/
+
+#ifndef BOOST_GRAPH_FLOYD_WARSHALL_HPP
+#define BOOST_GRAPH_FLOYD_WARSHALL_HPP
+
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/relax.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+namespace detail
+{
+ template < typename T, typename BinaryPredicate >
+ T min_with_compare(const T& x, const T& y, const BinaryPredicate& compare)
+ {
+ if (compare(x, y))
+ return x;
+ else
+ return y;
+ }
+
+ template < typename VertexListGraph, typename DistanceMatrix,
+ typename BinaryPredicate, typename BinaryFunction, typename Infinity,
+ typename Zero >
+ bool floyd_warshall_dispatch(const VertexListGraph& g, DistanceMatrix& d,
+ const BinaryPredicate& compare, const BinaryFunction& combine,
+ const Infinity& inf, const Zero& zero)
+ {
+ typename graph_traits< VertexListGraph >::vertex_iterator i, lasti, j,
+ lastj, k, lastk;
+
+ for (boost::tie(k, lastk) = vertices(g); k != lastk; k++)
+ for (boost::tie(i, lasti) = vertices(g); i != lasti; i++)
+ if (d[*i][*k] != inf)
+ for (boost::tie(j, lastj) = vertices(g); j != lastj; j++)
+ if (d[*k][*j] != inf)
+ d[*i][*j] = detail::min_with_compare(d[*i][*j],
+ combine(d[*i][*k], d[*k][*j]), compare);
+
+ for (boost::tie(i, lasti) = vertices(g); i != lasti; i++)
+ if (compare(d[*i][*i], zero))
+ return false;
+ return true;
+ }
+}
+
+template < typename VertexListGraph, typename DistanceMatrix,
+ typename BinaryPredicate, typename BinaryFunction, typename Infinity,
+ typename Zero >
+bool floyd_warshall_initialized_all_pairs_shortest_paths(
+ const VertexListGraph& g, DistanceMatrix& d, const BinaryPredicate& compare,
+ const BinaryFunction& combine, const Infinity& inf, const Zero& zero)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexListGraph >));
+
+ return detail::floyd_warshall_dispatch(g, d, compare, combine, inf, zero);
+}
+
+template < typename VertexAndEdgeListGraph, typename DistanceMatrix,
+ typename WeightMap, typename BinaryPredicate, typename BinaryFunction,
+ typename Infinity, typename Zero >
+bool floyd_warshall_all_pairs_shortest_paths(const VertexAndEdgeListGraph& g,
+ DistanceMatrix& d, const WeightMap& w, const BinaryPredicate& compare,
+ const BinaryFunction& combine, const Infinity& inf, const Zero& zero)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexAndEdgeListGraph >));
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< VertexAndEdgeListGraph >));
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< VertexAndEdgeListGraph >));
+
+ typename graph_traits< VertexAndEdgeListGraph >::vertex_iterator firstv,
+ lastv, firstv2, lastv2;
+ typename graph_traits< VertexAndEdgeListGraph >::edge_iterator first, last;
+
+ for (boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
+ for (boost::tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2;
+ firstv2++)
+ d[*firstv][*firstv2] = inf;
+
+ for (boost::tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
+ d[*firstv][*firstv] = zero;
+
+ for (boost::tie(first, last) = edges(g); first != last; first++)
+ {
+ if (d[source(*first, g)][target(*first, g)] != inf)
+ {
+ d[source(*first, g)][target(*first, g)]
+ = detail::min_with_compare(get(w, *first),
+ d[source(*first, g)][target(*first, g)], compare);
+ }
+ else
+ d[source(*first, g)][target(*first, g)] = get(w, *first);
+ }
+
+ bool is_undirected = is_same<
+ typename graph_traits< VertexAndEdgeListGraph >::directed_category,
+ undirected_tag >::value;
+ if (is_undirected)
+ {
+ for (boost::tie(first, last) = edges(g); first != last; first++)
+ {
+ if (d[target(*first, g)][source(*first, g)] != inf)
+ d[target(*first, g)][source(*first, g)]
+ = detail::min_with_compare(get(w, *first),
+ d[target(*first, g)][source(*first, g)], compare);
+ else
+ d[target(*first, g)][source(*first, g)] = get(w, *first);
+ }
+ }
+
+ return detail::floyd_warshall_dispatch(g, d, compare, combine, inf, zero);
+}
+
+namespace detail
+{
+ template < class VertexListGraph, class DistanceMatrix, class WeightMap,
+ class P, class T, class R >
+ bool floyd_warshall_init_dispatch(const VertexListGraph& g,
+ DistanceMatrix& d, WeightMap /*w*/,
+ const bgl_named_params< P, T, R >& params)
+ {
+ typedef typename property_traits< WeightMap >::value_type WM;
+ WM inf = choose_param(get_param(params, distance_inf_t()),
+ std::numeric_limits< WM >::max BOOST_PREVENT_MACRO_SUBSTITUTION());
+
+ return floyd_warshall_initialized_all_pairs_shortest_paths(g, d,
+ choose_param(
+ get_param(params, distance_compare_t()), std::less< WM >()),
+ choose_param(get_param(params, distance_combine_t()),
+ closed_plus< WM >(inf)),
+ inf, choose_param(get_param(params, distance_zero_t()), WM()));
+ }
+
+ template < class VertexAndEdgeListGraph, class DistanceMatrix,
+ class WeightMap, class P, class T, class R >
+ bool floyd_warshall_noninit_dispatch(const VertexAndEdgeListGraph& g,
+ DistanceMatrix& d, WeightMap w,
+ const bgl_named_params< P, T, R >& params)
+ {
+ typedef typename property_traits< WeightMap >::value_type WM;
+
+ WM inf = choose_param(get_param(params, distance_inf_t()),
+ std::numeric_limits< WM >::max BOOST_PREVENT_MACRO_SUBSTITUTION());
+ return floyd_warshall_all_pairs_shortest_paths(g, d, w,
+ choose_param(
+ get_param(params, distance_compare_t()), std::less< WM >()),
+ choose_param(get_param(params, distance_combine_t()),
+ closed_plus< WM >(inf)),
+ inf, choose_param(get_param(params, distance_zero_t()), WM()));
+ }
+
+} // namespace detail
+
+template < class VertexListGraph, class DistanceMatrix, class P, class T,
+ class R >
+bool floyd_warshall_initialized_all_pairs_shortest_paths(
+ const VertexListGraph& g, DistanceMatrix& d,
+ const bgl_named_params< P, T, R >& params)
+{
+ return detail::floyd_warshall_init_dispatch(g, d,
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ params);
+}
+
+template < class VertexListGraph, class DistanceMatrix >
+bool floyd_warshall_initialized_all_pairs_shortest_paths(
+ const VertexListGraph& g, DistanceMatrix& d)
+{
+ bgl_named_params< int, int > params(0);
+ return detail::floyd_warshall_init_dispatch(
+ g, d, get(edge_weight, g), params);
+}
+
+template < class VertexAndEdgeListGraph, class DistanceMatrix, class P, class T,
+ class R >
+bool floyd_warshall_all_pairs_shortest_paths(const VertexAndEdgeListGraph& g,
+ DistanceMatrix& d, const bgl_named_params< P, T, R >& params)
+{
+ return detail::floyd_warshall_noninit_dispatch(g, d,
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ params);
+}
+
+template < class VertexAndEdgeListGraph, class DistanceMatrix >
+bool floyd_warshall_all_pairs_shortest_paths(
+ const VertexAndEdgeListGraph& g, DistanceMatrix& d)
+{
+ bgl_named_params< int, int > params(0);
+ return detail::floyd_warshall_noninit_dispatch(
+ g, d, get(edge_weight, g), params);
+}
+
+} // namespace boost
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/fruchterman_reingold.hpp b/contrib/restricted/boost/graph/include/boost/graph/fruchterman_reingold.hpp
new file mode 100644
index 0000000000..d2a443427d
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/fruchterman_reingold.hpp
@@ -0,0 +1,460 @@
+// Copyright 2004, 2005 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP
+#define BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/topology.hpp> // For topology concepts
+#include <boost/graph/detail/mpi_include.hpp>
+#include <vector>
+#include <list>
+#include <algorithm> // for std::min and std::max
+#include <numeric> // for std::accumulate
+#include <cmath> // for std::sqrt and std::fabs
+#include <functional>
+
+namespace boost
+{
+
+struct square_distance_attractive_force
+{
+ template < typename Graph, typename T >
+ T operator()(typename graph_traits< Graph >::edge_descriptor, T k, T d,
+ const Graph&) const
+ {
+ return d * d / k;
+ }
+};
+
+struct square_distance_repulsive_force
+{
+ template < typename Graph, typename T >
+ T operator()(typename graph_traits< Graph >::vertex_descriptor,
+ typename graph_traits< Graph >::vertex_descriptor, T k, T d,
+ const Graph&) const
+ {
+ return k * k / d;
+ }
+};
+
+template < typename T > struct linear_cooling
+{
+ typedef T result_type;
+
+ linear_cooling(std::size_t iterations)
+ : temp(T(iterations) / T(10)), step(0.1)
+ {
+ }
+
+ linear_cooling(std::size_t iterations, T temp)
+ : temp(temp), step(temp / T(iterations))
+ {
+ }
+
+ T operator()()
+ {
+ T old_temp = temp;
+ temp -= step;
+ if (temp < T(0))
+ temp = T(0);
+ return old_temp;
+ }
+
+private:
+ T temp;
+ T step;
+};
+
+struct all_force_pairs
+{
+ template < typename Graph, typename ApplyForce >
+ void operator()(const Graph& g, ApplyForce apply_force)
+ {
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator;
+ vertex_iterator v, end;
+ for (boost::tie(v, end) = vertices(g); v != end; ++v)
+ {
+ vertex_iterator u = v;
+ for (++u; u != end; ++u)
+ {
+ apply_force(*u, *v);
+ apply_force(*v, *u);
+ }
+ }
+ }
+};
+
+template < typename Topology, typename PositionMap > struct grid_force_pairs
+{
+ typedef typename property_traits< PositionMap >::value_type Point;
+ BOOST_STATIC_ASSERT(Point::dimensions == 2);
+ typedef typename Topology::point_difference_type point_difference_type;
+
+ template < typename Graph >
+ explicit grid_force_pairs(
+ const Topology& topology, PositionMap position, const Graph& g)
+ : topology(topology), position(position)
+ {
+ two_k = 2. * this->topology.volume(this->topology.extent())
+ / std::sqrt((double)num_vertices(g));
+ }
+
+ template < typename Graph, typename ApplyForce >
+ void operator()(const Graph& g, ApplyForce apply_force)
+ {
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator;
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+ typedef std::list< vertex_descriptor > bucket_t;
+ typedef std::vector< bucket_t > buckets_t;
+
+ std::size_t columns = std::size_t(topology.extent()[0] / two_k + 1.);
+ std::size_t rows = std::size_t(topology.extent()[1] / two_k + 1.);
+ buckets_t buckets(rows * columns);
+ vertex_iterator v, v_end;
+ for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v)
+ {
+ std::size_t column = std::size_t(
+ (get(position, *v)[0] + topology.extent()[0] / 2) / two_k);
+ std::size_t row = std::size_t(
+ (get(position, *v)[1] + topology.extent()[1] / 2) / two_k);
+
+ if (column >= columns)
+ column = columns - 1;
+ if (row >= rows)
+ row = rows - 1;
+ buckets[row * columns + column].push_back(*v);
+ }
+
+ for (std::size_t row = 0; row < rows; ++row)
+ for (std::size_t column = 0; column < columns; ++column)
+ {
+ bucket_t& bucket = buckets[row * columns + column];
+ typedef typename bucket_t::iterator bucket_iterator;
+ for (bucket_iterator u = bucket.begin(); u != bucket.end(); ++u)
+ {
+ // Repulse vertices in this bucket
+ bucket_iterator v = u;
+ for (++v; v != bucket.end(); ++v)
+ {
+ apply_force(*u, *v);
+ apply_force(*v, *u);
+ }
+
+ std::size_t adj_start_row = row == 0 ? 0 : row - 1;
+ std::size_t adj_end_row = row == rows - 1 ? row : row + 1;
+ std::size_t adj_start_column = column == 0 ? 0 : column - 1;
+ std::size_t adj_end_column
+ = column == columns - 1 ? column : column + 1;
+ for (std::size_t other_row = adj_start_row;
+ other_row <= adj_end_row; ++other_row)
+ for (std::size_t other_column = adj_start_column;
+ other_column <= adj_end_column; ++other_column)
+ if (other_row != row || other_column != column)
+ {
+ // Repulse vertices in this bucket
+ bucket_t& other_bucket
+ = buckets[other_row * columns
+ + other_column];
+ for (v = other_bucket.begin();
+ v != other_bucket.end(); ++v)
+ {
+ double dist = topology.distance(
+ get(position, *u), get(position, *v));
+ if (dist < two_k)
+ apply_force(*u, *v);
+ }
+ }
+ }
+ }
+ }
+
+private:
+ const Topology& topology;
+ PositionMap position;
+ double two_k;
+};
+
+template < typename PositionMap, typename Topology, typename Graph >
+inline grid_force_pairs< Topology, PositionMap > make_grid_force_pairs(
+ const Topology& topology, const PositionMap& position, const Graph& g)
+{
+ return grid_force_pairs< Topology, PositionMap >(topology, position, g);
+}
+
+template < typename Graph, typename PositionMap, typename Topology >
+void scale_graph(const Graph& g, PositionMap position, const Topology& topology,
+ typename Topology::point_type upper_left,
+ typename Topology::point_type lower_right)
+{
+ if (num_vertices(g) == 0)
+ return;
+
+ typedef typename Topology::point_type Point;
+ typedef typename Topology::point_difference_type point_difference_type;
+
+ // Find min/max ranges
+ Point min_point = get(position, *vertices(g).first), max_point = min_point;
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ min_point = topology.pointwise_min(min_point, get(position, v));
+ max_point = topology.pointwise_max(max_point, get(position, v));
+ }
+
+ Point old_origin = topology.move_position_toward(min_point, 0.5, max_point);
+ Point new_origin
+ = topology.move_position_toward(upper_left, 0.5, lower_right);
+ point_difference_type old_size = topology.difference(max_point, min_point);
+ point_difference_type new_size
+ = topology.difference(lower_right, upper_left);
+
+ // Scale to bounding box provided
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ point_difference_type relative_loc
+ = topology.difference(get(position, v), old_origin);
+ relative_loc = (relative_loc / old_size) * new_size;
+ put(position, v, topology.adjust(new_origin, relative_loc));
+ }
+}
+
+namespace detail
+{
+ template < typename Topology, typename PropMap, typename Vertex >
+ void maybe_jitter_point(const Topology& topology, const PropMap& pm,
+ Vertex v, const typename Topology::point_type& p2)
+ {
+ double too_close = topology.norm(topology.extent()) / 10000.;
+ if (topology.distance(get(pm, v), p2) < too_close)
+ {
+ put(pm, v,
+ topology.move_position_toward(
+ get(pm, v), 1. / 200, topology.random_point()));
+ }
+ }
+
+ template < typename Topology, typename PositionMap,
+ typename DisplacementMap, typename RepulsiveForce, typename Graph >
+ struct fr_apply_force
+ {
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+ typedef typename Topology::point_type Point;
+ typedef typename Topology::point_difference_type PointDiff;
+
+ fr_apply_force(const Topology& topology, const PositionMap& position,
+ const DisplacementMap& displacement, RepulsiveForce repulsive_force,
+ double k, const Graph& g)
+ : topology(topology)
+ , position(position)
+ , displacement(displacement)
+ , repulsive_force(repulsive_force)
+ , k(k)
+ , g(g)
+ {
+ }
+
+ void operator()(vertex_descriptor u, vertex_descriptor v)
+ {
+ if (u != v)
+ {
+ // When the vertices land on top of each other, move the
+ // first vertex away from the boundaries.
+ maybe_jitter_point(topology, position, u, get(position, v));
+
+ double dist
+ = topology.distance(get(position, u), get(position, v));
+ typename Topology::point_difference_type dispv
+ = get(displacement, v);
+ if (dist == 0.)
+ {
+ for (std::size_t i = 0; i < Point::dimensions; ++i)
+ {
+ dispv[i] += 0.01;
+ }
+ }
+ else
+ {
+ double fr = repulsive_force(u, v, k, dist, g);
+ dispv += (fr / dist)
+ * topology.difference(
+ get(position, v), get(position, u));
+ }
+ put(displacement, v, dispv);
+ }
+ }
+
+ private:
+ const Topology& topology;
+ PositionMap position;
+ DisplacementMap displacement;
+ RepulsiveForce repulsive_force;
+ double k;
+ const Graph& g;
+ };
+
+} // end namespace detail
+
+template < typename Topology, typename Graph, typename PositionMap,
+ typename AttractiveForce, typename RepulsiveForce, typename ForcePairs,
+ typename Cooling, typename DisplacementMap >
+void fruchterman_reingold_force_directed_layout(const Graph& g,
+ PositionMap position, const Topology& topology,
+ AttractiveForce attractive_force, RepulsiveForce repulsive_force,
+ ForcePairs force_pairs, Cooling cool, DisplacementMap displacement)
+{
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator;
+
+ double volume = topology.volume(topology.extent());
+
+ // assume positions are initialized randomly
+ double k = pow(volume / num_vertices(g),
+ 1. / (double)(Topology::point_difference_type::dimensions));
+
+ detail::fr_apply_force< Topology, PositionMap, DisplacementMap,
+ RepulsiveForce, Graph >
+ apply_force(topology, position, displacement, repulsive_force, k, g);
+
+ do
+ {
+ // Calculate repulsive forces
+ vertex_iterator v, v_end;
+ for (boost::tie(v, v_end) = vertices(g); v != v_end; ++v)
+ put(displacement, *v, typename Topology::point_difference_type());
+ force_pairs(g, apply_force);
+
+ // Calculate attractive forces
+ edge_iterator e, e_end;
+ for (boost::tie(e, e_end) = edges(g); e != e_end; ++e)
+ {
+ vertex_descriptor v = source(*e, g);
+ vertex_descriptor u = target(*e, g);
+
+ // When the vertices land on top of each other, move the
+ // first vertex away from the boundaries.
+ ::boost::detail::maybe_jitter_point(
+ topology, position, u, get(position, v));
+
+ typename Topology::point_difference_type delta
+ = topology.difference(get(position, v), get(position, u));
+ double dist = topology.distance(get(position, u), get(position, v));
+ double fa = attractive_force(*e, k, dist, g);
+
+ put(displacement, v, get(displacement, v) - (fa / dist) * delta);
+ put(displacement, u, get(displacement, u) + (fa / dist) * delta);
+ }
+
+ if (double temp = cool())
+ {
+ // Update positions
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ double disp_size = topology.norm(get(displacement, v));
+ put(position, v,
+ topology.adjust(get(position, v),
+ get(displacement, v)
+ * (min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ disp_size, temp)
+ / disp_size)));
+ put(position, v, topology.bound(get(position, v)));
+ }
+ }
+ else
+ {
+ break;
+ }
+ } while (true);
+}
+
+namespace detail
+{
+ template < typename DisplacementMap > struct fr_force_directed_layout
+ {
+ template < typename Topology, typename Graph, typename PositionMap,
+ typename AttractiveForce, typename RepulsiveForce,
+ typename ForcePairs, typename Cooling, typename Param, typename Tag,
+ typename Rest >
+ static void run(const Graph& g, PositionMap position,
+ const Topology& topology, AttractiveForce attractive_force,
+ RepulsiveForce repulsive_force, ForcePairs force_pairs,
+ Cooling cool, DisplacementMap displacement,
+ const bgl_named_params< Param, Tag, Rest >&)
+ {
+ fruchterman_reingold_force_directed_layout(g, position, topology,
+ attractive_force, repulsive_force, force_pairs, cool,
+ displacement);
+ }
+ };
+
+ template <> struct fr_force_directed_layout< param_not_found >
+ {
+ template < typename Topology, typename Graph, typename PositionMap,
+ typename AttractiveForce, typename RepulsiveForce,
+ typename ForcePairs, typename Cooling, typename Param, typename Tag,
+ typename Rest >
+ static void run(const Graph& g, PositionMap position,
+ const Topology& topology, AttractiveForce attractive_force,
+ RepulsiveForce repulsive_force, ForcePairs force_pairs,
+ Cooling cool, param_not_found,
+ const bgl_named_params< Param, Tag, Rest >& params)
+ {
+ typedef typename Topology::point_difference_type PointDiff;
+ std::vector< PointDiff > displacements(num_vertices(g));
+ fruchterman_reingold_force_directed_layout(g, position, topology,
+ attractive_force, repulsive_force, force_pairs, cool,
+ make_iterator_property_map(displacements.begin(),
+ choose_const_pmap(
+ get_param(params, vertex_index), g, vertex_index),
+ PointDiff()));
+ }
+ };
+
+} // end namespace detail
+
+template < typename Topology, typename Graph, typename PositionMap,
+ typename Param, typename Tag, typename Rest >
+void fruchterman_reingold_force_directed_layout(const Graph& g,
+ PositionMap position, const Topology& topology,
+ const bgl_named_params< Param, Tag, Rest >& params)
+{
+ typedef typename get_param_type< vertex_displacement_t,
+ bgl_named_params< Param, Tag, Rest > >::type D;
+
+ detail::fr_force_directed_layout< D >::run(g, position, topology,
+ choose_param(get_param(params, attractive_force_t()),
+ square_distance_attractive_force()),
+ choose_param(get_param(params, repulsive_force_t()),
+ square_distance_repulsive_force()),
+ choose_param(get_param(params, force_pairs_t()),
+ make_grid_force_pairs(topology, position, g)),
+ choose_param(
+ get_param(params, cooling_t()), linear_cooling< double >(100)),
+ get_param(params, vertex_displacement_t()), params);
+}
+
+template < typename Topology, typename Graph, typename PositionMap >
+void fruchterman_reingold_force_directed_layout(
+ const Graph& g, PositionMap position, const Topology& topology)
+{
+ fruchterman_reingold_force_directed_layout(g, position, topology,
+ attractive_force(square_distance_attractive_force()));
+}
+
+} // end namespace boost
+
+
+
+#endif // BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/geodesic_distance.hpp b/contrib/restricted/boost/graph/include/boost/graph/geodesic_distance.hpp
new file mode 100644
index 0000000000..5675406a08
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/geodesic_distance.hpp
@@ -0,0 +1,217 @@
+// (C) Copyright Andrew Sutton 2007
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_GEODESIC_DISTANCE_HPP
+#define BOOST_GRAPH_GEODESIC_DISTANCE_HPP
+
+#include <boost/graph/detail/geodesic.hpp>
+#include <boost/graph/exterior_property.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+template < typename Graph, typename DistanceType, typename ResultType,
+ typename Divides = std::divides< ResultType > >
+struct mean_geodesic_measure
+: public geodesic_measure< Graph, DistanceType, ResultType >
+{
+ typedef geodesic_measure< Graph, DistanceType, ResultType > base_type;
+ typedef typename base_type::distance_type distance_type;
+ typedef typename base_type::result_type result_type;
+
+ result_type operator()(distance_type d, const Graph& g)
+ {
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((NumericValueConcept< DistanceType >));
+ BOOST_CONCEPT_ASSERT((NumericValueConcept< ResultType >));
+// NOTE: Disabled until this concept assert is fixed in Boost.ConceptCheck.
+// BOOST_CONCEPT_ASSERT((AdaptableBinaryFunctionConcept< Divides,
+// ResultType, ResultType, ResultType >));
+
+ return (d == base_type::infinite_distance())
+ ? base_type::infinite_result()
+ : div(result_type(d), result_type(num_vertices(g) - 1));
+ }
+ Divides div;
+};
+
+template < typename Graph, typename DistanceMap >
+inline mean_geodesic_measure< Graph,
+ typename property_traits< DistanceMap >::value_type, double >
+measure_mean_geodesic(const Graph&, DistanceMap)
+{
+ return mean_geodesic_measure< Graph,
+ typename property_traits< DistanceMap >::value_type, double >();
+}
+
+template < typename T, typename Graph, typename DistanceMap >
+inline mean_geodesic_measure< Graph,
+ typename property_traits< DistanceMap >::value_type, T >
+measure_mean_geodesic(const Graph&, DistanceMap)
+{
+ return mean_geodesic_measure< Graph,
+ typename property_traits< DistanceMap >::value_type, T >();
+}
+
+// This is a little different because it's expected that the result type
+// should (must?) be the same as the distance type. There's a type of
+// transitivity in this thinking... If the average of distances has type
+// X then the average of x's should also be type X. Is there a case where this
+// is not true?
+//
+// This type is a little under-genericized... It needs generic parameters
+// for addition and division.
+template < typename Graph, typename DistanceType >
+struct mean_graph_distance_measure
+: public geodesic_measure< Graph, DistanceType, DistanceType >
+{
+ typedef geodesic_measure< Graph, DistanceType, DistanceType > base_type;
+ typedef typename base_type::distance_type distance_type;
+ typedef typename base_type::result_type result_type;
+
+ inline result_type operator()(distance_type d, const Graph& g)
+ {
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((NumericValueConcept< DistanceType >));
+
+ if (d == base_type::infinite_distance())
+ {
+ return base_type::infinite_result();
+ }
+ else
+ {
+ return d / result_type(num_vertices(g));
+ }
+ }
+};
+
+template < typename Graph, typename DistanceMap >
+inline mean_graph_distance_measure< Graph,
+ typename property_traits< DistanceMap >::value_type >
+measure_graph_mean_geodesic(const Graph&, DistanceMap)
+{
+ typedef typename property_traits< DistanceMap >::value_type T;
+ return mean_graph_distance_measure< Graph, T >();
+}
+
+template < typename Graph, typename DistanceMap, typename Measure,
+ typename Combinator >
+inline typename Measure::result_type mean_geodesic(
+ const Graph& g, DistanceMap dist, Measure measure, Combinator combine)
+{
+ BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >));
+ typedef typename Measure::distance_type Distance;
+
+ Distance n = detail::combine_distances(g, dist, combine, Distance(0));
+ return measure(n, g);
+}
+
+template < typename Graph, typename DistanceMap, typename Measure >
+inline typename Measure::result_type mean_geodesic(
+ const Graph& g, DistanceMap dist, Measure measure)
+{
+ BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >));
+ typedef typename Measure::distance_type Distance;
+
+ return mean_geodesic(g, dist, measure, std::plus< Distance >());
+}
+
+template < typename Graph, typename DistanceMap >
+inline double mean_geodesic(const Graph& g, DistanceMap dist)
+{
+ return mean_geodesic(g, dist, measure_mean_geodesic(g, dist));
+}
+
+template < typename T, typename Graph, typename DistanceMap >
+inline T mean_geodesic(const Graph& g, DistanceMap dist)
+{
+ return mean_geodesic(g, dist, measure_mean_geodesic< T >(g, dist));
+}
+
+template < typename Graph, typename DistanceMatrixMap, typename GeodesicMap,
+ typename Measure >
+inline typename property_traits< GeodesicMap >::value_type all_mean_geodesics(
+ const Graph& g, DistanceMatrixMap dist, GeodesicMap geo, Measure measure)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< DistanceMatrixMap, Vertex >));
+ typedef
+ typename property_traits< DistanceMatrixMap >::value_type DistanceMap;
+ BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >));
+ typedef typename Measure::result_type Result;
+ BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< GeodesicMap, Vertex >));
+ BOOST_CONCEPT_ASSERT((NumericValueConcept< Result >));
+
+ // NOTE: We could compute the mean geodesic here by performing additional
+ // computations (i.e., adding and dividing). However, I don't really feel
+ // like fully genericizing the entire operation yet so I'm not going to.
+
+ Result inf = numeric_values< Result >::infinity();
+ Result sum = numeric_values< Result >::zero();
+ VertexIterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ {
+ DistanceMap dm = get(dist, *i);
+ Result r = mean_geodesic(g, dm, measure);
+ put(geo, *i, r);
+
+ // compute the sum along with geodesics
+ if (r == inf)
+ {
+ sum = inf;
+ }
+ else if (sum != inf)
+ {
+ sum += r;
+ }
+ }
+
+ // return the average of averages.
+ return sum / Result(num_vertices(g));
+}
+
+template < typename Graph, typename DistanceMatrixMap, typename GeodesicMap >
+inline typename property_traits< GeodesicMap >::value_type all_mean_geodesics(
+ const Graph& g, DistanceMatrixMap dist, GeodesicMap geo)
+{
+ BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< DistanceMatrixMap, Vertex >));
+ typedef
+ typename property_traits< DistanceMatrixMap >::value_type DistanceMap;
+ BOOST_CONCEPT_ASSERT((WritablePropertyMapConcept< GeodesicMap, Vertex >));
+ typedef typename property_traits< GeodesicMap >::value_type Result;
+
+ return all_mean_geodesics(
+ g, dist, geo, measure_mean_geodesic< Result >(g, DistanceMap()));
+}
+
+template < typename Graph, typename GeodesicMap, typename Measure >
+inline typename Measure::result_type small_world_distance(
+ const Graph& g, GeodesicMap geo, Measure measure)
+{
+ BOOST_CONCEPT_ASSERT((DistanceMeasureConcept< Measure, Graph >));
+ typedef typename Measure::result_type Result;
+
+ Result sum
+ = detail::combine_distances(g, geo, std::plus< Result >(), Result(0));
+ return measure(sum, g);
+}
+
+template < typename Graph, typename GeodesicMap >
+inline typename property_traits< GeodesicMap >::value_type small_world_distance(
+ const Graph& g, GeodesicMap geo)
+{
+ return small_world_distance(g, geo, measure_graph_mean_geodesic(g, geo));
+}
+
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/graph_archetypes.hpp b/contrib/restricted/boost/graph/include/boost/graph/graph_archetypes.hpp
new file mode 100644
index 0000000000..428c3c5afd
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/graph_archetypes.hpp
@@ -0,0 +1,326 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_ARCHETYPES_HPP
+#define BOOST_GRAPH_ARCHETYPES_HPP
+
+#include <boost/property_map/property_map.hpp>
+#include <boost/concept_archetype.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+
+namespace boost
+{ // should use a different namespace for this
+
+namespace detail
+{
+ struct null_graph_archetype : public null_archetype<>
+ {
+ struct traversal_category
+ {
+ };
+ };
+}
+
+//===========================================================================
+template < typename Vertex, typename Directed, typename ParallelCategory,
+ typename Base = detail::null_graph_archetype >
+struct incidence_graph_archetype : public Base
+{
+ typedef typename Base::traversal_category base_trav_cat;
+ struct traversal_category : public incidence_graph_tag, public base_trav_cat
+ {
+ };
+#if 0
+ typedef immutable_graph_tag mutability_category;
+#endif
+ typedef Vertex vertex_descriptor;
+ typedef unsigned int degree_size_type;
+ typedef unsigned int vertices_size_type;
+ typedef unsigned int edges_size_type;
+ struct edge_descriptor
+ {
+ edge_descriptor() {}
+ edge_descriptor(const detail::dummy_constructor&) {}
+ bool operator==(const edge_descriptor&) const { return false; }
+ bool operator!=(const edge_descriptor&) const { return false; }
+ };
+ typedef input_iterator_archetype< edge_descriptor > out_edge_iterator;
+
+ typedef Directed directed_category;
+ typedef ParallelCategory edge_parallel_category;
+
+ typedef void adjacency_iterator;
+ typedef void in_edge_iterator;
+ typedef void vertex_iterator;
+ typedef void edge_iterator;
+
+ static vertex_descriptor null_vertex() { return vertex_descriptor(); }
+};
+template < typename V, typename D, typename P, typename B >
+V source(
+ const typename incidence_graph_archetype< V, D, P, B >::edge_descriptor&,
+ const incidence_graph_archetype< V, D, P, B >&)
+{
+ return V(static_object< detail::dummy_constructor >::get());
+}
+template < typename V, typename D, typename P, typename B >
+V target(
+ const typename incidence_graph_archetype< V, D, P, B >::edge_descriptor&,
+ const incidence_graph_archetype< V, D, P, B >&)
+{
+ return V(static_object< detail::dummy_constructor >::get());
+}
+
+template < typename V, typename D, typename P, typename B >
+std::pair< typename incidence_graph_archetype< V, D, P, B >::out_edge_iterator,
+ typename incidence_graph_archetype< V, D, P, B >::out_edge_iterator >
+out_edges(const V&, const incidence_graph_archetype< V, D, P, B >&)
+{
+ typedef typename incidence_graph_archetype< V, D, P, B >::out_edge_iterator
+ Iter;
+ return std::make_pair(Iter(), Iter());
+}
+
+template < typename V, typename D, typename P, typename B >
+typename incidence_graph_archetype< V, D, P, B >::degree_size_type out_degree(
+ const V&, const incidence_graph_archetype< V, D, P, B >&)
+{
+ return 0;
+}
+
+//===========================================================================
+template < typename Vertex, typename Directed, typename ParallelCategory,
+ typename Base = detail::null_graph_archetype >
+struct adjacency_graph_archetype : public Base
+{
+ typedef typename Base::traversal_category base_trav_cat;
+ struct traversal_category : public adjacency_graph_tag, public base_trav_cat
+ {
+ };
+ typedef Vertex vertex_descriptor;
+ typedef unsigned int degree_size_type;
+ typedef unsigned int vertices_size_type;
+ typedef unsigned int edges_size_type;
+ typedef void edge_descriptor;
+ typedef input_iterator_archetype< Vertex > adjacency_iterator;
+
+ typedef Directed directed_category;
+ typedef ParallelCategory edge_parallel_category;
+
+ typedef void in_edge_iterator;
+ typedef void out_edge_iterator;
+ typedef void vertex_iterator;
+ typedef void edge_iterator;
+
+ static vertex_descriptor null_vertex() { return vertex_descriptor(); }
+};
+
+template < typename V, typename D, typename P, typename B >
+std::pair< typename adjacency_graph_archetype< V, D, P, B >::adjacency_iterator,
+ typename adjacency_graph_archetype< V, D, P, B >::adjacency_iterator >
+adjacent_vertices(const V&, const adjacency_graph_archetype< V, D, P, B >&)
+{
+ typedef typename adjacency_graph_archetype< V, D, P, B >::adjacency_iterator
+ Iter;
+ return std::make_pair(Iter(), Iter());
+}
+
+template < typename V, typename D, typename P, typename B >
+typename adjacency_graph_archetype< V, D, P, B >::degree_size_type out_degree(
+ const V&, const adjacency_graph_archetype< V, D, P, B >&)
+{
+ return 0;
+}
+
+//===========================================================================
+template < typename Vertex, typename Directed, typename ParallelCategory,
+ typename Base = detail::null_graph_archetype >
+struct vertex_list_graph_archetype : public Base
+{
+ typedef incidence_graph_archetype< Vertex, Directed, ParallelCategory >
+ Incidence;
+ typedef adjacency_graph_archetype< Vertex, Directed, ParallelCategory >
+ Adjacency;
+
+ typedef typename Base::traversal_category base_trav_cat;
+ struct traversal_category : public vertex_list_graph_tag,
+ public base_trav_cat
+ {
+ };
+#if 0
+ typedef immutable_graph_tag mutability_category;
+#endif
+ typedef Vertex vertex_descriptor;
+ typedef unsigned int degree_size_type;
+ typedef typename Incidence::edge_descriptor edge_descriptor;
+ typedef typename Incidence::out_edge_iterator out_edge_iterator;
+ typedef typename Adjacency::adjacency_iterator adjacency_iterator;
+
+ typedef input_iterator_archetype< Vertex > vertex_iterator;
+ typedef unsigned int vertices_size_type;
+ typedef unsigned int edges_size_type;
+
+ typedef Directed directed_category;
+ typedef ParallelCategory edge_parallel_category;
+
+ typedef void in_edge_iterator;
+ typedef void edge_iterator;
+
+ static vertex_descriptor null_vertex() { return vertex_descriptor(); }
+};
+
+template < typename V, typename D, typename P, typename B >
+std::pair< typename vertex_list_graph_archetype< V, D, P, B >::vertex_iterator,
+ typename vertex_list_graph_archetype< V, D, P, B >::vertex_iterator >
+vertices(const vertex_list_graph_archetype< V, D, P, B >&)
+{
+ typedef typename vertex_list_graph_archetype< V, D, P, B >::vertex_iterator
+ Iter;
+ return std::make_pair(Iter(), Iter());
+}
+
+template < typename V, typename D, typename P, typename B >
+typename vertex_list_graph_archetype< V, D, P, B >::vertices_size_type
+num_vertices(const vertex_list_graph_archetype< V, D, P, B >&)
+{
+ return 0;
+}
+
+// ambiguously inherited from incidence graph and adjacency graph
+template < typename V, typename D, typename P, typename B >
+typename vertex_list_graph_archetype< V, D, P, B >::degree_size_type out_degree(
+ const V&, const vertex_list_graph_archetype< V, D, P, B >&)
+{
+ return 0;
+}
+
+//===========================================================================
+
+struct property_graph_archetype_tag
+{
+};
+
+template < typename GraphArchetype, typename Property, typename ValueArch >
+struct property_graph_archetype : public GraphArchetype
+{
+ typedef property_graph_archetype_tag graph_tag;
+ typedef ValueArch vertex_property_type;
+ typedef ValueArch edge_property_type;
+};
+
+struct choose_edge_property_map_archetype
+{
+ template < typename Graph, typename Property, typename Tag > struct bind_
+ {
+ typedef mutable_lvalue_property_map_archetype<
+ typename Graph::edge_descriptor, Property >
+ type;
+ typedef lvalue_property_map_archetype< typename Graph::edge_descriptor,
+ Property >
+ const_type;
+ };
+};
+template <> struct edge_property_selector< property_graph_archetype_tag >
+{
+ typedef choose_edge_property_map_archetype type;
+};
+
+struct choose_vertex_property_map_archetype
+{
+ template < typename Graph, typename Property, typename Tag > struct bind_
+ {
+ typedef mutable_lvalue_property_map_archetype<
+ typename Graph::vertex_descriptor, Property >
+ type;
+ typedef lvalue_property_map_archetype<
+ typename Graph::vertex_descriptor, Property >
+ const_type;
+ };
+};
+
+template <> struct vertex_property_selector< property_graph_archetype_tag >
+{
+ typedef choose_vertex_property_map_archetype type;
+};
+
+template < typename G, typename P, typename V >
+typename property_map< property_graph_archetype< G, P, V >, P >::type get(
+ P, property_graph_archetype< G, P, V >&)
+{
+ typename property_map< property_graph_archetype< G, P, V >, P >::type pmap;
+ return pmap;
+}
+
+template < typename G, typename P, typename V >
+typename property_map< property_graph_archetype< G, P, V >, P >::const_type get(
+ P, const property_graph_archetype< G, P, V >&)
+{
+ typename property_map< property_graph_archetype< G, P, V >, P >::const_type
+ pmap;
+ return pmap;
+}
+
+template < typename G, typename P, typename K, typename V >
+typename property_traits< typename property_map<
+ property_graph_archetype< G, P, V >, P >::const_type >::value_type
+get(P p, const property_graph_archetype< G, P, V >& g, K k)
+{
+ return get(get(p, g), k);
+}
+
+template < typename G, typename P, typename V, typename Key >
+void put(
+ P p, property_graph_archetype< G, P, V >& g, const Key& key, const V& value)
+{
+ typedef typename boost::property_map< property_graph_archetype< G, P, V >,
+ P >::type Map;
+ Map pmap = get(p, g);
+ put(pmap, key, value);
+}
+
+struct color_value_archetype
+{
+ color_value_archetype() {}
+ color_value_archetype(detail::dummy_constructor) {}
+ bool operator==(const color_value_archetype&) const { return true; }
+ bool operator!=(const color_value_archetype&) const { return true; }
+};
+template <> struct color_traits< color_value_archetype >
+{
+ static color_value_archetype white()
+ {
+ return color_value_archetype(
+ static_object< detail::dummy_constructor >::get());
+ }
+ static color_value_archetype gray()
+ {
+ return color_value_archetype(
+ static_object< detail::dummy_constructor >::get());
+ }
+ static color_value_archetype black()
+ {
+ return color_value_archetype(
+ static_object< detail::dummy_constructor >::get());
+ }
+};
+
+template < typename T > class buffer_archetype
+{
+public:
+ void push(const T&) {}
+ void pop() {}
+ T& top() { return static_object< T >::get(); }
+ const T& top() const { return static_object< T >::get(); }
+ bool empty() const { return true; }
+};
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_ARCHETYPES_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/graph_as_tree.hpp b/contrib/restricted/boost/graph/include/boost/graph/graph_as_tree.hpp
new file mode 100644
index 0000000000..ce6057c981
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/graph_as_tree.hpp
@@ -0,0 +1,156 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_GRAPH_AS_TREE_HPP
+#define BOOST_GRAPH_GRAPH_AS_TREE_HPP
+
+#include <vector>
+#include <boost/config.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/tree_traits.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/visitors.hpp>
+
+namespace boost
+{
+
+template < class Graph, class Node, class ChIt, class Derived >
+class graph_as_tree_base
+{
+ typedef Derived Tree;
+
+public:
+ typedef Node node_descriptor;
+ typedef ChIt children_iterator;
+
+ graph_as_tree_base(Graph& g, Node root) : _g(g), _root(root) {}
+
+ friend Node root(const Tree& t) { return t._root; }
+
+ template < class N >
+ friend std::pair< ChIt, ChIt > children(N n, const Tree& t)
+ {
+ return adjacent_vertices(n, t._g);
+ }
+
+ template < class N > friend Node parent(N n, const Tree& t)
+ {
+ return boost::get(t.parent_pa(), n);
+ }
+
+ Graph& _g;
+ Node _root;
+};
+
+struct graph_as_tree_tag
+{
+};
+
+template < class Graph, class ParentMap,
+ class Node = typename graph_traits< Graph >::vertex_descriptor,
+ class ChIt = typename graph_traits< Graph >::adjacency_iterator >
+class graph_as_tree : public graph_as_tree_base< Graph, Node, ChIt,
+ graph_as_tree< Graph, ParentMap, Node, ChIt > >
+{
+ typedef graph_as_tree self;
+ typedef graph_as_tree_base< Graph, Node, ChIt, self > super;
+
+public:
+ graph_as_tree(Graph& g, Node root) : super(g, root) {}
+
+ graph_as_tree(Graph& g, Node root, ParentMap p) : super(g, root), _p(p)
+ {
+ breadth_first_search(g, root,
+ visitor(make_bfs_visitor(
+ record_predecessors(p, boost::on_tree_edge()))));
+ }
+ ParentMap parent_pa() const { return _p; }
+ typedef graph_as_tree_tag graph_tag; // for property_map
+protected:
+ ParentMap _p;
+};
+
+namespace detail
+{
+
+ struct graph_as_tree_vertex_property_selector
+ {
+ template < typename GraphAsTree, typename Property, typename Tag >
+ struct bind_
+ {
+ typedef typename GraphAsTree::base_type Graph;
+ typedef property_map< Graph, Tag > PMap;
+ typedef typename PMap::type type;
+ typedef typename PMap::const_type const_type;
+ };
+ };
+
+ struct graph_as_tree_edge_property_selector
+ {
+ template < typename GraphAsTree, typename Property, typename Tag >
+ struct bind_
+ {
+ typedef typename GraphAsTree::base_type Graph;
+ typedef property_map< Graph, Tag > PMap;
+ typedef typename PMap::type type;
+ typedef typename PMap::const_type const_type;
+ };
+ };
+
+} // namespace detail
+
+template <> struct vertex_property_selector< graph_as_tree_tag >
+{
+ typedef detail::graph_as_tree_vertex_property_selector type;
+};
+
+template <> struct edge_property_selector< graph_as_tree_tag >
+{
+ typedef detail::graph_as_tree_edge_property_selector type;
+};
+
+template < typename Graph, typename P, typename N, typename C,
+ typename Property >
+typename property_map< Graph, Property >::type get(
+ Property p, graph_as_tree< Graph, P, N, C >& g)
+{
+ return get(p, g._g);
+}
+
+template < typename Graph, typename P, typename N, typename C,
+ typename Property >
+typename property_map< Graph, Property >::const_type get(
+ Property p, const graph_as_tree< Graph, P, N, C >& g)
+{
+ const Graph& gref = g._g; // in case GRef is non-const
+ return get(p, gref);
+}
+
+template < typename Graph, typename P, typename N, typename C,
+ typename Property, typename Key >
+typename property_traits<
+ typename property_map< Graph, Property >::const_type >::value_type
+get(Property p, const graph_as_tree< Graph, P, N, C >& g, const Key& k)
+{
+ return get(p, g._g, k);
+}
+
+template < typename Graph, typename P, typename N, typename C,
+ typename Property, typename Key, typename Value >
+void put(Property p, const graph_as_tree< Graph, P, N, C >& g, const Key& k,
+ const Value& val)
+{
+ put(p, g._g, k, val);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_GRAPH_AS_TREE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/graph_stats.hpp b/contrib/restricted/boost/graph/include/boost/graph/graph_stats.hpp
new file mode 100644
index 0000000000..aff1f3550c
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/graph_stats.hpp
@@ -0,0 +1,148 @@
+// Copyright 2005 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Alex Breuer
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_GRAPH_STATS_HPP
+#define BOOST_GRAPH_GRAPH_STATS_HPP
+
+#include <map>
+#include <list>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+namespace graph
+{
+
+ template < typename Graph > struct sort_edge_by_origin
+ {
+ public:
+ typedef typename graph_traits< Graph >::edge_descriptor edge_type;
+
+ explicit sort_edge_by_origin(Graph& g) : g(g) {}
+
+ inline bool operator()(edge_type a, edge_type b)
+ {
+ return source(a, g) == source(b, g) ? target(a, g) < target(b, g)
+ : source(a, g) < source(b, g);
+ }
+
+ private:
+ Graph& g;
+ };
+
+ template < typename Graph > struct equal_edge
+ {
+ public:
+ typedef typename graph_traits< Graph >::edge_descriptor edge_type;
+
+ explicit equal_edge(Graph& g) : g(g) {}
+
+ inline bool operator()(edge_type a, edge_type b)
+ {
+ return source(a, g) == source(b, g) && target(a, g) == target(b, g);
+ }
+
+ private:
+ Graph& g;
+ };
+
+ template < typename Graph > unsigned long num_dup_edges(Graph& g)
+ {
+ typedef typename graph_traits< Graph >::edge_iterator e_iterator_type;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_type;
+
+ std::list< edge_type > all_edges;
+
+ BGL_FORALL_EDGES_T(e, g, Graph) { all_edges.push_back(e); }
+
+ sort_edge_by_origin< Graph > cmp1(g);
+ all_edges.sort(cmp1);
+ equal_edge< Graph > cmp2(g);
+ all_edges.unique(cmp2);
+
+ return num_edges(g) - all_edges.size();
+ }
+
+ template < typename Graph >
+ std::map< unsigned long, unsigned long > dup_edge_dist(Graph& g)
+ {
+ std::map< unsigned long, unsigned long > dist;
+ typedef
+ typename graph_traits< Graph >::adjacency_iterator a_iterator_type;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_type;
+
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ std::list< vertex_type > front_neighbors;
+ a_iterator_type a_iter, a_end;
+ for (boost::tie(a_iter, a_end) = adjacent_vertices(v, g);
+ a_iter != a_end; ++a_iter)
+ {
+ front_neighbors.push_back(*a_iter);
+ }
+
+ front_neighbors.sort();
+ front_neighbors.unique();
+ dist[out_degree(v, g) - front_neighbors.size()] += 1;
+ }
+ return dist;
+ }
+
+ template < typename Graph >
+ std::map< unsigned long, unsigned long > degree_dist(Graph& g)
+ {
+ std::map< unsigned long, unsigned long > dist;
+ typedef
+ typename graph_traits< Graph >::adjacency_iterator a_iterator_type;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_type;
+
+ BGL_FORALL_VERTICES_T(v, g, Graph) { dist[out_degree(v, g)] += 1; }
+
+ return dist;
+ }
+
+ template < typename Graph >
+ std::map< unsigned long, double > weight_degree_dist(Graph& g)
+ {
+ std::map< unsigned long, double > dist, n;
+ typedef
+ typename graph_traits< Graph >::adjacency_iterator a_iterator_type;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_type;
+ typedef typename property_map< Graph, edge_weight_t >::const_type
+ edge_map_type;
+ typedef typename property_traits< edge_map_type >::value_type
+ edge_weight_type;
+
+ typename property_map< Graph, edge_weight_t >::type em
+ = get(edge_weight, g);
+
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ edge_weight_type tmp = 0;
+ BGL_FORALL_OUTEDGES_T(v, e, g, Graph) { tmp += em[e]; }
+ n[out_degree(v, g)] += 1.;
+ dist[out_degree(v, g)] += tmp;
+ }
+
+ for (std::map< unsigned long, double >::iterator iter = dist.begin();
+ iter != dist.end(); ++iter)
+ {
+ BOOST_ASSERT(n[iter->first] != 0);
+ dist[iter->first] /= n[iter->first];
+ }
+
+ return dist;
+ }
+
+}
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/graph_utility.hpp b/contrib/restricted/boost/graph/include/boost/graph/graph_utility.hpp
new file mode 100644
index 0000000000..4e5ef141ac
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/graph_utility.hpp
@@ -0,0 +1,488 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_UTILITY_HPP
+#define BOOST_GRAPH_UTILITY_HPP
+
+#include <stdlib.h>
+#include <iostream>
+#include <algorithm>
+#include <assert.h>
+#include <boost/config.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/container_traits.hpp>
+#include <boost/graph/depth_first_search.hpp>
+// iota moved to detail/algorithm.hpp
+#include <boost/detail/algorithm.hpp>
+
+namespace boost
+{
+
+// Provide an undirected graph interface alternative to the
+// the source() and target() edge functions.
+template < class UndirectedGraph >
+inline std::pair< typename graph_traits< UndirectedGraph >::vertex_descriptor,
+ typename graph_traits< UndirectedGraph >::vertex_descriptor >
+incident(typename graph_traits< UndirectedGraph >::edge_descriptor e,
+ UndirectedGraph& g)
+{
+ return std::make_pair(source(e, g), target(e, g));
+}
+
+// Provide an undirected graph interface alternative
+// to the out_edges() function.
+template < class Graph >
+inline std::pair< typename graph_traits< Graph >::out_edge_iterator,
+ typename graph_traits< Graph >::out_edge_iterator >
+incident_edges(typename graph_traits< Graph >::vertex_descriptor u, Graph& g)
+{
+ return out_edges(u, g);
+}
+
+template < class Graph >
+inline typename graph_traits< Graph >::vertex_descriptor opposite(
+ typename graph_traits< Graph >::edge_descriptor e,
+ typename graph_traits< Graph >::vertex_descriptor v, const Graph& g)
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+ if (v == source(e, g))
+ return target(e, g);
+ else if (v == target(e, g))
+ return source(e, g);
+ else
+ return vertex_descriptor();
+}
+
+//===========================================================================
+// Some handy predicates
+
+template < typename Vertex, typename Graph > struct incident_from_predicate
+{
+ incident_from_predicate(Vertex u, const Graph& g) : m_u(u), m_g(g) {}
+ template < class Edge > bool operator()(const Edge& e) const
+ {
+ return source(e, m_g) == m_u;
+ }
+ Vertex m_u;
+ const Graph& m_g;
+};
+template < typename Vertex, typename Graph >
+inline incident_from_predicate< Vertex, Graph > incident_from(
+ Vertex u, const Graph& g)
+{
+ return incident_from_predicate< Vertex, Graph >(u, g);
+}
+
+template < typename Vertex, typename Graph > struct incident_to_predicate
+{
+ incident_to_predicate(Vertex u, const Graph& g) : m_u(u), m_g(g) {}
+ template < class Edge > bool operator()(const Edge& e) const
+ {
+ return target(e, m_g) == m_u;
+ }
+ Vertex m_u;
+ const Graph& m_g;
+};
+template < typename Vertex, typename Graph >
+inline incident_to_predicate< Vertex, Graph > incident_to(
+ Vertex u, const Graph& g)
+{
+ return incident_to_predicate< Vertex, Graph >(u, g);
+}
+
+template < typename Vertex, typename Graph > struct incident_on_predicate
+{
+ incident_on_predicate(Vertex u, const Graph& g) : m_u(u), m_g(g) {}
+ template < class Edge > bool operator()(const Edge& e) const
+ {
+ return source(e, m_g) == m_u || target(e, m_g) == m_u;
+ }
+ Vertex m_u;
+ const Graph& m_g;
+};
+template < typename Vertex, typename Graph >
+inline incident_on_predicate< Vertex, Graph > incident_on(
+ Vertex u, const Graph& g)
+{
+ return incident_on_predicate< Vertex, Graph >(u, g);
+}
+
+template < typename Vertex, typename Graph > struct connects_predicate
+{
+ connects_predicate(Vertex u, Vertex v, const Graph& g)
+ : m_u(u), m_v(v), m_g(g)
+ {
+ }
+ template < class Edge > bool operator()(const Edge& e) const
+ {
+ if (is_directed(m_g))
+ return source(e, m_g) == m_u && target(e, m_g) == m_v;
+ else
+ return (source(e, m_g) == m_u && target(e, m_g) == m_v)
+ || (source(e, m_g) == m_v && target(e, m_g) == m_u);
+ }
+ Vertex m_u, m_v;
+ const Graph& m_g;
+};
+template < typename Vertex, typename Graph >
+inline connects_predicate< Vertex, Graph > connects(
+ Vertex u, Vertex v, const Graph& g)
+{
+ return connects_predicate< Vertex, Graph >(u, v, g);
+}
+
+// Need to convert all of these printing functions to take an ostream object
+// -JGS
+
+template < class IncidenceGraph, class Name >
+void print_in_edges(
+ const IncidenceGraph& G, Name name, std::ostream& os = std::cout)
+{
+ typename graph_traits< IncidenceGraph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
+ {
+ os << get(name, *ui) << " <-- ";
+ typename graph_traits< IncidenceGraph >::in_edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = in_edges(*ui, G); ei != ei_end; ++ei)
+ os << get(name, source(*ei, G)) << " ";
+ os << '\n';
+ }
+}
+
+template < class IncidenceGraph, class Name >
+void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag,
+ std::ostream& os = std::cout)
+{
+ typename graph_traits< IncidenceGraph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
+ {
+ os << get(name, *ui) << " --> ";
+ typename graph_traits< IncidenceGraph >::out_edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = out_edges(*ui, G); ei != ei_end; ++ei)
+ os << get(name, target(*ei, G)) << " ";
+ os << '\n';
+ }
+}
+template < class IncidenceGraph, class Name >
+void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag,
+ std::ostream& os = std::cout)
+{
+ typename graph_traits< IncidenceGraph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
+ {
+ os << get(name, *ui) << " <--> ";
+ typename graph_traits< IncidenceGraph >::out_edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = out_edges(*ui, G); ei != ei_end; ++ei)
+ os << get(name, target(*ei, G)) << " ";
+ os << '\n';
+ }
+}
+template < class IncidenceGraph, class Name >
+void print_graph(
+ const IncidenceGraph& G, Name name, std::ostream& os = std::cout)
+{
+ typedef typename graph_traits< IncidenceGraph >::directed_category Cat;
+ print_graph_dispatch(G, name, Cat(), os);
+}
+template < class IncidenceGraph >
+void print_graph(const IncidenceGraph& G, std::ostream& os = std::cout)
+{
+ print_graph(G, get(vertex_index, G), os);
+}
+
+template < class EdgeListGraph, class Name >
+void print_edges(
+ const EdgeListGraph& G, Name name, std::ostream& os = std::cout)
+{
+ typename graph_traits< EdgeListGraph >::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
+ os << "(" << get(name, source(*ei, G)) << ","
+ << get(name, target(*ei, G)) << ") ";
+ os << '\n';
+}
+
+template < class EdgeListGraph, class VertexName, class EdgeName >
+void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename,
+ std::ostream& os = std::cout)
+{
+ typename graph_traits< EdgeListGraph >::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
+ os << get(ename, *ei) << "(" << get(vname, source(*ei, G)) << ","
+ << get(vname, target(*ei, G)) << ") ";
+ os << '\n';
+}
+
+template < class VertexListGraph, class Name >
+void print_vertices(
+ const VertexListGraph& G, Name name, std::ostream& os = std::cout)
+{
+ typename graph_traits< VertexListGraph >::vertex_iterator vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(G); vi != vi_end; ++vi)
+ os << get(name, *vi) << " ";
+ os << '\n';
+}
+
+template < class Graph, class Vertex >
+bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag)
+{
+ typename graph_traits< Graph >::adjacency_iterator vi, viend, adj_found;
+ boost::tie(vi, viend) = adjacent_vertices(a, g);
+ adj_found = std::find(vi, viend, b);
+ if (adj_found == viend)
+ return false;
+
+ typename graph_traits< Graph >::out_edge_iterator oi, oiend, out_found;
+ boost::tie(oi, oiend) = out_edges(a, g);
+ out_found = std::find_if(oi, oiend, incident_to(b, g));
+ if (out_found == oiend)
+ return false;
+
+ typename graph_traits< Graph >::in_edge_iterator ii, iiend, in_found;
+ boost::tie(ii, iiend) = in_edges(b, g);
+ in_found = std::find_if(ii, iiend, incident_from(a, g));
+ if (in_found == iiend)
+ return false;
+
+ return true;
+}
+template < class Graph, class Vertex >
+bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag)
+{
+ typename graph_traits< Graph >::adjacency_iterator vi, viend, found;
+ boost::tie(vi, viend) = adjacent_vertices(a, g);
+ found = std::find(vi, viend, b);
+ if (found == viend)
+ return false;
+
+ typename graph_traits< Graph >::out_edge_iterator oi, oiend, out_found;
+ boost::tie(oi, oiend) = out_edges(a, g);
+
+ out_found = std::find_if(oi, oiend, incident_to(b, g));
+ if (out_found == oiend)
+ return false;
+ return true;
+}
+template < class Graph, class Vertex >
+bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, undirected_tag)
+{
+ return is_adj_dispatch(g, a, b, directed_tag());
+}
+
+template < class Graph, class Vertex >
+bool is_adjacent(Graph& g, Vertex a, Vertex b)
+{
+ typedef typename graph_traits< Graph >::directed_category Cat;
+ return is_adj_dispatch(g, a, b, Cat());
+}
+
+template < class Graph, class Edge > bool in_edge_set(Graph& g, Edge e)
+{
+ typename Graph::edge_iterator ei, ei_end, found;
+ boost::tie(ei, ei_end) = edges(g);
+ found = std::find(ei, ei_end, e);
+ return found != ei_end;
+}
+
+template < class Graph, class Vertex > bool in_vertex_set(Graph& g, Vertex v)
+{
+ typename Graph::vertex_iterator vi, vi_end, found;
+ boost::tie(vi, vi_end) = vertices(g);
+ found = std::find(vi, vi_end, v);
+ return found != vi_end;
+}
+
+template < class Graph, class Vertex >
+bool in_edge_set(Graph& g, Vertex u, Vertex v)
+{
+ typename Graph::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ if (source(*ei, g) == u && target(*ei, g) == v)
+ return true;
+ return false;
+}
+
+// is x a descendant of y?
+template < typename ParentMap >
+inline bool is_descendant(typename property_traits< ParentMap >::value_type x,
+ typename property_traits< ParentMap >::value_type y, ParentMap parent)
+{
+ if (get(parent, x) == x) // x is the root of the tree
+ return false;
+ else if (get(parent, x) == y)
+ return true;
+ else
+ return is_descendant(get(parent, x), y, parent);
+}
+
+// is y reachable from x?
+template < typename IncidenceGraph, typename VertexColorMap >
+inline bool is_reachable(
+ typename graph_traits< IncidenceGraph >::vertex_descriptor x,
+ typename graph_traits< IncidenceGraph >::vertex_descriptor y,
+ const IncidenceGraph& g,
+ VertexColorMap color) // should start out white for every vertex
+{
+ typedef typename property_traits< VertexColorMap >::value_type ColorValue;
+ dfs_visitor<> vis;
+ depth_first_visit(g, x, vis, color);
+ return get(color, y) != color_traits< ColorValue >::white();
+}
+
+// Is the undirected graph connected?
+// Is the directed graph strongly connected?
+template < typename VertexListGraph, typename VertexColorMap >
+inline bool is_connected(const VertexListGraph& g, VertexColorMap color)
+{
+ typedef typename property_traits< VertexColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+ typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end, vi,
+ vi_end, ci, ci_end;
+ for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ if (*ui != *vi)
+ {
+ for (boost::tie(ci, ci_end) = vertices(g); ci != ci_end; ++ci)
+ put(color, *ci, Color::white());
+ if (!is_reachable(*ui, *vi, g, color))
+ return false;
+ }
+ return true;
+}
+
+template < typename Graph >
+bool is_self_loop(
+ typename graph_traits< Graph >::edge_descriptor e, const Graph& g)
+{
+ return source(e, g) == target(e, g);
+}
+
+template < class T1, class T2 >
+std::pair< T1, T2 > make_list(const T1& t1, const T2& t2)
+{
+ return std::make_pair(t1, t2);
+}
+
+template < class T1, class T2, class T3 >
+std::pair< T1, std::pair< T2, T3 > > make_list(
+ const T1& t1, const T2& t2, const T3& t3)
+{
+ return std::make_pair(t1, std::make_pair(t2, t3));
+}
+
+template < class T1, class T2, class T3, class T4 >
+std::pair< T1, std::pair< T2, std::pair< T3, T4 > > > make_list(
+ const T1& t1, const T2& t2, const T3& t3, const T4& t4)
+{
+ return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, t4)));
+}
+
+template < class T1, class T2, class T3, class T4, class T5 >
+std::pair< T1, std::pair< T2, std::pair< T3, std::pair< T4, T5 > > > >
+make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
+{
+ return std::make_pair(
+ t1, std::make_pair(t2, std::make_pair(t3, std::make_pair(t4, t5))));
+}
+
+namespace graph
+{
+
+ // Functor for remove_parallel_edges: edge property of the removed edge is
+ // added to the remaining
+ template < typename EdgeProperty > struct add_removed_edge_property
+ {
+ add_removed_edge_property(EdgeProperty ep) : ep(ep) {}
+
+ template < typename Edge > void operator()(Edge stay, Edge away)
+ {
+ put(ep, stay, get(ep, stay) + get(ep, away));
+ }
+ EdgeProperty ep;
+ };
+
+ // Same as above: edge property is capacity here
+ template < typename Graph >
+ struct add_removed_edge_capacity
+ : add_removed_edge_property<
+ typename property_map< Graph, edge_capacity_t >::type >
+ {
+ typedef add_removed_edge_property<
+ typename property_map< Graph, edge_capacity_t >::type >
+ base;
+ add_removed_edge_capacity(Graph& g) : base(get(edge_capacity, g)) {}
+ };
+
+ template < typename Graph > bool has_no_vertices(const Graph& g)
+ {
+ typedef typename boost::graph_traits< Graph >::vertex_iterator vi;
+ std::pair< vi, vi > p = vertices(g);
+ return (p.first == p.second);
+ }
+
+ template < typename Graph > bool has_no_edges(const Graph& g)
+ {
+ typedef typename boost::graph_traits< Graph >::edge_iterator ei;
+ std::pair< ei, ei > p = edges(g);
+ return (p.first == p.second);
+ }
+
+ template < typename Graph >
+ bool has_no_out_edges(
+ const typename boost::graph_traits< Graph >::vertex_descriptor& v,
+ const Graph& g)
+ {
+ typedef typename boost::graph_traits< Graph >::out_edge_iterator ei;
+ std::pair< ei, ei > p = out_edges(v, g);
+ return (p.first == p.second);
+ }
+
+} // namespace graph
+
+template < class PropertyIn, class PropertyOut, class Graph >
+void copy_vertex_property(PropertyIn p_in, PropertyOut p_out, Graph& g)
+{
+ BGL_FORALL_VERTICES_T(u, g, Graph)
+ put(p_out, u, get(p_in, g));
+}
+
+template < class PropertyIn, class PropertyOut, class Graph >
+void copy_edge_property(PropertyIn p_in, PropertyOut p_out, Graph& g)
+{
+ BGL_FORALL_EDGES_T(e, g, Graph)
+ put(p_out, e, get(p_in, g));
+}
+
+// Return true if property_map1 and property_map2 differ
+// for any of the vertices in graph.
+template < typename PropertyMapFirst, typename PropertyMapSecond,
+ typename Graph >
+bool are_property_maps_different(const PropertyMapFirst property_map1,
+ const PropertyMapSecond property_map2, const Graph& graph)
+{
+
+ BGL_FORALL_VERTICES_T(vertex, graph, Graph)
+ {
+ if (get(property_map1, vertex) != get(property_map2, vertex))
+ {
+
+ return (true);
+ }
+ }
+
+ return (false);
+}
+
+} /* namespace boost */
+
+#endif /* BOOST_GRAPH_UTILITY_HPP*/
diff --git a/contrib/restricted/boost/graph/include/boost/graph/grid_graph.hpp b/contrib/restricted/boost/graph/include/boost/graph/grid_graph.hpp
new file mode 100644
index 0000000000..bdcbc6f4d1
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/grid_graph.hpp
@@ -0,0 +1,1059 @@
+//=======================================================================
+// Copyright 2009 Trustees of Indiana University.
+// Authors: Michael Hansen, Andrew Lumsdaine
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_GRID_GRAPH_HPP
+#define BOOST_GRAPH_GRID_GRAPH_HPP
+
+#include <cmath>
+#include <functional>
+#include <numeric>
+
+#include <boost/array.hpp>
+#include <boost/limits.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/property_map/property_map.hpp>
+
+#define BOOST_GRID_GRAPH_TEMPLATE_PARAMS \
+ std::size_t DimensionsT, typename VertexIndexT, typename EdgeIndexT
+
+#define BOOST_GRID_GRAPH_TYPE \
+ grid_graph< DimensionsT, VertexIndexT, EdgeIndexT >
+
+#define BOOST_GRID_GRAPH_TRAITS_T typename graph_traits< BOOST_GRID_GRAPH_TYPE >
+
+namespace boost
+{
+
+// Class prototype for grid_graph
+template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS > class grid_graph;
+
+//===================
+// Index Property Map
+//===================
+
+template < typename Graph, typename Descriptor, typename Index >
+struct grid_graph_index_map
+{
+public:
+ typedef Index value_type;
+ typedef Index reference_type;
+ typedef reference_type reference;
+ typedef Descriptor key_type;
+ typedef readable_property_map_tag category;
+
+ grid_graph_index_map() {}
+
+ grid_graph_index_map(const Graph& graph) : m_graph(&graph) {}
+
+ value_type operator[](key_type key) const
+ {
+ return (m_graph->index_of(key));
+ }
+
+ friend inline Index get(
+ const grid_graph_index_map< Graph, Descriptor, Index >& index_map,
+ const typename grid_graph_index_map< Graph, Descriptor,
+ Index >::key_type& key)
+ {
+ return (index_map[key]);
+ }
+
+protected:
+ const Graph* m_graph;
+};
+
+template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS >
+struct property_map< BOOST_GRID_GRAPH_TYPE, vertex_index_t >
+{
+ typedef grid_graph_index_map< BOOST_GRID_GRAPH_TYPE,
+ BOOST_GRID_GRAPH_TRAITS_T::vertex_descriptor,
+ BOOST_GRID_GRAPH_TRAITS_T::vertices_size_type >
+ type;
+ typedef type const_type;
+};
+
+template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS >
+struct property_map< BOOST_GRID_GRAPH_TYPE, edge_index_t >
+{
+ typedef grid_graph_index_map< BOOST_GRID_GRAPH_TYPE,
+ BOOST_GRID_GRAPH_TRAITS_T::edge_descriptor,
+ BOOST_GRID_GRAPH_TRAITS_T::edges_size_type >
+ type;
+ typedef type const_type;
+};
+
+//==========================
+// Reverse Edge Property Map
+//==========================
+
+template < typename Descriptor > struct grid_graph_reverse_edge_map
+{
+public:
+ typedef Descriptor value_type;
+ typedef Descriptor reference_type;
+ typedef reference_type reference;
+ typedef Descriptor key_type;
+ typedef readable_property_map_tag category;
+
+ grid_graph_reverse_edge_map() {}
+
+ value_type operator[](const key_type& key) const
+ {
+ return (value_type(key.second, key.first));
+ }
+
+ friend inline Descriptor get(
+ const grid_graph_reverse_edge_map< Descriptor >& rev_map,
+ const typename grid_graph_reverse_edge_map< Descriptor >::key_type& key)
+ {
+ return (rev_map[key]);
+ }
+};
+
+template < BOOST_GRID_GRAPH_TEMPLATE_PARAMS >
+struct property_map< BOOST_GRID_GRAPH_TYPE, edge_reverse_t >
+{
+ typedef grid_graph_reverse_edge_map<
+ BOOST_GRID_GRAPH_TRAITS_T::edge_descriptor >
+ type;
+ typedef type const_type;
+};
+
+//=================
+// Function Objects
+//=================
+
+namespace detail
+{
+
+ // vertex_at
+ template < typename Graph > struct grid_graph_vertex_at
+ {
+
+ typedef typename graph_traits< Graph >::vertex_descriptor result_type;
+
+ grid_graph_vertex_at() : m_graph(0) {}
+
+ grid_graph_vertex_at(const Graph* graph) : m_graph(graph) {}
+
+ result_type operator()(
+ typename graph_traits< Graph >::vertices_size_type vertex_index)
+ const
+ {
+ return (vertex(vertex_index, *m_graph));
+ }
+
+ private:
+ const Graph* m_graph;
+ };
+
+ // out_edge_at
+ template < typename Graph > struct grid_graph_out_edge_at
+ {
+
+ private:
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+
+ public:
+ typedef typename graph_traits< Graph >::edge_descriptor result_type;
+
+ grid_graph_out_edge_at() : m_vertex(), m_graph(0) {}
+
+ grid_graph_out_edge_at(
+ vertex_descriptor source_vertex, const Graph* graph)
+ : m_vertex(source_vertex), m_graph(graph)
+ {
+ }
+
+ result_type operator()(
+ typename graph_traits< Graph >::degree_size_type out_edge_index)
+ const
+ {
+ return (out_edge_at(m_vertex, out_edge_index, *m_graph));
+ }
+
+ private:
+ vertex_descriptor m_vertex;
+ const Graph* m_graph;
+ };
+
+ // in_edge_at
+ template < typename Graph > struct grid_graph_in_edge_at
+ {
+
+ private:
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+
+ public:
+ typedef typename graph_traits< Graph >::edge_descriptor result_type;
+
+ grid_graph_in_edge_at() : m_vertex(), m_graph(0) {}
+
+ grid_graph_in_edge_at(
+ vertex_descriptor target_vertex, const Graph* graph)
+ : m_vertex(target_vertex), m_graph(graph)
+ {
+ }
+
+ result_type operator()(
+ typename graph_traits< Graph >::degree_size_type in_edge_index)
+ const
+ {
+ return (in_edge_at(m_vertex, in_edge_index, *m_graph));
+ }
+
+ private:
+ vertex_descriptor m_vertex;
+ const Graph* m_graph;
+ };
+
+ // edge_at
+ template < typename Graph > struct grid_graph_edge_at
+ {
+
+ typedef typename graph_traits< Graph >::edge_descriptor result_type;
+
+ grid_graph_edge_at() : m_graph(0) {}
+
+ grid_graph_edge_at(const Graph* graph) : m_graph(graph) {}
+
+ result_type operator()(
+ typename graph_traits< Graph >::edges_size_type edge_index) const
+ {
+ return (edge_at(edge_index, *m_graph));
+ }
+
+ private:
+ const Graph* m_graph;
+ };
+
+ // adjacent_vertex_at
+ template < typename Graph > struct grid_graph_adjacent_vertex_at
+ {
+
+ public:
+ typedef typename graph_traits< Graph >::vertex_descriptor result_type;
+
+ grid_graph_adjacent_vertex_at(
+ result_type source_vertex, const Graph* graph)
+ : m_vertex(source_vertex), m_graph(graph)
+ {
+ }
+
+ result_type operator()(
+ typename graph_traits< Graph >::degree_size_type adjacent_index)
+ const
+ {
+ return (target(
+ out_edge_at(m_vertex, adjacent_index, *m_graph), *m_graph));
+ }
+
+ private:
+ result_type m_vertex;
+ const Graph* m_graph;
+ };
+
+} // namespace detail
+
+//===========
+// Grid Graph
+//===========
+
+template < std::size_t Dimensions, typename VertexIndex = std::size_t,
+ typename EdgeIndex = VertexIndex >
+class grid_graph
+{
+
+private:
+ typedef boost::array< bool, Dimensions > WrapDimensionArray;
+ grid_graph() {};
+
+public:
+ typedef grid_graph< Dimensions, VertexIndex, EdgeIndex > type;
+
+ // sizes
+ typedef VertexIndex vertices_size_type;
+ typedef EdgeIndex edges_size_type;
+ typedef EdgeIndex degree_size_type;
+
+ // descriptors
+ typedef boost::array< VertexIndex, Dimensions > vertex_descriptor;
+ typedef std::pair< vertex_descriptor, vertex_descriptor > edge_descriptor;
+
+ // vertex_iterator
+ typedef counting_iterator< vertices_size_type > vertex_index_iterator;
+ typedef detail::grid_graph_vertex_at< type > vertex_function;
+ typedef transform_iterator< vertex_function, vertex_index_iterator >
+ vertex_iterator;
+
+ // edge_iterator
+ typedef counting_iterator< edges_size_type > edge_index_iterator;
+ typedef detail::grid_graph_edge_at< type > edge_function;
+ typedef transform_iterator< edge_function, edge_index_iterator >
+ edge_iterator;
+
+ // out_edge_iterator
+ typedef counting_iterator< degree_size_type > degree_iterator;
+ typedef detail::grid_graph_out_edge_at< type > out_edge_function;
+ typedef transform_iterator< out_edge_function, degree_iterator >
+ out_edge_iterator;
+
+ // in_edge_iterator
+ typedef detail::grid_graph_in_edge_at< type > in_edge_function;
+ typedef transform_iterator< in_edge_function, degree_iterator >
+ in_edge_iterator;
+
+ // adjacency_iterator
+ typedef detail::grid_graph_adjacent_vertex_at< type >
+ adjacent_vertex_function;
+ typedef transform_iterator< adjacent_vertex_function, degree_iterator >
+ adjacency_iterator;
+
+ // categories
+ typedef directed_tag directed_category;
+ typedef disallow_parallel_edge_tag edge_parallel_category;
+ struct traversal_category : virtual public incidence_graph_tag,
+ virtual public adjacency_graph_tag,
+ virtual public vertex_list_graph_tag,
+ virtual public edge_list_graph_tag,
+ virtual public bidirectional_graph_tag,
+ virtual public adjacency_matrix_tag
+ {
+ };
+
+ static inline vertex_descriptor null_vertex()
+ {
+ vertex_descriptor maxed_out_vertex;
+ std::fill(maxed_out_vertex.begin(), maxed_out_vertex.end(),
+ (std::numeric_limits< vertices_size_type >::max)());
+
+ return (maxed_out_vertex);
+ }
+
+ // Constructor that defaults to no wrapping for all dimensions.
+ grid_graph(vertex_descriptor dimension_lengths)
+ : m_dimension_lengths(dimension_lengths)
+ {
+
+ std::fill(m_wrap_dimension.begin(), m_wrap_dimension.end(), false);
+
+ precalculate();
+ }
+
+ // Constructor that allows for wrapping to be specified for all
+ // dimensions at once.
+ grid_graph(vertex_descriptor dimension_lengths, bool wrap_all_dimensions)
+ : m_dimension_lengths(dimension_lengths)
+ {
+
+ std::fill(m_wrap_dimension.begin(), m_wrap_dimension.end(),
+ wrap_all_dimensions);
+
+ precalculate();
+ }
+
+ // Constructor that allows for individual dimension wrapping to be
+ // specified.
+ grid_graph(
+ vertex_descriptor dimension_lengths, WrapDimensionArray wrap_dimension)
+ : m_dimension_lengths(dimension_lengths), m_wrap_dimension(wrap_dimension)
+ {
+
+ precalculate();
+ }
+
+ // Returns the number of dimensions in the graph
+ inline std::size_t dimensions() const { return (Dimensions); }
+
+ // Returns the length of dimension [dimension_index]
+ inline vertices_size_type length(std::size_t dimension) const
+ {
+ return (m_dimension_lengths[dimension]);
+ }
+
+ // Returns a value indicating if dimension [dimension_index] wraps
+ inline bool wrapped(std::size_t dimension) const
+ {
+ return (m_wrap_dimension[dimension]);
+ }
+
+ // Gets the vertex that is [distance] units ahead of [vertex] in
+ // dimension [dimension_index].
+ vertex_descriptor next(vertex_descriptor vertex,
+ std::size_t dimension_index, vertices_size_type distance = 1) const
+ {
+
+ vertices_size_type new_position = vertex[dimension_index] + distance;
+
+ if (wrapped(dimension_index))
+ {
+ new_position %= length(dimension_index);
+ }
+ else
+ {
+ // Stop at the end of this dimension if necessary.
+ new_position = (std::min)(
+ new_position, vertices_size_type(length(dimension_index) - 1));
+ }
+
+ vertex[dimension_index] = new_position;
+
+ return (vertex);
+ }
+
+ // Gets the vertex that is [distance] units behind [vertex] in
+ // dimension [dimension_index].
+ vertex_descriptor previous(vertex_descriptor vertex,
+ std::size_t dimension_index, vertices_size_type distance = 1) const
+ {
+
+ // We're assuming that vertices_size_type is unsigned, so we
+ // need to be careful about the math.
+ vertex[dimension_index] = (distance > vertex[dimension_index])
+ ? (wrapped(dimension_index) ? (length(dimension_index)
+ - (distance % length(dimension_index)))
+ : 0)
+ : vertex[dimension_index] - distance;
+
+ return (vertex);
+ }
+
+protected:
+ // Returns the number of vertices in the graph
+ inline vertices_size_type num_vertices() const { return (m_num_vertices); }
+
+ // Returns the number of edges in the graph
+ inline edges_size_type num_edges() const { return (m_num_edges); }
+
+ // Returns the number of edges in dimension [dimension_index]
+ inline edges_size_type num_edges(std::size_t dimension_index) const
+ {
+ return (m_edge_count[dimension_index]);
+ }
+
+ // Returns the index of [vertex] (See also vertex_at)
+ vertices_size_type index_of(vertex_descriptor vertex) const
+ {
+
+ vertices_size_type vertex_index = 0;
+ vertices_size_type index_multiplier = 1;
+
+ for (std::size_t dimension_index = 0; dimension_index < Dimensions;
+ ++dimension_index)
+ {
+
+ vertex_index += (vertex[dimension_index] * index_multiplier);
+ index_multiplier *= length(dimension_index);
+ }
+
+ return (vertex_index);
+ }
+
+ // Returns the vertex whose index is [vertex_index] (See also
+ // index_of(vertex_descriptor))
+ vertex_descriptor vertex_at(vertices_size_type vertex_index) const
+ {
+
+ boost::array< vertices_size_type, Dimensions > vertex;
+ vertices_size_type index_divider = 1;
+
+ for (std::size_t dimension_index = 0; dimension_index < Dimensions;
+ ++dimension_index)
+ {
+
+ vertex[dimension_index]
+ = (vertex_index / index_divider) % length(dimension_index);
+
+ index_divider *= length(dimension_index);
+ }
+
+ return (vertex);
+ }
+
+ // Returns the edge whose index is [edge_index] (See also
+ // index_of(edge_descriptor)). NOTE: The index mapping is
+ // dependent upon dimension wrapping.
+ edge_descriptor edge_at(edges_size_type edge_index) const
+ {
+
+ // Edge indices are sorted into bins by dimension
+ std::size_t dimension_index = 0;
+ edges_size_type dimension_edges = num_edges(0);
+
+ while (edge_index >= dimension_edges)
+ {
+ edge_index -= dimension_edges;
+ ++dimension_index;
+ dimension_edges = num_edges(dimension_index);
+ }
+
+ vertex_descriptor vertex_source, vertex_target;
+ bool is_forward
+ = ((edge_index / (num_edges(dimension_index) / 2)) == 0);
+
+ if (wrapped(dimension_index))
+ {
+ vertex_source = vertex_at(edge_index % num_vertices());
+ vertex_target = is_forward
+ ? next(vertex_source, dimension_index)
+ : previous(vertex_source, dimension_index);
+ }
+ else
+ {
+
+ // Dimensions can wrap arbitrarily, so an index needs to be
+ // computed in a more complex manner. This is done by
+ // grouping the edges for each dimension together into "bins"
+ // and considering [edge_index] as an offset into the bin.
+ // Each bin consists of two parts: the "forward" looking edges
+ // and the "backward" looking edges for the dimension.
+
+ edges_size_type vertex_offset
+ = edge_index % num_edges(dimension_index);
+
+ // Consider vertex_offset an index into the graph's vertex
+ // space but with the dimension [dimension_index] reduced in
+ // size by one.
+ vertices_size_type index_divider = 1;
+
+ for (std::size_t dimension_index_iter = 0;
+ dimension_index_iter < Dimensions; ++dimension_index_iter)
+ {
+
+ std::size_t dimension_length
+ = (dimension_index_iter == dimension_index)
+ ? length(dimension_index_iter) - 1
+ : length(dimension_index_iter);
+
+ vertex_source[dimension_index_iter]
+ = (vertex_offset / index_divider) % dimension_length;
+
+ index_divider *= dimension_length;
+ }
+
+ if (is_forward)
+ {
+ vertex_target = next(vertex_source, dimension_index);
+ }
+ else
+ {
+ // Shift forward one more unit in the dimension for backward
+ // edges since the algorithm above will leave us one behind.
+ vertex_target = vertex_source;
+ ++vertex_source[dimension_index];
+ }
+
+ } // if (wrapped(dimension_index))
+
+ return (std::make_pair(vertex_source, vertex_target));
+ }
+
+ // Returns the index for [edge] (See also edge_at)
+ edges_size_type index_of(edge_descriptor edge) const
+ {
+ vertex_descriptor source_vertex = source(edge, *this);
+ vertex_descriptor target_vertex = target(edge, *this);
+
+ BOOST_ASSERT(source_vertex != target_vertex);
+
+ // Determine the dimension where the source and target vertices
+ // differ (should only be one if this is a valid edge).
+ std::size_t different_dimension_index = 0;
+
+ while (source_vertex[different_dimension_index]
+ == target_vertex[different_dimension_index])
+ {
+
+ ++different_dimension_index;
+ }
+
+ edges_size_type edge_index = 0;
+
+ // Offset the edge index into the appropriate "bin" (see edge_at
+ // for a more in-depth description).
+ for (std::size_t dimension_index = 0;
+ dimension_index < different_dimension_index; ++dimension_index)
+ {
+
+ edge_index += num_edges(dimension_index);
+ }
+
+ // Get the position of both vertices in the differing dimension.
+ vertices_size_type source_position
+ = source_vertex[different_dimension_index];
+ vertices_size_type target_position
+ = target_vertex[different_dimension_index];
+
+ // Determine if edge is forward or backward
+ bool is_forward = true;
+
+ if (wrapped(different_dimension_index))
+ {
+
+ // If the dimension is wrapped, an edge is going backward if
+ // either A: its target precedes the source in the differing
+ // dimension and the vertices are adjacent or B: its source
+ // precedes the target and they're not adjacent.
+ if (((target_position < source_position)
+ && ((source_position - target_position) == 1))
+ || ((source_position < target_position)
+ && ((target_position - source_position) > 1)))
+ {
+
+ is_forward = false;
+ }
+ }
+ else if (target_position < source_position)
+ {
+ is_forward = false;
+ }
+
+ // "Backward" edges are in the second half of the bin.
+ if (!is_forward)
+ {
+ edge_index += (num_edges(different_dimension_index) / 2);
+ }
+
+ // Finally, apply the vertex offset
+ if (wrapped(different_dimension_index))
+ {
+ edge_index += index_of(source_vertex);
+ }
+ else
+ {
+ vertices_size_type index_multiplier = 1;
+
+ if (!is_forward)
+ {
+ --source_vertex[different_dimension_index];
+ }
+
+ for (std::size_t dimension_index = 0; dimension_index < Dimensions;
+ ++dimension_index)
+ {
+
+ edge_index
+ += (source_vertex[dimension_index] * index_multiplier);
+ index_multiplier
+ *= (dimension_index == different_dimension_index)
+ ? length(dimension_index) - 1
+ : length(dimension_index);
+ }
+ }
+
+ return (edge_index);
+ }
+
+ // Returns the number of out-edges for [vertex]
+ degree_size_type out_degree(vertex_descriptor vertex) const
+ {
+
+ degree_size_type out_edge_count = 0;
+
+ for (std::size_t dimension_index = 0; dimension_index < Dimensions;
+ ++dimension_index)
+ {
+
+ // If the vertex is on the edge of this dimension, then its
+ // number of out edges is dependent upon whether the dimension
+ // wraps or not.
+ if ((vertex[dimension_index] == 0)
+ || (vertex[dimension_index] == (length(dimension_index) - 1)))
+ {
+ out_edge_count += (wrapped(dimension_index) ? 2 : 1);
+ }
+ else
+ {
+ // Next and previous edges, regardless or wrapping
+ out_edge_count += 2;
+ }
+ }
+
+ return (out_edge_count);
+ }
+
+ // Returns an out-edge for [vertex] by index. Indices are in the
+ // range [0, out_degree(vertex)).
+ edge_descriptor out_edge_at(
+ vertex_descriptor vertex, degree_size_type out_edge_index) const
+ {
+
+ edges_size_type edges_left = out_edge_index + 1;
+ std::size_t dimension_index = 0;
+ bool is_forward = false;
+
+ // Walks the out edges of [vertex] and accommodates for dimension
+ // wrapping.
+ while (edges_left > 0)
+ {
+
+ if (!wrapped(dimension_index))
+ {
+ if (!is_forward && (vertex[dimension_index] == 0))
+ {
+ is_forward = true;
+ continue;
+ }
+ else if (is_forward
+ && (vertex[dimension_index]
+ == (length(dimension_index) - 1)))
+ {
+ is_forward = false;
+ ++dimension_index;
+ continue;
+ }
+ }
+
+ --edges_left;
+
+ if (edges_left > 0)
+ {
+ is_forward = !is_forward;
+
+ if (!is_forward)
+ {
+ ++dimension_index;
+ }
+ }
+ }
+
+ return (std::make_pair(vertex,
+ is_forward ? next(vertex, dimension_index)
+ : previous(vertex, dimension_index)));
+ }
+
+ // Returns the number of in-edges for [vertex]
+ inline degree_size_type in_degree(vertex_descriptor vertex) const
+ {
+ return (out_degree(vertex));
+ }
+
+ // Returns an in-edge for [vertex] by index. Indices are in the
+ // range [0, in_degree(vertex)).
+ edge_descriptor in_edge_at(
+ vertex_descriptor vertex, edges_size_type in_edge_index) const
+ {
+
+ edge_descriptor out_edge = out_edge_at(vertex, in_edge_index);
+ return (
+ std::make_pair(target(out_edge, *this), source(out_edge, *this)));
+ }
+
+ // Pre-computes the number of vertices and edges
+ void precalculate()
+ {
+ m_num_vertices = std::accumulate(m_dimension_lengths.begin(),
+ m_dimension_lengths.end(), vertices_size_type(1),
+ std::multiplies< vertices_size_type >());
+
+ // Calculate number of edges in each dimension
+ m_num_edges = 0;
+
+ for (std::size_t dimension_index = 0; dimension_index < Dimensions;
+ ++dimension_index)
+ {
+
+ if (wrapped(dimension_index))
+ {
+ m_edge_count[dimension_index] = num_vertices() * 2;
+ }
+ else
+ {
+ m_edge_count[dimension_index]
+ = (num_vertices()
+ - (num_vertices() / length(dimension_index)))
+ * 2;
+ }
+
+ m_num_edges += num_edges(dimension_index);
+ }
+ }
+
+ const vertex_descriptor m_dimension_lengths;
+ WrapDimensionArray m_wrap_dimension;
+ vertices_size_type m_num_vertices;
+
+ boost::array< edges_size_type, Dimensions > m_edge_count;
+ edges_size_type m_num_edges;
+
+public:
+ //================
+ // VertexListGraph
+ //================
+
+ friend inline std::pair< typename type::vertex_iterator,
+ typename type::vertex_iterator >
+ vertices(const type& graph)
+ {
+ typedef typename type::vertex_iterator vertex_iterator;
+ typedef typename type::vertex_function vertex_function;
+ typedef typename type::vertex_index_iterator vertex_index_iterator;
+
+ return (std::make_pair(
+ vertex_iterator(vertex_index_iterator(0), vertex_function(&graph)),
+ vertex_iterator(vertex_index_iterator(graph.num_vertices()),
+ vertex_function(&graph))));
+ }
+
+ friend inline typename type::vertices_size_type num_vertices(
+ const type& graph)
+ {
+ return (graph.num_vertices());
+ }
+
+ friend inline typename type::vertex_descriptor vertex(
+ typename type::vertices_size_type vertex_index, const type& graph)
+ {
+
+ return (graph.vertex_at(vertex_index));
+ }
+
+ //===============
+ // IncidenceGraph
+ //===============
+
+ friend inline std::pair< typename type::out_edge_iterator,
+ typename type::out_edge_iterator >
+ out_edges(typename type::vertex_descriptor vertex, const type& graph)
+ {
+ typedef typename type::degree_iterator degree_iterator;
+ typedef typename type::out_edge_function out_edge_function;
+ typedef typename type::out_edge_iterator out_edge_iterator;
+
+ return (std::make_pair(out_edge_iterator(degree_iterator(0),
+ out_edge_function(vertex, &graph)),
+ out_edge_iterator(degree_iterator(graph.out_degree(vertex)),
+ out_edge_function(vertex, &graph))));
+ }
+
+ friend inline typename type::degree_size_type out_degree(
+ typename type::vertex_descriptor vertex, const type& graph)
+ {
+ return (graph.out_degree(vertex));
+ }
+
+ friend inline typename type::edge_descriptor out_edge_at(
+ typename type::vertex_descriptor vertex,
+ typename type::degree_size_type out_edge_index, const type& graph)
+ {
+ return (graph.out_edge_at(vertex, out_edge_index));
+ }
+
+ //===============
+ // AdjacencyGraph
+ //===============
+
+ friend typename std::pair< typename type::adjacency_iterator,
+ typename type::adjacency_iterator >
+ adjacent_vertices(
+ typename type::vertex_descriptor vertex, const type& graph)
+ {
+ typedef typename type::degree_iterator degree_iterator;
+ typedef
+ typename type::adjacent_vertex_function adjacent_vertex_function;
+ typedef typename type::adjacency_iterator adjacency_iterator;
+
+ return (std::make_pair(adjacency_iterator(degree_iterator(0),
+ adjacent_vertex_function(vertex, &graph)),
+ adjacency_iterator(degree_iterator(graph.out_degree(vertex)),
+ adjacent_vertex_function(vertex, &graph))));
+ }
+
+ //==============
+ // EdgeListGraph
+ //==============
+
+ friend inline typename type::edges_size_type num_edges(const type& graph)
+ {
+ return (graph.num_edges());
+ }
+
+ friend inline typename type::edge_descriptor edge_at(
+ typename type::edges_size_type edge_index, const type& graph)
+ {
+ return (graph.edge_at(edge_index));
+ }
+
+ friend inline std::pair< typename type::edge_iterator,
+ typename type::edge_iterator >
+ edges(const type& graph)
+ {
+ typedef typename type::edge_index_iterator edge_index_iterator;
+ typedef typename type::edge_function edge_function;
+ typedef typename type::edge_iterator edge_iterator;
+
+ return (std::make_pair(
+ edge_iterator(edge_index_iterator(0), edge_function(&graph)),
+ edge_iterator(edge_index_iterator(graph.num_edges()),
+ edge_function(&graph))));
+ }
+
+ //===================
+ // BiDirectionalGraph
+ //===================
+
+ friend inline std::pair< typename type::in_edge_iterator,
+ typename type::in_edge_iterator >
+ in_edges(typename type::vertex_descriptor vertex, const type& graph)
+ {
+ typedef typename type::in_edge_function in_edge_function;
+ typedef typename type::degree_iterator degree_iterator;
+ typedef typename type::in_edge_iterator in_edge_iterator;
+
+ return (std::make_pair(in_edge_iterator(degree_iterator(0),
+ in_edge_function(vertex, &graph)),
+ in_edge_iterator(degree_iterator(graph.in_degree(vertex)),
+ in_edge_function(vertex, &graph))));
+ }
+
+ friend inline typename type::degree_size_type in_degree(
+ typename type::vertex_descriptor vertex, const type& graph)
+ {
+ return (graph.in_degree(vertex));
+ }
+
+ friend inline typename type::degree_size_type degree(
+ typename type::vertex_descriptor vertex, const type& graph)
+ {
+ return (graph.out_degree(vertex) * 2);
+ }
+
+ friend inline typename type::edge_descriptor in_edge_at(
+ typename type::vertex_descriptor vertex,
+ typename type::degree_size_type in_edge_index, const type& graph)
+ {
+ return (graph.in_edge_at(vertex, in_edge_index));
+ }
+
+ //==================
+ // Adjacency Matrix
+ //==================
+
+ friend std::pair< typename type::edge_descriptor, bool > edge(
+ typename type::vertex_descriptor source_vertex,
+ typename type::vertex_descriptor destination_vertex, const type& graph)
+ {
+
+ std::pair< typename type::edge_descriptor, bool > edge_exists
+ = std::make_pair(
+ std::make_pair(source_vertex, destination_vertex), false);
+
+ for (std::size_t dimension_index = 0; dimension_index < Dimensions;
+ ++dimension_index)
+ {
+
+ typename type::vertices_size_type dim_difference = 0;
+ typename type::vertices_size_type source_dim
+ = source_vertex[dimension_index],
+ dest_dim = destination_vertex[dimension_index];
+
+ dim_difference = (source_dim > dest_dim) ? (source_dim - dest_dim)
+ : (dest_dim - source_dim);
+
+ if (dim_difference > 0)
+ {
+
+ // If we've already found a valid edge, this would mean that
+ // the vertices are really diagonal across dimensions and
+ // therefore not connected.
+ if (edge_exists.second)
+ {
+ edge_exists.second = false;
+ break;
+ }
+
+ // If the difference is one, the vertices are right next to
+ // each other and the edge is valid. The edge is still
+ // valid, though, if the dimension wraps and the vertices
+ // are on opposite ends.
+ if ((dim_difference == 1)
+ || (graph.wrapped(dimension_index)
+ && (((source_dim == 0)
+ && (dest_dim
+ == (graph.length(dimension_index) - 1)))
+ || ((dest_dim == 0)
+ && (source_dim
+ == (graph.length(dimension_index) - 1))))))
+ {
+
+ edge_exists.second = true;
+ // Stay in the loop to check for diagonal vertices.
+ }
+ else
+ {
+
+ // Stop checking - the vertices are too far apart.
+ edge_exists.second = false;
+ break;
+ }
+ }
+
+ } // for dimension_index
+
+ return (edge_exists);
+ }
+
+ //=============================
+ // Index Property Map Functions
+ //=============================
+
+ friend inline typename type::vertices_size_type get(vertex_index_t,
+ const type& graph, typename type::vertex_descriptor vertex)
+ {
+ return (graph.index_of(vertex));
+ }
+
+ friend inline typename type::edges_size_type get(
+ edge_index_t, const type& graph, typename type::edge_descriptor edge)
+ {
+ return (graph.index_of(edge));
+ }
+
+ friend inline grid_graph_index_map< type, typename type::vertex_descriptor,
+ typename type::vertices_size_type >
+ get(vertex_index_t, const type& graph)
+ {
+ return (grid_graph_index_map< type, typename type::vertex_descriptor,
+ typename type::vertices_size_type >(graph));
+ }
+
+ friend inline grid_graph_index_map< type, typename type::edge_descriptor,
+ typename type::edges_size_type >
+ get(edge_index_t, const type& graph)
+ {
+ return (grid_graph_index_map< type, typename type::edge_descriptor,
+ typename type::edges_size_type >(graph));
+ }
+
+ friend inline grid_graph_reverse_edge_map< typename type::edge_descriptor >
+ get(edge_reverse_t, const type& graph)
+ {
+ return (
+ grid_graph_reverse_edge_map< typename type::edge_descriptor >());
+ }
+
+ template < typename Graph, typename Descriptor, typename Index >
+ friend struct grid_graph_index_map;
+
+ template < typename Descriptor > friend struct grid_graph_reverse_edge_map;
+
+}; // grid_graph
+
+} // namespace boost
+
+#undef BOOST_GRID_GRAPH_TYPE
+#undef BOOST_GRID_GRAPH_TEMPLATE_PARAMS
+#undef BOOST_GRID_GRAPH_TRAITS_T
+
+#endif // BOOST_GRAPH_GRID_GRAPH_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/gursoy_atun_layout.hpp b/contrib/restricted/boost/graph/include/boost/graph/gursoy_atun_layout.hpp
new file mode 100644
index 0000000000..1a8709b178
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/gursoy_atun_layout.hpp
@@ -0,0 +1,338 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jeremiah Willcock
+// Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP
+#define BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP
+
+// Gürsoy-Atun graph layout, based on:
+// "Neighbourhood Preserving Load Balancing: A Self-Organizing Approach"
+// in 6th International Euro-Par Conference Munich, Germany, August 29 –
+// September 1, 2000 Proceedings, pp 234-241
+// https://doi.org/10.1007/3-540-44520-X_32
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/assert.hpp>
+#include <vector>
+#include <exception>
+#include <algorithm>
+
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/topology.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ struct over_distance_limit : public std::exception
+ {
+ };
+
+ template < typename PositionMap, typename NodeDistanceMap,
+ typename Topology, typename Graph >
+ struct update_position_visitor
+ {
+ typedef typename Topology::point_type Point;
+ PositionMap position_map;
+ NodeDistanceMap node_distance;
+ const Topology& space;
+ Point input_vector;
+ double distance_limit;
+ double learning_constant;
+ double falloff_ratio;
+
+ typedef boost::on_examine_vertex event_filter;
+
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+
+ update_position_visitor(PositionMap position_map,
+ NodeDistanceMap node_distance, const Topology& space,
+ const Point& input_vector, double distance_limit,
+ double learning_constant, double falloff_ratio)
+ : position_map(position_map)
+ , node_distance(node_distance)
+ , space(space)
+ , input_vector(input_vector)
+ , distance_limit(distance_limit)
+ , learning_constant(learning_constant)
+ , falloff_ratio(falloff_ratio)
+ {
+ }
+
+ void operator()(vertex_descriptor v, const Graph&) const
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::pow;
+#endif
+
+ if (get(node_distance, v) > distance_limit)
+ BOOST_THROW_EXCEPTION(over_distance_limit());
+ Point old_position = get(position_map, v);
+ double distance = get(node_distance, v);
+ double fraction
+ = learning_constant * pow(falloff_ratio, distance * distance);
+ put(position_map, v,
+ space.move_position_toward(
+ old_position, fraction, input_vector));
+ }
+ };
+
+ template < typename EdgeWeightMap > struct gursoy_shortest
+ {
+ template < typename Graph, typename NodeDistanceMap,
+ typename UpdatePosition >
+ static inline void run(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ NodeDistanceMap node_distance, UpdatePosition& update_position,
+ EdgeWeightMap weight)
+ {
+ boost::dijkstra_shortest_paths(g, s,
+ weight_map(weight).visitor(boost::make_dijkstra_visitor(
+ std::make_pair(boost::record_distances(
+ node_distance, boost::on_edge_relaxed()),
+ update_position))));
+ }
+ };
+
+ template <> struct gursoy_shortest< dummy_property_map >
+ {
+ template < typename Graph, typename NodeDistanceMap,
+ typename UpdatePosition >
+ static inline void run(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ NodeDistanceMap node_distance, UpdatePosition& update_position,
+ dummy_property_map)
+ {
+ boost::breadth_first_search(g, s,
+ visitor(boost::make_bfs_visitor(
+ std::make_pair(boost::record_distances(
+ node_distance, boost::on_tree_edge()),
+ update_position))));
+ }
+ };
+
+} // namespace detail
+
+template < typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename Diameter, typename VertexIndexMap,
+ typename EdgeWeightMap >
+void gursoy_atun_step(const VertexListAndIncidenceGraph& graph,
+ const Topology& space, PositionMap position, Diameter diameter,
+ double learning_constant, VertexIndexMap vertex_index_map,
+ EdgeWeightMap weight)
+{
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::exp;
+ using std::pow;
+#endif
+
+ typedef
+ typename graph_traits< VertexListAndIncidenceGraph >::vertex_iterator
+ vertex_iterator;
+ typedef
+ typename graph_traits< VertexListAndIncidenceGraph >::vertex_descriptor
+ vertex_descriptor;
+ typedef typename Topology::point_type point_type;
+ vertex_iterator i, iend;
+ std::vector< double > distance_from_input_vector(num_vertices(graph));
+ typedef boost::iterator_property_map< std::vector< double >::iterator,
+ VertexIndexMap, double, double& >
+ DistanceFromInputMap;
+ DistanceFromInputMap distance_from_input(
+ distance_from_input_vector.begin(), vertex_index_map);
+ std::vector< double > node_distance_map_vector(num_vertices(graph));
+ typedef boost::iterator_property_map< std::vector< double >::iterator,
+ VertexIndexMap, double, double& >
+ NodeDistanceMap;
+ NodeDistanceMap node_distance(
+ node_distance_map_vector.begin(), vertex_index_map);
+ point_type input_vector = space.random_point();
+ vertex_descriptor min_distance_loc
+ = graph_traits< VertexListAndIncidenceGraph >::null_vertex();
+ double min_distance = 0.0;
+ bool min_distance_unset = true;
+ for (boost::tie(i, iend) = vertices(graph); i != iend; ++i)
+ {
+ double this_distance = space.distance(get(position, *i), input_vector);
+ put(distance_from_input, *i, this_distance);
+ if (min_distance_unset || this_distance < min_distance)
+ {
+ min_distance = this_distance;
+ min_distance_loc = *i;
+ }
+ min_distance_unset = false;
+ }
+ BOOST_ASSERT(!min_distance_unset); // Graph must have at least one vertex
+ boost::detail::update_position_visitor< PositionMap, NodeDistanceMap,
+ Topology, VertexListAndIncidenceGraph >
+ update_position(position, node_distance, space, input_vector, diameter,
+ learning_constant, exp(-1. / (2 * diameter * diameter)));
+ std::fill(
+ node_distance_map_vector.begin(), node_distance_map_vector.end(), 0);
+ try
+ {
+ typedef detail::gursoy_shortest< EdgeWeightMap > shortest;
+ shortest::run(
+ graph, min_distance_loc, node_distance, update_position, weight);
+ }
+ catch (const detail::over_distance_limit&)
+ {
+ /* Thrown to break out of BFS or Dijkstra early */
+ }
+}
+
+template < typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename VertexIndexMap, typename EdgeWeightMap >
+void gursoy_atun_refine(const VertexListAndIncidenceGraph& graph,
+ const Topology& space, PositionMap position, int nsteps,
+ double diameter_initial, double diameter_final,
+ double learning_constant_initial, double learning_constant_final,
+ VertexIndexMap vertex_index_map, EdgeWeightMap weight)
+{
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::exp;
+ using std::pow;
+#endif
+
+ typedef
+ typename graph_traits< VertexListAndIncidenceGraph >::vertex_iterator
+ vertex_iterator;
+ vertex_iterator i, iend;
+ double diameter_ratio = (double)diameter_final / diameter_initial;
+ double learning_constant_ratio
+ = learning_constant_final / learning_constant_initial;
+ std::vector< double > distance_from_input_vector(num_vertices(graph));
+ typedef boost::iterator_property_map< std::vector< double >::iterator,
+ VertexIndexMap, double, double& >
+ DistanceFromInputMap;
+ DistanceFromInputMap distance_from_input(
+ distance_from_input_vector.begin(), vertex_index_map);
+ std::vector< int > node_distance_map_vector(num_vertices(graph));
+ typedef boost::iterator_property_map< std::vector< int >::iterator,
+ VertexIndexMap, double, double& >
+ NodeDistanceMap;
+ NodeDistanceMap node_distance(
+ node_distance_map_vector.begin(), vertex_index_map);
+ for (int round = 0; round < nsteps; ++round)
+ {
+ double part_done = (double)round / (nsteps - 1);
+ // fprintf(stderr, "%2d%% done\n", int(rint(part_done * 100.)));
+ int diameter = (int)(diameter_initial * pow(diameter_ratio, part_done));
+ double learning_constant = learning_constant_initial
+ * pow(learning_constant_ratio, part_done);
+ gursoy_atun_step(graph, space, position, diameter, learning_constant,
+ vertex_index_map, weight);
+ }
+}
+
+template < typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename VertexIndexMap, typename EdgeWeightMap >
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space, PositionMap position, int nsteps,
+ double diameter_initial, double diameter_final,
+ double learning_constant_initial, double learning_constant_final,
+ VertexIndexMap vertex_index_map, EdgeWeightMap weight)
+{
+ typedef
+ typename graph_traits< VertexListAndIncidenceGraph >::vertex_iterator
+ vertex_iterator;
+ vertex_iterator i, iend;
+ for (boost::tie(i, iend) = vertices(graph); i != iend; ++i)
+ {
+ put(position, *i, space.random_point());
+ }
+ gursoy_atun_refine(graph, space, position, nsteps, diameter_initial,
+ diameter_final, learning_constant_initial, learning_constant_final,
+ vertex_index_map, weight);
+}
+
+template < typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename VertexIndexMap >
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space, PositionMap position, int nsteps,
+ double diameter_initial, double diameter_final,
+ double learning_constant_initial, double learning_constant_final,
+ VertexIndexMap vertex_index_map)
+{
+ gursoy_atun_layout(graph, space, position, nsteps, diameter_initial,
+ diameter_final, learning_constant_initial, learning_constant_final,
+ vertex_index_map, dummy_property_map());
+}
+
+template < typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap >
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space, PositionMap position, int nsteps,
+ double diameter_initial, double diameter_final = 1.0,
+ double learning_constant_initial = 0.8,
+ double learning_constant_final = 0.2)
+{
+ gursoy_atun_layout(graph, space, position, nsteps, diameter_initial,
+ diameter_final, learning_constant_initial, learning_constant_final,
+ get(vertex_index, graph));
+}
+
+template < typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap >
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space, PositionMap position, int nsteps)
+{
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif
+
+ gursoy_atun_layout(
+ graph, space, position, nsteps, sqrt((double)num_vertices(graph)));
+}
+
+template < typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap >
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space, PositionMap position)
+{
+ gursoy_atun_layout(graph, space, position, num_vertices(graph));
+}
+
+template < typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename P, typename T, typename R >
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space, PositionMap position,
+ const bgl_named_params< P, T, R >& params)
+{
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif
+
+ std::pair< double, double > diam(sqrt(double(num_vertices(graph))), 1.0);
+ std::pair< double, double > learn(0.8, 0.2);
+ gursoy_atun_layout(graph, space, position,
+ choose_param(get_param(params, iterations_t()), num_vertices(graph)),
+ choose_param(get_param(params, diameter_range_t()), diam).first,
+ choose_param(get_param(params, diameter_range_t()), diam).second,
+ choose_param(get_param(params, learning_constant_range_t()), learn)
+ .first,
+ choose_param(get_param(params, learning_constant_range_t()), learn)
+ .second,
+ choose_const_pmap(get_param(params, vertex_index), graph, vertex_index),
+ choose_param(get_param(params, edge_weight), dummy_property_map()));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/hawick_circuits.hpp b/contrib/restricted/boost/graph/include/boost/graph/hawick_circuits.hpp
new file mode 100644
index 0000000000..cefd6a13a6
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/hawick_circuits.hpp
@@ -0,0 +1,409 @@
+// Copyright Louis Dionne 2013
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
+// at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_HAWICK_CIRCUITS_HPP
+#define BOOST_GRAPH_HAWICK_CIRCUITS_HPP
+
+#include <algorithm>
+#include <boost/assert.hpp>
+#include <boost/foreach.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/one_bit_color_map.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/tuple/tuple.hpp> // for boost::tie
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/utility/result_of.hpp>
+#include <set>
+#include <utility> // for std::pair
+#include <vector>
+
+namespace boost
+{
+namespace hawick_circuits_detail
+{
+ //! @internal Functor returning all the vertices adjacent to a vertex.
+ struct get_all_adjacent_vertices
+ {
+ template < typename Sig > struct result;
+
+ template < typename This, typename Vertex, typename Graph >
+ struct result< This(Vertex, Graph) >
+ {
+ private:
+ typedef typename remove_reference< Graph >::type RawGraph;
+ typedef graph_traits< RawGraph > Traits;
+ typedef typename Traits::adjacency_iterator AdjacencyIterator;
+
+ public:
+ typedef std::pair< AdjacencyIterator, AdjacencyIterator > type;
+ };
+
+ template < typename Vertex, typename Graph >
+ typename result< get_all_adjacent_vertices(
+ BOOST_FWD_REF(Vertex), BOOST_FWD_REF(Graph)) >::type
+ operator()(BOOST_FWD_REF(Vertex) v, BOOST_FWD_REF(Graph) g) const
+ {
+ return adjacent_vertices(
+ boost::forward< Vertex >(v), boost::forward< Graph >(g));
+ }
+ };
+
+ //! @internal Functor returning a set of the vertices adjacent to a vertex.
+ struct get_unique_adjacent_vertices
+ {
+ template < typename Sig > struct result;
+
+ template < typename This, typename Vertex, typename Graph >
+ struct result< This(Vertex, Graph) >
+ {
+ typedef std::set< typename remove_reference< Vertex >::type > type;
+ };
+
+ template < typename Vertex, typename Graph >
+ typename result< get_unique_adjacent_vertices(
+ Vertex, Graph const&) >::type
+ operator()(Vertex v, Graph const& g) const
+ {
+ typedef typename result< get_unique_adjacent_vertices(
+ Vertex, Graph const&) >::type Set;
+ return Set(
+ adjacent_vertices(v, g).first, adjacent_vertices(v, g).second);
+ }
+ };
+
+ //! @internal
+ //! Return whether a container contains a given value.
+ //! This is not meant as a general purpose membership testing function; it
+ //! would have to be more clever about possible optimizations.
+ template < typename Container, typename Value >
+ bool contains(Container const& c, Value const& v)
+ {
+ return std::find(boost::begin(c), boost::end(c), v) != boost::end(c);
+ }
+
+ /*!
+ * @internal
+ * Algorithm finding all the cycles starting from a given vertex.
+ *
+ * The search is only done in the subgraph induced by the starting vertex
+ * and the vertices with an index higher than the starting vertex.
+ */
+ template < typename Graph, typename Visitor, typename VertexIndexMap,
+ typename Stack, typename ClosedMatrix, typename GetAdjacentVertices >
+ struct hawick_circuits_from
+ {
+ private:
+ typedef graph_traits< Graph > Traits;
+ typedef typename Traits::vertex_descriptor Vertex;
+ typedef typename Traits::edge_descriptor Edge;
+ typedef typename Traits::vertices_size_type VerticesSize;
+ typedef
+ typename property_traits< VertexIndexMap >::value_type VertexIndex;
+
+ typedef typename result_of< GetAdjacentVertices(
+ Vertex, Graph const&) >::type AdjacentVertices;
+ typedef typename range_iterator< AdjacentVertices const >::type
+ AdjacencyIterator;
+
+ // The one_bit_color_map starts all white, i.e. not blocked.
+ // Since we make that assumption (I looked at the implementation, but
+ // I can't find anything that documents this behavior), we're gonna
+ // assert it in the constructor.
+ typedef one_bit_color_map< VertexIndexMap > BlockedMap;
+ typedef typename property_traits< BlockedMap >::value_type BlockedColor;
+
+ static BlockedColor blocked_false_color()
+ {
+ return color_traits< BlockedColor >::white();
+ }
+
+ static BlockedColor blocked_true_color()
+ {
+ return color_traits< BlockedColor >::black();
+ }
+
+ // This is used by the constructor to secure the assumption
+ // documented above.
+ bool blocked_map_starts_all_unblocked() const
+ {
+ BOOST_FOREACH (Vertex v, vertices(graph_))
+ if (is_blocked(v))
+ return false;
+ return true;
+ }
+
+ // This is only used in the constructor to make sure the optimization of
+ // sharing data structures between iterations does not break the code.
+ bool all_closed_rows_are_empty() const
+ {
+ BOOST_FOREACH (typename ClosedMatrix::reference row, closed_)
+ if (!row.empty())
+ return false;
+ return true;
+ }
+
+ public:
+ hawick_circuits_from(Graph const& graph, Visitor& visitor,
+ VertexIndexMap const& vim, Stack& stack, ClosedMatrix& closed,
+ VerticesSize n_vertices, unsigned int max_length)
+ : graph_(graph)
+ , visitor_(visitor)
+ , vim_(vim)
+ , stack_(stack)
+ , closed_(closed)
+ , blocked_(n_vertices, vim_)
+ , max_length_(max_length)
+ {
+ BOOST_ASSERT(blocked_map_starts_all_unblocked());
+
+ // Since sharing the data structures between iterations is
+ // just an optimization, it must always be equivalent to
+ // constructing new ones in this constructor.
+ BOOST_ASSERT(stack_.empty());
+ BOOST_ASSERT(closed_.size() == n_vertices);
+ BOOST_ASSERT(all_closed_rows_are_empty());
+ }
+
+ private:
+ //! @internal Return the index of a given vertex.
+ VertexIndex index_of(Vertex v) const { return get(vim_, v); }
+
+ //! @internal Return whether a vertex `v` is closed to a vertex `u`.
+ bool is_closed_to(Vertex u, Vertex v) const
+ {
+ typedef typename ClosedMatrix::const_reference VertexList;
+ VertexList closed_to_u = closed_[index_of(u)];
+ return contains(closed_to_u, v);
+ }
+
+ //! @internal Close a vertex `v` to a vertex `u`.
+ void close_to(Vertex u, Vertex v)
+ {
+ BOOST_ASSERT(!is_closed_to(u, v));
+ closed_[index_of(u)].push_back(v);
+ }
+
+ //! @internal Return whether a given vertex is blocked.
+ bool is_blocked(Vertex v) const
+ {
+ return get(blocked_, v) == blocked_true_color();
+ }
+
+ //! @internal Block a given vertex.
+ void block(Vertex v) { put(blocked_, v, blocked_true_color()); }
+
+ //! @internal Unblock a given vertex.
+ void unblock(Vertex u)
+ {
+ typedef typename ClosedMatrix::reference VertexList;
+
+ put(blocked_, u, blocked_false_color());
+ VertexList closed_to_u = closed_[index_of(u)];
+
+ while (!closed_to_u.empty())
+ {
+ Vertex const w = closed_to_u.back();
+ closed_to_u.pop_back();
+ if (is_blocked(w))
+ unblock(w);
+ }
+ BOOST_ASSERT(closed_to_u.empty());
+ }
+
+ //! @internal Main procedure as described in the paper.
+ bool circuit(Vertex start, Vertex v)
+ {
+ bool found_circuit = false;
+ stack_.push_back(v);
+ block(v);
+
+ // Truncate the search if any circuits would exceed max_length_.
+ bool const truncate_search =
+ (max_length_ > 0 && stack_.size() >= max_length_);
+
+ // Cache some values that are used more than once in the function.
+ VertexIndex const index_of_start = index_of(start);
+ AdjacentVertices const adj_vertices
+ = GetAdjacentVertices()(v, graph_);
+ AdjacencyIterator const w_end = boost::end(adj_vertices);
+
+ for (AdjacencyIterator w_it = boost::begin(adj_vertices);
+ w_it != w_end; ++w_it)
+ {
+ Vertex const w = *w_it;
+ // Since we're only looking in the subgraph induced by `start`
+ // and the vertices with an index higher than `start`, we skip
+ // any vertex that does not satisfy that.
+ if (index_of(w) < index_of_start)
+ continue;
+
+ // If the last vertex is equal to `start`, we have a circuit.
+ else if (w == start)
+ {
+ // const_cast to ensure the visitor does not modify the
+ // stack
+ visitor_.cycle(const_cast< Stack const& >(stack_), graph_);
+ found_circuit = true;
+ }
+
+ // If required, truncate the search before the subsequent
+ // recursive call to circuit().
+ else if (truncate_search)
+ continue;
+
+ // If `w` is not blocked, we continue searching further down the
+ // same path for a cycle with `w` in it.
+ else if (!is_blocked(w) && circuit(start, w))
+ found_circuit = true;
+ }
+
+ bool const finish_circuit = (found_circuit || truncate_search);
+ if (finish_circuit)
+ unblock(v);
+ else
+ for (AdjacencyIterator w_it = boost::begin(adj_vertices);
+ w_it != w_end; ++w_it)
+ {
+ Vertex const w = *w_it;
+ // Like above, we skip vertices that are not in the subgraph
+ // we're considering.
+ if (index_of(w) < index_of_start)
+ continue;
+
+ // If `v` is not closed to `w`, we make it so.
+ if (!is_closed_to(w, v))
+ close_to(w, v);
+ }
+
+ BOOST_ASSERT(v == stack_.back());
+ stack_.pop_back();
+ return finish_circuit;
+ }
+
+ public:
+ void operator()(Vertex start) { circuit(start, start); }
+
+ private:
+ Graph const& graph_;
+ Visitor& visitor_;
+ VertexIndexMap const& vim_;
+ Stack& stack_;
+ ClosedMatrix& closed_;
+ BlockedMap blocked_;
+ unsigned int max_length_;
+ };
+
+ template < typename GetAdjacentVertices, typename Graph, typename Visitor,
+ typename VertexIndexMap >
+ void call_hawick_circuits(Graph const& graph,
+ Visitor /* by value */ visitor, VertexIndexMap const& vertex_index_map,
+ unsigned int max_length)
+ {
+ typedef graph_traits< Graph > Traits;
+ typedef typename Traits::vertex_descriptor Vertex;
+ typedef typename Traits::vertices_size_type VerticesSize;
+ typedef typename Traits::vertex_iterator VertexIterator;
+
+ typedef std::vector< Vertex > Stack;
+ typedef std::vector< std::vector< Vertex > > ClosedMatrix;
+
+ typedef hawick_circuits_from< Graph, Visitor, VertexIndexMap, Stack,
+ ClosedMatrix, GetAdjacentVertices >
+ SubAlgorithm;
+
+ VerticesSize const n_vertices = num_vertices(graph);
+ Stack stack;
+ stack.reserve(n_vertices);
+ ClosedMatrix closed(n_vertices);
+
+ VertexIterator start, last;
+ for (boost::tie(start, last) = vertices(graph); start != last; ++start)
+ {
+ // Note1: The sub algorithm may NOT be reused once it has been
+ // called.
+
+ // Note2: We reuse the Stack and the ClosedMatrix (after clearing
+ // them) in each iteration to avoid redundant destruction and
+ // construction. It would be strictly equivalent to have these as
+ // member variables of the sub algorithm.
+ SubAlgorithm sub_algo(
+ graph, visitor, vertex_index_map, stack, closed, n_vertices,
+ max_length);
+ sub_algo(*start);
+ stack.clear();
+ typename ClosedMatrix::iterator row, last_row = closed.end();
+ for (row = closed.begin(); row != last_row; ++row)
+ row->clear();
+ }
+ }
+
+ template < typename GetAdjacentVertices, typename Graph, typename Visitor >
+ void call_hawick_circuits(
+ Graph const& graph, BOOST_FWD_REF(Visitor) visitor,
+ unsigned int max_length)
+ {
+ call_hawick_circuits< GetAdjacentVertices >(graph,
+ boost::forward< Visitor >(visitor), get(vertex_index, graph),
+ max_length);
+ }
+} // end namespace hawick_circuits_detail
+
+//! Enumerate all the elementary circuits in a directed multigraph.
+template < typename Graph, typename Visitor, typename VertexIndexMap >
+void hawick_circuits(BOOST_FWD_REF(Graph) graph, BOOST_FWD_REF(Visitor) visitor,
+ BOOST_FWD_REF(VertexIndexMap) vertex_index_map,
+ unsigned int max_length = 0)
+{
+ hawick_circuits_detail::call_hawick_circuits<
+ hawick_circuits_detail::get_all_adjacent_vertices >(
+ boost::forward< Graph >(graph), boost::forward< Visitor >(visitor),
+ boost::forward< VertexIndexMap >(vertex_index_map), max_length);
+}
+
+template < typename Graph, typename Visitor >
+void hawick_circuits(BOOST_FWD_REF(Graph) graph, BOOST_FWD_REF(Visitor) visitor,
+ unsigned int max_length = 0)
+{
+ hawick_circuits_detail::call_hawick_circuits<
+ hawick_circuits_detail::get_all_adjacent_vertices >(
+ boost::forward< Graph >(graph), boost::forward< Visitor >(visitor),
+ max_length);
+}
+
+/*!
+ * Same as `boost::hawick_circuits`, but duplicate circuits caused by parallel
+ * edges will not be considered. Each circuit will be considered only once.
+ */
+template < typename Graph, typename Visitor, typename VertexIndexMap >
+void hawick_unique_circuits(BOOST_FWD_REF(Graph) graph,
+ BOOST_FWD_REF(Visitor) visitor,
+ BOOST_FWD_REF(VertexIndexMap) vertex_index_map,
+ unsigned int max_length = 0)
+{
+ hawick_circuits_detail::call_hawick_circuits<
+ hawick_circuits_detail::get_unique_adjacent_vertices >(
+ boost::forward< Graph >(graph), boost::forward< Visitor >(visitor),
+ boost::forward< VertexIndexMap >(vertex_index_map), max_length);
+}
+
+template < typename Graph, typename Visitor >
+void hawick_unique_circuits(
+ BOOST_FWD_REF(Graph) graph, BOOST_FWD_REF(Visitor) visitor,
+ unsigned int max_length = 0)
+{
+ hawick_circuits_detail::call_hawick_circuits<
+ hawick_circuits_detail::get_unique_adjacent_vertices >(
+ boost::forward< Graph >(graph), boost::forward< Visitor >(visitor),
+ max_length);
+}
+} // end namespace boost
+
+#endif // !BOOST_GRAPH_HAWICK_CIRCUITS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/howard_cycle_ratio.hpp b/contrib/restricted/boost/graph/include/boost/graph/howard_cycle_ratio.hpp
new file mode 100644
index 0000000000..fe6c5bd94d
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/howard_cycle_ratio.hpp
@@ -0,0 +1,643 @@
+// Copyright (C) 2006-2009 Dmitry Bufistov and Andrey Parfenov
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_CYCLE_RATIO_HOWARD_HPP
+#define BOOST_GRAPH_CYCLE_RATIO_HOWARD_HPP
+
+#include <vector>
+#include <list>
+#include <algorithm>
+#include <functional>
+#include <limits>
+
+#include <boost/bind/bind.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/pending/queue.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/concept/assert.hpp>
+#include <boost/algorithm/minmax_element.hpp>
+
+/** @file howard_cycle_ratio.hpp
+ * @brief The implementation of the maximum/minimum cycle ratio/mean algorithm.
+ * @author Dmitry Bufistov
+ * @author Andrey Parfenov
+ */
+
+namespace boost
+{
+
+/**
+ * The mcr_float is like numeric_limits, but only for floating point types
+ * and only defines infinity() and epsilon(). This class is primarily used
+ * to encapsulate a less-precise epsilon than natively supported by the
+ * floating point type.
+ */
+template < typename Float = double > struct mcr_float
+{
+ typedef Float value_type;
+
+ static Float infinity()
+ {
+ return std::numeric_limits< value_type >::infinity();
+ }
+
+ static Float epsilon() { return Float(-0.005); }
+};
+
+namespace detail
+{
+
+ template < typename FloatTraits > struct min_comparator_props
+ {
+ typedef std::greater< typename FloatTraits::value_type > comparator;
+ static const int multiplier = 1;
+ };
+
+ template < typename FloatTraits > struct max_comparator_props
+ {
+ typedef std::less< typename FloatTraits::value_type > comparator;
+ static const int multiplier = -1;
+ };
+
+ template < typename FloatTraits, typename ComparatorProps >
+ struct float_wrapper
+ {
+ typedef typename FloatTraits::value_type value_type;
+ typedef ComparatorProps comparator_props_t;
+ typedef typename ComparatorProps::comparator comparator;
+
+ static value_type infinity()
+ {
+ return FloatTraits::infinity() * ComparatorProps::multiplier;
+ }
+
+ static value_type epsilon()
+ {
+ return FloatTraits::epsilon() * ComparatorProps::multiplier;
+ }
+ };
+
+ /*! @class mcr_howard
+ * @brief Calculates optimum (maximum/minimum) cycle ratio of a directed
+ * graph. Uses Howard's iteration policy algorithm. </br>(It is described
+ * in the paper "Experimental Analysis of the Fastest Optimum Cycle Ratio
+ * and Mean Algorithm" by Ali Dasdan).
+ */
+ template < typename FloatTraits, typename Graph, typename VertexIndexMap,
+ typename EdgeWeight1, typename EdgeWeight2 >
+ class mcr_howard
+ {
+ public:
+ typedef typename FloatTraits::value_type float_t;
+ typedef typename FloatTraits::comparator_props_t cmp_props_t;
+ typedef typename FloatTraits::comparator comparator_t;
+ typedef enum
+ {
+ my_white = 0,
+ my_black
+ } my_color_type;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef typename graph_traits< Graph >::vertices_size_type vn_t;
+ typedef std::vector< float_t > vp_t;
+ typedef typename boost::iterator_property_map< typename vp_t::iterator,
+ VertexIndexMap >
+ distance_map_t; // V -> float_t
+
+ typedef typename std::vector< edge_t > ve_t;
+ typedef std::vector< my_color_type > vcol_t;
+ typedef
+ typename ::boost::iterator_property_map< typename ve_t::iterator,
+ VertexIndexMap >
+ policy_t; // Vertex -> Edge
+ typedef
+ typename ::boost::iterator_property_map< typename vcol_t::iterator,
+ VertexIndexMap >
+ color_map_t;
+
+ typedef typename std::list< vertex_t >
+ pinel_t; // The in_edges list of the policy graph
+ typedef typename std::vector< pinel_t > inedges1_t;
+ typedef typename ::boost::iterator_property_map<
+ typename inedges1_t::iterator, VertexIndexMap >
+ inedges_t;
+ typedef typename std::vector< edge_t > critical_cycle_t;
+
+ // Bad vertex flag. If true, then the vertex is "bad".
+ // Vertex is "bad" if its out_degree is equal to zero.
+ typedef
+ typename boost::iterator_property_map< std::vector< int >::iterator,
+ VertexIndexMap >
+ badv_t;
+
+ /*!
+ * Constructor
+ * \param g = (V, E) - a directed multigraph.
+ * \param vim Vertex Index Map. Read property Map: V -> [0,
+ * num_vertices(g)). \param ewm edge weight map. Read property map: E
+ * -> R \param ew2m edge weight map. Read property map: E -> R+ \param
+ * infty A big enough value to guaranty that there exist a cycle with
+ * better ratio.
+ * \param cmp The compare operator for float_ts.
+ */
+ mcr_howard(const Graph& g, VertexIndexMap vim, EdgeWeight1 ewm,
+ EdgeWeight2 ew2m)
+ : m_g(g)
+ , m_vim(vim)
+ , m_ew1m(ewm)
+ , m_ew2m(ew2m)
+ , m_bound(mcr_bound())
+ , m_cr(m_bound)
+ , m_V(num_vertices(m_g))
+ , m_dis(m_V, 0)
+ , m_dm(m_dis.begin(), m_vim)
+ , m_policyc(m_V)
+ , m_policy(m_policyc.begin(), m_vim)
+ , m_inelc(m_V)
+ , m_inel(m_inelc.begin(), m_vim)
+ , m_badvc(m_V, false)
+ , m_badv(m_badvc.begin(), m_vim)
+ , m_colcv(m_V)
+ , m_col_bfs(m_V)
+ {
+ }
+
+ /*!
+ * \return maximum/minimum_{for all cycles C}
+ * [sum_{e in C} w1(e)] / [sum_{e in C} w2(e)],
+ * or FloatTraits::infinity() if graph has no cycles.
+ */
+ float_t ocr_howard()
+ {
+ construct_policy_graph();
+ int k = 0;
+ float_t mcr = 0;
+ do
+ {
+ mcr = policy_mcr();
+ ++k;
+ } while (
+ try_improve_policy(mcr) && k < 100); // To avoid infinite loop
+
+ const float_t eps_ = -0.00000001 * cmp_props_t::multiplier;
+ if (m_cmp(mcr, m_bound + eps_))
+ {
+ return FloatTraits::infinity();
+ }
+ else
+ {
+ return mcr;
+ }
+ }
+ virtual ~mcr_howard() {}
+
+ protected:
+ virtual void store_critical_edge(edge_t, critical_cycle_t&) {}
+ virtual void store_critical_cycle(critical_cycle_t&) {}
+
+ private:
+ /*!
+ * \return lower/upper bound for the maximal/minimal cycle ratio
+ */
+ float_t mcr_bound()
+ {
+ typename graph_traits< Graph >::vertex_iterator vi, vie;
+ typename graph_traits< Graph >::out_edge_iterator oei, oeie;
+ float_t cz = (std::numeric_limits< float_t >::max)(); // Closest to
+ // zero value
+ float_t s = 0;
+ const float_t eps_ = std::numeric_limits< float_t >::epsilon();
+ for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi)
+ {
+ for (boost::tie(oei, oeie) = out_edges(*vi, m_g); oei != oeie;
+ ++oei)
+ {
+ s += std::abs(m_ew1m[*oei]);
+ float_t a = std::abs(m_ew2m[*oei]);
+ if (a > eps_ && a < cz)
+ {
+ cz = a;
+ }
+ }
+ }
+ return cmp_props_t::multiplier * (s / cz);
+ }
+
+ /*!
+ * Constructs an arbitrary policy graph.
+ */
+ void construct_policy_graph()
+ {
+ m_sink = graph_traits< Graph >().null_vertex();
+ typename graph_traits< Graph >::vertex_iterator vi, vie;
+ typename graph_traits< Graph >::out_edge_iterator oei, oeie;
+ for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi)
+ {
+ using namespace boost::placeholders;
+
+ boost::tie(oei, oeie) = out_edges(*vi, m_g);
+ typename graph_traits< Graph >::out_edge_iterator mei
+ = boost::first_max_element(oei, oeie,
+ boost::bind(m_cmp,
+ boost::bind(&EdgeWeight1::operator[], m_ew1m, _1),
+ boost::bind(&EdgeWeight1::operator[], m_ew1m, _2)));
+ if (mei == oeie)
+ {
+ if (m_sink == graph_traits< Graph >().null_vertex())
+ {
+ m_sink = *vi;
+ }
+ m_badv[*vi] = true;
+ m_inel[m_sink].push_back(*vi);
+ }
+ else
+ {
+ m_inel[target(*mei, m_g)].push_back(*vi);
+ m_policy[*vi] = *mei;
+ }
+ }
+ }
+ /*! Sets the distance value for all vertices "v" such that there is
+ * a path from "v" to "sv". It does "inverse" breadth first visit of the
+ * policy graph, starting from the vertex "sv".
+ */
+ void mcr_bfv(vertex_t sv, float_t cr, color_map_t c)
+ {
+ boost::queue< vertex_t > Q;
+ c[sv] = my_black;
+ Q.push(sv);
+ while (!Q.empty())
+ {
+ vertex_t v = Q.top();
+ Q.pop();
+ for (typename pinel_t::const_iterator itr = m_inel[v].begin();
+ itr != m_inel[v].end(); ++itr)
+ // For all in_edges of the policy graph
+ {
+ if (*itr != sv)
+ {
+ if (m_badv[*itr])
+ {
+ m_dm[*itr] = m_dm[v] + m_bound - cr;
+ }
+ else
+ {
+ m_dm[*itr] = m_dm[v] + m_ew1m[m_policy[*itr]]
+ - m_ew2m[m_policy[*itr]] * cr;
+ }
+ c[*itr] = my_black;
+ Q.push(*itr);
+ }
+ }
+ }
+ }
+
+ /*!
+ * \param sv an arbitrary (undiscovered) vertex of the policy graph.
+ * \return a vertex in the policy graph that belongs to a cycle.
+ * Performs a depth first visit until a cycle edge is found.
+ */
+ vertex_t find_cycle_vertex(vertex_t sv)
+ {
+ vertex_t gv = sv;
+ std::fill(m_colcv.begin(), m_colcv.end(), my_white);
+ color_map_t cm(m_colcv.begin(), m_vim);
+ do
+ {
+ cm[gv] = my_black;
+ if (!m_badv[gv])
+ {
+ gv = target(m_policy[gv], m_g);
+ }
+ else
+ {
+ gv = m_sink;
+ }
+ } while (cm[gv] != my_black);
+ return gv;
+ }
+
+ /*!
+ * \param sv - vertex that belongs to a cycle in the policy graph.
+ */
+ float_t cycle_ratio(vertex_t sv)
+ {
+ if (sv == m_sink)
+ return m_bound;
+ std::pair< float_t, float_t > sums_(float_t(0), float_t(0));
+ vertex_t v = sv;
+ critical_cycle_t cc;
+ do
+ {
+ store_critical_edge(m_policy[v], cc);
+ sums_.first += m_ew1m[m_policy[v]];
+ sums_.second += m_ew2m[m_policy[v]];
+ v = target(m_policy[v], m_g);
+ } while (v != sv);
+ float_t cr = sums_.first / sums_.second;
+ if (m_cmp(m_cr, cr))
+ {
+ m_cr = cr;
+ store_critical_cycle(cc);
+ }
+ return cr;
+ }
+
+ /*!
+ * Finds the optimal cycle ratio of the policy graph
+ */
+ float_t policy_mcr()
+ {
+ using namespace boost::placeholders;
+
+ std::fill(m_col_bfs.begin(), m_col_bfs.end(), my_white);
+ color_map_t vcm_ = color_map_t(m_col_bfs.begin(), m_vim);
+ typename graph_traits< Graph >::vertex_iterator uv_itr, vie;
+ boost::tie(uv_itr, vie) = vertices(m_g);
+ float_t mcr = m_bound;
+ while ((uv_itr = std::find_if(uv_itr, vie,
+ boost::bind(std::equal_to< my_color_type >(), my_white,
+ boost::bind(&color_map_t::operator[], vcm_, _1))))
+ != vie)
+ /// While there are undiscovered vertices
+ {
+ vertex_t gv = find_cycle_vertex(*uv_itr);
+ float_t cr = cycle_ratio(gv);
+ mcr_bfv(gv, cr, vcm_);
+ if (m_cmp(mcr, cr))
+ mcr = cr;
+ ++uv_itr;
+ }
+ return mcr;
+ }
+
+ /*!
+ * Changes the edge m_policy[s] to the new_edge.
+ */
+ void improve_policy(vertex_t s, edge_t new_edge)
+ {
+ vertex_t t = target(m_policy[s], m_g);
+ typename property_traits< VertexIndexMap >::value_type ti
+ = m_vim[t];
+ m_inelc[ti].erase(
+ std::find(m_inelc[ti].begin(), m_inelc[ti].end(), s));
+ m_policy[s] = new_edge;
+ t = target(new_edge, m_g);
+ m_inel[t].push_back(s); /// Maintain in_edge list
+ }
+
+ /*!
+ * A negative cycle detector.
+ */
+ bool try_improve_policy(float_t cr)
+ {
+ bool improved = false;
+ typename graph_traits< Graph >::vertex_iterator vi, vie;
+ typename graph_traits< Graph >::out_edge_iterator oei, oeie;
+ const float_t eps_ = FloatTraits::epsilon();
+ for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi)
+ {
+ if (!m_badv[*vi])
+ {
+ for (boost::tie(oei, oeie) = out_edges(*vi, m_g);
+ oei != oeie; ++oei)
+ {
+ vertex_t t = target(*oei, m_g);
+ // Current distance from *vi to some vertex
+ float_t dis_
+ = m_ew1m[*oei] - m_ew2m[*oei] * cr + m_dm[t];
+ if (m_cmp(m_dm[*vi] + eps_, dis_))
+ {
+ improve_policy(*vi, *oei);
+ m_dm[*vi] = dis_;
+ improved = true;
+ }
+ }
+ }
+ else
+ {
+ float_t dis_ = m_bound - cr + m_dm[m_sink];
+ if (m_cmp(m_dm[*vi] + eps_, dis_))
+ {
+ m_dm[*vi] = dis_;
+ }
+ }
+ }
+ return improved;
+ }
+
+ private:
+ const Graph& m_g;
+ VertexIndexMap m_vim;
+ EdgeWeight1 m_ew1m;
+ EdgeWeight2 m_ew2m;
+ comparator_t m_cmp;
+ float_t m_bound; //> The lower/upper bound to the maximal/minimal cycle
+ // ratio
+ float_t m_cr; //>The best cycle ratio that has been found so far
+
+ vn_t m_V; //>The number of the vertices in the graph
+ vp_t m_dis; //>Container for the distance map
+ distance_map_t m_dm; //>Distance map
+
+ ve_t m_policyc; //>Container for the policy graph
+ policy_t m_policy; //>The interface for the policy graph
+
+ inedges1_t m_inelc; //>Container fot in edges list
+ inedges_t m_inel; //>Policy graph, input edges list
+
+ std::vector< int > m_badvc;
+ badv_t m_badv; // Marks "bad" vertices
+
+ vcol_t m_colcv, m_col_bfs; // Color maps
+ vertex_t m_sink; // To convert any graph to "good"
+ };
+
+ /*! \class mcr_howard1
+ * \brief Finds optimum cycle raio and a critical cycle
+ */
+ template < typename FloatTraits, typename Graph, typename VertexIndexMap,
+ typename EdgeWeight1, typename EdgeWeight2 >
+ class mcr_howard1 : public mcr_howard< FloatTraits, Graph, VertexIndexMap,
+ EdgeWeight1, EdgeWeight2 >
+ {
+ public:
+ typedef mcr_howard< FloatTraits, Graph, VertexIndexMap, EdgeWeight1,
+ EdgeWeight2 >
+ inhr_t;
+ mcr_howard1(const Graph& g, VertexIndexMap vim, EdgeWeight1 ewm,
+ EdgeWeight2 ew2m)
+ : inhr_t(g, vim, ewm, ew2m)
+ {
+ }
+
+ void get_critical_cycle(typename inhr_t::critical_cycle_t& cc)
+ {
+ return cc.swap(m_cc);
+ }
+
+ protected:
+ void store_critical_edge(
+ typename inhr_t::edge_t ed, typename inhr_t::critical_cycle_t& cc)
+ {
+ cc.push_back(ed);
+ }
+
+ void store_critical_cycle(typename inhr_t::critical_cycle_t& cc)
+ {
+ m_cc.swap(cc);
+ }
+
+ private:
+ typename inhr_t::critical_cycle_t m_cc; // Critical cycle
+ };
+
+ /*!
+ * \param g a directed multigraph.
+ * \param vim Vertex Index Map. A map V->[0, num_vertices(g))
+ * \param ewm Edge weight1 map.
+ * \param ew2m Edge weight2 map.
+ * \param pcc pointer to the critical edges list.
+ * \return Optimum cycle ratio of g or FloatTraits::infinity() if g has no
+ * cycles.
+ */
+ template < typename FT, typename TG, typename TVIM, typename TEW1,
+ typename TEW2, typename EV >
+ typename FT::value_type optimum_cycle_ratio(
+ const TG& g, TVIM vim, TEW1 ewm, TEW2 ew2m, EV* pcc)
+ {
+ typedef typename graph_traits< TG >::directed_category DirCat;
+ BOOST_STATIC_ASSERT(
+ (is_convertible< DirCat*, directed_tag* >::value == true));
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< TG >));
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< TG >));
+ typedef typename graph_traits< TG >::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< TVIM, Vertex >));
+ typedef typename graph_traits< TG >::edge_descriptor Edge;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< TEW1, Edge >));
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< TEW2, Edge >));
+
+ if (pcc == 0)
+ {
+ return detail::mcr_howard< FT, TG, TVIM, TEW1, TEW2 >(
+ g, vim, ewm, ew2m)
+ .ocr_howard();
+ }
+
+ detail::mcr_howard1< FT, TG, TVIM, TEW1, TEW2 > obj(g, vim, ewm, ew2m);
+ double ocr = obj.ocr_howard();
+ obj.get_critical_cycle(*pcc);
+ return ocr;
+ }
+} // namespace detail
+
+// Algorithms
+// Maximum Cycle Ratio
+
+template < typename FloatTraits, typename Graph, typename VertexIndexMap,
+ typename EdgeWeight1Map, typename EdgeWeight2Map >
+inline typename FloatTraits::value_type maximum_cycle_ratio(const Graph& g,
+ VertexIndexMap vim, EdgeWeight1Map ew1m, EdgeWeight2Map ew2m,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0,
+ FloatTraits = FloatTraits())
+{
+ typedef detail::float_wrapper< FloatTraits,
+ detail::max_comparator_props< FloatTraits > >
+ Traits;
+ return detail::optimum_cycle_ratio< Traits >(g, vim, ew1m, ew2m, pcc);
+}
+
+template < typename Graph, typename VertexIndexMap, typename EdgeWeight1Map,
+ typename EdgeWeight2Map >
+inline double maximum_cycle_ratio(const Graph& g, VertexIndexMap vim,
+ EdgeWeight1Map ew1m, EdgeWeight2Map ew2m,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0)
+{
+ return maximum_cycle_ratio(g, vim, ew1m, ew2m, pcc, mcr_float<>());
+}
+
+// Minimum Cycle Ratio
+
+template < typename FloatTraits, typename Graph, typename VertexIndexMap,
+ typename EdgeWeight1Map, typename EdgeWeight2Map >
+typename FloatTraits::value_type minimum_cycle_ratio(const Graph& g,
+ VertexIndexMap vim, EdgeWeight1Map ew1m, EdgeWeight2Map ew2m,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0,
+ FloatTraits = FloatTraits())
+{
+ typedef detail::float_wrapper< FloatTraits,
+ detail::min_comparator_props< FloatTraits > >
+ Traits;
+ return detail::optimum_cycle_ratio< Traits >(g, vim, ew1m, ew2m, pcc);
+}
+
+template < typename Graph, typename VertexIndexMap, typename EdgeWeight1Map,
+ typename EdgeWeight2Map >
+inline double minimum_cycle_ratio(const Graph& g, VertexIndexMap vim,
+ EdgeWeight1Map ew1m, EdgeWeight2Map ew2m,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0)
+{
+ return minimum_cycle_ratio(g, vim, ew1m, ew2m, pcc, mcr_float<>());
+}
+
+// Maximum Cycle Mean
+
+template < typename FloatTraits, typename Graph, typename VertexIndexMap,
+ typename EdgeWeightMap, typename EdgeIndexMap >
+inline typename FloatTraits::value_type maximum_cycle_mean(const Graph& g,
+ VertexIndexMap vim, EdgeWeightMap ewm, EdgeIndexMap eim,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0,
+ FloatTraits ft = FloatTraits())
+{
+ typedef typename remove_const<
+ typename property_traits< EdgeWeightMap >::value_type >::type Weight;
+ typename std::vector< Weight > ed_w2(boost::num_edges(g), 1);
+ return maximum_cycle_ratio(
+ g, vim, ewm, make_iterator_property_map(ed_w2.begin(), eim), pcc, ft);
+}
+
+template < typename Graph, typename VertexIndexMap, typename EdgeWeightMap,
+ typename EdgeIndexMap >
+inline double maximum_cycle_mean(const Graph& g, VertexIndexMap vim,
+ EdgeWeightMap ewm, EdgeIndexMap eim,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0)
+{
+ return maximum_cycle_mean(g, vim, ewm, eim, pcc, mcr_float<>());
+}
+
+// Minimum Cycle Mean
+
+template < typename FloatTraits, typename Graph, typename VertexIndexMap,
+ typename EdgeWeightMap, typename EdgeIndexMap >
+inline typename FloatTraits::value_type minimum_cycle_mean(const Graph& g,
+ VertexIndexMap vim, EdgeWeightMap ewm, EdgeIndexMap eim,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0,
+ FloatTraits ft = FloatTraits())
+{
+ typedef typename remove_const<
+ typename property_traits< EdgeWeightMap >::value_type >::type Weight;
+ typename std::vector< Weight > ed_w2(boost::num_edges(g), 1);
+ return minimum_cycle_ratio(
+ g, vim, ewm, make_iterator_property_map(ed_w2.begin(), eim), pcc, ft);
+}
+
+template < typename Graph, typename VertexIndexMap, typename EdgeWeightMap,
+ typename EdgeIndexMap >
+inline double minimum_cycle_mean(const Graph& g, VertexIndexMap vim,
+ EdgeWeightMap ewm, EdgeIndexMap eim,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >* pcc = 0)
+{
+ return minimum_cycle_mean(g, vim, ewm, eim, pcc, mcr_float<>());
+}
+
+} // namespace boost
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/incremental_components.hpp b/contrib/restricted/boost/graph/include/boost/graph/incremental_components.hpp
new file mode 100644
index 0000000000..f16882e2a5
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/incremental_components.hpp
@@ -0,0 +1,234 @@
+//
+//=======================================================================
+// Copyright 1997-2001 University of Notre Dame.
+// Copyright 2009 Trustees of Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Michael Hansen
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+
+#ifndef BOOST_INCREMENTAL_COMPONENTS_HPP
+#define BOOST_INCREMENTAL_COMPONENTS_HPP
+
+#include <boost/tuple/tuple.hpp>
+#include <boost/graph/detail/incremental_components.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/pending/disjoint_sets.hpp>
+#include <iterator>
+
+namespace boost
+{
+
+// A connected component algorithm for the case when dynamically
+// adding (but not removing) edges is common. The
+// incremental_components() function is a preparing operation. Call
+// same_component to check whether two vertices are in the same
+// component, or use disjoint_set::find_set to determine the
+// representative for a vertex.
+
+// This version of connected components does not require a full
+// Graph. Instead, it just needs an edge list, where the vertices of
+// each edge need to be of integer type. The edges are assumed to
+// be undirected. The other difference is that the result is stored in
+// a container, instead of just a decorator. The container should be
+// empty before the algorithm is called. It will grow during the
+// course of the algorithm. The container must be a model of
+// BackInsertionSequence and RandomAccessContainer
+// (std::vector is a good choice). After running the algorithm the
+// index container will map each vertex to the representative
+// vertex of the component to which it belongs.
+//
+// Adapted from an implementation by Alex Stepanov. The disjoint
+// sets data structure is from Tarjan's "Data Structures and Network
+// Algorithms", and the application to connected components is
+// similar to the algorithm described in Ch. 22 of "Intro to
+// Algorithms" by Cormen, et. all.
+//
+
+// An implementation of disjoint sets can be found in
+// boost/pending/disjoint_sets.hpp
+
+template < class EdgeListGraph, class DisjointSets >
+void incremental_components(EdgeListGraph& g, DisjointSets& ds)
+{
+ typename graph_traits< EdgeListGraph >::edge_iterator e, end;
+ for (boost::tie(e, end) = edges(g); e != end; ++e)
+ ds.union_set(source(*e, g), target(*e, g));
+}
+
+template < class ParentIterator >
+void compress_components(ParentIterator first, ParentIterator last)
+{
+ for (ParentIterator current = first; current != last; ++current)
+ detail::find_representative_with_full_compression(
+ first, current - first);
+}
+
+template < class ParentIterator >
+typename std::iterator_traits< ParentIterator >::difference_type
+component_count(ParentIterator first, ParentIterator last)
+{
+ std::ptrdiff_t count = 0;
+ for (ParentIterator current = first; current != last; ++current)
+ if (*current == current - first)
+ ++count;
+ return count;
+}
+
+// This algorithm can be applied to the result container of the
+// connected_components algorithm to normalize
+// the components.
+template < class ParentIterator >
+void normalize_components(ParentIterator first, ParentIterator last)
+{
+ for (ParentIterator current = first; current != last; ++current)
+ detail::normalize_node(first, current - first);
+}
+
+template < class VertexListGraph, class DisjointSets >
+void initialize_incremental_components(VertexListGraph& G, DisjointSets& ds)
+{
+ typename graph_traits< VertexListGraph >::vertex_iterator v, vend;
+ for (boost::tie(v, vend) = vertices(G); v != vend; ++v)
+ ds.make_set(*v);
+}
+
+template < class Vertex, class DisjointSet >
+inline bool same_component(Vertex u, Vertex v, DisjointSet& ds)
+{
+ return ds.find_set(u) == ds.find_set(v);
+}
+
+// Class that builds a quick-access indexed linked list that allows
+// for fast iterating through a parent component's children.
+template < typename IndexType > class component_index
+{
+
+private:
+ typedef std::vector< IndexType > IndexContainer;
+
+public:
+ typedef counting_iterator< IndexType > iterator;
+ typedef iterator const_iterator;
+ typedef IndexType value_type;
+ typedef IndexType size_type;
+
+ typedef detail::component_index_iterator<
+ typename IndexContainer::iterator >
+ component_iterator;
+
+public:
+ template < typename ParentIterator, typename ElementIndexMap >
+ component_index(ParentIterator parent_start, ParentIterator parent_end,
+ const ElementIndexMap& index_map)
+ : m_num_elements(std::distance(parent_start, parent_end))
+ , m_components(make_shared< IndexContainer >())
+ , m_index_list(make_shared< IndexContainer >(m_num_elements))
+ {
+
+ build_index_lists(parent_start, index_map);
+
+ } // component_index
+
+ template < typename ParentIterator >
+ component_index(ParentIterator parent_start, ParentIterator parent_end)
+ : m_num_elements(std::distance(parent_start, parent_end))
+ , m_components(make_shared< IndexContainer >())
+ , m_index_list(make_shared< IndexContainer >(m_num_elements))
+ {
+
+ build_index_lists(parent_start, boost::identity_property_map());
+
+ } // component_index
+
+ // Returns the number of components
+ inline std::size_t size() const { return (m_components->size()); }
+
+ // Beginning iterator for component indices
+ iterator begin() const { return (iterator(0)); }
+
+ // End iterator for component indices
+ iterator end() const { return (iterator(this->size())); }
+
+ // Returns a pair of begin and end iterators for the child
+ // elements of component [component_index].
+ std::pair< component_iterator, component_iterator > operator[](
+ IndexType component_index) const
+ {
+
+ IndexType first_index = (*m_components)[component_index];
+
+ return (std::make_pair(
+ component_iterator(m_index_list->begin(), first_index),
+ component_iterator(m_num_elements)));
+ }
+
+private:
+ template < typename ParentIterator, typename ElementIndexMap >
+ void build_index_lists(
+ ParentIterator parent_start, const ElementIndexMap& index_map)
+ {
+
+ typedef
+ typename std::iterator_traits< ParentIterator >::value_type Element;
+ typename IndexContainer::iterator index_list = m_index_list->begin();
+
+ // First pass - find root elements, construct index list
+ for (IndexType element_index = 0; element_index < m_num_elements;
+ ++element_index)
+ {
+
+ Element parent_element = parent_start[element_index];
+ IndexType parent_index = get(index_map, parent_element);
+
+ if (element_index != parent_index)
+ {
+ index_list[element_index] = parent_index;
+ }
+ else
+ {
+ m_components->push_back(element_index);
+
+ // m_num_elements is the linked list terminator
+ index_list[element_index] = m_num_elements;
+ }
+ }
+
+ // Second pass - build linked list
+ for (IndexType element_index = 0; element_index < m_num_elements;
+ ++element_index)
+ {
+
+ Element parent_element = parent_start[element_index];
+ IndexType parent_index = get(index_map, parent_element);
+
+ if (element_index != parent_index)
+ {
+
+ // Follow list until a component parent is found
+ while (index_list[parent_index] != m_num_elements)
+ {
+ parent_index = index_list[parent_index];
+ }
+
+ // Push element to the front of the linked list
+ index_list[element_index] = index_list[parent_index];
+ index_list[parent_index] = element_index;
+ }
+ }
+
+ } // build_index_lists
+
+protected:
+ IndexType m_num_elements;
+ shared_ptr< IndexContainer > m_components, m_index_list;
+
+}; // class component_index
+
+} // namespace boost
+
+#endif // BOOST_INCREMENTAL_COMPONENTS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/is_kuratowski_subgraph.hpp b/contrib/restricted/boost/graph/include/boost/graph/is_kuratowski_subgraph.hpp
new file mode 100644
index 0000000000..1624a96462
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/is_kuratowski_subgraph.hpp
@@ -0,0 +1,295 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef __IS_KURATOWSKI_SUBGRAPH_HPP__
+#define __IS_KURATOWSKI_SUBGRAPH_HPP__
+
+#include <boost/config.hpp>
+#include <boost/tuple/tuple.hpp> //for tie
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/isomorphism.hpp>
+#include <boost/graph/adjacency_list.hpp>
+
+#include <algorithm>
+#include <vector>
+#include <set>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < typename Graph > Graph make_K_5()
+ {
+ typename graph_traits< Graph >::vertex_iterator vi, vi_end, inner_vi;
+ Graph K_5(5);
+ for (boost::tie(vi, vi_end) = vertices(K_5); vi != vi_end; ++vi)
+ for (inner_vi = next(vi); inner_vi != vi_end; ++inner_vi)
+ add_edge(*vi, *inner_vi, K_5);
+ return K_5;
+ }
+
+ template < typename Graph > Graph make_K_3_3()
+ {
+ typename graph_traits< Graph >::vertex_iterator vi, vi_end,
+ bipartition_start, inner_vi;
+ Graph K_3_3(6);
+ bipartition_start = next(next(next(vertices(K_3_3).first)));
+ for (boost::tie(vi, vi_end) = vertices(K_3_3); vi != bipartition_start;
+ ++vi)
+ for (inner_vi = bipartition_start; inner_vi != vi_end; ++inner_vi)
+ add_edge(*vi, *inner_vi, K_3_3);
+ return K_3_3;
+ }
+
+ template < typename AdjacencyList, typename Vertex >
+ void contract_edge(AdjacencyList& neighbors, Vertex u, Vertex v)
+ {
+ // Remove u from v's neighbor list
+ neighbors[v].erase(
+ std::remove(neighbors[v].begin(), neighbors[v].end(), u),
+ neighbors[v].end());
+
+ // Replace any references to u with references to v
+ typedef
+ typename AdjacencyList::value_type::iterator adjacency_iterator_t;
+
+ adjacency_iterator_t u_neighbor_end = neighbors[u].end();
+ for (adjacency_iterator_t u_neighbor_itr = neighbors[u].begin();
+ u_neighbor_itr != u_neighbor_end; ++u_neighbor_itr)
+ {
+ Vertex u_neighbor(*u_neighbor_itr);
+ std::replace(neighbors[u_neighbor].begin(),
+ neighbors[u_neighbor].end(), u, v);
+ }
+
+ // Remove v from u's neighbor list
+ neighbors[u].erase(
+ std::remove(neighbors[u].begin(), neighbors[u].end(), v),
+ neighbors[u].end());
+
+ // Add everything in u's neighbor list to v's neighbor list
+ std::copy(neighbors[u].begin(), neighbors[u].end(),
+ std::back_inserter(neighbors[v]));
+
+ // Clear u's neighbor list
+ neighbors[u].clear();
+ }
+
+ enum target_graph_t
+ {
+ tg_k_3_3,
+ tg_k_5
+ };
+
+} // namespace detail
+
+template < typename Graph, typename ForwardIterator, typename VertexIndexMap >
+bool is_kuratowski_subgraph(const Graph& g, ForwardIterator begin,
+ ForwardIterator end, VertexIndexMap vm)
+{
+
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef typename graph_traits< Graph >::edges_size_type e_size_t;
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+ typedef typename std::vector< vertex_t > v_list_t;
+ typedef typename v_list_t::iterator v_list_iterator_t;
+ typedef iterator_property_map< typename std::vector< v_list_t >::iterator,
+ VertexIndexMap >
+ vertex_to_v_list_map_t;
+
+ typedef adjacency_list< vecS, vecS, undirectedS > small_graph_t;
+
+ detail::target_graph_t target_graph
+ = detail::tg_k_3_3; // unless we decide otherwise later
+
+ static small_graph_t K_5(detail::make_K_5< small_graph_t >());
+
+ static small_graph_t K_3_3(detail::make_K_3_3< small_graph_t >());
+
+ v_size_t n_vertices(num_vertices(g));
+ v_size_t max_num_edges(3 * n_vertices - 5);
+
+ std::vector< v_list_t > neighbors_vector(n_vertices);
+ vertex_to_v_list_map_t neighbors(neighbors_vector.begin(), vm);
+
+ e_size_t count = 0;
+ for (ForwardIterator itr = begin; itr != end; ++itr)
+ {
+
+ if (count++ > max_num_edges)
+ return false;
+
+ edge_t e(*itr);
+ vertex_t u(source(e, g));
+ vertex_t v(target(e, g));
+
+ neighbors[u].push_back(v);
+ neighbors[v].push_back(u);
+ }
+
+ for (v_size_t max_size = 2; max_size < 5; ++max_size)
+ {
+
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+
+ // a hack to make sure we don't contract the middle edge of a path
+ // of four degree-3 vertices
+ if (max_size == 4 && neighbors[v].size() == 3)
+ {
+ if (neighbors[neighbors[v][0]].size()
+ + neighbors[neighbors[v][1]].size()
+ + neighbors[neighbors[v][2]].size()
+ < 11 // so, it has two degree-3 neighbors
+ )
+ continue;
+ }
+
+ while (neighbors[v].size() > 0 && neighbors[v].size() < max_size)
+ {
+ // Find one of v's neighbors u such that v and u
+ // have no neighbors in common. We'll look for such a
+ // neighbor with a naive cubic-time algorithm since the
+ // max size of any of the neighbor sets we'll consider
+ // merging is 3
+
+ bool neighbor_sets_intersect = false;
+
+ vertex_t min_u = graph_traits< Graph >::null_vertex();
+ vertex_t u;
+ v_list_iterator_t v_neighbor_end = neighbors[v].end();
+ for (v_list_iterator_t v_neighbor_itr = neighbors[v].begin();
+ v_neighbor_itr != v_neighbor_end; ++v_neighbor_itr)
+ {
+ neighbor_sets_intersect = false;
+ u = *v_neighbor_itr;
+ v_list_iterator_t u_neighbor_end = neighbors[u].end();
+ for (v_list_iterator_t u_neighbor_itr
+ = neighbors[u].begin();
+ u_neighbor_itr != u_neighbor_end
+ && !neighbor_sets_intersect;
+ ++u_neighbor_itr)
+ {
+ for (v_list_iterator_t inner_v_neighbor_itr
+ = neighbors[v].begin();
+ inner_v_neighbor_itr != v_neighbor_end;
+ ++inner_v_neighbor_itr)
+ {
+ if (*u_neighbor_itr == *inner_v_neighbor_itr)
+ {
+ neighbor_sets_intersect = true;
+ break;
+ }
+ }
+ }
+ if (!neighbor_sets_intersect
+ && (min_u == graph_traits< Graph >::null_vertex()
+ || neighbors[u].size() < neighbors[min_u].size()))
+ {
+ min_u = u;
+ }
+ }
+
+ if (min_u == graph_traits< Graph >::null_vertex())
+ // Exited the loop without finding an appropriate neighbor
+ // of v, so v must be a lost cause. Move on to other
+ // vertices.
+ break;
+ else
+ u = min_u;
+
+ detail::contract_edge(neighbors, u, v);
+
+ } // end iteration over v's neighbors
+
+ } // end iteration through vertices v
+
+ if (max_size == 3)
+ {
+ // check to see whether we should go on to find a K_5
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ if (neighbors[*vi].size() == 4)
+ {
+ target_graph = detail::tg_k_5;
+ break;
+ }
+
+ if (target_graph == detail::tg_k_3_3)
+ break;
+ }
+
+ } // end iteration through max degree 2,3, and 4
+
+ // Now, there should only be 5 or 6 vertices with any neighbors. Find them.
+
+ v_list_t main_vertices;
+ vertex_iterator_t vi, vi_end;
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ if (!neighbors[*vi].empty())
+ main_vertices.push_back(*vi);
+ }
+
+ // create a graph isomorphic to the contracted graph to test
+ // against K_5 and K_3_3
+ small_graph_t contracted_graph(main_vertices.size());
+ std::map< vertex_t,
+ typename graph_traits< small_graph_t >::vertex_descriptor >
+ contracted_vertex_map;
+
+ typename v_list_t::iterator itr, itr_end;
+ itr_end = main_vertices.end();
+ typename graph_traits< small_graph_t >::vertex_iterator si
+ = vertices(contracted_graph).first;
+
+ for (itr = main_vertices.begin(); itr != itr_end; ++itr, ++si)
+ {
+ contracted_vertex_map[*itr] = *si;
+ }
+
+ typename v_list_t::iterator jtr, jtr_end;
+ for (itr = main_vertices.begin(); itr != itr_end; ++itr)
+ {
+ jtr_end = neighbors[*itr].end();
+ for (jtr = neighbors[*itr].begin(); jtr != jtr_end; ++jtr)
+ {
+ if (get(vm, *itr) < get(vm, *jtr))
+ {
+ add_edge(contracted_vertex_map[*itr],
+ contracted_vertex_map[*jtr], contracted_graph);
+ }
+ }
+ }
+
+ if (target_graph == detail::tg_k_5)
+ {
+ return boost::isomorphism(K_5, contracted_graph);
+ }
+ else // target_graph == tg_k_3_3
+ {
+ return boost::isomorphism(K_3_3, contracted_graph);
+ }
+}
+
+template < typename Graph, typename ForwardIterator >
+bool is_kuratowski_subgraph(
+ const Graph& g, ForwardIterator begin, ForwardIterator end)
+{
+ return is_kuratowski_subgraph(g, begin, end, get(vertex_index, g));
+}
+
+}
+
+#endif //__IS_KURATOWSKI_SUBGRAPH_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/is_straight_line_drawing.hpp b/contrib/restricted/boost/graph/include/boost/graph/is_straight_line_drawing.hpp
new file mode 100644
index 0000000000..013f4b400a
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/is_straight_line_drawing.hpp
@@ -0,0 +1,209 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef __IS_STRAIGHT_LINE_DRAWING_HPP__
+#define __IS_STRAIGHT_LINE_DRAWING_HPP__
+
+#include <boost/config.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/planar_detail/bucket_sort.hpp>
+
+#include <algorithm>
+#include <vector>
+#include <set>
+#include <map>
+
+namespace boost
+{
+
+// Return true exactly when the line segments s1 = ((x1,y1), (x2,y2)) and
+// s2 = ((a1,b1), (a2,b2)) intersect in a point other than the endpoints of
+// the line segments. The one exception to this rule is when s1 = s2, in
+// which case false is returned - this is to accomodate multiple edges
+// between the same pair of vertices, which shouldn't invalidate the straight
+// line embedding. A tolerance variable epsilon can also be used, which
+// defines how far away from the endpoints of s1 and s2 we want to consider
+// an intersection.
+
+inline bool intersects(double x1, double y1, double x2, double y2, double a1,
+ double b1, double a2, double b2, double epsilon = 0.000001)
+{
+
+ if (x1 - x2 == 0)
+ {
+ std::swap(x1, a1);
+ std::swap(y1, b1);
+ std::swap(x2, a2);
+ std::swap(y2, b2);
+ }
+
+ if (x1 - x2 == 0)
+ {
+ BOOST_USING_STD_MAX();
+ BOOST_USING_STD_MIN();
+
+ // two vertical line segments
+ double min_y = min BOOST_PREVENT_MACRO_SUBSTITUTION(y1, y2);
+ double max_y = max BOOST_PREVENT_MACRO_SUBSTITUTION(y1, y2);
+ double min_b = min BOOST_PREVENT_MACRO_SUBSTITUTION(b1, b2);
+ double max_b = max BOOST_PREVENT_MACRO_SUBSTITUTION(b1, b2);
+ if ((max_y > max_b && max_b > min_y)
+ || (max_b > max_y && max_y > min_b))
+ return true;
+ else
+ return false;
+ }
+
+ double x_diff = x1 - x2;
+ double y_diff = y1 - y2;
+ double a_diff = a2 - a1;
+ double b_diff = b2 - b1;
+
+ double beta_denominator = b_diff - (y_diff / ((double)x_diff)) * a_diff;
+
+ if (beta_denominator == 0)
+ {
+ // parallel lines
+ return false;
+ }
+
+ double beta = (b2 - y2 - (y_diff / ((double)x_diff)) * (a2 - x2))
+ / beta_denominator;
+ double alpha = (a2 - x2 - beta * (a_diff)) / x_diff;
+
+ double upper_bound = 1 - epsilon;
+ double lower_bound = 0 + epsilon;
+
+ return (beta < upper_bound && beta > lower_bound && alpha < upper_bound
+ && alpha > lower_bound);
+}
+
+template < typename Graph, typename GridPositionMap, typename VertexIndexMap >
+bool is_straight_line_drawing(
+ const Graph& g, GridPositionMap drawing, VertexIndexMap)
+{
+
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+
+ typedef std::size_t x_coord_t;
+ typedef std::size_t y_coord_t;
+ typedef boost::tuple< edge_t, x_coord_t, y_coord_t > edge_event_t;
+ typedef typename std::vector< edge_event_t > edge_event_queue_t;
+
+ typedef tuple< y_coord_t, y_coord_t, x_coord_t, x_coord_t >
+ active_map_key_t;
+ typedef edge_t active_map_value_t;
+ typedef std::map< active_map_key_t, active_map_value_t > active_map_t;
+ typedef typename active_map_t::iterator active_map_iterator_t;
+
+ edge_event_queue_t edge_event_queue;
+ active_map_t active_edges;
+
+ edge_iterator_t ei, ei_end;
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ vertex_t s(source(e, g));
+ vertex_t t(target(e, g));
+ edge_event_queue.push_back(
+ make_tuple(e, static_cast< std::size_t >(drawing[s].x),
+ static_cast< std::size_t >(drawing[s].y)));
+ edge_event_queue.push_back(
+ make_tuple(e, static_cast< std::size_t >(drawing[t].x),
+ static_cast< std::size_t >(drawing[t].y)));
+ }
+
+ // Order by edge_event_queue by first, then second coordinate
+ // (bucket_sort is a stable sort.)
+ bucket_sort(edge_event_queue.begin(), edge_event_queue.end(),
+ property_map_tuple_adaptor< edge_event_t, 2 >());
+
+ bucket_sort(edge_event_queue.begin(), edge_event_queue.end(),
+ property_map_tuple_adaptor< edge_event_t, 1 >());
+
+ typedef typename edge_event_queue_t::iterator event_queue_iterator_t;
+ event_queue_iterator_t itr_end = edge_event_queue.end();
+ for (event_queue_iterator_t itr = edge_event_queue.begin(); itr != itr_end;
+ ++itr)
+ {
+ edge_t e(get< 0 >(*itr));
+ vertex_t source_v(source(e, g));
+ vertex_t target_v(target(e, g));
+ if (drawing[source_v].y > drawing[target_v].y)
+ std::swap(source_v, target_v);
+
+ active_map_key_t key(get(drawing, source_v).y, get(drawing, target_v).y,
+ get(drawing, source_v).x, get(drawing, target_v).x);
+
+ active_map_iterator_t a_itr = active_edges.find(key);
+ if (a_itr == active_edges.end())
+ {
+ active_edges[key] = e;
+ }
+ else
+ {
+ active_map_iterator_t before, after;
+ if (a_itr == active_edges.begin())
+ before = active_edges.end();
+ else
+ before = prior(a_itr);
+ after = boost::next(a_itr);
+
+ if (before != active_edges.end())
+ {
+
+ edge_t f = before->second;
+ vertex_t e_source(source(e, g));
+ vertex_t e_target(target(e, g));
+ vertex_t f_source(source(f, g));
+ vertex_t f_target(target(f, g));
+
+ if (intersects(drawing[e_source].x, drawing[e_source].y,
+ drawing[e_target].x, drawing[e_target].y,
+ drawing[f_source].x, drawing[f_source].y,
+ drawing[f_target].x, drawing[f_target].y))
+ return false;
+ }
+
+ if (after != active_edges.end())
+ {
+
+ edge_t f = after->second;
+ vertex_t e_source(source(e, g));
+ vertex_t e_target(target(e, g));
+ vertex_t f_source(source(f, g));
+ vertex_t f_target(target(f, g));
+
+ if (intersects(drawing[e_source].x, drawing[e_source].y,
+ drawing[e_target].x, drawing[e_target].y,
+ drawing[f_source].x, drawing[f_source].y,
+ drawing[f_target].x, drawing[f_target].y))
+ return false;
+ }
+
+ active_edges.erase(a_itr);
+ }
+ }
+
+ return true;
+}
+
+template < typename Graph, typename GridPositionMap >
+bool is_straight_line_drawing(const Graph& g, GridPositionMap drawing)
+{
+ return is_straight_line_drawing(g, drawing, get(vertex_index, g));
+}
+
+}
+
+#endif // __IS_STRAIGHT_LINE_DRAWING_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/isomorphism.hpp b/contrib/restricted/boost/graph/include/boost/graph/isomorphism.hpp
new file mode 100644
index 0000000000..5a7d31ddc6
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/isomorphism.hpp
@@ -0,0 +1,781 @@
+// Copyright (C) 2001 Jeremy Siek, Douglas Gregor, Brian Osman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_GRAPH_ISOMORPHISM_HPP
+#define BOOST_GRAPH_ISOMORPHISM_HPP
+
+#include <utility>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/smart_ptr.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/detail/algorithm.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/unordered/unordered_flat_map.hpp>
+#include <boost/pending/indirect_cmp.hpp> // for make_indirect_pmap
+#include <boost/concept/assert.hpp>
+
+#ifndef BOOST_GRAPH_ITERATION_MACROS_HPP
+#define BOOST_ISO_INCLUDED_ITER_MACROS // local macro, see bottom of file
+#include <boost/graph/iteration_macros.hpp>
+#endif
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < typename Graph1, typename Graph2, typename IsoMapping,
+ typename Invariant1, typename Invariant2, typename IndexMap1,
+ typename IndexMap2, typename InvariantCountMap = boost::unordered_flat_map<typename Invariant1::result_type, typename graph_traits< Graph1 >::vertices_size_type > >
+ class isomorphism_algo
+ {
+ typedef typename graph_traits< Graph1 >::vertex_descriptor vertex1_t;
+ typedef typename graph_traits< Graph2 >::vertex_descriptor vertex2_t;
+ typedef typename graph_traits< Graph1 >::edge_descriptor edge1_t;
+ typedef typename graph_traits< Graph1 >::vertices_size_type size_type;
+ typedef typename Invariant1::result_type invariant_t;
+
+ const Graph1& G1;
+ const Graph2& G2;
+ IsoMapping f;
+ Invariant1 invariant1;
+ Invariant2 invariant2;
+ IndexMap1 index_map1;
+ IndexMap2 index_map2;
+
+ std::vector< vertex1_t > dfs_vertices;
+ typedef typename std::vector< vertex1_t >::iterator vertex_iter;
+ std::vector< int > dfs_num_vec;
+ typedef safe_iterator_property_map<
+ typename std::vector< int >::iterator, IndexMap1
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ ,
+ int, int&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ >
+ DFSNumMap;
+ DFSNumMap dfs_num;
+ std::vector< edge1_t > ordered_edges;
+ typedef typename std::vector< edge1_t >::iterator edge_iter;
+
+ std::vector< char > in_S_vec;
+ typedef safe_iterator_property_map<
+ typename std::vector< char >::iterator, IndexMap2
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ ,
+ char, char&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ >
+ InSMap;
+ InSMap in_S;
+
+ int num_edges_on_k;
+
+ friend struct compare_multiplicity;
+ struct compare_multiplicity
+ {
+ compare_multiplicity(Invariant1 invariant1, const InvariantCountMap& multiplicity)
+ : invariant1(invariant1), multiplicity(&multiplicity)
+ {
+ }
+ bool operator()(const vertex1_t& x, const vertex1_t& y) const
+ {
+ auto x_multiplicity_iter = multiplicity->find(invariant1(x));
+ assert(x_multiplicity_iter != multiplicity->end());
+ auto y_multiplicity_iter = multiplicity->find(invariant1(y));
+ assert(y_multiplicity_iter != multiplicity->end());
+ return *x_multiplicity_iter < *y_multiplicity_iter;
+ }
+ Invariant1 invariant1;
+ const InvariantCountMap* multiplicity;
+ };
+
+ struct record_dfs_order : default_dfs_visitor
+ {
+ record_dfs_order(
+ std::vector< vertex1_t >& v, std::vector< edge1_t >& e)
+ : vertices(v), edges(e)
+ {
+ }
+
+ void discover_vertex(vertex1_t v, const Graph1&) const
+ {
+ vertices.push_back(v);
+ }
+ void examine_edge(edge1_t e, const Graph1&) const
+ {
+ edges.push_back(e);
+ }
+ std::vector< vertex1_t >& vertices;
+ std::vector< edge1_t >& edges;
+ };
+
+ struct edge_cmp
+ {
+ edge_cmp(const Graph1& G1, DFSNumMap dfs_num)
+ : G1(G1), dfs_num(dfs_num)
+ {
+ }
+ bool operator()(const edge1_t& e1, const edge1_t& e2) const
+ {
+ using namespace std;
+ int u1 = dfs_num[source(e1, G1)], v1 = dfs_num[target(e1, G1)];
+ int u2 = dfs_num[source(e2, G1)], v2 = dfs_num[target(e2, G1)];
+ int m1 = (max)(u1, v1);
+ int m2 = (max)(u2, v2);
+ // lexicographical comparison
+ return std::make_pair(m1, std::make_pair(u1, v1))
+ < std::make_pair(m2, std::make_pair(u2, v2));
+ }
+ const Graph1& G1;
+ DFSNumMap dfs_num;
+ };
+
+ public:
+ isomorphism_algo(const Graph1& G1, const Graph2& G2, IsoMapping f,
+ Invariant1 invariant1, Invariant2 invariant2,
+ std::size_t /* max_invariant */, IndexMap1 index_map1,
+ IndexMap2 index_map2)
+ : G1(G1)
+ , G2(G2)
+ , f(f)
+ , invariant1(invariant1)
+ , invariant2(invariant2)
+ , index_map1(index_map1)
+ , index_map2(index_map2)
+ {
+ in_S_vec.resize(num_vertices(G1));
+ in_S = make_safe_iterator_property_map(
+ in_S_vec.begin(), in_S_vec.size(), index_map2
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ ,
+ in_S_vec.front()
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ );
+ }
+
+ // Generates map of invariant multiplicity from sorted invariants
+ template<typename ForwardIterator>
+ InvariantCountMap multiplicities(ForwardIterator first, const ForwardIterator last)
+ {
+ typedef typename InvariantCountMap::iterator invar_map_iter;
+
+ assert(std::is_sorted(first, last));
+ InvariantCountMap invar_multiplicity;
+
+ if(first == last)
+ return invar_multiplicity;
+
+ invariant_t invar = *first;
+ invar_map_iter inserted = invar_multiplicity.emplace(invar, 1).first;
+ ++first;
+ for(; first != last; ++first)
+ {
+ if(*first == invar)
+ {
+ inserted->second += 1;
+ }
+ else
+ {
+ invar = *first;
+ inserted = invar_multiplicity.emplace(invar, 1).first;
+ }
+ }
+
+ return invar_multiplicity;
+ }
+
+ bool test_isomorphism()
+ {
+ // reset isomapping
+ BGL_FORALL_VERTICES_T(v, G1, Graph1)
+ f[v] = graph_traits< Graph2 >::null_vertex();
+
+ // Calculate all invariants of G1 and G2, sort and compare
+ std::vector< invariant_t > invar1_array;
+ invar1_array.reserve(num_vertices(G1));
+ BGL_FORALL_VERTICES_T(v, G1, Graph1)
+ invar1_array.push_back(invariant1(v));
+ sort(invar1_array);
+
+ std::vector< invariant_t > invar2_array;
+ invar2_array.reserve(num_vertices(G2));
+ BGL_FORALL_VERTICES_T(v, G2, Graph2)
+ invar2_array.push_back(invariant2(v));
+ sort(invar2_array);
+ if (!equal(invar1_array, invar2_array))
+ return false;
+
+ // Sort vertices by the multiplicity of their invariants
+ std::vector< vertex1_t > V_mult;
+ BGL_FORALL_VERTICES_T(v, G1, Graph1)
+ V_mult.push_back(v);
+ sort(V_mult, compare_multiplicity(invariant1, multiplicities(invar1_array.begin(), invar1_array.end())));
+
+ std::vector< default_color_type > color_vec(num_vertices(G1));
+ safe_iterator_property_map<
+ std::vector< default_color_type >::iterator, IndexMap1
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ ,
+ default_color_type, default_color_type&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ >
+ color_map(color_vec.begin(), color_vec.size(), index_map1);
+ record_dfs_order dfs_visitor(dfs_vertices, ordered_edges);
+ typedef color_traits< default_color_type > Color;
+ for (vertex_iter u = V_mult.begin(); u != V_mult.end(); ++u)
+ {
+ if (color_map[*u] == Color::white())
+ {
+ dfs_visitor.start_vertex(*u, G1);
+ depth_first_visit(G1, *u, dfs_visitor, color_map);
+ }
+ }
+ // Create the dfs_num array and dfs_num_map
+ dfs_num_vec.resize(num_vertices(G1));
+ dfs_num = make_safe_iterator_property_map(
+ dfs_num_vec.begin(), dfs_num_vec.size(), index_map1
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ ,
+ dfs_num_vec.front()
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ );
+ size_type n = 0;
+ for (vertex_iter v = dfs_vertices.begin(); v != dfs_vertices.end();
+ ++v)
+ dfs_num[*v] = n++;
+
+ sort(ordered_edges, edge_cmp(G1, dfs_num));
+
+ int dfs_num_k = -1;
+ return this->match(ordered_edges.begin(), dfs_num_k);
+ }
+
+ private:
+ struct match_continuation
+ {
+ enum
+ {
+ pos_G2_vertex_loop,
+ pos_fi_adj_loop,
+ pos_dfs_num
+ } position;
+ typedef typename graph_traits< Graph2 >::vertex_iterator
+ vertex_iterator;
+ std::pair< vertex_iterator, vertex_iterator > G2_verts;
+ typedef typename graph_traits< Graph2 >::adjacency_iterator
+ adjacency_iterator;
+ std::pair< adjacency_iterator, adjacency_iterator > fi_adj;
+ edge_iter iter;
+ int dfs_num_k;
+ };
+
+ bool match(edge_iter iter, int dfs_num_k)
+ {
+ std::vector< match_continuation > k;
+ typedef typename graph_traits< Graph2 >::vertex_iterator
+ vertex_iterator;
+ std::pair< vertex_iterator, vertex_iterator > G2_verts(
+ vertices(G2));
+ typedef typename graph_traits< Graph2 >::adjacency_iterator
+ adjacency_iterator;
+ std::pair< adjacency_iterator, adjacency_iterator > fi_adj;
+ vertex1_t i, j;
+
+ recur:
+ if (iter != ordered_edges.end())
+ {
+ i = source(*iter, G1);
+ j = target(*iter, G1);
+ if (dfs_num[i] > dfs_num_k)
+ {
+ G2_verts = vertices(G2);
+ while (G2_verts.first != G2_verts.second)
+ {
+ {
+ vertex2_t u = *G2_verts.first;
+ vertex1_t kp1 = dfs_vertices[dfs_num_k + 1];
+ if (invariant1(kp1) == invariant2(u)
+ && in_S[u] == false)
+ {
+ {
+ f[kp1] = u;
+ in_S[u] = true;
+ num_edges_on_k = 0;
+
+ match_continuation new_k;
+ new_k.position = match_continuation::
+ pos_G2_vertex_loop;
+ new_k.G2_verts = G2_verts;
+ new_k.iter = iter;
+ new_k.dfs_num_k = dfs_num_k;
+ k.push_back(new_k);
+ ++dfs_num_k;
+ goto recur;
+ }
+ }
+ }
+ G2_loop_k:
+ ++G2_verts.first;
+ }
+ }
+ else if (dfs_num[j] > dfs_num_k)
+ {
+ {
+ vertex1_t vk = dfs_vertices[dfs_num_k];
+ num_edges_on_k -= count_if(adjacent_vertices(f[vk], G2),
+ make_indirect_pmap(in_S));
+
+ for (int jj = 0; jj < dfs_num_k; ++jj)
+ {
+ vertex1_t j = dfs_vertices[jj];
+ num_edges_on_k
+ -= count(adjacent_vertices(f[j], G2), f[vk]);
+ }
+ }
+
+ if (num_edges_on_k != 0)
+ goto return_point_false;
+ fi_adj = adjacent_vertices(f[i], G2);
+ while (fi_adj.first != fi_adj.second)
+ {
+ {
+ vertex2_t v = *fi_adj.first;
+ if (invariant2(v) == invariant1(j)
+ && in_S[v] == false)
+ {
+ f[j] = v;
+ in_S[v] = true;
+ num_edges_on_k = 1;
+ BOOST_USING_STD_MAX();
+ int next_k
+ = max BOOST_PREVENT_MACRO_SUBSTITUTION(
+ dfs_num_k,
+ max BOOST_PREVENT_MACRO_SUBSTITUTION(
+ dfs_num[i], dfs_num[j]));
+ match_continuation new_k;
+ new_k.position
+ = match_continuation::pos_fi_adj_loop;
+ new_k.fi_adj = fi_adj;
+ new_k.iter = iter;
+ new_k.dfs_num_k = dfs_num_k;
+ ++iter;
+ dfs_num_k = next_k;
+ k.push_back(new_k);
+ goto recur;
+ }
+ }
+ fi_adj_loop_k:
+ ++fi_adj.first;
+ }
+ }
+ else
+ {
+ if (container_contains(adjacent_vertices(f[i], G2), f[j]))
+ {
+ ++num_edges_on_k;
+ match_continuation new_k;
+ new_k.position = match_continuation::pos_dfs_num;
+ k.push_back(new_k);
+ ++iter;
+ goto recur;
+ }
+ }
+ }
+ else
+ goto return_point_true;
+ goto return_point_false;
+
+ {
+ return_point_true:
+ // At this point, there may still be null vertices in the
+ // mapping for disconnected vertices
+ map_disconnected_vertices();
+ return true;
+
+ return_point_false:
+ if (k.empty())
+ return false;
+ const match_continuation& this_k = k.back();
+ switch (this_k.position)
+ {
+ case match_continuation::pos_G2_vertex_loop:
+ {
+ G2_verts = this_k.G2_verts;
+ iter = this_k.iter;
+ dfs_num_k = this_k.dfs_num_k;
+ k.pop_back();
+ in_S[*G2_verts.first] = false;
+ i = source(*iter, G1);
+ j = target(*iter, G1);
+ goto G2_loop_k;
+ }
+ case match_continuation::pos_fi_adj_loop:
+ {
+ fi_adj = this_k.fi_adj;
+ iter = this_k.iter;
+ dfs_num_k = this_k.dfs_num_k;
+ k.pop_back();
+ in_S[*fi_adj.first] = false;
+ i = source(*iter, G1);
+ j = target(*iter, G1);
+ goto fi_adj_loop_k;
+ }
+ case match_continuation::pos_dfs_num:
+ {
+ k.pop_back();
+ goto return_point_false;
+ }
+ default:
+ {
+ BOOST_ASSERT(!"Bad position");
+#ifdef UNDER_CE
+ exit(-1);
+#else
+ abort();
+#endif
+ }
+ }
+ }
+ }
+
+ void map_disconnected_vertices()
+ {
+ std::vector< vertex1_t > unmatched_g1_vertices;
+ BGL_FORALL_VERTICES_T(v, G1, Graph1)
+ {
+ if(f[v] == graph_traits< Graph2 >::null_vertex()) {
+ unmatched_g1_vertices.push_back(v);
+ }
+ }
+
+ if(!unmatched_g1_vertices.empty())
+ {
+ typedef unordered_multimap< invariant_t, vertex2_t > g2_invariant_vertex_multimap;
+ typedef typename g2_invariant_vertex_multimap::iterator multimap_iter;
+ g2_invariant_vertex_multimap unmatched_invariants;
+ BGL_FORALL_VERTICES_T(v, G2, Graph2)
+ {
+ if(!in_S[v])
+ {
+ unmatched_invariants.emplace(invariant2(v), v);
+ }
+ }
+
+ typedef typename std::vector< vertex1_t >::iterator v1_iter;
+ const v1_iter end = unmatched_g1_vertices.end();
+ for(v1_iter iter = unmatched_g1_vertices.begin(); iter != end; ++iter)
+ {
+ invariant_t unmatched_g1_vertex_invariant = invariant1(*iter);
+ multimap_iter matching_invariant = unmatched_invariants.find(unmatched_g1_vertex_invariant);
+ BOOST_ASSERT(matching_invariant != unmatched_invariants.end());
+ f[*iter] = matching_invariant->second;
+ unmatched_invariants.erase(matching_invariant);
+ }
+ }
+ }
+ };
+
+ template < typename Graph, typename InDegreeMap >
+ void compute_in_degree(const Graph& g, InDegreeMap in_degree_map)
+ {
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ put(in_degree_map, v, 0);
+
+ BGL_FORALL_VERTICES_T(u, g, Graph)
+ BGL_FORALL_ADJ_T(u, v, g, Graph)
+ put(in_degree_map, v, get(in_degree_map, v) + 1);
+ }
+
+} // namespace detail
+
+template < typename InDegreeMap, typename Graph > class degree_vertex_invariant
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::degree_size_type size_type;
+
+public:
+ typedef vertex_t argument_type;
+ typedef size_type result_type;
+
+ degree_vertex_invariant(const InDegreeMap& in_degree_map, const Graph& g)
+ : m_in_degree_map(in_degree_map)
+ , m_max_vertex_in_degree(0)
+ , m_max_vertex_out_degree(0)
+ , m_g(g)
+ {
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ m_max_vertex_in_degree
+ = (std::max)(m_max_vertex_in_degree, get(m_in_degree_map, v));
+ m_max_vertex_out_degree
+ = (std::max)(m_max_vertex_out_degree, out_degree(v, g));
+ }
+ }
+
+ size_type operator()(vertex_t v) const
+ {
+ return (m_max_vertex_in_degree + 1) * out_degree(v, m_g)
+ + get(m_in_degree_map, v);
+ }
+ // The largest possible vertex invariant number
+ size_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const
+ {
+ return (m_max_vertex_in_degree + 1) * (m_max_vertex_out_degree + 1);
+ }
+
+private:
+ InDegreeMap m_in_degree_map;
+ size_type m_max_vertex_in_degree;
+ size_type m_max_vertex_out_degree;
+ const Graph& m_g;
+};
+
+// Count actual number of vertices, even in filtered graphs.
+template < typename Graph > size_t count_vertices(const Graph& g)
+{
+ size_t n = 0;
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ (void)v;
+ ++n;
+ }
+ return n;
+}
+
+template < typename Graph1, typename Graph2, typename IsoMapping,
+ typename Invariant1, typename Invariant2, typename IndexMap1,
+ typename IndexMap2 >
+bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f,
+ Invariant1 invariant1, Invariant2 invariant2, std::size_t /* max_invariant */,
+ IndexMap1 index_map1, IndexMap2 index_map2)
+
+{
+ // Graph requirements
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph1 >));
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph1 >));
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph2 >));
+ // BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<Graph2> ));
+
+ typedef typename graph_traits< Graph1 >::vertex_descriptor vertex1_t;
+ typedef typename graph_traits< Graph2 >::vertex_descriptor vertex2_t;
+ typedef typename graph_traits< Graph1 >::vertices_size_type size_type;
+
+ typedef typename Invariant1::result_type invariant1_t;
+ typedef typename Invariant2::result_type invariant2_t;
+
+ BOOST_STATIC_ASSERT(is_same<invariant1_t, invariant2_t>::value);
+
+ // Vertex invariant requirement
+ BOOST_CONCEPT_ASSERT(
+ (AdaptableUnaryFunctionConcept< Invariant1, invariant1_t, vertex1_t >));
+ BOOST_CONCEPT_ASSERT(
+ (AdaptableUnaryFunctionConcept< Invariant2, invariant2_t, vertex2_t >));
+
+ // Property map requirements
+ BOOST_CONCEPT_ASSERT(
+ (ReadWritePropertyMapConcept< IsoMapping, vertex1_t >));
+ typedef typename property_traits< IsoMapping >::value_type IsoMappingValue;
+ BOOST_STATIC_ASSERT((is_convertible< IsoMappingValue, vertex2_t >::value));
+
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< IndexMap1, vertex1_t >));
+ typedef typename property_traits< IndexMap1 >::value_type IndexMap1Value;
+ BOOST_STATIC_ASSERT((is_convertible< IndexMap1Value, size_type >::value));
+
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< IndexMap2, vertex2_t >));
+ typedef typename property_traits< IndexMap2 >::value_type IndexMap2Value;
+ BOOST_STATIC_ASSERT((is_convertible< IndexMap2Value, size_type >::value));
+
+ if (count_vertices(G1) != count_vertices(G2))
+ return false;
+ if (count_vertices(G1) == 0 && count_vertices(G2) == 0)
+ return true;
+
+ detail::isomorphism_algo< Graph1, Graph2, IsoMapping, Invariant1,
+ Invariant2, IndexMap1, IndexMap2 >
+ algo(G1, G2, f, invariant1, invariant2, 0, index_map1,
+ index_map2);
+ return algo.test_isomorphism();
+}
+
+namespace detail
+{
+
+ template < typename Graph1, typename Graph2, typename IsoMapping,
+ typename IndexMap1, typename IndexMap2, typename P, typename T,
+ typename R >
+ bool isomorphism_impl(const Graph1& G1, const Graph2& G2, IsoMapping f,
+ IndexMap1 index_map1, IndexMap2 index_map2,
+ const bgl_named_params< P, T, R >& params)
+ {
+ std::vector< std::size_t > in_degree1_vec(num_vertices(G1));
+ typedef safe_iterator_property_map<
+ std::vector< std::size_t >::iterator, IndexMap1
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ ,
+ std::size_t, std::size_t&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ >
+ InDeg1;
+ InDeg1 in_degree1(
+ in_degree1_vec.begin(), in_degree1_vec.size(), index_map1);
+ compute_in_degree(G1, in_degree1);
+
+ std::vector< std::size_t > in_degree2_vec(num_vertices(G2));
+ typedef safe_iterator_property_map<
+ std::vector< std::size_t >::iterator, IndexMap2
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ ,
+ std::size_t, std::size_t&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ >
+ InDeg2;
+ InDeg2 in_degree2(
+ in_degree2_vec.begin(), in_degree2_vec.size(), index_map2);
+ compute_in_degree(G2, in_degree2);
+
+ degree_vertex_invariant< InDeg1, Graph1 > invariant1(in_degree1, G1);
+ degree_vertex_invariant< InDeg2, Graph2 > invariant2(in_degree2, G2);
+
+ return isomorphism(G1, G2, f,
+ choose_param(get_param(params, vertex_invariant1_t()), invariant1),
+ choose_param(get_param(params, vertex_invariant2_t()), invariant2),
+ 0,
+ index_map1, index_map2);
+ }
+
+ template < typename G, typename Index > struct make_degree_invariant
+ {
+ const G& g;
+ const Index& index;
+ make_degree_invariant(const G& g, const Index& index)
+ : g(g), index(index)
+ {
+ }
+ typedef typename boost::graph_traits< G >::degree_size_type
+ degree_size_type;
+ typedef shared_array_property_map< degree_size_type, Index >
+ prop_map_type;
+ typedef degree_vertex_invariant< prop_map_type, G > result_type;
+ result_type operator()() const
+ {
+ prop_map_type pm = make_shared_array_property_map(
+ num_vertices(g), degree_size_type(), index);
+ compute_in_degree(g, pm);
+ return result_type(pm, g);
+ }
+ };
+
+} // namespace detail
+
+namespace graph
+{
+ namespace detail
+ {
+ template < typename Graph1, typename Graph2 > struct isomorphism_impl
+ {
+ typedef bool result_type;
+ typedef result_type type;
+ template < typename ArgPack >
+ bool operator()(const Graph1& g1, const Graph2& g2,
+ const ArgPack& arg_pack) const
+ {
+ using namespace boost::graph::keywords;
+ typedef typename boost::detail::override_const_property_result<
+ ArgPack, tag::vertex_index1_map, boost::vertex_index_t,
+ Graph1 >::type index1_map_type;
+ typedef typename boost::detail::override_const_property_result<
+ ArgPack, tag::vertex_index2_map, boost::vertex_index_t,
+ Graph2 >::type index2_map_type;
+ index1_map_type index1_map
+ = boost::detail::override_const_property(
+ arg_pack, _vertex_index1_map, g1, boost::vertex_index);
+ index2_map_type index2_map
+ = boost::detail::override_const_property(
+ arg_pack, _vertex_index2_map, g2, boost::vertex_index);
+ typedef typename graph_traits< Graph2 >::vertex_descriptor
+ vertex2_t;
+ typename std::vector< vertex2_t >::size_type n
+ = (typename std::vector< vertex2_t >::size_type)
+ num_vertices(g1);
+ std::vector< vertex2_t > f(n);
+ typename boost::parameter::lazy_binding< ArgPack,
+ tag::vertex_invariant1,
+ boost::detail::make_degree_invariant< Graph1,
+ index1_map_type > >::type invariant1
+ = arg_pack[_vertex_invariant1
+ || boost::detail::make_degree_invariant< Graph1,
+ index1_map_type >(g1, index1_map)];
+ typename boost::parameter::lazy_binding< ArgPack,
+ tag::vertex_invariant2,
+ boost::detail::make_degree_invariant< Graph2,
+ index2_map_type > >::type invariant2
+ = arg_pack[_vertex_invariant2
+ || boost::detail::make_degree_invariant< Graph2,
+ index2_map_type >(g2, index2_map)];
+ return boost::isomorphism(g1, g2,
+ choose_param(
+ arg_pack[_isomorphism_map | boost::param_not_found()],
+ make_shared_array_property_map(
+ num_vertices(g1), vertex2_t(), index1_map)),
+ invariant1, invariant2,
+ 0,
+ index1_map, index2_map);
+ }
+ };
+ }
+ BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(isomorphism, 2, 6)
+}
+
+// Named parameter interface
+BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(isomorphism, 2)
+
+// Verify that the given mapping iso_map from the vertices of g1 to the
+// vertices of g2 describes an isomorphism.
+// Note: this could be made much faster by specializing based on the graph
+// concepts modeled, but since we're verifying an O(n^(lg n)) algorithm,
+// O(n^4) won't hurt us.
+template < typename Graph1, typename Graph2, typename IsoMap >
+inline bool verify_isomorphism(
+ const Graph1& g1, const Graph2& g2, IsoMap iso_map)
+{
+#if 0
+ // problematic for filtered_graph!
+ if (num_vertices(g1) != num_vertices(g2) || num_edges(g1) != num_edges(g2))
+ return false;
+#endif
+
+ BGL_FORALL_EDGES_T(e1, g1, Graph1)
+ {
+ bool found_edge = false;
+ BGL_FORALL_EDGES_T(e2, g2, Graph2)
+ {
+ if (source(e2, g2) == get(iso_map, source(e1, g1))
+ && target(e2, g2) == get(iso_map, target(e1, g1)))
+ {
+ found_edge = true;
+ }
+ }
+
+ if (!found_edge)
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace boost
+
+#ifdef BOOST_ISO_INCLUDED_ITER_MACROS
+#undef BOOST_ISO_INCLUDED_ITER_MACROS
+#include <boost/graph/iteration_macros_undef.hpp>
+#endif
+
+#endif // BOOST_GRAPH_ISOMORPHISM_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/iteration_macros_undef.hpp b/contrib/restricted/boost/graph/include/boost/graph/iteration_macros_undef.hpp
new file mode 100644
index 0000000000..0b3f4174df
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/iteration_macros_undef.hpp
@@ -0,0 +1,22 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifdef BOOST_GRAPH_ITERATION_MACROS_HPP
+
+#undef BOOST_GRAPH_ITERATION_MACROS_HPP
+#undef BGL_CAT
+#undef BGL_FIRST
+#undef BGL_LAST
+#undef BGL_FORALL_VERTICES
+#undef BGL_FORALL_EDGES
+#undef BGL_FORALL_ADJACENT
+#undef BGL_FORALL_OUTEDGES
+#undef BGL_FORALL_INEDGES
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/johnson_all_pairs_shortest.hpp b/contrib/restricted/boost/graph/include/boost/graph/johnson_all_pairs_shortest.hpp
new file mode 100644
index 0000000000..2cc4697a11
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/johnson_all_pairs_shortest.hpp
@@ -0,0 +1,198 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+/*
+ This file implements the function
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class P, class T, class R>
+ bool
+ johnson_all_pairs_shortest_paths
+ (VertexAndEdgeListGraph& g,
+ DistanceMatrix& D,
+ const bgl_named_params<P, T, R>& params)
+ */
+
+#ifndef BOOST_GRAPH_JOHNSON_HPP
+#define BOOST_GRAPH_JOHNSON_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/property_map/shared_array_property_map.hpp>
+#include <boost/graph/bellman_ford_shortest_paths.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/type_traits/same_traits.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+
+template < class VertexAndEdgeListGraph, class DistanceMatrix, class VertexID,
+ class Weight, typename BinaryPredicate, typename BinaryFunction,
+ typename Infinity, class DistanceZero >
+bool johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1,
+ DistanceMatrix& D, VertexID id1, Weight w1, const BinaryPredicate& compare,
+ const BinaryFunction& combine, const Infinity& inf, DistanceZero zero)
+{
+ typedef graph_traits< VertexAndEdgeListGraph > Traits1;
+ typedef typename property_traits< Weight >::value_type DT;
+ BOOST_CONCEPT_ASSERT((BasicMatrixConcept< DistanceMatrix,
+ typename Traits1::vertices_size_type, DT >));
+
+ typedef typename Traits1::directed_category DirCat;
+ bool is_undirected = is_same< DirCat, undirected_tag >::value;
+
+ typedef adjacency_list< vecS, vecS, directedS,
+ property< vertex_distance_t, DT >,
+ property< edge_weight_t, DT, property< edge_weight2_t, DT > > >
+ Graph2;
+ typedef graph_traits< Graph2 > Traits2;
+
+ Graph2 g2(num_vertices(g1) + 1);
+ typename property_map< Graph2, edge_weight_t >::type w
+ = get(edge_weight, g2);
+ typename property_map< Graph2, edge_weight2_t >::type w_hat
+ = get(edge_weight2, g2);
+ typename property_map< Graph2, vertex_distance_t >::type d
+ = get(vertex_distance, g2);
+ typedef typename property_map< Graph2, vertex_index_t >::type VertexID2;
+ VertexID2 id2 = get(vertex_index, g2);
+
+ // Construct g2 where V[g2] = V[g1] U {s}
+ // and E[g2] = E[g1] U {(s,v)| v in V[g1]}
+ std::vector< typename Traits1::vertex_descriptor > verts1(
+ num_vertices(g1) + 1);
+ typename Traits2::vertex_descriptor s = *vertices(g2).first;
+ {
+ typename Traits1::vertex_iterator v, v_end;
+ int i = 1;
+ for (boost::tie(v, v_end) = vertices(g1); v != v_end; ++v, ++i)
+ {
+ typename Traits2::edge_descriptor e;
+ bool z;
+ boost::tie(e, z) = add_edge(s, get(id1, *v) + 1, g2);
+ put(w, e, zero);
+ verts1[i] = *v;
+ }
+ typename Traits1::edge_iterator e, e_end;
+ for (boost::tie(e, e_end) = edges(g1); e != e_end; ++e)
+ {
+ typename Traits2::edge_descriptor e2;
+ bool z;
+ boost::tie(e2, z) = add_edge(
+ get(id1, source(*e, g1)) + 1, get(id1, target(*e, g1)) + 1, g2);
+ put(w, e2, get(w1, *e));
+ if (is_undirected)
+ {
+ boost::tie(e2, z) = add_edge(get(id1, target(*e, g1)) + 1,
+ get(id1, source(*e, g1)) + 1, g2);
+ put(w, e2, get(w1, *e));
+ }
+ }
+ }
+ typename Traits2::vertex_iterator v, v_end, u, u_end;
+ typename Traits2::edge_iterator e, e_end;
+ shared_array_property_map< DT, VertexID2 > h(num_vertices(g2), id2);
+
+ for (boost::tie(v, v_end) = vertices(g2); v != v_end; ++v)
+ put(d, *v, inf);
+
+ put(d, s, zero);
+ // Using the non-named parameter versions of bellman_ford and
+ // dijkstra for portability reasons.
+ dummy_property_map pred;
+ bellman_visitor<> bvis;
+ if (bellman_ford_shortest_paths(
+ g2, num_vertices(g2), w, pred, d, combine, compare, bvis))
+ {
+ for (boost::tie(v, v_end) = vertices(g2); v != v_end; ++v)
+ put(h, *v, get(d, *v));
+ // Reweight the edges to remove negatives
+ for (boost::tie(e, e_end) = edges(g2); e != e_end; ++e)
+ {
+ typename Traits2::vertex_descriptor a = source(*e, g2),
+ b = target(*e, g2);
+ put(w_hat, *e, combine((get(h, a) - get(h, b)), get(w, *e)));
+ }
+ for (boost::tie(u, u_end) = vertices(g2); u != u_end; ++u)
+ {
+ dijkstra_visitor<> dvis;
+ dijkstra_shortest_paths(
+ g2, *u, pred, d, w_hat, id2, compare, combine, inf, zero, dvis);
+ for (boost::tie(v, v_end) = vertices(g2); v != v_end; ++v)
+ {
+ if (*u != s && *v != s)
+ {
+ D[get(id2, *u) - 1][get(id2, *v) - 1]
+ = combine((get(h, *v) - get(h, *u)), get(d, *v));
+ }
+ }
+ }
+ return true;
+ }
+ else
+ return false;
+}
+
+template < class VertexAndEdgeListGraph, class DistanceMatrix, class VertexID,
+ class Weight, class DistanceZero >
+bool johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1,
+ DistanceMatrix& D, VertexID id1, Weight w1, DistanceZero zero)
+{
+ typedef typename property_traits< Weight >::value_type WT;
+ return johnson_all_pairs_shortest_paths(g1, D, id1, w1, std::less< WT >(),
+ closed_plus< WT >(), (std::numeric_limits< WT >::max)(), zero);
+}
+
+namespace detail
+{
+
+ template < class VertexAndEdgeListGraph, class DistanceMatrix, class P,
+ class T, class R, class Weight, class VertexID >
+ bool johnson_dispatch(VertexAndEdgeListGraph& g, DistanceMatrix& D,
+ const bgl_named_params< P, T, R >& params, Weight w, VertexID id)
+ {
+ typedef typename property_traits< Weight >::value_type WT;
+
+ return johnson_all_pairs_shortest_paths(g, D, id, w,
+ choose_param(
+ get_param(params, distance_compare_t()), std::less< WT >()),
+ choose_param(
+ get_param(params, distance_combine_t()), closed_plus< WT >()),
+ choose_param(get_param(params, distance_inf_t()),
+ std::numeric_limits< WT >::max
+ BOOST_PREVENT_MACRO_SUBSTITUTION()),
+ choose_param(get_param(params, distance_zero_t()), WT()));
+ }
+
+} // namespace detail
+
+template < class VertexAndEdgeListGraph, class DistanceMatrix, class P, class T,
+ class R >
+bool johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g,
+ DistanceMatrix& D, const bgl_named_params< P, T, R >& params)
+{
+ return detail::johnson_dispatch(g, D, params,
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index));
+}
+
+template < class VertexAndEdgeListGraph, class DistanceMatrix >
+bool johnson_all_pairs_shortest_paths(
+ VertexAndEdgeListGraph& g, DistanceMatrix& D)
+{
+ bgl_named_params< int, int > params(1);
+ return detail::johnson_dispatch(
+ g, D, params, get(edge_weight, g), get(vertex_index, g));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_JOHNSON_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/kamada_kawai_spring_layout.hpp b/contrib/restricted/boost/graph/include/boost/graph/kamada_kawai_spring_layout.hpp
new file mode 100644
index 0000000000..148ebd9ee9
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/kamada_kawai_spring_layout.hpp
@@ -0,0 +1,688 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP
+#define BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/topology.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/johnson_all_pairs_shortest.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <utility>
+#include <iterator>
+#include <vector>
+#include <iostream>
+#include <boost/limits.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
+
+namespace boost
+{
+namespace detail
+{
+ namespace graph
+ {
+ /**
+ * Denotes an edge or display area side length used to scale a
+ * Kamada-Kawai drawing.
+ */
+ template < bool Edge, typename T > struct edge_or_side
+ {
+ explicit edge_or_side(T value) : value(value) {}
+
+ T value;
+ };
+
+ /**
+ * Compute the edge length from an edge length. This is trivial.
+ */
+ template < typename Graph, typename DistanceMap, typename IndexMap,
+ typename T >
+ T compute_edge_length(
+ const Graph&, DistanceMap, IndexMap, edge_or_side< true, T > length)
+ {
+ return length.value;
+ }
+
+ /**
+ * Compute the edge length based on the display area side
+ length. We do this by dividing the side length by the largest
+ shortest distance between any two vertices in the graph.
+ */
+ template < typename Graph, typename DistanceMap, typename IndexMap,
+ typename T >
+ T compute_edge_length(const Graph& g, DistanceMap distance,
+ IndexMap index, edge_or_side< false, T > length)
+ {
+ T result(0);
+
+ typedef
+ typename graph_traits< Graph >::vertex_iterator vertex_iterator;
+
+ for (vertex_iterator ui = vertices(g).first,
+ end = vertices(g).second;
+ ui != end; ++ui)
+ {
+ vertex_iterator vi = ui;
+ for (++vi; vi != end; ++vi)
+ {
+ T dij = distance[get(index, *ui)][get(index, *vi)];
+ if (dij > result)
+ result = dij;
+ }
+ }
+ return length.value / result;
+ }
+
+ /**
+ * Dense linear solver for fixed-size matrices.
+ */
+ template < std::size_t Size > struct linear_solver
+ {
+ // Indices in mat are (row, column)
+ // template <typename Vec>
+ // static Vec solve(double mat[Size][Size], Vec rhs);
+ };
+
+ template <> struct linear_solver< 1 >
+ {
+ template < typename Vec >
+ static Vec solve(double mat[1][1], Vec rhs)
+ {
+ return rhs / mat[0][0];
+ }
+ };
+
+ // These are from http://en.wikipedia.org/wiki/Cramer%27s_rule
+ template <> struct linear_solver< 2 >
+ {
+ template < typename Vec >
+ static Vec solve(double mat[2][2], Vec rhs)
+ {
+ double denom = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];
+ double x_num = rhs[0] * mat[1][1] - rhs[1] * mat[0][1];
+ double y_num = mat[0][0] * rhs[1] - mat[1][0] * rhs[0];
+ Vec result;
+ result[0] = x_num / denom;
+ result[1] = y_num / denom;
+ return result;
+ }
+ };
+
+ template <> struct linear_solver< 3 >
+ {
+ template < typename Vec >
+ static Vec solve(double mat[3][3], Vec rhs)
+ {
+ double denom = mat[0][0]
+ * (mat[1][1] * mat[2][2] - mat[2][1] * mat[1][2])
+ - mat[1][0]
+ * (mat[0][1] * mat[2][2] - mat[2][1] * mat[0][2])
+ + mat[2][0]
+ * (mat[0][1] * mat[1][2] - mat[1][1] * mat[0][2]);
+ double x_num
+ = rhs[0] * (mat[1][1] * mat[2][2] - mat[2][1] * mat[1][2])
+ - rhs[1] * (mat[0][1] * mat[2][2] - mat[2][1] * mat[0][2])
+ + rhs[2] * (mat[0][1] * mat[1][2] - mat[1][1] * mat[0][2]);
+ double y_num
+ = mat[0][0] * (rhs[1] * mat[2][2] - rhs[2] * mat[1][2])
+ - mat[1][0] * (rhs[0] * mat[2][2] - rhs[2] * mat[0][2])
+ + mat[2][0] * (rhs[0] * mat[1][2] - rhs[1] * mat[0][2]);
+ double z_num
+ = mat[0][0] * (mat[1][1] * rhs[2] - mat[2][1] * rhs[1])
+ - mat[1][0] * (mat[0][1] * rhs[2] - mat[2][1] * rhs[0])
+ + mat[2][0] * (mat[0][1] * rhs[1] - mat[1][1] * rhs[0]);
+ Vec result;
+ result[0] = x_num / denom;
+ result[1] = y_num / denom;
+ result[2] = z_num / denom;
+ return result;
+ }
+ };
+
+ /**
+ * Implementation of the Kamada-Kawai spring layout algorithm.
+ */
+ template < typename Topology, typename Graph, typename PositionMap,
+ typename WeightMap, typename EdgeOrSideLength, typename Done,
+ typename VertexIndexMap, typename DistanceMatrix,
+ typename SpringStrengthMatrix, typename PartialDerivativeMap >
+ struct kamada_kawai_spring_layout_impl
+ {
+ typedef
+ typename property_traits< WeightMap >::value_type weight_type;
+ typedef typename Topology::point_type Point;
+ typedef
+ typename Topology::point_difference_type point_difference_type;
+ typedef point_difference_type deriv_type;
+ typedef
+ typename graph_traits< Graph >::vertex_iterator vertex_iterator;
+ typedef typename graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+
+ kamada_kawai_spring_layout_impl(const Topology& topology,
+ const Graph& g, PositionMap position, WeightMap weight,
+ EdgeOrSideLength edge_or_side_length, Done done,
+ weight_type spring_constant, VertexIndexMap index,
+ DistanceMatrix distance, SpringStrengthMatrix spring_strength,
+ PartialDerivativeMap partial_derivatives)
+ : topology(topology)
+ , g(g)
+ , position(position)
+ , weight(weight)
+ , edge_or_side_length(edge_or_side_length)
+ , done(done)
+ , spring_constant(spring_constant)
+ , index(index)
+ , distance(distance)
+ , spring_strength(spring_strength)
+ , partial_derivatives(partial_derivatives)
+ {
+ }
+
+ // Compute contribution of vertex i to the first partial
+ // derivatives (dE/dx_m, dE/dy_m) (for vertex m)
+ deriv_type compute_partial_derivative(
+ vertex_descriptor m, vertex_descriptor i)
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ deriv_type result;
+ if (i != m)
+ {
+ point_difference_type diff
+ = topology.difference(position[m], position[i]);
+ weight_type dist = topology.norm(diff);
+ result = spring_strength[get(index, m)][get(index, i)]
+ * (diff
+ - distance[get(index, m)][get(index, i)] / dist
+ * diff);
+ }
+
+ return result;
+ }
+
+ // Compute partial derivatives dE/dx_m and dE/dy_m
+ deriv_type compute_partial_derivatives(vertex_descriptor m)
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ deriv_type result;
+
+ // TBD: looks like an accumulate to me
+ BGL_FORALL_VERTICES_T(i, g, Graph)
+ {
+ deriv_type deriv = compute_partial_derivative(m, i);
+ result += deriv;
+ }
+
+ return result;
+ }
+
+ // The actual Kamada-Kawai spring layout algorithm implementation
+ bool run()
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ // Compute d_{ij} and place it in the distance matrix
+ if (!johnson_all_pairs_shortest_paths(
+ g, distance, index, weight, weight_type(0)))
+ return false;
+
+ // Compute L based on side length (if needed), or retrieve L
+ weight_type edge_length = detail::graph::compute_edge_length(
+ g, distance, index, edge_or_side_length);
+
+ // std::cerr << "edge_length = " << edge_length << std::endl;
+
+ // Compute l_{ij} and k_{ij}
+ const weight_type K = spring_constant;
+ vertex_iterator ui, end;
+ for (ui = vertices(g).first, end = vertices(g).second;
+ ui != end; ++ui)
+ {
+ vertex_iterator vi = ui;
+ for (++vi; vi != end; ++vi)
+ {
+ weight_type dij
+ = distance[get(index, *ui)][get(index, *vi)];
+ if (dij == (std::numeric_limits< weight_type >::max)())
+ return false;
+ distance[get(index, *ui)][get(index, *vi)]
+ = edge_length * dij;
+ distance[get(index, *vi)][get(index, *ui)]
+ = edge_length * dij;
+ spring_strength[get(index, *ui)][get(index, *vi)]
+ = K / (dij * dij);
+ spring_strength[get(index, *vi)][get(index, *ui)]
+ = K / (dij * dij);
+ }
+ }
+
+ // Compute Delta_i and find max
+ vertex_descriptor p = *vertices(g).first;
+ weight_type delta_p(0);
+
+ for (ui = vertices(g).first, end = vertices(g).second;
+ ui != end; ++ui)
+ {
+ deriv_type deriv = compute_partial_derivatives(*ui);
+ put(partial_derivatives, *ui, deriv);
+
+ weight_type delta = topology.norm(deriv);
+
+ if (delta > delta_p)
+ {
+ p = *ui;
+ delta_p = delta;
+ }
+ }
+
+ while (!done(delta_p, p, g, true))
+ {
+ // The contribution p makes to the partial derivatives of
+ // each vertex. Computing this (at O(n) cost) allows us to
+ // update the delta_i values in O(n) time instead of O(n^2)
+ // time.
+ std::vector< deriv_type > p_partials(num_vertices(g));
+ for (ui = vertices(g).first, end = vertices(g).second;
+ ui != end; ++ui)
+ {
+ vertex_descriptor i = *ui;
+ p_partials[get(index, i)]
+ = compute_partial_derivative(i, p);
+ }
+
+ do
+ {
+ // For debugging, compute the energy value E
+ double E = 0.;
+ for (ui = vertices(g).first, end = vertices(g).second;
+ ui != end; ++ui)
+ {
+ vertex_iterator vi = ui;
+ for (++vi; vi != end; ++vi)
+ {
+ double dist = topology.distance(
+ position[*ui], position[*vi]);
+ weight_type k_ij = spring_strength[get(
+ index, *ui)][get(index, *vi)];
+ weight_type l_ij = distance[get(index, *ui)]
+ [get(index, *vi)];
+ E += .5 * k_ij * (dist - l_ij) * (dist - l_ij);
+ }
+ }
+ // std::cerr << "E = " << E << std::endl;
+
+ // Compute the elements of the Jacobian
+ // From
+ // http://www.cs.panam.edu/~rfowler/papers/1994_kumar_fowler_A_Spring_UTPACSTR.pdf
+ // with the bugs fixed in the off-diagonal case
+ weight_type dE_d_d[Point::dimensions]
+ [Point::dimensions];
+ for (std::size_t i = 0; i < Point::dimensions; ++i)
+ for (std::size_t j = 0; j < Point::dimensions; ++j)
+ dE_d_d[i][j] = 0.;
+ for (ui = vertices(g).first, end = vertices(g).second;
+ ui != end; ++ui)
+ {
+ vertex_descriptor i = *ui;
+ if (i != p)
+ {
+ point_difference_type diff
+ = topology.difference(
+ position[p], position[i]);
+ weight_type dist = topology.norm(diff);
+ weight_type dist_squared = dist * dist;
+ weight_type inv_dist_cubed
+ = 1. / (dist_squared * dist);
+ weight_type k_mi = spring_strength[get(
+ index, p)][get(index, i)];
+ weight_type l_mi
+ = distance[get(index, p)][get(index, i)];
+ for (std::size_t i = 0; i < Point::dimensions;
+ ++i)
+ {
+ for (std::size_t j = 0;
+ j < Point::dimensions; ++j)
+ {
+ if (i == j)
+ {
+ dE_d_d[i][i] += k_mi
+ * (1
+ + (l_mi
+ * (diff[i] * diff[i]
+ - dist_squared)
+ * inv_dist_cubed));
+ }
+ else
+ {
+ dE_d_d[i][j] += k_mi * l_mi
+ * diff[i] * diff[j]
+ * inv_dist_cubed;
+ // dE_d_d[i][j] += k_mi * l_mi *
+ // sqrt(hypot(diff[i], diff[j])) *
+ // inv_dist_cubed;
+ }
+ }
+ }
+ }
+ }
+
+ deriv_type dE_d = get(partial_derivatives, p);
+
+ // Solve dE_d_d * delta = -dE_d to get delta
+ point_difference_type delta
+ = -linear_solver< Point::dimensions >::solve(
+ dE_d_d, dE_d);
+
+ // Move p by delta
+ position[p] = topology.adjust(position[p], delta);
+
+ // Recompute partial derivatives and delta_p
+ deriv_type deriv = compute_partial_derivatives(p);
+ put(partial_derivatives, p, deriv);
+
+ delta_p = topology.norm(deriv);
+ } while (!done(delta_p, p, g, false));
+
+ // Select new p by updating each partial derivative and
+ // delta
+ vertex_descriptor old_p = p;
+ for (ui = vertices(g).first, end = vertices(g).second;
+ ui != end; ++ui)
+ {
+ deriv_type old_deriv_p = p_partials[get(index, *ui)];
+ deriv_type old_p_partial
+ = compute_partial_derivative(*ui, old_p);
+ deriv_type deriv = get(partial_derivatives, *ui);
+
+ deriv += old_p_partial - old_deriv_p;
+
+ put(partial_derivatives, *ui, deriv);
+ weight_type delta = topology.norm(deriv);
+
+ if (delta > delta_p)
+ {
+ p = *ui;
+ delta_p = delta;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ const Topology& topology;
+ const Graph& g;
+ PositionMap position;
+ WeightMap weight;
+ EdgeOrSideLength edge_or_side_length;
+ Done done;
+ weight_type spring_constant;
+ VertexIndexMap index;
+ DistanceMatrix distance;
+ SpringStrengthMatrix spring_strength;
+ PartialDerivativeMap partial_derivatives;
+ };
+ }
+} // end namespace detail::graph
+
+/// States that the given quantity is an edge length.
+template < typename T >
+inline detail::graph::edge_or_side< true, T > edge_length(T x)
+{
+ return detail::graph::edge_or_side< true, T >(x);
+}
+
+/// States that the given quantity is a display area side length.
+template < typename T >
+inline detail::graph::edge_or_side< false, T > side_length(T x)
+{
+ return detail::graph::edge_or_side< false, T >(x);
+}
+
+/**
+ * \brief Determines when to terminate layout of a particular graph based
+ * on a given relative tolerance.
+ */
+template < typename T = double > struct layout_tolerance
+{
+ layout_tolerance(const T& tolerance = T(0.001))
+ : tolerance(tolerance)
+ , last_energy((std::numeric_limits< T >::max)())
+ , last_local_energy((std::numeric_limits< T >::max)())
+ {
+ }
+
+ template < typename Graph >
+ bool operator()(T delta_p,
+ typename boost::graph_traits< Graph >::vertex_descriptor p,
+ const Graph& g, bool global)
+ {
+ if (global)
+ {
+ if (last_energy == (std::numeric_limits< T >::max)())
+ {
+ last_energy = delta_p;
+ return false;
+ }
+
+ T diff = last_energy - delta_p;
+ if (diff < T(0))
+ diff = -diff;
+ bool done = (delta_p == T(0) || diff / last_energy < tolerance);
+ last_energy = delta_p;
+ return done;
+ }
+ else
+ {
+ if (last_local_energy == (std::numeric_limits< T >::max)())
+ {
+ last_local_energy = delta_p;
+ return delta_p == T(0);
+ }
+
+ T diff = last_local_energy - delta_p;
+ bool done
+ = (delta_p == T(0) || (diff / last_local_energy) < tolerance);
+ last_local_energy = delta_p;
+ return done;
+ }
+ }
+
+private:
+ T tolerance;
+ T last_energy;
+ T last_local_energy;
+};
+
+/** \brief Kamada-Kawai spring layout for undirected graphs.
+ *
+ * This algorithm performs graph layout (in two dimensions) for
+ * connected, undirected graphs. It operates by relating the layout
+ * of graphs to a dynamic spring system and minimizing the energy
+ * within that system. The strength of a spring between two vertices
+ * is inversely proportional to the square of the shortest distance
+ * (in graph terms) between those two vertices. Essentially,
+ * vertices that are closer in the graph-theoretic sense (i.e., by
+ * following edges) will have stronger springs and will therefore be
+ * placed closer together.
+ *
+ * Prior to invoking this algorithm, it is recommended that the
+ * vertices be placed along the vertices of a regular n-sided
+ * polygon.
+ *
+ * \param g (IN) must be a model of Vertex List Graph, Edge List
+ * Graph, and Incidence Graph and must be undirected.
+ *
+ * \param position (OUT) must be a model of Lvalue Property Map,
+ * where the value type is a class containing fields @c x and @c y
+ * that will be set to the @c x and @c y coordinates of each vertex.
+ *
+ * \param weight (IN) must be a model of Readable Property Map,
+ * which provides the weight of each edge in the graph @p g.
+ *
+ * \param topology (IN) must be a topology object (see topology.hpp),
+ * which provides operations on points and differences between them.
+ *
+ * \param edge_or_side_length (IN) provides either the unit length
+ * @c e of an edge in the layout or the length of a side @c s of the
+ * display area, and must be either @c boost::edge_length(e) or @c
+ * boost::side_length(s), respectively.
+ *
+ * \param done (IN) is a 4-argument function object that is passed
+ * the current value of delta_p (i.e., the energy of vertex @p p),
+ * the vertex @p p, the graph @p g, and a boolean flag indicating
+ * whether @p delta_p is the maximum energy in the system (when @c
+ * true) or the energy of the vertex being moved. Defaults to @c
+ * layout_tolerance instantiated over the value type of the weight
+ * map.
+ *
+ * \param spring_constant (IN) is the constant multiplied by each
+ * spring's strength. Larger values create systems with more energy
+ * that can take longer to stabilize; smaller values create systems
+ * with less energy that stabilize quickly but do not necessarily
+ * result in pleasing layouts. The default value is 1.
+ *
+ * \param index (IN) is a mapping from vertices to index values
+ * between 0 and @c num_vertices(g). The default is @c
+ * get(vertex_index,g).
+ *
+ * \param distance (UTIL/OUT) will be used to store the distance
+ * from every vertex to every other vertex, which is computed in the
+ * first stages of the algorithm. This value's type must be a model
+ * of BasicMatrix with value type equal to the value type of the
+ * weight map. The default is a vector of vectors.
+ *
+ * \param spring_strength (UTIL/OUT) will be used to store the
+ * strength of the spring between every pair of vertices. This
+ * value's type must be a model of BasicMatrix with value type equal
+ * to the value type of the weight map. The default is a vector of
+ * vectors.
+ *
+ * \param partial_derivatives (UTIL) will be used to store the
+ * partial derivates of each vertex with respect to the @c x and @c
+ * y coordinates. This must be a Read/Write Property Map whose value
+ * type is a pair with both types equivalent to the value type of
+ * the weight map. The default is an iterator property map.
+ *
+ * \returns @c true if layout was successful or @c false if a
+ * negative weight cycle was detected.
+ */
+template < typename Topology, typename Graph, typename PositionMap,
+ typename WeightMap, typename T, bool EdgeOrSideLength, typename Done,
+ typename VertexIndexMap, typename DistanceMatrix,
+ typename SpringStrengthMatrix, typename PartialDerivativeMap >
+bool kamada_kawai_spring_layout(const Graph& g, PositionMap position,
+ WeightMap weight, const Topology& topology,
+ detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length,
+ Done done,
+ typename property_traits< WeightMap >::value_type spring_constant,
+ VertexIndexMap index, DistanceMatrix distance,
+ SpringStrengthMatrix spring_strength,
+ PartialDerivativeMap partial_derivatives)
+{
+ BOOST_STATIC_ASSERT(
+ (is_convertible< typename graph_traits< Graph >::directed_category*,
+ undirected_tag* >::value));
+
+ detail::graph::kamada_kawai_spring_layout_impl< Topology, Graph,
+ PositionMap, WeightMap,
+ detail::graph::edge_or_side< EdgeOrSideLength, T >, Done,
+ VertexIndexMap, DistanceMatrix, SpringStrengthMatrix,
+ PartialDerivativeMap >
+ alg(topology, g, position, weight, edge_or_side_length, done,
+ spring_constant, index, distance, spring_strength,
+ partial_derivatives);
+ return alg.run();
+}
+
+/**
+ * \overload
+ */
+template < typename Topology, typename Graph, typename PositionMap,
+ typename WeightMap, typename T, bool EdgeOrSideLength, typename Done,
+ typename VertexIndexMap >
+bool kamada_kawai_spring_layout(const Graph& g, PositionMap position,
+ WeightMap weight, const Topology& topology,
+ detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length,
+ Done done,
+ typename property_traits< WeightMap >::value_type spring_constant,
+ VertexIndexMap index)
+{
+ typedef typename property_traits< WeightMap >::value_type weight_type;
+
+ typename graph_traits< Graph >::vertices_size_type n = num_vertices(g);
+ typedef std::vector< weight_type > weight_vec;
+
+ std::vector< weight_vec > distance(n, weight_vec(n));
+ std::vector< weight_vec > spring_strength(n, weight_vec(n));
+ std::vector< typename Topology::point_difference_type > partial_derivatives(
+ n);
+
+ return kamada_kawai_spring_layout(g, position, weight, topology,
+ edge_or_side_length, done, spring_constant, index, distance.begin(),
+ spring_strength.begin(),
+ make_iterator_property_map(partial_derivatives.begin(), index,
+ typename Topology::point_difference_type()));
+}
+
+/**
+ * \overload
+ */
+template < typename Topology, typename Graph, typename PositionMap,
+ typename WeightMap, typename T, bool EdgeOrSideLength, typename Done >
+bool kamada_kawai_spring_layout(const Graph& g, PositionMap position,
+ WeightMap weight, const Topology& topology,
+ detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length,
+ Done done,
+ typename property_traits< WeightMap >::value_type spring_constant)
+{
+ return kamada_kawai_spring_layout(g, position, weight, topology,
+ edge_or_side_length, done, spring_constant, get(vertex_index, g));
+}
+
+/**
+ * \overload
+ */
+template < typename Topology, typename Graph, typename PositionMap,
+ typename WeightMap, typename T, bool EdgeOrSideLength, typename Done >
+bool kamada_kawai_spring_layout(const Graph& g, PositionMap position,
+ WeightMap weight, const Topology& topology,
+ detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length,
+ Done done)
+{
+ typedef typename property_traits< WeightMap >::value_type weight_type;
+ return kamada_kawai_spring_layout(g, position, weight, topology,
+ edge_or_side_length, done, weight_type(1));
+}
+
+/**
+ * \overload
+ */
+template < typename Topology, typename Graph, typename PositionMap,
+ typename WeightMap, typename T, bool EdgeOrSideLength >
+bool kamada_kawai_spring_layout(const Graph& g, PositionMap position,
+ WeightMap weight, const Topology& topology,
+ detail::graph::edge_or_side< EdgeOrSideLength, T > edge_or_side_length)
+{
+ typedef typename property_traits< WeightMap >::value_type weight_type;
+ return kamada_kawai_spring_layout(g, position, weight, topology,
+ edge_or_side_length, layout_tolerance< weight_type >(),
+ weight_type(1.0), get(vertex_index, g));
+}
+} // end namespace boost
+
+#endif // BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/king_ordering.hpp b/contrib/restricted/boost/graph/include/boost/graph/king_ordering.hpp
new file mode 100644
index 0000000000..6a0bd93944
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/king_ordering.hpp
@@ -0,0 +1,346 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004, 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
+// Doug Gregor, D. Kevin McGrath
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================//
+#ifndef BOOST_GRAPH_KING_HPP
+#define BOOST_GRAPH_KING_HPP
+
+#include <deque>
+#include <vector>
+#include <algorithm>
+#include <boost/config.hpp>
+#include <boost/bind/bind.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/graph/detail/sparse_ordering.hpp>
+#include <boost/graph/graph_utility.hpp>
+
+/*
+ King Algorithm for matrix reordering
+*/
+
+namespace boost
+{
+namespace detail
+{
+ template < typename OutputIterator, typename Buffer, typename Compare,
+ typename PseudoDegreeMap, typename VecMap, typename VertexIndexMap >
+ class bfs_king_visitor : public default_bfs_visitor
+ {
+ public:
+ bfs_king_visitor(OutputIterator* iter, Buffer* b, Compare compare,
+ PseudoDegreeMap deg, std::vector< int > loc, VecMap color,
+ VertexIndexMap vertices)
+ : permutation(iter)
+ , Qptr(b)
+ , degree(deg)
+ , comp(compare)
+ , Qlocation(loc)
+ , colors(color)
+ , vertex_map(vertices)
+ {
+ }
+
+ template < typename Vertex, typename Graph >
+ void finish_vertex(Vertex, Graph& g)
+ {
+ using namespace boost::placeholders;
+
+ typename graph_traits< Graph >::out_edge_iterator ei, ei_end;
+ Vertex v, w;
+
+ typedef typename std::deque< Vertex >::reverse_iterator
+ reverse_iterator;
+
+ reverse_iterator rend = Qptr->rend() - index_begin;
+ reverse_iterator rbegin = Qptr->rbegin();
+
+ // heap the vertices already there
+ std::make_heap(rbegin, rend, boost::bind< bool >(comp, _2, _1));
+
+ unsigned i = 0;
+
+ for (i = index_begin; i != Qptr->size(); ++i)
+ {
+ colors[get(vertex_map, (*Qptr)[i])] = 1;
+ Qlocation[get(vertex_map, (*Qptr)[i])] = i;
+ }
+
+ i = 0;
+
+ for (; rbegin != rend; rend--)
+ {
+ percolate_down< Vertex >(i);
+ w = (*Qptr)[index_begin + i];
+ for (boost::tie(ei, ei_end) = out_edges(w, g); ei != ei_end;
+ ++ei)
+ {
+ v = target(*ei, g);
+ put(degree, v, get(degree, v) - 1);
+
+ if (colors[get(vertex_map, v)] == 1)
+ {
+ percolate_up< Vertex >(get(vertex_map, v), i);
+ }
+ }
+
+ colors[get(vertex_map, w)] = 0;
+ i++;
+ }
+ }
+
+ template < typename Vertex, typename Graph >
+ void examine_vertex(Vertex u, const Graph&)
+ {
+
+ *(*permutation)++ = u;
+ index_begin = Qptr->size();
+ }
+
+ protected:
+ // this function replaces pop_heap, and tracks state information
+ template < typename Vertex > void percolate_down(int offset)
+ {
+ int heap_last = index_begin + offset;
+ int heap_first = Qptr->size() - 1;
+
+ // pop_heap functionality:
+ // swap first, last
+ std::swap((*Qptr)[heap_last], (*Qptr)[heap_first]);
+
+ // swap in the location queue
+ std::swap(Qlocation[heap_first], Qlocation[heap_last]);
+
+ // set drifter, children
+ int drifter = heap_first;
+ int drifter_heap = Qptr->size() - drifter;
+
+ int right_child_heap = drifter_heap * 2 + 1;
+ int right_child = Qptr->size() - right_child_heap;
+
+ int left_child_heap = drifter_heap * 2;
+ int left_child = Qptr->size() - left_child_heap;
+
+ // check that we are staying in the heap
+ bool valid = (right_child < heap_last) ? false : true;
+
+ // pick smallest child of drifter, and keep in mind there might only
+ // be left child
+ int smallest_child = (valid
+ && get(degree, (*Qptr)[left_child])
+ > get(degree, (*Qptr)[right_child]))
+ ? right_child
+ : left_child;
+
+ while (valid && smallest_child < heap_last
+ && comp((*Qptr)[drifter], (*Qptr)[smallest_child]))
+ {
+
+ // if smallest child smaller than drifter, swap them
+ std::swap((*Qptr)[smallest_child], (*Qptr)[drifter]);
+ std::swap(Qlocation[drifter], Qlocation[smallest_child]);
+
+ // update the values, run again, as necessary
+ drifter = smallest_child;
+ drifter_heap = Qptr->size() - drifter;
+
+ right_child_heap = drifter_heap * 2 + 1;
+ right_child = Qptr->size() - right_child_heap;
+
+ left_child_heap = drifter_heap * 2;
+ left_child = Qptr->size() - left_child_heap;
+
+ valid = (right_child < heap_last) ? false : true;
+
+ smallest_child = (valid
+ && get(degree, (*Qptr)[left_child])
+ > get(degree, (*Qptr)[right_child]))
+ ? right_child
+ : left_child;
+ }
+ }
+
+ // this is like percolate down, but we always compare against the
+ // parent, as there is only a single choice
+ template < typename Vertex > void percolate_up(int vertex, int offset)
+ {
+
+ int child_location = Qlocation[vertex];
+ int heap_child_location = Qptr->size() - child_location;
+ int heap_parent_location = (int)(heap_child_location / 2);
+ unsigned parent_location = Qptr->size() - heap_parent_location;
+
+ bool valid = (heap_parent_location != 0
+ && child_location > index_begin + offset
+ && parent_location < Qptr->size());
+
+ while (valid
+ && comp((*Qptr)[child_location], (*Qptr)[parent_location]))
+ {
+
+ // swap in the heap
+ std::swap((*Qptr)[child_location], (*Qptr)[parent_location]);
+
+ // swap in the location queue
+ std::swap(
+ Qlocation[child_location], Qlocation[parent_location]);
+
+ child_location = parent_location;
+ heap_child_location = heap_parent_location;
+ heap_parent_location = (int)(heap_child_location / 2);
+ parent_location = Qptr->size() - heap_parent_location;
+ valid = (heap_parent_location != 0
+ && child_location > index_begin + offset);
+ }
+ }
+
+ OutputIterator* permutation;
+ int index_begin;
+ Buffer* Qptr;
+ PseudoDegreeMap degree;
+ Compare comp;
+ std::vector< int > Qlocation;
+ VecMap colors;
+ VertexIndexMap vertex_map;
+ };
+
+} // namespace detail
+
+template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
+ typename VertexIndexMap >
+OutputIterator king_ordering(const Graph& g,
+ std::deque< typename graph_traits< Graph >::vertex_descriptor >
+ vertex_queue,
+ OutputIterator permutation, ColorMap color, DegreeMap degree,
+ VertexIndexMap index_map)
+{
+ typedef typename property_traits< DegreeMap >::value_type ds_type;
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef iterator_property_map< typename std::vector< ds_type >::iterator,
+ VertexIndexMap, ds_type, ds_type& >
+ PseudoDegreeMap;
+ typedef indirect_cmp< PseudoDegreeMap, std::less< ds_type > > Compare;
+ typedef typename boost::sparse::sparse_ordering_queue< Vertex > queue;
+ typedef typename detail::bfs_king_visitor< OutputIterator, queue, Compare,
+ PseudoDegreeMap, std::vector< int >, VertexIndexMap >
+ Visitor;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+ std::vector< ds_type > pseudo_degree_vec(num_vertices(g));
+ PseudoDegreeMap pseudo_degree(pseudo_degree_vec.begin(), index_map);
+
+ typename graph_traits< Graph >::vertex_iterator ui, ui_end;
+ queue Q;
+ // Copy degree to pseudo_degree
+ // initialize the color map
+ for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ put(pseudo_degree, *ui, get(degree, *ui));
+ put(color, *ui, Color::white());
+ }
+
+ Compare comp(pseudo_degree);
+ std::vector< int > colors(num_vertices(g));
+
+ for (vertices_size_type i = 0; i < num_vertices(g); i++)
+ colors[i] = 0;
+
+ std::vector< int > loc(num_vertices(g));
+
+ // create the visitor
+ Visitor vis(&permutation, &Q, comp, pseudo_degree, loc, colors, index_map);
+
+ while (!vertex_queue.empty())
+ {
+ Vertex s = vertex_queue.front();
+ vertex_queue.pop_front();
+
+ // call BFS with visitor
+ breadth_first_visit(g, s, Q, vis, color);
+ }
+
+ return permutation;
+}
+
+// This is the case where only a single starting vertex is supplied.
+template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
+ typename VertexIndexMap >
+OutputIterator king_ordering(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ OutputIterator permutation, ColorMap color, DegreeMap degree,
+ VertexIndexMap index_map)
+{
+
+ std::deque< typename graph_traits< Graph >::vertex_descriptor >
+ vertex_queue;
+ vertex_queue.push_front(s);
+ return king_ordering(
+ g, vertex_queue, permutation, color, degree, index_map);
+}
+
+template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
+ class VertexIndexMap >
+OutputIterator king_ordering(const Graph& G, OutputIterator permutation,
+ ColorMap color, DegreeMap degree, VertexIndexMap index_map)
+{
+ if (has_no_vertices(G))
+ return permutation;
+
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+
+ std::deque< Vertex > vertex_queue;
+
+ // Mark everything white
+ BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white());
+
+ // Find one vertex from each connected component
+ BGL_FORALL_VERTICES_T(v, G, Graph)
+ {
+ if (get(color, v) == Color::white())
+ {
+ depth_first_visit(G, v, dfs_visitor<>(), color);
+ vertex_queue.push_back(v);
+ }
+ }
+
+ // Find starting nodes for all vertices
+ // TBD: How to do this with a directed graph?
+ for (typename std::deque< Vertex >::iterator i = vertex_queue.begin();
+ i != vertex_queue.end(); ++i)
+ *i = find_starting_node(G, *i, color, degree);
+
+ return king_ordering(
+ G, vertex_queue, permutation, color, degree, index_map);
+}
+
+template < typename Graph, typename OutputIterator, typename VertexIndexMap >
+OutputIterator king_ordering(
+ const Graph& G, OutputIterator permutation, VertexIndexMap index_map)
+{
+ if (has_no_vertices(G))
+ return permutation;
+
+ std::vector< default_color_type > colors(num_vertices(G));
+ return king_ordering(G, permutation,
+ make_iterator_property_map(&colors[0], index_map, colors[0]),
+ make_out_degree_map(G), index_map);
+}
+
+template < typename Graph, typename OutputIterator >
+inline OutputIterator king_ordering(const Graph& G, OutputIterator permutation)
+{
+ return king_ordering(G, permutation, get(vertex_index, G));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_KING_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/kruskal_min_spanning_tree.hpp b/contrib/restricted/boost/graph/include/boost/graph/kruskal_min_spanning_tree.hpp
new file mode 100644
index 0000000000..1e91feb49c
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/kruskal_min_spanning_tree.hpp
@@ -0,0 +1,152 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_MST_KRUSKAL_HPP
+#define BOOST_GRAPH_MST_KRUSKAL_HPP
+
+/*
+ *Minimum Spanning Tree
+ * Kruskal Algorithm
+ *
+ *Requirement:
+ * undirected graph
+ */
+
+#include <vector>
+#include <queue>
+#include <functional>
+
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/pending/disjoint_sets.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+
+// Kruskal's algorithm for Minimum Spanning Tree
+//
+// This is a greedy algorithm to calculate the Minimum Spanning Tree
+// for an undirected graph with weighted edges. The output will be a
+// set of edges.
+//
+
+namespace detail
+{
+
+ template < class Graph, class OutputIterator, class Rank, class Parent,
+ class Weight >
+ void kruskal_mst_impl(const Graph& G, OutputIterator spanning_tree_edges,
+ Rank rank, Parent parent, Weight weight)
+ {
+ if (num_vertices(G) == 0)
+ return; // Nothing to do in this case
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::edge_descriptor Edge;
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((OutputIteratorConcept< OutputIterator, Edge >));
+ BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< Rank, Vertex >));
+ BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< Parent, Vertex >));
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< Weight, Edge >));
+ typedef typename property_traits< Weight >::value_type W_value;
+ typedef typename property_traits< Rank >::value_type R_value;
+ typedef typename property_traits< Parent >::value_type P_value;
+ BOOST_CONCEPT_ASSERT((ComparableConcept< W_value >));
+ BOOST_CONCEPT_ASSERT((ConvertibleConcept< P_value, Vertex >));
+ BOOST_CONCEPT_ASSERT((IntegerConcept< R_value >));
+
+ disjoint_sets< Rank, Parent > dset(rank, parent);
+
+ typename graph_traits< Graph >::vertex_iterator ui, uiend;
+ for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui)
+ dset.make_set(*ui);
+
+ typedef indirect_cmp< Weight, std::greater< W_value > > weight_greater;
+ weight_greater wl(weight);
+ std::priority_queue< Edge, std::vector< Edge >, weight_greater > Q(wl);
+ /*push all edge into Q*/
+ typename graph_traits< Graph >::edge_iterator ei, eiend;
+ for (boost::tie(ei, eiend) = edges(G); ei != eiend; ++ei)
+ Q.push(*ei);
+
+ while (!Q.empty())
+ {
+ Edge e = Q.top();
+ Q.pop();
+ Vertex u = dset.find_set(source(e, G));
+ Vertex v = dset.find_set(target(e, G));
+ if (u != v)
+ {
+ *spanning_tree_edges++ = e;
+ dset.link(u, v);
+ }
+ }
+ }
+
+} // namespace detail
+
+// Named Parameters Variants
+
+template < class Graph, class OutputIterator >
+inline void kruskal_minimum_spanning_tree(
+ const Graph& g, OutputIterator spanning_tree_edges)
+{
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ if (num_vertices(g) == 0)
+ return; // Nothing to do in this case
+ typename graph_traits< Graph >::vertices_size_type n = num_vertices(g);
+ std::vector< size_type > rank_map(n);
+ std::vector< vertex_t > pred_map(n);
+
+ detail::kruskal_mst_impl(g, spanning_tree_edges,
+ make_iterator_property_map(
+ rank_map.begin(), get(vertex_index, g), rank_map[0]),
+ make_iterator_property_map(
+ pred_map.begin(), get(vertex_index, g), pred_map[0]),
+ get(edge_weight, g));
+}
+
+template < class Graph, class OutputIterator, class P, class T, class R >
+inline void kruskal_minimum_spanning_tree(const Graph& g,
+ OutputIterator spanning_tree_edges,
+ const bgl_named_params< P, T, R >& params)
+{
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ if (num_vertices(g) == 0)
+ return; // Nothing to do in this case
+ typename graph_traits< Graph >::vertices_size_type n;
+ n = is_default_param(get_param(params, vertex_rank)) ? num_vertices(g) : 1;
+ std::vector< size_type > rank_map(n);
+ n = is_default_param(get_param(params, vertex_predecessor))
+ ? num_vertices(g)
+ : 1;
+ std::vector< vertex_t > pred_map(n);
+
+ detail::kruskal_mst_impl(g, spanning_tree_edges,
+ choose_param(get_param(params, vertex_rank),
+ make_iterator_property_map(rank_map.begin(),
+ choose_pmap(get_param(params, vertex_index), g, vertex_index),
+ rank_map[0])),
+ choose_param(get_param(params, vertex_predecessor),
+ make_iterator_property_map(pred_map.begin(),
+ choose_const_pmap(
+ get_param(params, vertex_index), g, vertex_index),
+ pred_map[0])),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_MST_KRUSKAL_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/labeled_graph.hpp b/contrib/restricted/boost/graph/include/boost/graph/labeled_graph.hpp
new file mode 100644
index 0000000000..1c7706e101
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/labeled_graph.hpp
@@ -0,0 +1,1010 @@
+// Copyright (C) 2009 Andrew Sutton
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_LABELED_GRAPH_HPP
+#define BOOST_GRAPH_LABELED_GRAPH_HPP
+
+#include <boost/config.hpp>
+#include <vector>
+#include <map>
+
+#include <boost/static_assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
+#include <boost/pending/container_traits.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map/property_map.hpp>
+
+// This file implements a utility for creating mappings from arbitrary
+// identifiers to the vertices of a graph.
+
+namespace boost
+{
+
+// A type selector that denotes the use of some default value.
+struct defaultS
+{
+};
+
+/** @internal */
+namespace graph_detail
+{
+ /** Returns true if the selector is the default selector. */
+ template < typename Selector >
+ struct is_default : mpl::bool_< is_same< Selector, defaultS >::value >
+ {
+ };
+
+ /**
+ * Choose the default map instance. If Label is an unsigned integral type
+ * the we can use a vector to store the information.
+ */
+ template < typename Label, typename Vertex > struct choose_default_map
+ {
+ typedef typename mpl::if_< is_unsigned< Label >, std::vector< Vertex >,
+ std::map< Label, Vertex > // TODO: Should use unordered_map?
+ >::type type;
+ };
+
+ /**
+ * @name Generate Label Map
+ * These type generators are responsible for instantiating an associative
+ * container for the the labeled graph. Note that the Selector must be
+ * select a pair associative container or a vecS, which is only valid if
+ * Label is an integral type.
+ */
+ //@{
+ template < typename Selector, typename Label, typename Vertex >
+ struct generate_label_map
+ {
+ };
+
+ template < typename Label, typename Vertex >
+ struct generate_label_map< vecS, Label, Vertex >
+ {
+ typedef std::vector< Vertex > type;
+ };
+
+ template < typename Label, typename Vertex >
+ struct generate_label_map< mapS, Label, Vertex >
+ {
+ typedef std::map< Label, Vertex > type;
+ };
+
+ template < typename Label, typename Vertex >
+ struct generate_label_map< multimapS, Label, Vertex >
+ {
+ typedef std::multimap< Label, Vertex > type;
+ };
+
+ template < typename Label, typename Vertex >
+ struct generate_label_map< hash_mapS, Label, Vertex >
+ {
+ typedef boost::unordered_map< Label, Vertex > type;
+ };
+
+ template < typename Label, typename Vertex >
+ struct generate_label_map< hash_multimapS, Label, Vertex >
+ {
+ typedef boost::unordered_multimap< Label, Vertex > type;
+ };
+
+ template < typename Selector, typename Label, typename Vertex >
+ struct choose_custom_map
+ {
+ typedef
+ typename generate_label_map< Selector, Label, Vertex >::type type;
+ };
+ //@}
+
+ /**
+ * Choose and instantiate an "associative" container. Note that this can
+ * also choose vector.
+ */
+ template < typename Selector, typename Label, typename Vertex >
+ struct choose_map
+ {
+ typedef typename mpl::eval_if< is_default< Selector >,
+ choose_default_map< Label, Vertex >,
+ choose_custom_map< Selector, Label, Vertex > >::type type;
+ };
+
+ /** @name Insert Labeled Vertex */
+ //@{
+ // Tag dispatch on random access containers (i.e., vectors). This function
+ // basically requires a) that Container is vector<Label> and that Label
+ // is an unsigned integral value. Note that this will resize the vector
+ // to accommodate indices.
+ template < typename Container, typename Graph, typename Label,
+ typename Prop >
+ std::pair< typename graph_traits< Graph >::vertex_descriptor, bool >
+ insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p,
+ random_access_container_tag)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+
+ // If the label is out of bounds, resize the vector to accommodate.
+ // Resize by 2x the index so we don't cause quadratic insertions over
+ // time.
+ if (l >= c.size())
+ {
+ c.resize((l + 1) * 2);
+ }
+ Vertex v = add_vertex(p, g);
+ c[l] = v;
+ return std::make_pair(c[l], true);
+ }
+
+ // Tag dispatch on multi associative containers (i.e. multimaps).
+ template < typename Container, typename Graph, typename Label,
+ typename Prop >
+ std::pair< typename graph_traits< Graph >::vertex_descriptor, bool >
+ insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p,
+ multiple_associative_container_tag const&)
+ {
+ // Note that insertion always succeeds so we can add the vertex first
+ // and then the mapping to the label.
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ Vertex v = add_vertex(p, g);
+ c.insert(std::make_pair(l, v));
+ return std::make_pair(v, true);
+ }
+
+ // Tag dispatch on unique associative containers (i.e. maps).
+ template < typename Container, typename Graph, typename Label,
+ typename Prop >
+ std::pair< typename graph_traits< Graph >::vertex_descriptor, bool >
+ insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p,
+ unique_associative_container_tag)
+ {
+ // Here, we actually have to try the insertion first, and only add
+ // the vertex if we get a new element.
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename Container::iterator Iterator;
+ std::pair< Iterator, bool > x = c.insert(std::make_pair(l, Vertex()));
+ if (x.second)
+ {
+ x.first->second = add_vertex(g);
+ put(boost::vertex_all, g, x.first->second, p);
+ }
+ return std::make_pair(x.first->second, x.second);
+ }
+
+ // Dispatcher
+ template < typename Container, typename Graph, typename Label,
+ typename Prop >
+ std::pair< typename graph_traits< Graph >::vertex_descriptor, bool >
+ insert_labeled_vertex(Container& c, Graph& g, Label const& l, Prop const& p)
+ {
+ return insert_labeled_vertex(c, g, l, p, container_category(c));
+ }
+ //@}
+
+ /** @name Find Labeled Vertex */
+ //@{
+ // Tag dispatch for sequential maps (i.e., vectors).
+ template < typename Container, typename Graph, typename Label >
+ typename graph_traits< Graph >::vertex_descriptor find_labeled_vertex(
+ Container const& c, Graph const&, Label const& l,
+ random_access_container_tag)
+ {
+ return l < c.size() ? c[l] : graph_traits< Graph >::null_vertex();
+ }
+
+ // Tag dispatch for pair associative maps (more or less).
+ template < typename Container, typename Graph, typename Label >
+ typename graph_traits< Graph >::vertex_descriptor find_labeled_vertex(
+ Container const& c, Graph const&, Label const& l,
+ associative_container_tag)
+ {
+ typename Container::const_iterator i = c.find(l);
+ return i != c.end() ? i->second : graph_traits< Graph >::null_vertex();
+ }
+
+ // Dispatcher
+ template < typename Container, typename Graph, typename Label >
+ typename graph_traits< Graph >::vertex_descriptor find_labeled_vertex(
+ Container const& c, Graph const& g, Label const& l)
+ {
+ return find_labeled_vertex(c, g, l, container_category(c));
+ }
+ //@}
+
+ /** @name Put Vertex Label */
+ //@{
+ // Tag dispatch on vectors.
+ template < typename Container, typename Label, typename Graph,
+ typename Vertex >
+ bool put_vertex_label(Container& c, Graph const&, Label const& l, Vertex v,
+ random_access_container_tag)
+ {
+ // If the element is already occupied, then we probably don't want to
+ // overwrite it.
+ if (c[l] == graph_traits< Graph >::null_vertex())
+ return false;
+ c[l] = v;
+ return true;
+ }
+
+ // Attempt the insertion and return its result.
+ template < typename Container, typename Label, typename Graph,
+ typename Vertex >
+ bool put_vertex_label(Container& c, Graph const&, Label const& l, Vertex v,
+ unique_associative_container_tag)
+ {
+ return c.insert(std::make_pair(l, v)).second;
+ }
+
+ // Insert the pair and return true.
+ template < typename Container, typename Label, typename Graph,
+ typename Vertex >
+ bool put_vertex_label(Container& c, Graph const&, Label const& l, Vertex v,
+ multiple_associative_container_tag)
+ {
+ c.insert(std::make_pair(l, v));
+ return true;
+ }
+
+ // Dispatcher
+ template < typename Container, typename Label, typename Graph,
+ typename Vertex >
+ bool put_vertex_label(
+ Container& c, Graph const& g, Label const& l, Vertex v)
+ {
+ return put_vertex_label(c, g, l, v, container_category(c));
+ }
+ //@}
+
+ /** @name Remove Labeled Vertex */
+ //@{
+ // Tag dispatch on random access containers (i.e., vectors)
+ template <typename Container, typename Label, typename Graph>
+ void remove_labeled_vertex(Container& c, Graph& g, Label const& l,
+ random_access_container_tag)
+ {
+ if (l < c.size())
+ {
+ boost::remove_vertex(c[l], g);
+ c.erase(c.begin() + l);
+ }
+ }
+
+ // Tag dispatch on multi associative containers (i.e. multimaps).
+ template <typename Container, typename Label, typename Graph>
+ void remove_labeled_vertex(Container& c, Graph& g, Label const& l,
+ multiple_associative_container_tag)
+ {
+ typename Container::iterator c_it = c.find(l);
+ if (c_it != c.end())
+ {
+ boost::remove_vertex(c_it->second, g);
+ c.erase(c_it);
+ }
+ }
+
+ // Tag dispatch on unique associative containers (i.e. maps).
+ template <typename Container, typename Label, typename Graph>
+ void remove_labeled_vertex(Container& c, Graph& g, Label const& l,
+ unique_associative_container_tag)
+ {
+ typename Container::iterator c_it = c.find(l);
+ if (c_it != c.end())
+ {
+ boost::remove_vertex(c_it->second, g);
+ c.erase(c_it);
+ }
+ }
+
+ // Dispatcher
+ template <typename Container, typename Label, typename Graph>
+ void remove_labeled_vertex(Container& c, Graph& g, Label const& l)
+ {
+ remove_labeled_vertex(c, g, l, container_category(c));
+ }
+ //@}
+
+} // namespace detail
+
+struct labeled_graph_class_tag
+{
+};
+
+/** @internal
+ * This class is responsible for the deduction and declaration of type names
+ * for the labeled_graph class template.
+ */
+template < typename Graph, typename Label, typename Selector >
+struct labeled_graph_types
+{
+ typedef Graph graph_type;
+
+ // Label and maps
+ typedef Label label_type;
+ typedef typename graph_detail::choose_map< Selector, Label,
+ typename graph_traits< Graph >::vertex_descriptor >::type map_type;
+};
+
+/**
+ * The labeled_graph class is a graph adaptor that maintains a mapping between
+ * vertex labels and vertex descriptors.
+ *
+ * @todo This class is somewhat redundant for adjacency_list<*, vecS> if
+ * the intended label is an unsigned int (and perhaps some other cases), but
+ * it does avoid some weird ambiguities (i.e. adding a vertex with a label that
+ * does not match its target index).
+ *
+ * @todo This needs to be reconciled with the named_graph, but since there is
+ * no documentation or examples, its not going to happen.
+ */
+template < typename Graph, typename Label, typename Selector = defaultS >
+class labeled_graph : protected labeled_graph_types< Graph, Label, Selector >
+{
+ typedef labeled_graph_types< Graph, Label, Selector > Base;
+
+public:
+ typedef labeled_graph_class_tag graph_tag;
+
+ typedef typename Base::graph_type graph_type;
+ typedef typename graph_traits< graph_type >::vertex_descriptor
+ vertex_descriptor;
+ typedef
+ typename graph_traits< graph_type >::edge_descriptor edge_descriptor;
+ typedef typename graph_traits< graph_type >::directed_category
+ directed_category;
+ typedef typename graph_traits< graph_type >::edge_parallel_category
+ edge_parallel_category;
+ typedef typename graph_traits< graph_type >::traversal_category
+ traversal_category;
+
+ typedef typename graph_traits< graph_type >::out_edge_iterator
+ out_edge_iterator;
+ typedef
+ typename graph_traits< graph_type >::in_edge_iterator in_edge_iterator;
+ typedef typename graph_traits< graph_type >::adjacency_iterator
+ adjacency_iterator;
+ typedef
+ typename graph_traits< graph_type >::degree_size_type degree_size_type;
+
+ typedef
+ typename graph_traits< graph_type >::vertex_iterator vertex_iterator;
+ typedef typename graph_traits< graph_type >::vertices_size_type
+ vertices_size_type;
+ typedef typename graph_traits< graph_type >::edge_iterator edge_iterator;
+ typedef
+ typename graph_traits< graph_type >::edges_size_type edges_size_type;
+
+ typedef typename graph_type::graph_property_type graph_property_type;
+ typedef typename graph_type::graph_bundled graph_bundled;
+
+ typedef typename graph_type::vertex_property_type vertex_property_type;
+ typedef typename graph_type::vertex_bundled vertex_bundled;
+
+ typedef typename graph_type::edge_property_type edge_property_type;
+ typedef typename graph_type::edge_bundled edge_bundled;
+
+ typedef typename Base::label_type label_type;
+ typedef typename Base::map_type map_type;
+
+public:
+ labeled_graph(graph_property_type const& gp = graph_property_type())
+ : _graph(gp), _map()
+ {
+ }
+
+ labeled_graph(labeled_graph const& x) : _graph(x._graph), _map(x._map) {}
+
+ // This constructor can only be used if map_type supports positional
+ // range insertion (i.e. its a vector). This is the only case where we can
+ // try to guess the intended labels for graph.
+ labeled_graph(vertices_size_type n,
+ graph_property_type const& gp = graph_property_type())
+ : _graph(n, gp), _map()
+ {
+ std::pair< vertex_iterator, vertex_iterator > rng = vertices(_graph);
+ _map.insert(_map.end(), rng.first, rng.second);
+ }
+
+ // Construct a graph over n vertices, each of which receives a label from
+ // the range [l, l + n). Note that the graph is not directly constructed
+ // over the n vertices, but added sequentially. This constructor is
+ // necessarily slower than the underlying counterpart.
+ template < typename LabelIter >
+ labeled_graph(vertices_size_type n, LabelIter l,
+ graph_property_type const& gp = graph_property_type())
+ : _graph(gp)
+ {
+ while (n-- > 0)
+ add_vertex(*l++);
+ }
+
+ // Construct the graph over n vertices each of which has a label in the
+ // range [l, l + n) and a property in the range [p, p + n).
+ template < typename LabelIter, typename PropIter >
+ labeled_graph(vertices_size_type n, LabelIter l, PropIter p,
+ graph_property_type const& gp = graph_property_type())
+ : _graph(gp)
+ {
+ while (n-- > 0)
+ add_vertex(*l++, *p++);
+ }
+
+ labeled_graph& operator=(labeled_graph const& x)
+ {
+ _graph = x._graph;
+ _map = x._map;
+ return *this;
+ }
+
+ /** @name Graph Accessors */
+ //@{
+ graph_type& graph() { return _graph; }
+ graph_type const& graph() const { return _graph; }
+ //@}
+
+ /**
+ * Create a new label for the given vertex, returning false, if the label
+ * cannot be created.
+ */
+ bool label_vertex(vertex_descriptor v, Label const& l)
+ {
+ return graph_detail::put_vertex_label(_map, _graph, l, v);
+ }
+
+ /** @name Add Vertex
+ * Add a vertex to the graph, returning the descriptor. If the vertices
+ * are uniquely labeled and the label already exists within the graph,
+ * then no vertex is added, and the returned descriptor refers to the
+ * existing vertex. A vertex property can be given as a parameter, if
+ * needed.
+ */
+ //@{
+ vertex_descriptor add_vertex(Label const& l)
+ {
+ return graph_detail::insert_labeled_vertex(
+ _map, _graph, l, vertex_property_type())
+ .first;
+ }
+
+ vertex_descriptor add_vertex(Label const& l, vertex_property_type const& p)
+ {
+ return graph_detail::insert_labeled_vertex(_map, _graph, l, p).first;
+ }
+ //@}
+
+ /** @name Insert Vertex
+ * Insert a vertex into the graph, returning a pair containing the
+ * descriptor of a vertex and a boolean value that describes whether or not
+ * a new vertex was inserted. If vertices are not uniquely labeled, then
+ * insertion will always succeed.
+ */
+ //@{
+ std::pair< vertex_descriptor, bool > insert_vertex(Label const& l)
+ {
+ return graph_detail::insert_labeled_vertex(
+ _map, _graph, l, vertex_property_type());
+ }
+
+ std::pair< vertex_descriptor, bool > insert_vertex(
+ Label const& l, vertex_property_type const& p)
+ {
+ return graph_detail::insert_labeled_vertex(_map, _graph, l, p);
+ }
+ //@}
+
+ /** Remove the vertex with the given label. */
+ void remove_vertex(Label const& l)
+ {
+ return graph_detail::remove_labeled_vertex(_map, _graph, l);
+ }
+
+ /** Return a descriptor for the given label. */
+ vertex_descriptor vertex(Label const& l) const
+ {
+ return graph_detail::find_labeled_vertex(_map, _graph, l);
+ }
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ /** @name Bundled Properties */
+ //@{
+ // Lookup the requested vertex and return the bundle.
+ vertex_bundled& operator[](Label const& l) { return _graph[vertex(l)]; }
+
+ vertex_bundled const& operator[](Label const& l) const
+ {
+ return _graph[vertex(l)];
+ }
+
+ // Delegate edge lookup to the underlying graph.
+ edge_bundled& operator[](edge_descriptor e) { return _graph[e]; }
+
+ edge_bundled const& operator[](edge_descriptor e) const
+ {
+ return _graph[e];
+ }
+ //@}
+#endif
+
+ /** Return a null descriptor */
+ static vertex_descriptor null_vertex()
+ {
+ return graph_traits< graph_type >::null_vertex();
+ }
+
+private:
+ graph_type _graph;
+ map_type _map;
+};
+
+/**
+ * The partial specialization over graph pointers allows the construction
+ * of temporary labeled graph objects. In this case, the labels are destructed
+ * when the wrapper goes out of scope.
+ */
+template < typename Graph, typename Label, typename Selector >
+class labeled_graph< Graph*, Label, Selector >
+: protected labeled_graph_types< Graph, Label, Selector >
+{
+ typedef labeled_graph_types< Graph, Label, Selector > Base;
+
+public:
+ typedef labeled_graph_class_tag graph_tag;
+
+ typedef typename Base::graph_type graph_type;
+ typedef typename graph_traits< graph_type >::vertex_descriptor
+ vertex_descriptor;
+ typedef
+ typename graph_traits< graph_type >::edge_descriptor edge_descriptor;
+ typedef typename graph_traits< graph_type >::directed_category
+ directed_category;
+ typedef typename graph_traits< graph_type >::edge_parallel_category
+ edge_parallel_category;
+ typedef typename graph_traits< graph_type >::traversal_category
+ traversal_category;
+
+ typedef typename graph_traits< graph_type >::out_edge_iterator
+ out_edge_iterator;
+ typedef
+ typename graph_traits< graph_type >::in_edge_iterator in_edge_iterator;
+ typedef typename graph_traits< graph_type >::adjacency_iterator
+ adjacency_iterator;
+ typedef
+ typename graph_traits< graph_type >::degree_size_type degree_size_type;
+
+ typedef
+ typename graph_traits< graph_type >::vertex_iterator vertex_iterator;
+ typedef typename graph_traits< graph_type >::vertices_size_type
+ vertices_size_type;
+ typedef typename graph_traits< graph_type >::edge_iterator edge_iterator;
+ typedef
+ typename graph_traits< graph_type >::edges_size_type edges_size_type;
+
+ typedef typename graph_type::vertex_property_type vertex_property_type;
+ typedef typename graph_type::edge_property_type edge_property_type;
+ typedef typename graph_type::graph_property_type graph_property_type;
+ typedef typename graph_type::vertex_bundled vertex_bundled;
+ typedef typename graph_type::edge_bundled edge_bundled;
+
+ typedef typename Base::label_type label_type;
+ typedef typename Base::map_type map_type;
+
+ labeled_graph(graph_type* g) : _graph(g) {}
+
+ /** @name Graph Access */
+ //@{
+ graph_type& graph() { return *_graph; }
+ graph_type const& graph() const { return *_graph; }
+ //@}
+
+ /**
+ * Create a new label for the given vertex, returning false, if the label
+ * cannot be created.
+ */
+ bool label_vertex(vertex_descriptor v, Label const& l)
+ {
+ return graph_detail::put_vertex_label(_map, *_graph, l, v);
+ }
+
+ /** @name Add Vertex */
+ //@{
+ vertex_descriptor add_vertex(Label const& l)
+ {
+ return graph_detail::insert_labeled_vertex(
+ _map, *_graph, l, vertex_property_type())
+ .first;
+ }
+
+ vertex_descriptor add_vertex(Label const& l, vertex_property_type const& p)
+ {
+ return graph_detail::insert_labeled_vertex(_map, *_graph, l, p).first;
+ }
+
+ std::pair< vertex_descriptor, bool > insert_vertex(Label const& l)
+ {
+ return graph_detail::insert_labeled_vertex(
+ _map, *_graph, l, vertex_property_type());
+ }
+ //@}
+
+ /** Try to insert a vertex with the given label. */
+ std::pair< vertex_descriptor, bool > insert_vertex(
+ Label const& l, vertex_property_type const& p)
+ {
+ return graph_detail::insert_labeled_vertex(_map, *_graph, l, p);
+ }
+
+ /** Remove the vertex with the given label. */
+ void remove_vertex(Label const& l)
+ {
+ return boost::remove_vertex(vertex(l), *_graph);
+ }
+
+ /** Return a descriptor for the given label. */
+ vertex_descriptor vertex(Label const& l) const
+ {
+ return graph_detail::find_labeled_vertex(_map, *_graph, l);
+ }
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ /** @name Bundled Properties */
+ //@{
+ // Lookup the requested vertex and return the bundle.
+ vertex_bundled& operator[](Label const& l) { return (*_graph)[vertex(l)]; }
+
+ vertex_bundled const& operator[](Label const& l) const
+ {
+ return (*_graph)[vertex(l)];
+ }
+
+ // Delegate edge lookup to the underlying graph.
+ edge_bundled& operator[](edge_descriptor e) { return (*_graph)[e]; }
+
+ edge_bundled const& operator[](edge_descriptor e) const
+ {
+ return (*_graph)[e];
+ }
+ //@}
+#endif
+
+ static vertex_descriptor null_vertex()
+ {
+ return graph_traits< graph_type >::null_vertex();
+ }
+
+private:
+ graph_type* _graph;
+ map_type _map;
+};
+
+#define LABELED_GRAPH_PARAMS typename G, typename L, typename S
+#define LABELED_GRAPH labeled_graph< G, L, S >
+
+/** @name Labeled Graph */
+//@{
+template < LABELED_GRAPH_PARAMS >
+inline bool label_vertex(typename LABELED_GRAPH::vertex_descriptor v,
+ typename LABELED_GRAPH::label_type const l, LABELED_GRAPH& g)
+{
+ return g.label_vertex(v, l);
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::vertex_descriptor vertex_by_label(
+ typename LABELED_GRAPH::label_type const l, LABELED_GRAPH& g)
+{
+ return g.vertex(l);
+}
+//@}
+
+/** @name Graph */
+//@{
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool > edge(
+ typename LABELED_GRAPH::vertex_descriptor const& u,
+ typename LABELED_GRAPH::vertex_descriptor const& v, LABELED_GRAPH const& g)
+{
+ return edge(u, v, g.graph());
+}
+
+// Labeled Extensions
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool > edge_by_label(
+ typename LABELED_GRAPH::label_type const& u,
+ typename LABELED_GRAPH::label_type const& v, LABELED_GRAPH const& g)
+{
+ return edge(g.vertex(u), g.vertex(v), g);
+}
+//@}
+
+/** @name Incidence Graph */
+//@{
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::out_edge_iterator,
+ typename LABELED_GRAPH::out_edge_iterator >
+out_edges(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
+{
+ return out_edges(v, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::degree_size_type out_degree(
+ typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
+{
+ return out_degree(v, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::vertex_descriptor source(
+ typename LABELED_GRAPH::edge_descriptor e, LABELED_GRAPH const& g)
+{
+ return source(e, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::vertex_descriptor target(
+ typename LABELED_GRAPH::edge_descriptor e, LABELED_GRAPH const& g)
+{
+ return target(e, g.graph());
+}
+//@}
+
+/** @name Bidirectional Graph */
+//@{
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::in_edge_iterator,
+ typename LABELED_GRAPH::in_edge_iterator >
+in_edges(typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
+{
+ return in_edges(v, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::degree_size_type in_degree(
+ typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
+{
+ return in_degree(v, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::degree_size_type degree(
+ typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
+{
+ return degree(v, g.graph());
+}
+//@}
+
+/** @name Adjacency Graph */
+//@{
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::adjacency_iterator,
+ typename LABELED_GRAPH::adjacency_iterator >
+adjacent_vertices(
+ typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH const& g)
+{
+ return adjacent_vertices(v, g.graph());
+}
+//@}
+
+/** @name VertexListGraph */
+//@{
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::vertex_iterator,
+ typename LABELED_GRAPH::vertex_iterator >
+vertices(LABELED_GRAPH const& g)
+{
+ return vertices(g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::vertices_size_type num_vertices(
+ LABELED_GRAPH const& g)
+{
+ return num_vertices(g.graph());
+}
+//@}
+
+/** @name EdgeListGraph */
+//@{
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::edge_iterator,
+ typename LABELED_GRAPH::edge_iterator >
+edges(LABELED_GRAPH const& g)
+{
+ return edges(g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::edges_size_type num_edges(LABELED_GRAPH const& g)
+{
+ return num_edges(g.graph());
+}
+//@}
+
+/** @internal @name Property Lookup */
+//@{
+namespace graph_detail
+{
+ struct labeled_graph_vertex_property_selector
+ {
+ template < class LabeledGraph, class Property, class Tag > struct bind_
+ {
+ typedef typename LabeledGraph::graph_type Graph;
+ typedef property_map< Graph, Tag > PropertyMap;
+ typedef typename PropertyMap::type type;
+ typedef typename PropertyMap::const_type const_type;
+ };
+ };
+
+ struct labeled_graph_edge_property_selector
+ {
+ template < class LabeledGraph, class Property, class Tag > struct bind_
+ {
+ typedef typename LabeledGraph::graph_type Graph;
+ typedef property_map< Graph, Tag > PropertyMap;
+ typedef typename PropertyMap::type type;
+ typedef typename PropertyMap::const_type const_type;
+ };
+ };
+}
+
+template <> struct vertex_property_selector< labeled_graph_class_tag >
+{
+ typedef graph_detail::labeled_graph_vertex_property_selector type;
+};
+
+template <> struct edge_property_selector< labeled_graph_class_tag >
+{
+ typedef graph_detail::labeled_graph_edge_property_selector type;
+};
+//@}
+
+/** @name Property Graph */
+//@{
+template < LABELED_GRAPH_PARAMS, typename Prop >
+inline typename property_map< LABELED_GRAPH, Prop >::type get(
+ Prop p, LABELED_GRAPH& g)
+{
+ return get(p, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS, typename Prop >
+inline typename property_map< LABELED_GRAPH, Prop >::const_type get(
+ Prop p, LABELED_GRAPH const& g)
+{
+ return get(p, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS, typename Prop, typename Key >
+inline typename property_traits< typename property_map<
+ typename LABELED_GRAPH::graph_type, Prop >::const_type >::value_type
+get(Prop p, LABELED_GRAPH const& g, const Key& k)
+{
+ return get(p, g.graph(), k);
+}
+
+template < LABELED_GRAPH_PARAMS, typename Prop, typename Key, typename Value >
+inline void put(Prop p, LABELED_GRAPH& g, Key const& k, Value const& v)
+{
+ put(p, g.graph(), k, v);
+}
+//@}
+
+/** @name Mutable Graph */
+//@{
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool > add_edge(
+ typename LABELED_GRAPH::vertex_descriptor const& u,
+ typename LABELED_GRAPH::vertex_descriptor const& v, LABELED_GRAPH& g)
+{
+ return add_edge(u, v, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool > add_edge(
+ typename LABELED_GRAPH::vertex_descriptor const& u,
+ typename LABELED_GRAPH::vertex_descriptor const& v,
+ typename LABELED_GRAPH::edge_property_type const& p, LABELED_GRAPH& g)
+{
+ return add_edge(u, v, p, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline void clear_vertex(
+ typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH& g)
+{
+ return clear_vertex(v, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline void remove_edge(
+ typename LABELED_GRAPH::edge_descriptor e, LABELED_GRAPH& g)
+{
+ return remove_edge(e, g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline void remove_edge(typename LABELED_GRAPH::vertex_descriptor u,
+ typename LABELED_GRAPH::vertex_descriptor v, LABELED_GRAPH& g)
+{
+ return remove_edge(u, v, g.graph());
+}
+
+// Labeled extensions
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool >
+add_edge_by_label(typename LABELED_GRAPH::label_type const& u,
+ typename LABELED_GRAPH::label_type const& v, LABELED_GRAPH& g)
+{
+ return add_edge(g.vertex(u), g.vertex(v), g);
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline std::pair< typename LABELED_GRAPH::edge_descriptor, bool >
+add_edge_by_label(typename LABELED_GRAPH::label_type const& u,
+ typename LABELED_GRAPH::label_type const& v,
+ typename LABELED_GRAPH::edge_property_type const& p, LABELED_GRAPH& g)
+{
+ return add_edge(g.vertex(u), g.vertex(v), p, g);
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline void clear_vertex_by_label(
+ typename LABELED_GRAPH::label_type const& l, LABELED_GRAPH& g)
+{
+ clear_vertex(g.vertex(l), g.graph());
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline void remove_edge_by_label(typename LABELED_GRAPH::label_type const& u,
+ typename LABELED_GRAPH::label_type const& v, LABELED_GRAPH& g)
+{
+ remove_edge(g.vertex(u), g.vertex(v), g.graph());
+}
+//@}
+
+/** @name Labeled Mutable Graph
+ * The labeled mutable graph hides the add_ and remove_ vertex functions from
+ * the mutable graph concept. Note that the remove_vertex is hidden because
+ * removing the vertex without its key could leave a dangling reference in
+ * the map.
+ */
+//@{
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::vertex_descriptor add_vertex(
+ typename LABELED_GRAPH::label_type const& l, LABELED_GRAPH& g)
+{
+ return g.add_vertex(l);
+}
+
+// MutableLabeledPropertyGraph::add_vertex(l, vp, g)
+template < LABELED_GRAPH_PARAMS >
+inline typename LABELED_GRAPH::vertex_descriptor add_vertex(
+ typename LABELED_GRAPH::label_type const& l,
+ typename LABELED_GRAPH::vertex_property_type const& p, LABELED_GRAPH& g)
+{
+ return g.add_vertex(l, p);
+}
+
+template < LABELED_GRAPH_PARAMS >
+inline void remove_vertex(
+ typename LABELED_GRAPH::label_type const& l, LABELED_GRAPH& g)
+{
+ g.remove_vertex(l);
+}
+//@}
+
+#undef LABELED_GRAPH_PARAMS
+#undef LABELED_GRAPH
+
+} // namespace boost
+
+// Pull the labeled graph traits
+#include <boost/graph/detail/labeled_graph_traits.hpp>
+
+#endif // BOOST_GRAPH_LABELED_GRAPH_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/leda_graph.hpp b/contrib/restricted/boost/graph/include/boost/graph/leda_graph.hpp
new file mode 100644
index 0000000000..7d58518a7d
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/leda_graph.hpp
@@ -0,0 +1,942 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004 The Trustees of Indiana University.
+// Copyright 2007 University of Karlsruhe
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Douglas Gregor,
+// Jens Mueller
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_LEDA_HPP
+#define BOOST_GRAPH_LEDA_HPP
+
+#include <boost/config.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+
+#include <LEDA/graph/graph.h>
+#include <LEDA/graph/node_array.h>
+#include <LEDA/graph/node_map.h>
+
+// The functions and classes in this file allows the user to
+// treat a LEDA GRAPH object as a boost graph "as is". No
+// wrapper is needed for the GRAPH object.
+
+// Warning: this implementation relies on partial specialization
+// for the graph_traits class (so it won't compile with Visual C++)
+
+// Warning: this implementation is in alpha and has not been tested
+
+namespace boost
+{
+
+struct leda_graph_traversal_category : public virtual bidirectional_graph_tag,
+ public virtual adjacency_graph_tag,
+ public virtual vertex_list_graph_tag
+{
+};
+
+template < class vtype, class etype >
+struct graph_traits< leda::GRAPH< vtype, etype > >
+{
+ typedef leda::node vertex_descriptor;
+ typedef leda::edge edge_descriptor;
+
+ class adjacency_iterator
+ : public iterator_facade< adjacency_iterator, leda::node,
+ bidirectional_traversal_tag, leda::node, const leda::node* >
+ {
+ public:
+ adjacency_iterator(
+ leda::node node = 0, const leda::GRAPH< vtype, etype >* g = 0)
+ : base(node), g(g)
+ {
+ }
+
+ private:
+ leda::node dereference() const { return leda::target(base); }
+
+ bool equal(const adjacency_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->adj_succ(base); }
+ void decrement() { base = g->adj_pred(base); }
+
+ leda::edge base;
+ const leda::GRAPH< vtype, etype >* g;
+
+ friend class iterator_core_access;
+ };
+
+ class out_edge_iterator
+ : public iterator_facade< out_edge_iterator, leda::edge,
+ bidirectional_traversal_tag, const leda::edge&, const leda::edge* >
+ {
+ public:
+ out_edge_iterator(
+ leda::node node = 0, const leda::GRAPH< vtype, etype >* g = 0)
+ : base(node), g(g)
+ {
+ }
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const out_edge_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->adj_succ(base); }
+ void decrement() { base = g->adj_pred(base); }
+
+ leda::edge base;
+ const leda::GRAPH< vtype, etype >* g;
+
+ friend class iterator_core_access;
+ };
+
+ class in_edge_iterator
+ : public iterator_facade< in_edge_iterator, leda::edge,
+ bidirectional_traversal_tag, const leda::edge&, const leda::edge* >
+ {
+ public:
+ in_edge_iterator(
+ leda::node node = 0, const leda::GRAPH< vtype, etype >* g = 0)
+ : base(node), g(g)
+ {
+ }
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const in_edge_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->in_succ(base); }
+ void decrement() { base = g->in_pred(base); }
+
+ leda::edge base;
+ const leda::GRAPH< vtype, etype >* g;
+
+ friend class iterator_core_access;
+ };
+
+ class vertex_iterator
+ : public iterator_facade< vertex_iterator, leda::node,
+ bidirectional_traversal_tag, const leda::node&, const leda::node* >
+ {
+ public:
+ vertex_iterator(
+ leda::node node = 0, const leda::GRAPH< vtype, etype >* g = 0)
+ : base(node), g(g)
+ {
+ }
+
+ private:
+ const leda::node& dereference() const { return base; }
+
+ bool equal(const vertex_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->succ_node(base); }
+ void decrement() { base = g->pred_node(base); }
+
+ leda::node base;
+ const leda::GRAPH< vtype, etype >* g;
+
+ friend class iterator_core_access;
+ };
+
+ class edge_iterator
+ : public iterator_facade< edge_iterator, leda::edge,
+ bidirectional_traversal_tag, const leda::edge&, const leda::edge* >
+ {
+ public:
+ edge_iterator(
+ leda::edge edge = 0, const leda::GRAPH< vtype, etype >* g = 0)
+ : base(edge), g(g)
+ {
+ }
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const edge_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->succ_edge(base); }
+ void decrement() { base = g->pred_edge(base); }
+
+ leda::node base;
+ const leda::GRAPH< vtype, etype >* g;
+
+ friend class iterator_core_access;
+ };
+
+ typedef directed_tag directed_category;
+ typedef allow_parallel_edge_tag edge_parallel_category; // not sure here
+ typedef leda_graph_traversal_category traversal_category;
+ typedef int vertices_size_type;
+ typedef int edges_size_type;
+ typedef int degree_size_type;
+};
+
+template <> struct graph_traits< leda::graph >
+{
+ typedef leda::node vertex_descriptor;
+ typedef leda::edge edge_descriptor;
+
+ class adjacency_iterator
+ : public iterator_facade< adjacency_iterator, leda::node,
+ bidirectional_traversal_tag, leda::node, const leda::node* >
+ {
+ public:
+ adjacency_iterator(leda::edge edge = 0, const leda::graph* g = 0)
+ : base(edge), g(g)
+ {
+ }
+
+ private:
+ leda::node dereference() const { return leda::target(base); }
+
+ bool equal(const adjacency_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->adj_succ(base); }
+ void decrement() { base = g->adj_pred(base); }
+
+ leda::edge base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ class out_edge_iterator
+ : public iterator_facade< out_edge_iterator, leda::edge,
+ bidirectional_traversal_tag, const leda::edge&, const leda::edge* >
+ {
+ public:
+ out_edge_iterator(leda::edge edge = 0, const leda::graph* g = 0)
+ : base(edge), g(g)
+ {
+ }
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const out_edge_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->adj_succ(base); }
+ void decrement() { base = g->adj_pred(base); }
+
+ leda::edge base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ class in_edge_iterator
+ : public iterator_facade< in_edge_iterator, leda::edge,
+ bidirectional_traversal_tag, const leda::edge&, const leda::edge* >
+ {
+ public:
+ in_edge_iterator(leda::edge edge = 0, const leda::graph* g = 0)
+ : base(edge), g(g)
+ {
+ }
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const in_edge_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->in_succ(base); }
+ void decrement() { base = g->in_pred(base); }
+
+ leda::edge base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ class vertex_iterator
+ : public iterator_facade< vertex_iterator, leda::node,
+ bidirectional_traversal_tag, const leda::node&, const leda::node* >
+ {
+ public:
+ vertex_iterator(leda::node node = 0, const leda::graph* g = 0)
+ : base(node), g(g)
+ {
+ }
+
+ private:
+ const leda::node& dereference() const { return base; }
+
+ bool equal(const vertex_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->succ_node(base); }
+ void decrement() { base = g->pred_node(base); }
+
+ leda::node base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ class edge_iterator
+ : public iterator_facade< edge_iterator, leda::edge,
+ bidirectional_traversal_tag, const leda::edge&, const leda::edge* >
+ {
+ public:
+ edge_iterator(leda::edge edge = 0, const leda::graph* g = 0)
+ : base(edge), g(g)
+ {
+ }
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const edge_iterator& other) const
+ {
+ return base == other.base;
+ }
+
+ void increment() { base = g->succ_edge(base); }
+ void decrement() { base = g->pred_edge(base); }
+
+ leda::edge base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ typedef directed_tag directed_category;
+ typedef allow_parallel_edge_tag edge_parallel_category; // not sure here
+ typedef leda_graph_traversal_category traversal_category;
+ typedef int vertices_size_type;
+ typedef int edges_size_type;
+ typedef int degree_size_type;
+};
+
+} // namespace boost
+
+namespace boost
+{
+
+//===========================================================================
+// functions for GRAPH<vtype,etype>
+
+template < class vtype, class etype >
+typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor source(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::edge_descriptor e,
+ const leda::GRAPH< vtype, etype >& g)
+{
+ return source(e);
+}
+
+template < class vtype, class etype >
+typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor target(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::edge_descriptor e,
+ const leda::GRAPH< vtype, etype >& g)
+{
+ return target(e);
+}
+
+template < class vtype, class etype >
+inline std::pair<
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_iterator,
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_iterator >
+vertices(const leda::GRAPH< vtype, etype >& g)
+{
+ typedef
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_iterator
+ Iter;
+ return std::make_pair(Iter(g.first_node(), &g), Iter(0, &g));
+}
+
+template < class vtype, class etype >
+inline std::pair<
+ typename graph_traits< leda::GRAPH< vtype, etype > >::edge_iterator,
+ typename graph_traits< leda::GRAPH< vtype, etype > >::edge_iterator >
+edges(const leda::GRAPH< vtype, etype >& g)
+{
+ typedef typename graph_traits< leda::GRAPH< vtype, etype > >::edge_iterator
+ Iter;
+ return std::make_pair(Iter(g.first_edge(), &g), Iter(0, &g));
+}
+
+template < class vtype, class etype >
+inline std::pair<
+ typename graph_traits< leda::GRAPH< vtype, etype > >::out_edge_iterator,
+ typename graph_traits< leda::GRAPH< vtype, etype > >::out_edge_iterator >
+out_edges(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ const leda::GRAPH< vtype, etype >& g)
+{
+ typedef
+ typename graph_traits< leda::GRAPH< vtype, etype > >::out_edge_iterator
+ Iter;
+ return std::make_pair(Iter(g.first_adj_edge(u, 0), &g), Iter(0, &g));
+}
+
+template < class vtype, class etype >
+inline std::pair<
+ typename graph_traits< leda::GRAPH< vtype, etype > >::in_edge_iterator,
+ typename graph_traits< leda::GRAPH< vtype, etype > >::in_edge_iterator >
+in_edges(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ const leda::GRAPH< vtype, etype >& g)
+{
+ typedef
+ typename graph_traits< leda::GRAPH< vtype, etype > >::in_edge_iterator
+ Iter;
+ return std::make_pair(Iter(g.first_adj_edge(u, 1), &g), Iter(0, &g));
+}
+
+template < class vtype, class etype >
+inline std::pair<
+ typename graph_traits< leda::GRAPH< vtype, etype > >::adjacency_iterator,
+ typename graph_traits< leda::GRAPH< vtype, etype > >::adjacency_iterator >
+adjacent_vertices(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ const leda::GRAPH< vtype, etype >& g)
+{
+ typedef
+ typename graph_traits< leda::GRAPH< vtype, etype > >::adjacency_iterator
+ Iter;
+ return std::make_pair(Iter(g.first_adj_edge(u, 0), &g), Iter(0, &g));
+}
+
+template < class vtype, class etype >
+typename graph_traits< leda::GRAPH< vtype, etype > >::vertices_size_type
+num_vertices(const leda::GRAPH< vtype, etype >& g)
+{
+ return g.number_of_nodes();
+}
+
+template < class vtype, class etype >
+typename graph_traits< leda::GRAPH< vtype, etype > >::edges_size_type num_edges(
+ const leda::GRAPH< vtype, etype >& g)
+{
+ return g.number_of_edges();
+}
+
+template < class vtype, class etype >
+typename graph_traits< leda::GRAPH< vtype, etype > >::degree_size_type
+out_degree(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ const leda::GRAPH< vtype, etype >& g)
+{
+ return g.outdeg(u);
+}
+
+template < class vtype, class etype >
+typename graph_traits< leda::GRAPH< vtype, etype > >::degree_size_type
+in_degree(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ const leda::GRAPH< vtype, etype >& g)
+{
+ return g.indeg(u);
+}
+
+template < class vtype, class etype >
+typename graph_traits< leda::GRAPH< vtype, etype > >::degree_size_type degree(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ const leda::GRAPH< vtype, etype >& g)
+{
+ return g.outdeg(u) + g.indeg(u);
+}
+
+template < class vtype, class etype >
+typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor
+add_vertex(leda::GRAPH< vtype, etype >& g)
+{
+ return g.new_node();
+}
+
+template < class vtype, class etype >
+typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor
+add_vertex(const vtype& vp, leda::GRAPH< vtype, etype >& g)
+{
+ return g.new_node(vp);
+}
+
+template < class vtype, class etype >
+void clear_vertex(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ leda::GRAPH< vtype, etype >& g)
+{
+ typename graph_traits< leda::GRAPH< vtype, etype > >::out_edge_iterator ei,
+ ei_end;
+ for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ei++)
+ remove_edge(*ei);
+
+ typename graph_traits< leda::GRAPH< vtype, etype > >::in_edge_iterator iei,
+ iei_end;
+ for (boost::tie(iei, iei_end) = in_edges(u, g); iei != iei_end; iei++)
+ remove_edge(*iei);
+}
+
+template < class vtype, class etype >
+void remove_vertex(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ leda::GRAPH< vtype, etype >& g)
+{
+ g.del_node(u);
+}
+
+template < class vtype, class etype >
+std::pair<
+ typename graph_traits< leda::GRAPH< vtype, etype > >::edge_descriptor,
+ bool >
+add_edge(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor v,
+ leda::GRAPH< vtype, etype >& g)
+{
+ return std::make_pair(g.new_edge(u, v), true);
+}
+
+template < class vtype, class etype >
+std::pair<
+ typename graph_traits< leda::GRAPH< vtype, etype > >::edge_descriptor,
+ bool >
+add_edge(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor v,
+ const etype& et, leda::GRAPH< vtype, etype >& g)
+{
+ return std::make_pair(g.new_edge(u, v, et), true);
+}
+
+template < class vtype, class etype >
+void remove_edge(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor u,
+ typename graph_traits< leda::GRAPH< vtype, etype > >::vertex_descriptor v,
+ leda::GRAPH< vtype, etype >& g)
+{
+ typename graph_traits< leda::GRAPH< vtype, etype > >::out_edge_iterator i,
+ iend;
+ for (boost::tie(i, iend) = out_edges(u, g); i != iend; ++i)
+ if (target(*i, g) == v)
+ g.del_edge(*i);
+}
+
+template < class vtype, class etype >
+void remove_edge(
+ typename graph_traits< leda::GRAPH< vtype, etype > >::edge_descriptor e,
+ leda::GRAPH< vtype, etype >& g)
+{
+ g.del_edge(e);
+}
+
+//===========================================================================
+// functions for graph (non-templated version)
+
+graph_traits< leda::graph >::vertex_descriptor source(
+ graph_traits< leda::graph >::edge_descriptor e, const leda::graph& g)
+{
+ return source(e);
+}
+
+graph_traits< leda::graph >::vertex_descriptor target(
+ graph_traits< leda::graph >::edge_descriptor e, const leda::graph& g)
+{
+ return target(e);
+}
+
+inline std::pair< graph_traits< leda::graph >::vertex_iterator,
+ graph_traits< leda::graph >::vertex_iterator >
+vertices(const leda::graph& g)
+{
+ typedef graph_traits< leda::graph >::vertex_iterator Iter;
+ return std::make_pair(Iter(g.first_node(), &g), Iter(0, &g));
+}
+
+inline std::pair< graph_traits< leda::graph >::edge_iterator,
+ graph_traits< leda::graph >::edge_iterator >
+edges(const leda::graph& g)
+{
+ typedef graph_traits< leda::graph >::edge_iterator Iter;
+ return std::make_pair(Iter(g.first_edge(), &g), Iter(0, &g));
+}
+
+inline std::pair< graph_traits< leda::graph >::out_edge_iterator,
+ graph_traits< leda::graph >::out_edge_iterator >
+out_edges(
+ graph_traits< leda::graph >::vertex_descriptor u, const leda::graph& g)
+{
+ typedef graph_traits< leda::graph >::out_edge_iterator Iter;
+ return std::make_pair(Iter(g.first_adj_edge(u), &g), Iter(0, &g));
+}
+
+inline std::pair< graph_traits< leda::graph >::in_edge_iterator,
+ graph_traits< leda::graph >::in_edge_iterator >
+in_edges(graph_traits< leda::graph >::vertex_descriptor u, const leda::graph& g)
+{
+ typedef graph_traits< leda::graph >::in_edge_iterator Iter;
+ return std::make_pair(Iter(g.first_in_edge(u), &g), Iter(0, &g));
+}
+
+inline std::pair< graph_traits< leda::graph >::adjacency_iterator,
+ graph_traits< leda::graph >::adjacency_iterator >
+adjacent_vertices(
+ graph_traits< leda::graph >::vertex_descriptor u, const leda::graph& g)
+{
+ typedef graph_traits< leda::graph >::adjacency_iterator Iter;
+ return std::make_pair(Iter(g.first_adj_edge(u), &g), Iter(0, &g));
+}
+
+graph_traits< leda::graph >::vertices_size_type num_vertices(
+ const leda::graph& g)
+{
+ return g.number_of_nodes();
+}
+
+graph_traits< leda::graph >::edges_size_type num_edges(const leda::graph& g)
+{
+ return g.number_of_edges();
+}
+
+graph_traits< leda::graph >::degree_size_type out_degree(
+ graph_traits< leda::graph >::vertex_descriptor u, const leda::graph& g)
+{
+ return g.outdeg(u);
+}
+
+graph_traits< leda::graph >::degree_size_type in_degree(
+ graph_traits< leda::graph >::vertex_descriptor u, const leda::graph& g)
+{
+ return g.indeg(u);
+}
+
+graph_traits< leda::graph >::degree_size_type degree(
+ graph_traits< leda::graph >::vertex_descriptor u, const leda::graph& g)
+{
+ return g.outdeg(u) + g.indeg(u);
+}
+
+graph_traits< leda::graph >::vertex_descriptor add_vertex(leda::graph& g)
+{
+ return g.new_node();
+}
+
+void remove_edge(graph_traits< leda::graph >::vertex_descriptor u,
+ graph_traits< leda::graph >::vertex_descriptor v, leda::graph& g)
+{
+ graph_traits< leda::graph >::out_edge_iterator i, iend;
+ for (boost::tie(i, iend) = out_edges(u, g); i != iend; ++i)
+ if (target(*i, g) == v)
+ g.del_edge(*i);
+}
+
+void remove_edge(graph_traits< leda::graph >::edge_descriptor e, leda::graph& g)
+{
+ g.del_edge(e);
+}
+
+void clear_vertex(
+ graph_traits< leda::graph >::vertex_descriptor u, leda::graph& g)
+{
+ graph_traits< leda::graph >::out_edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ei++)
+ remove_edge(*ei, g);
+
+ graph_traits< leda::graph >::in_edge_iterator iei, iei_end;
+ for (boost::tie(iei, iei_end) = in_edges(u, g); iei != iei_end; iei++)
+ remove_edge(*iei, g);
+}
+
+void remove_vertex(
+ graph_traits< leda::graph >::vertex_descriptor u, leda::graph& g)
+{
+ g.del_node(u);
+}
+
+std::pair< graph_traits< leda::graph >::edge_descriptor, bool > add_edge(
+ graph_traits< leda::graph >::vertex_descriptor u,
+ graph_traits< leda::graph >::vertex_descriptor v, leda::graph& g)
+{
+ return std::make_pair(g.new_edge(u, v), true);
+}
+
+//===========================================================================
+// property maps for GRAPH<vtype,etype>
+
+class leda_graph_id_map : public put_get_helper< int, leda_graph_id_map >
+{
+public:
+ typedef readable_property_map_tag category;
+ typedef int value_type;
+ typedef int reference;
+ typedef leda::node key_type;
+ leda_graph_id_map() {}
+ template < class T > long operator[](T x) const { return x->id(); }
+};
+template < class vtype, class etype >
+inline leda_graph_id_map get(
+ vertex_index_t, const leda::GRAPH< vtype, etype >& g)
+{
+ return leda_graph_id_map();
+}
+template < class vtype, class etype >
+inline leda_graph_id_map get(edge_index_t, const leda::GRAPH< vtype, etype >& g)
+{
+ return leda_graph_id_map();
+}
+
+template < class Tag > struct leda_property_map
+{
+};
+
+template <> struct leda_property_map< vertex_index_t >
+{
+ template < class vtype, class etype > struct bind_
+ {
+ typedef leda_graph_id_map type;
+ typedef leda_graph_id_map const_type;
+ };
+};
+template <> struct leda_property_map< edge_index_t >
+{
+ template < class vtype, class etype > struct bind_
+ {
+ typedef leda_graph_id_map type;
+ typedef leda_graph_id_map const_type;
+ };
+};
+
+template < class Data, class DataRef, class GraphPtr >
+class leda_graph_data_map : public put_get_helper< DataRef,
+ leda_graph_data_map< Data, DataRef, GraphPtr > >
+{
+public:
+ typedef Data value_type;
+ typedef DataRef reference;
+ typedef void key_type;
+ typedef lvalue_property_map_tag category;
+ leda_graph_data_map(GraphPtr g) : m_g(g) {}
+ template < class NodeOrEdge > DataRef operator[](NodeOrEdge x) const
+ {
+ return (*m_g)[x];
+ }
+
+protected:
+ GraphPtr m_g;
+};
+
+template <> struct leda_property_map< vertex_all_t >
+{
+ template < class vtype, class etype > struct bind_
+ {
+ typedef leda_graph_data_map< vtype, vtype&,
+ leda::GRAPH< vtype, etype >* >
+ type;
+ typedef leda_graph_data_map< vtype, const vtype&,
+ const leda::GRAPH< vtype, etype >* >
+ const_type;
+ };
+};
+template < class vtype, class etype >
+inline typename property_map< leda::GRAPH< vtype, etype >, vertex_all_t >::type
+get(vertex_all_t, leda::GRAPH< vtype, etype >& g)
+{
+ typedef
+ typename property_map< leda::GRAPH< vtype, etype >, vertex_all_t >::type
+ pmap_type;
+ return pmap_type(&g);
+}
+template < class vtype, class etype >
+inline typename property_map< leda::GRAPH< vtype, etype >,
+ vertex_all_t >::const_type
+get(vertex_all_t, const leda::GRAPH< vtype, etype >& g)
+{
+ typedef typename property_map< leda::GRAPH< vtype, etype >,
+ vertex_all_t >::const_type pmap_type;
+ return pmap_type(&g);
+}
+
+template <> struct leda_property_map< edge_all_t >
+{
+ template < class vtype, class etype > struct bind_
+ {
+ typedef leda_graph_data_map< etype, etype&,
+ leda::GRAPH< vtype, etype >* >
+ type;
+ typedef leda_graph_data_map< etype, const etype&,
+ const leda::GRAPH< vtype, etype >* >
+ const_type;
+ };
+};
+template < class vtype, class etype >
+inline typename property_map< leda::GRAPH< vtype, etype >, edge_all_t >::type
+get(edge_all_t, leda::GRAPH< vtype, etype >& g)
+{
+ typedef
+ typename property_map< leda::GRAPH< vtype, etype >, edge_all_t >::type
+ pmap_type;
+ return pmap_type(&g);
+}
+template < class vtype, class etype >
+inline
+ typename property_map< leda::GRAPH< vtype, etype >, edge_all_t >::const_type
+ get(edge_all_t, const leda::GRAPH< vtype, etype >& g)
+{
+ typedef typename property_map< leda::GRAPH< vtype, etype >,
+ edge_all_t >::const_type pmap_type;
+ return pmap_type(&g);
+}
+
+// property map interface to the LEDA node_array class
+
+template < class E, class ERef, class NodeMapPtr >
+class leda_node_property_map
+: public put_get_helper< ERef, leda_node_property_map< E, ERef, NodeMapPtr > >
+{
+public:
+ typedef E value_type;
+ typedef ERef reference;
+ typedef leda::node key_type;
+ typedef lvalue_property_map_tag category;
+ leda_node_property_map(NodeMapPtr a) : m_array(a) {}
+ ERef operator[](leda::node n) const { return (*m_array)[n]; }
+
+protected:
+ NodeMapPtr m_array;
+};
+template < class E >
+leda_node_property_map< E, const E&, const leda::node_array< E >* >
+make_leda_node_property_map(const leda::node_array< E >& a)
+{
+ typedef leda_node_property_map< E, const E&, const leda::node_array< E >* >
+ pmap_type;
+ return pmap_type(&a);
+}
+template < class E >
+leda_node_property_map< E, E&, leda::node_array< E >* >
+make_leda_node_property_map(leda::node_array< E >& a)
+{
+ typedef leda_node_property_map< E, E&, leda::node_array< E >* > pmap_type;
+ return pmap_type(&a);
+}
+
+template < class E >
+leda_node_property_map< E, const E&, const leda::node_map< E >* >
+make_leda_node_property_map(const leda::node_map< E >& a)
+{
+ typedef leda_node_property_map< E, const E&, const leda::node_map< E >* >
+ pmap_type;
+ return pmap_type(&a);
+}
+template < class E >
+leda_node_property_map< E, E&, leda::node_map< E >* >
+make_leda_node_property_map(leda::node_map< E >& a)
+{
+ typedef leda_node_property_map< E, E&, leda::node_map< E >* > pmap_type;
+ return pmap_type(&a);
+}
+
+// g++ 'enumeral_type' in template unification not implemented workaround
+template < class vtype, class etype, class Tag >
+struct property_map< leda::GRAPH< vtype, etype >, Tag >
+{
+ typedef typename leda_property_map< Tag >::template bind_< vtype, etype >
+ map_gen;
+ typedef typename map_gen::type type;
+ typedef typename map_gen::const_type const_type;
+};
+
+template < class vtype, class etype, class PropertyTag, class Key >
+inline typename boost::property_traits< typename boost::property_map<
+ leda::GRAPH< vtype, etype >, PropertyTag >::const_type >::value_type
+get(PropertyTag p, const leda::GRAPH< vtype, etype >& g, const Key& key)
+{
+ return get(get(p, g), key);
+}
+
+template < class vtype, class etype, class PropertyTag, class Key, class Value >
+inline void put(PropertyTag p, leda::GRAPH< vtype, etype >& g, const Key& key,
+ const Value& value)
+{
+ typedef
+ typename property_map< leda::GRAPH< vtype, etype >, PropertyTag >::type
+ Map;
+ Map pmap = get(p, g);
+ put(pmap, key, value);
+}
+
+// property map interface to the LEDA edge_array class
+
+template < class E, class ERef, class EdgeMapPtr >
+class leda_edge_property_map
+: public put_get_helper< ERef, leda_edge_property_map< E, ERef, EdgeMapPtr > >
+{
+public:
+ typedef E value_type;
+ typedef ERef reference;
+ typedef leda::edge key_type;
+ typedef lvalue_property_map_tag category;
+ leda_edge_property_map(EdgeMapPtr a) : m_array(a) {}
+ ERef operator[](leda::edge n) const { return (*m_array)[n]; }
+
+protected:
+ EdgeMapPtr m_array;
+};
+template < class E >
+leda_edge_property_map< E, const E&, const leda::edge_array< E >* >
+make_leda_node_property_map(const leda::node_array< E >& a)
+{
+ typedef leda_edge_property_map< E, const E&, const leda::node_array< E >* >
+ pmap_type;
+ return pmap_type(&a);
+}
+template < class E >
+leda_edge_property_map< E, E&, leda::edge_array< E >* >
+make_leda_edge_property_map(leda::edge_array< E >& a)
+{
+ typedef leda_edge_property_map< E, E&, leda::edge_array< E >* > pmap_type;
+ return pmap_type(&a);
+}
+
+template < class E >
+leda_edge_property_map< E, const E&, const leda::edge_map< E >* >
+make_leda_edge_property_map(const leda::edge_map< E >& a)
+{
+ typedef leda_edge_property_map< E, const E&, const leda::edge_map< E >* >
+ pmap_type;
+ return pmap_type(&a);
+}
+template < class E >
+leda_edge_property_map< E, E&, leda::edge_map< E >* >
+make_leda_edge_property_map(leda::edge_map< E >& a)
+{
+ typedef leda_edge_property_map< E, E&, leda::edge_map< E >* > pmap_type;
+ return pmap_type(&a);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_LEDA_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/loop_erased_random_walk.hpp b/contrib/restricted/boost/graph/include/boost/graph/loop_erased_random_walk.hpp
new file mode 100644
index 0000000000..432d515940
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/loop_erased_random_walk.hpp
@@ -0,0 +1,141 @@
+// Copyright 2010 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jeremiah Willcock
+// Andrew Lumsdaine
+
+#ifndef BOOST_GRAPH_LOOP_ERASED_RANDOM_WALK_HPP
+#define BOOST_GRAPH_LOOP_ERASED_RANDOM_WALK_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/random.hpp>
+#include <boost/next_prior.hpp>
+#include <vector>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+
+struct BOOST_SYMBOL_VISIBLE loop_erased_random_walk_stuck
+: public std::exception
+{
+ ~loop_erased_random_walk_stuck() BOOST_OVERRIDE {}
+ const char* what() const noexcept BOOST_OVERRIDE
+ {
+ return "Loop-erased random walk found a vertex with no out-edges";
+ }
+};
+
+// Do a loop-erased random walk from vertex s to any vertex colored black (or
+// actually any color other than white or gray) in the color map. The color
+// white is for vertices that are not part of the path, while gray is for
+// those that are on the path (for cycle detection). The vector path is used
+// for temporary storage and as the result of the algorithm; while all
+// elements of the path except the last have their colors set to gray upon
+// return. Vertex s must start off colored white.
+//
+// Useful references:
+// http://everything2.com/title/loop-erased+random+walk
+// Wikipedia page on "Loop-Erased Random Walk"
+
+template < typename Graph, typename ColorMap, typename NextEdge >
+void loop_erased_random_walk(const Graph& g,
+ typename boost::graph_traits< Graph >::vertex_descriptor s,
+ NextEdge next_edge, ColorMap color,
+ std::vector< typename boost::graph_traits< Graph >::vertex_descriptor >&
+ path)
+{
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+ typedef
+ typename boost::graph_traits< Graph >::edge_descriptor edge_descriptor;
+ typedef typename boost::property_traits< ColorMap >::value_type color_t;
+ typedef boost::color_traits< color_t > color_gen;
+
+ BOOST_ASSERT(get(color, s) == color_gen::white());
+ path.clear();
+ path.push_back(s);
+ put(color, s, color_gen::gray());
+ while (true)
+ {
+ edge_descriptor e = next_edge(s, g);
+ vertex_descriptor t = target(e, g);
+ color_t t_color = get(color, t);
+ if (t_color == color_gen::white())
+ {
+ path.push_back(t);
+ put(color, t, color_gen::gray());
+ s = t;
+ }
+ else if (t_color == color_gen::gray())
+ {
+ // Found a loop; delete from path from the first occurrence of t to
+ // the end, coloring vertices white.
+ typename std::vector< vertex_descriptor >::iterator it
+ = std::find(path.begin(), path.end(), t);
+ BOOST_ASSERT(it != path.end());
+ ++it;
+ for (typename std::vector< vertex_descriptor >::iterator j = it;
+ j != path.end(); ++j)
+ {
+ put(color, *j, color_gen::white());
+ }
+ path.erase(it, path.end());
+ s = t;
+ }
+ else
+ {
+ // Done
+ path.push_back(t);
+ break;
+ }
+ }
+}
+
+template < typename Graph, typename Gen > class unweighted_random_out_edge_gen
+{
+ Gen& gen;
+
+ typedef boost::graph_traits< Graph > gt;
+
+public:
+ unweighted_random_out_edge_gen(Gen& gen) : gen(gen) {}
+
+ typename gt::edge_descriptor operator()(
+ typename gt::vertex_descriptor src, const Graph& g) const
+ {
+ if (out_degree(src, g) == 0)
+ throw loop_erased_random_walk_stuck();
+ return boost::random_out_edge(g, src, gen);
+ }
+};
+
+template < typename Graph, typename WeightMap, typename Gen >
+class weighted_random_out_edge_gen
+{
+ WeightMap weight;
+ Gen& gen;
+
+ typedef boost::graph_traits< Graph > gt;
+
+public:
+ weighted_random_out_edge_gen(const WeightMap& weight, Gen& gen)
+ : weight(weight), gen(gen)
+ {
+ }
+
+ typename gt::edge_descriptor operator()(
+ typename gt::vertex_descriptor src, const Graph& g) const
+ {
+ if (out_degree(src, g) == 0)
+ throw loop_erased_random_walk_stuck();
+ return boost::weighted_random_out_edge(g, src, weight, gen);
+ }
+};
+}
+
+#endif // BOOST_GRAPH_LOOP_ERASED_RANDOM_WALK_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/make_biconnected_planar.hpp b/contrib/restricted/boost/graph/include/boost/graph/make_biconnected_planar.hpp
new file mode 100644
index 0000000000..60f40772a8
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/make_biconnected_planar.hpp
@@ -0,0 +1,96 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef __MAKE_BICONNECTED_PLANAR_HPP__
+#define __MAKE_BICONNECTED_PLANAR_HPP__
+
+#include <boost/config.hpp>
+#include <boost/tuple/tuple.hpp> //for tie
+#include <boost/graph/biconnected_components.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+
+#include <boost/graph/planar_detail/add_edge_visitors.hpp>
+
+namespace boost
+{
+
+template < typename Graph, typename PlanarEmbedding, typename EdgeIndexMap,
+ typename AddEdgeVisitor >
+void make_biconnected_planar(
+ Graph& g, PlanarEmbedding embedding, EdgeIndexMap em, AddEdgeVisitor& vis)
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef typename graph_traits< Graph >::edges_size_type edge_size_t;
+ typedef typename property_traits< PlanarEmbedding >::value_type
+ embedding_value_t;
+ typedef typename embedding_value_t::const_iterator embedding_iterator_t;
+ typedef iterator_property_map< std::vector< std::size_t >::iterator,
+ EdgeIndexMap >
+ component_map_t;
+
+ edge_size_t n_edges(num_edges(g));
+ std::vector< vertex_t > articulation_points;
+ std::vector< edge_size_t > component_vector(n_edges);
+ component_map_t component_map(component_vector.begin(), em);
+
+ biconnected_components(
+ g, component_map, std::back_inserter(articulation_points));
+
+ typename std::vector< vertex_t >::iterator ap, ap_end;
+ ap_end = articulation_points.end();
+ for (ap = articulation_points.begin(); ap != ap_end; ++ap)
+ {
+ vertex_t v(*ap);
+ embedding_iterator_t pi = embedding[v].begin();
+ embedding_iterator_t pi_end = embedding[v].end();
+ edge_size_t previous_component(n_edges + 1);
+ vertex_t previous_vertex = graph_traits< Graph >::null_vertex();
+
+ for (; pi != pi_end; ++pi)
+ {
+ edge_t e(*pi);
+ vertex_t e_source(source(e, g));
+ vertex_t e_target(target(e, g));
+
+ // Skip self-loops and parallel edges
+ if (e_source == e_target || previous_vertex == e_target)
+ continue;
+
+ vertex_t current_vertex = e_source == v ? e_target : e_source;
+ edge_size_t current_component = component_map[e];
+ if (previous_vertex != graph_traits< Graph >::null_vertex()
+ && current_component != previous_component)
+ {
+ vis.visit_vertex_pair(current_vertex, previous_vertex, g);
+ }
+ previous_vertex = current_vertex;
+ previous_component = current_component;
+ }
+ }
+}
+
+template < typename Graph, typename PlanarEmbedding, typename EdgeIndexMap >
+inline void make_biconnected_planar(
+ Graph& g, PlanarEmbedding embedding, EdgeIndexMap em)
+{
+ default_add_edge_visitor vis;
+ make_biconnected_planar(g, embedding, em, vis);
+}
+
+template < typename Graph, typename PlanarEmbedding >
+inline void make_biconnected_planar(Graph& g, PlanarEmbedding embedding)
+{
+ make_biconnected_planar(g, embedding, get(edge_index, g));
+}
+
+} // namespace boost
+
+#endif //__MAKE_BICONNECTED_PLANAR_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/make_connected.hpp b/contrib/restricted/boost/graph/include/boost/graph/make_connected.hpp
new file mode 100644
index 0000000000..de36590673
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/make_connected.hpp
@@ -0,0 +1,79 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef __MAKE_CONNECTED_HPP__
+#define __MAKE_CONNECTED_HPP__
+
+#include <boost/config.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/tuple/tuple.hpp> //for tie
+#include <boost/graph/connected_components.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <vector>
+
+#include <boost/graph/planar_detail/add_edge_visitors.hpp>
+#include <boost/graph/planar_detail/bucket_sort.hpp>
+
+namespace boost
+{
+
+template < typename Graph, typename VertexIndexMap, typename AddEdgeVisitor >
+void make_connected(Graph& g, VertexIndexMap vm, AddEdgeVisitor& vis)
+{
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+ typedef iterator_property_map< typename std::vector< v_size_t >::iterator,
+ VertexIndexMap >
+ vertex_to_v_size_map_t;
+
+ std::vector< v_size_t > component_vector(num_vertices(g));
+ vertex_to_v_size_map_t component(component_vector.begin(), vm);
+ std::vector< vertex_t > vertices_by_component(num_vertices(g));
+
+ v_size_t num_components = connected_components(g, component);
+
+ if (num_components < 2)
+ return;
+
+ vertex_iterator_t vi, vi_end;
+ boost::tie(vi, vi_end) = vertices(g);
+ std::copy(vi, vi_end, vertices_by_component.begin());
+
+ bucket_sort(vertices_by_component.begin(), vertices_by_component.end(),
+ component, num_components);
+
+ typedef typename std::vector< vertex_t >::iterator vec_of_vertices_itr_t;
+
+ vec_of_vertices_itr_t ci_end = vertices_by_component.end();
+ vec_of_vertices_itr_t ci_prev = vertices_by_component.begin();
+ if (ci_prev == ci_end)
+ return;
+
+ for (vec_of_vertices_itr_t ci = boost::next(ci_prev); ci != ci_end;
+ ci_prev = ci, ++ci)
+ {
+ if (component[*ci_prev] != component[*ci])
+ vis.visit_vertex_pair(*ci_prev, *ci, g);
+ }
+}
+
+template < typename Graph, typename VertexIndexMap >
+inline void make_connected(Graph& g, VertexIndexMap vm)
+{
+ default_add_edge_visitor vis;
+ make_connected(g, vm, vis);
+}
+
+template < typename Graph > inline void make_connected(Graph& g)
+{
+ make_connected(g, get(vertex_index, g));
+}
+
+} // namespace boost
+
+#endif //__MAKE_CONNECTED_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/make_maximal_planar.hpp b/contrib/restricted/boost/graph/include/boost/graph/make_maximal_planar.hpp
new file mode 100644
index 0000000000..4f19b8a6fc
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/make_maximal_planar.hpp
@@ -0,0 +1,213 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef __MAKE_MAXIMAL_PLANAR_HPP__
+#define __MAKE_MAXIMAL_PLANAR_HPP__
+
+#include <boost/config.hpp>
+#include <boost/tuple/tuple.hpp> //for tie
+#include <boost/graph/biconnected_components.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+
+#include <boost/graph/planar_face_traversal.hpp>
+#include <boost/graph/planar_detail/add_edge_visitors.hpp>
+
+namespace boost
+{
+
+template < typename Graph, typename VertexIndexMap, typename AddEdgeVisitor >
+struct triangulation_visitor : public planar_face_traversal_visitor
+{
+
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+ typedef typename graph_traits< Graph >::degree_size_type degree_size_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef
+ typename graph_traits< Graph >::adjacency_iterator adjacency_iterator_t;
+ typedef typename std::vector< vertex_t > vertex_vector_t;
+ typedef typename std::vector< v_size_t > v_size_vector_t;
+ typedef typename std::vector< degree_size_t > degree_size_vector_t;
+ typedef iterator_property_map< typename v_size_vector_t::iterator,
+ VertexIndexMap >
+ vertex_to_v_size_map_t;
+ typedef iterator_property_map< typename degree_size_vector_t::iterator,
+ VertexIndexMap >
+ vertex_to_degree_size_map_t;
+ typedef typename vertex_vector_t::iterator face_iterator;
+
+ triangulation_visitor(Graph& arg_g, VertexIndexMap arg_vm,
+ AddEdgeVisitor arg_add_edge_visitor)
+ : g(arg_g)
+ , vm(arg_vm)
+ , add_edge_visitor(arg_add_edge_visitor)
+ , timestamp(0)
+ , marked_vector(num_vertices(g), timestamp)
+ , degree_vector(num_vertices(g), 0)
+ , marked(marked_vector.begin(), vm)
+ , degree(degree_vector.begin(), vm)
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(degree, *vi, out_degree(*vi, g));
+ }
+
+ template < typename Vertex > void next_vertex(Vertex v)
+ {
+ // Self-loops will appear as consecutive vertices in the list of
+ // vertices on a face. We want to skip these.
+ if (!vertices_on_face.empty()
+ && (vertices_on_face.back() == v || vertices_on_face.front() == v))
+ return;
+
+ vertices_on_face.push_back(v);
+ }
+
+ void end_face()
+ {
+ ++timestamp;
+
+ if (vertices_on_face.size() <= 3)
+ {
+ // At most three vertices on this face - don't need to triangulate
+ vertices_on_face.clear();
+ return;
+ }
+
+ // Find vertex on face of minimum degree
+ degree_size_t min_degree = num_vertices(g);
+ typename vertex_vector_t::iterator min_degree_vertex_itr;
+ face_iterator fi_end = vertices_on_face.end();
+ for (face_iterator fi = vertices_on_face.begin(); fi != fi_end; ++fi)
+ {
+ degree_size_t deg = get(degree, *fi);
+ if (deg < min_degree)
+ {
+ min_degree_vertex_itr = fi;
+ min_degree = deg;
+ }
+ }
+
+ // To simplify some of the manipulations, we'll re-arrange
+ // vertices_on_face so that it still contains the same
+ // (counter-clockwise) order of the vertices on this face, but now the
+ // min_degree_vertex is the first element in vertices_on_face.
+ vertex_vector_t temp_vector;
+ std::copy(min_degree_vertex_itr, vertices_on_face.end(),
+ std::back_inserter(temp_vector));
+ std::copy(vertices_on_face.begin(), min_degree_vertex_itr,
+ std::back_inserter(temp_vector));
+ vertices_on_face.swap(temp_vector);
+
+ // Mark all of the min degree vertex's neighbors
+ adjacency_iterator_t ai, ai_end;
+ for (boost::tie(ai, ai_end)
+ = adjacent_vertices(vertices_on_face.front(), g);
+ ai != ai_end; ++ai)
+ {
+ put(marked, *ai, timestamp);
+ }
+
+ typename vertex_vector_t::iterator marked_neighbor
+ = vertices_on_face.end();
+
+ // The iterator manipulations on the next two lines are safe because
+ // vertices_on_face.size() > 3 (from the first test in this function)
+ fi_end = prior(vertices_on_face.end());
+ for (face_iterator fi
+ = boost::next(boost::next(vertices_on_face.begin()));
+ fi != fi_end; ++fi)
+ {
+ if (get(marked, *fi) == timestamp)
+ {
+ marked_neighbor = fi;
+ break;
+ }
+ }
+
+ if (marked_neighbor == vertices_on_face.end())
+ {
+ add_edge_range(vertices_on_face[0],
+ boost::next(boost::next(vertices_on_face.begin())),
+ prior(vertices_on_face.end()));
+ }
+ else
+ {
+ add_edge_range(vertices_on_face[1], boost::next(marked_neighbor),
+ vertices_on_face.end());
+
+ add_edge_range(*boost::next(marked_neighbor),
+ boost::next(boost::next(vertices_on_face.begin())),
+ marked_neighbor);
+ }
+
+ // reset for the next face
+ vertices_on_face.clear();
+ }
+
+private:
+ void add_edge_range(vertex_t anchor, face_iterator fi, face_iterator fi_end)
+ {
+ for (; fi != fi_end; ++fi)
+ {
+ vertex_t v(*fi);
+ add_edge_visitor.visit_vertex_pair(anchor, v, g);
+ put(degree, anchor, get(degree, anchor) + 1);
+ put(degree, v, get(degree, v) + 1);
+ }
+ }
+
+ Graph& g;
+ VertexIndexMap vm;
+ AddEdgeVisitor add_edge_visitor;
+ v_size_t timestamp;
+ vertex_vector_t vertices_on_face;
+ v_size_vector_t marked_vector;
+ degree_size_vector_t degree_vector;
+ vertex_to_v_size_map_t marked;
+ vertex_to_degree_size_map_t degree;
+};
+
+template < typename Graph, typename PlanarEmbedding, typename VertexIndexMap,
+ typename EdgeIndexMap, typename AddEdgeVisitor >
+void make_maximal_planar(Graph& g, PlanarEmbedding embedding, VertexIndexMap vm,
+ EdgeIndexMap em, AddEdgeVisitor& vis)
+{
+ triangulation_visitor< Graph, VertexIndexMap, AddEdgeVisitor > visitor(
+ g, vm, vis);
+ planar_face_traversal(g, embedding, visitor, em);
+}
+
+template < typename Graph, typename PlanarEmbedding, typename VertexIndexMap,
+ typename EdgeIndexMap >
+void make_maximal_planar(
+ Graph& g, PlanarEmbedding embedding, VertexIndexMap vm, EdgeIndexMap em)
+{
+ default_add_edge_visitor vis;
+ make_maximal_planar(g, embedding, vm, em, vis);
+}
+
+template < typename Graph, typename PlanarEmbedding, typename VertexIndexMap >
+void make_maximal_planar(Graph& g, PlanarEmbedding embedding, VertexIndexMap vm)
+{
+ make_maximal_planar(g, embedding, vm, get(edge_index, g));
+}
+
+template < typename Graph, typename PlanarEmbedding >
+void make_maximal_planar(Graph& g, PlanarEmbedding embedding)
+{
+ make_maximal_planar(g, embedding, get(vertex_index, g));
+}
+
+} // namespace boost
+
+#endif //__MAKE_MAXIMAL_PLANAR_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/matrix_as_graph.hpp b/contrib/restricted/boost/graph/include/boost/graph/matrix_as_graph.hpp
new file mode 100644
index 0000000000..b5df6cd9fe
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/matrix_as_graph.hpp
@@ -0,0 +1,167 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_MATRIX2GRAPH_HPP
+#define BOOST_GRAPH_MATRIX2GRAPH_HPP
+
+#include <utility>
+#include <cstddef>
+#include <iterator>
+#include <boost/config.hpp>
+#include <boost/operators.hpp>
+#include <boost/pending/detail/int_iterator.hpp>
+#include <boost/graph/graph_traits.hpp>
+
+namespace boost
+{
+
+template < class Iter, class Vertex > class matrix_adj_iterator;
+
+template < class Iter, class Vertex > class matrix_incidence_iterator;
+
+}
+
+#define BOOST_GRAPH_ADAPT_MATRIX_TO_GRAPH(Matrix) \
+ namespace boost \
+ { \
+ template <> struct graph_traits< Matrix > \
+ { \
+ typedef Matrix::OneD::const_iterator Iter; \
+ typedef Matrix::size_type V; \
+ typedef V vertex_descriptor; \
+ typedef Iter E; \
+ typedef E edge_descriptor; \
+ typedef boost::matrix_incidence_iterator< Iter, V > \
+ out_edge_iterator; \
+ typedef boost::matrix_adj_iterator< Iter, V > adjacency_iterator; \
+ typedef Matrix::size_type size_type; \
+ typedef boost::int_iterator< size_type > vertex_iterator; \
+ \
+ friend std::pair< vertex_iterator, vertex_iterator > vertices( \
+ const Matrix& g) \
+ { \
+ typedef vertex_iterator VIter; \
+ return std::make_pair(VIter(0), VIter(g.nrows())); \
+ } \
+ \
+ friend std::pair< out_edge_iterator, out_edge_iterator > \
+ out_edges(V v, const Matrix& g) \
+ { \
+ typedef out_edge_iterator IncIter; \
+ return std::make_pair( \
+ IncIter(g[v].begin()), IncIter(g[v].end())); \
+ } \
+ friend std::pair< adjacency_iterator, adjacency_iterator > \
+ adjacent_vertices(V v, const Matrix& g) \
+ { \
+ typedef adjacency_iterator AdjIter; \
+ return std::make_pair( \
+ AdjIter(g[v].begin()), AdjIter(g[v].end())); \
+ } \
+ friend vertex_descriptor source(E e, const Matrix& g) \
+ { \
+ return e.row(); \
+ } \
+ friend vertex_descriptor target(E e, const Matrix& g) \
+ { \
+ return e.column(); \
+ } \
+ friend size_type num_vertices(const Matrix& g) \
+ { \
+ return g.nrows(); \
+ } \
+ friend size_type num_edges(const Matrix& g) { return g.nnz(); } \
+ friend size_type out_degree(V i, const Matrix& g) \
+ { \
+ return g[i].nnz(); \
+ } \
+ }; \
+ }
+
+namespace boost
+{
+
+template < class Iter, class Vertex > class matrix_adj_iterator
+{
+ typedef matrix_adj_iterator self;
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef Vertex value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef Vertex* pointer;
+ typedef Vertex& reference;
+ matrix_adj_iterator() {}
+ matrix_adj_iterator(Iter i) : _iter(i) {}
+ matrix_adj_iterator(const self& x) : _iter(x._iter) {}
+ self& operator=(const self& x)
+ {
+ _iter = x._iter;
+ return *this;
+ }
+ Vertex operator*() { return _iter.column(); }
+ self& operator++()
+ {
+ ++_iter;
+ return *this;
+ }
+ self operator++(int)
+ {
+ self t = *this;
+ ++_iter;
+ return t;
+ }
+ bool operator==(const self& x) const { return _iter == x._iter; }
+ bool operator!=(const self& x) const { return _iter != x._iter; }
+
+protected:
+ Iter _iter;
+};
+
+template < class Iter, class Vertex > class matrix_incidence_iterator
+{
+ typedef matrix_incidence_iterator self;
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef Iter value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef Iter* pointer;
+ typedef Iter& reference;
+ matrix_incidence_iterator() {}
+ matrix_incidence_iterator(Iter i) : _iter(i) {}
+ matrix_incidence_iterator(const self& x) : _iter(x._iter) {}
+ self& operator=(const self& x)
+ {
+ _iter = x._iter;
+ return *this;
+ }
+ Iter operator*() { return _iter; }
+ self& operator++()
+ {
+ ++_iter;
+ return *this;
+ }
+ self operator++(int)
+ {
+ self t = *this;
+ ++_iter;
+ return t;
+ }
+ bool operator==(const self& x) const { return _iter == x._iter; }
+ bool operator!=(const self& x) const { return _iter != x._iter; }
+
+protected:
+ Iter _iter;
+};
+
+} /* namespace boost */
+
+#endif /* BOOST_GRAPH_MATRIX2GRAPH_HPP*/
diff --git a/contrib/restricted/boost/graph/include/boost/graph/max_cardinality_matching.hpp b/contrib/restricted/boost/graph/include/boost/graph/max_cardinality_matching.hpp
new file mode 100644
index 0000000000..082c2bd38a
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/max_cardinality_matching.hpp
@@ -0,0 +1,844 @@
+//=======================================================================
+// Copyright (c) 2005 Aaron Windsor
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//=======================================================================
+
+#ifndef BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP
+#define BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP
+
+#include <vector>
+#include <list>
+#include <deque>
+#include <algorithm> // for std::sort and std::stable_sort
+#include <utility> // for std::pair
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/filtered_graph.hpp>
+#include <boost/pending/disjoint_sets.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+namespace graph
+{
+ namespace detail
+ {
+ enum VERTEX_STATE
+ {
+ V_EVEN,
+ V_ODD,
+ V_UNREACHED
+ };
+ }
+} // end namespace graph::detail
+
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+typename graph_traits< Graph >::vertices_size_type matching_size(
+ const Graph& g, MateMap mate, VertexIndexMap vm)
+{
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+
+ v_size_t size_of_matching = 0;
+ vertex_iterator_t vi, vi_end;
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t v = *vi;
+ if (get(mate, v) != graph_traits< Graph >::null_vertex()
+ && get(vm, v) < get(vm, get(mate, v)))
+ ++size_of_matching;
+ }
+ return size_of_matching;
+}
+
+template < typename Graph, typename MateMap >
+inline typename graph_traits< Graph >::vertices_size_type matching_size(
+ const Graph& g, MateMap mate)
+{
+ return matching_size(g, mate, get(vertex_index, g));
+}
+
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+bool is_a_matching(const Graph& g, MateMap mate, VertexIndexMap)
+{
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t v = *vi;
+ if (get(mate, v) != graph_traits< Graph >::null_vertex()
+ && v != get(mate, get(mate, v)))
+ return false;
+ }
+ return true;
+}
+
+template < typename Graph, typename MateMap >
+inline bool is_a_matching(const Graph& g, MateMap mate)
+{
+ return is_a_matching(g, mate, get(vertex_index, g));
+}
+
+//***************************************************************************
+//***************************************************************************
+// Maximum Cardinality Matching Functors
+//***************************************************************************
+//***************************************************************************
+
+template < typename Graph, typename MateMap,
+ typename VertexIndexMap = dummy_property_map >
+struct no_augmenting_path_finder
+{
+ no_augmenting_path_finder(const Graph&, MateMap, VertexIndexMap) {}
+
+ inline bool augment_matching() { return false; }
+
+ template < typename PropertyMap > void get_current_matching(PropertyMap) {}
+};
+
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+class edmonds_augmenting_path_finder
+{
+ // This implementation of Edmonds' matching algorithm closely
+ // follows Tarjan's description of the algorithm in "Data
+ // Structures and Network Algorithms."
+
+public:
+ // generates the type of an iterator property map from vertices to type X
+ template < typename X > struct map_vertex_to_
+ {
+ typedef boost::iterator_property_map<
+ typename std::vector< X >::iterator, VertexIndexMap >
+ type;
+ };
+
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename std::pair< vertex_descriptor_t, vertex_descriptor_t >
+ vertex_pair_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t;
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+ typedef typename graph_traits< Graph >::edges_size_type e_size_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef
+ typename graph_traits< Graph >::out_edge_iterator out_edge_iterator_t;
+ typedef typename std::deque< vertex_descriptor_t > vertex_list_t;
+ typedef typename std::vector< edge_descriptor_t > edge_list_t;
+ typedef typename map_vertex_to_< vertex_descriptor_t >::type
+ vertex_to_vertex_map_t;
+ typedef typename map_vertex_to_< int >::type vertex_to_int_map_t;
+ typedef typename map_vertex_to_< vertex_pair_t >::type
+ vertex_to_vertex_pair_map_t;
+ typedef typename map_vertex_to_< v_size_t >::type vertex_to_vsize_map_t;
+ typedef typename map_vertex_to_< e_size_t >::type vertex_to_esize_map_t;
+
+ edmonds_augmenting_path_finder(
+ const Graph& arg_g, MateMap arg_mate, VertexIndexMap arg_vm)
+ : g(arg_g)
+ , vm(arg_vm)
+ , n_vertices(num_vertices(arg_g))
+ ,
+
+ mate_vector(n_vertices)
+ , ancestor_of_v_vector(n_vertices)
+ , ancestor_of_w_vector(n_vertices)
+ , vertex_state_vector(n_vertices)
+ , origin_vector(n_vertices)
+ , pred_vector(n_vertices)
+ , bridge_vector(n_vertices)
+ , ds_parent_vector(n_vertices)
+ , ds_rank_vector(n_vertices)
+ ,
+
+ mate(mate_vector.begin(), vm)
+ , ancestor_of_v(ancestor_of_v_vector.begin(), vm)
+ , ancestor_of_w(ancestor_of_w_vector.begin(), vm)
+ , vertex_state(vertex_state_vector.begin(), vm)
+ , origin(origin_vector.begin(), vm)
+ , pred(pred_vector.begin(), vm)
+ , bridge(bridge_vector.begin(), vm)
+ , ds_parent_map(ds_parent_vector.begin(), vm)
+ , ds_rank_map(ds_rank_vector.begin(), vm)
+ ,
+
+ ds(ds_rank_map, ds_parent_map)
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ mate[*vi] = get(arg_mate, *vi);
+ }
+
+ bool augment_matching()
+ {
+ // As an optimization, some of these values can be saved from one
+ // iteration to the next instead of being re-initialized each
+ // iteration, allowing for "lazy blossom expansion." This is not
+ // currently implemented.
+
+ e_size_t timestamp = 0;
+ even_edges.clear();
+
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t u = *vi;
+
+ origin[u] = u;
+ pred[u] = u;
+ ancestor_of_v[u] = 0;
+ ancestor_of_w[u] = 0;
+ ds.make_set(u);
+
+ if (mate[u] == graph_traits< Graph >::null_vertex())
+ {
+ vertex_state[u] = graph::detail::V_EVEN;
+ out_edge_iterator_t ei, ei_end;
+ for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end;
+ ++ei)
+ {
+ if (target(*ei, g) != u)
+ {
+ even_edges.push_back(*ei);
+ }
+ }
+ }
+ else
+ vertex_state[u] = graph::detail::V_UNREACHED;
+ }
+
+ // end initializations
+
+ vertex_descriptor_t v, w, w_free_ancestor, v_free_ancestor;
+ w_free_ancestor = graph_traits< Graph >::null_vertex();
+ v_free_ancestor = graph_traits< Graph >::null_vertex();
+ bool found_alternating_path = false;
+
+ while (!even_edges.empty() && !found_alternating_path)
+ {
+ // since we push even edges onto the back of the list as
+ // they're discovered, taking them off the back will search
+ // for augmenting paths depth-first.
+ edge_descriptor_t current_edge = even_edges.back();
+ even_edges.pop_back();
+
+ v = source(current_edge, g);
+ w = target(current_edge, g);
+
+ vertex_descriptor_t v_prime = origin[ds.find_set(v)];
+ vertex_descriptor_t w_prime = origin[ds.find_set(w)];
+
+ // because of the way we put all of the edges on the queue,
+ // v_prime should be labeled V_EVEN; the following is a
+ // little paranoid but it could happen...
+ if (vertex_state[v_prime] != graph::detail::V_EVEN)
+ {
+ std::swap(v_prime, w_prime);
+ std::swap(v, w);
+ }
+
+ if (vertex_state[w_prime] == graph::detail::V_UNREACHED)
+ {
+ vertex_state[w_prime] = graph::detail::V_ODD;
+ vertex_descriptor_t w_prime_mate = mate[w_prime];
+ vertex_state[w_prime_mate] = graph::detail::V_EVEN;
+ out_edge_iterator_t ei, ei_end;
+ for (boost::tie(ei, ei_end) = out_edges(w_prime_mate, g);
+ ei != ei_end; ++ei)
+ {
+ if (target(*ei, g) != w_prime_mate)
+ {
+ even_edges.push_back(*ei);
+ }
+ }
+ pred[w_prime] = v;
+ }
+
+ // w_prime == v_prime can happen below if we get an edge that has
+ // been shrunk into a blossom
+ else if (vertex_state[w_prime] == graph::detail::V_EVEN
+ && w_prime != v_prime)
+ {
+ vertex_descriptor_t w_up = w_prime;
+ vertex_descriptor_t v_up = v_prime;
+ vertex_descriptor_t nearest_common_ancestor
+ = graph_traits< Graph >::null_vertex();
+ w_free_ancestor = graph_traits< Graph >::null_vertex();
+ v_free_ancestor = graph_traits< Graph >::null_vertex();
+
+ // We now need to distinguish between the case that
+ // w_prime and v_prime share an ancestor under the
+ // "parent" relation, in which case we've found a
+ // blossom and should shrink it, or the case that
+ // w_prime and v_prime both have distinct ancestors that
+ // are free, in which case we've found an alternating
+ // path between those two ancestors.
+
+ ++timestamp;
+
+ while (nearest_common_ancestor
+ == graph_traits< Graph >::null_vertex()
+ && (v_free_ancestor == graph_traits< Graph >::null_vertex()
+ || w_free_ancestor
+ == graph_traits< Graph >::null_vertex()))
+ {
+ ancestor_of_w[w_up] = timestamp;
+ ancestor_of_v[v_up] = timestamp;
+
+ if (w_free_ancestor == graph_traits< Graph >::null_vertex())
+ w_up = parent(w_up);
+ if (v_free_ancestor == graph_traits< Graph >::null_vertex())
+ v_up = parent(v_up);
+
+ if (mate[v_up] == graph_traits< Graph >::null_vertex())
+ v_free_ancestor = v_up;
+ if (mate[w_up] == graph_traits< Graph >::null_vertex())
+ w_free_ancestor = w_up;
+
+ if (ancestor_of_w[v_up] == timestamp)
+ nearest_common_ancestor = v_up;
+ else if (ancestor_of_v[w_up] == timestamp)
+ nearest_common_ancestor = w_up;
+ else if (v_free_ancestor == w_free_ancestor
+ && v_free_ancestor
+ != graph_traits< Graph >::null_vertex())
+ nearest_common_ancestor = v_up;
+ }
+
+ if (nearest_common_ancestor
+ == graph_traits< Graph >::null_vertex())
+ found_alternating_path = true; // to break out of the loop
+ else
+ {
+ // shrink the blossom
+ link_and_set_bridges(
+ w_prime, nearest_common_ancestor, std::make_pair(w, v));
+ link_and_set_bridges(
+ v_prime, nearest_common_ancestor, std::make_pair(v, w));
+ }
+ }
+ }
+
+ if (!found_alternating_path)
+ return false;
+
+ // retrieve the augmenting path and put it in aug_path
+ reversed_retrieve_augmenting_path(v, v_free_ancestor);
+ retrieve_augmenting_path(w, w_free_ancestor);
+
+ // augment the matching along aug_path
+ vertex_descriptor_t a, b;
+ while (!aug_path.empty())
+ {
+ a = aug_path.front();
+ aug_path.pop_front();
+ b = aug_path.front();
+ aug_path.pop_front();
+ mate[a] = b;
+ mate[b] = a;
+ }
+
+ return true;
+ }
+
+ template < typename PropertyMap > void get_current_matching(PropertyMap pm)
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(pm, *vi, mate[*vi]);
+ }
+
+ template < typename PropertyMap > void get_vertex_state_map(PropertyMap pm)
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(pm, *vi, vertex_state[origin[ds.find_set(*vi)]]);
+ }
+
+private:
+ vertex_descriptor_t parent(vertex_descriptor_t x)
+ {
+ if (vertex_state[x] == graph::detail::V_EVEN
+ && mate[x] != graph_traits< Graph >::null_vertex())
+ return mate[x];
+ else if (vertex_state[x] == graph::detail::V_ODD)
+ return origin[ds.find_set(pred[x])];
+ else
+ return x;
+ }
+
+ void link_and_set_bridges(vertex_descriptor_t x,
+ vertex_descriptor_t stop_vertex, vertex_pair_t the_bridge)
+ {
+ for (vertex_descriptor_t v = x; v != stop_vertex; v = parent(v))
+ {
+ ds.union_set(v, stop_vertex);
+ origin[ds.find_set(stop_vertex)] = stop_vertex;
+
+ if (vertex_state[v] == graph::detail::V_ODD)
+ {
+ bridge[v] = the_bridge;
+ out_edge_iterator_t oei, oei_end;
+ for (boost::tie(oei, oei_end) = out_edges(v, g); oei != oei_end;
+ ++oei)
+ {
+ if (target(*oei, g) != v)
+ {
+ even_edges.push_back(*oei);
+ }
+ }
+ }
+ }
+ }
+
+ // Since none of the STL containers support both constant-time
+ // concatenation and reversal, the process of expanding an
+ // augmenting path once we know one exists is a little more
+ // complicated than it has to be. If we know the path is from v to
+ // w, then the augmenting path is recursively defined as:
+ //
+ // path(v,w) = [v], if v = w
+ // = concat([v, mate[v]], path(pred[mate[v]], w),
+ // if v != w and vertex_state[v] == graph::detail::V_EVEN
+ // = concat([v], reverse(path(x,mate[v])), path(y,w)),
+ // if v != w, vertex_state[v] == graph::detail::V_ODD, and
+ // bridge[v] = (x,y)
+ //
+ // These next two mutually recursive functions implement this definition.
+
+ void retrieve_augmenting_path(vertex_descriptor_t v, vertex_descriptor_t w)
+ {
+ if (v == w)
+ aug_path.push_back(v);
+ else if (vertex_state[v] == graph::detail::V_EVEN)
+ {
+ aug_path.push_back(v);
+ aug_path.push_back(mate[v]);
+ retrieve_augmenting_path(pred[mate[v]], w);
+ }
+ else // vertex_state[v] == graph::detail::V_ODD
+ {
+ aug_path.push_back(v);
+ reversed_retrieve_augmenting_path(bridge[v].first, mate[v]);
+ retrieve_augmenting_path(bridge[v].second, w);
+ }
+ }
+
+ void reversed_retrieve_augmenting_path(
+ vertex_descriptor_t v, vertex_descriptor_t w)
+ {
+
+ if (v == w)
+ aug_path.push_back(v);
+ else if (vertex_state[v] == graph::detail::V_EVEN)
+ {
+ reversed_retrieve_augmenting_path(pred[mate[v]], w);
+ aug_path.push_back(mate[v]);
+ aug_path.push_back(v);
+ }
+ else // vertex_state[v] == graph::detail::V_ODD
+ {
+ reversed_retrieve_augmenting_path(bridge[v].second, w);
+ retrieve_augmenting_path(bridge[v].first, mate[v]);
+ aug_path.push_back(v);
+ }
+ }
+
+ // private data members
+
+ const Graph& g;
+ VertexIndexMap vm;
+ v_size_t n_vertices;
+
+ // storage for the property maps below
+ std::vector< vertex_descriptor_t > mate_vector;
+ std::vector< e_size_t > ancestor_of_v_vector;
+ std::vector< e_size_t > ancestor_of_w_vector;
+ std::vector< int > vertex_state_vector;
+ std::vector< vertex_descriptor_t > origin_vector;
+ std::vector< vertex_descriptor_t > pred_vector;
+ std::vector< vertex_pair_t > bridge_vector;
+ std::vector< vertex_descriptor_t > ds_parent_vector;
+ std::vector< v_size_t > ds_rank_vector;
+
+ // iterator property maps
+ vertex_to_vertex_map_t mate;
+ vertex_to_esize_map_t ancestor_of_v;
+ vertex_to_esize_map_t ancestor_of_w;
+ vertex_to_int_map_t vertex_state;
+ vertex_to_vertex_map_t origin;
+ vertex_to_vertex_map_t pred;
+ vertex_to_vertex_pair_map_t bridge;
+ vertex_to_vertex_map_t ds_parent_map;
+ vertex_to_vsize_map_t ds_rank_map;
+
+ vertex_list_t aug_path;
+ edge_list_t even_edges;
+ disjoint_sets< vertex_to_vsize_map_t, vertex_to_vertex_map_t > ds;
+};
+
+//***************************************************************************
+//***************************************************************************
+// Initial Matching Functors
+//***************************************************************************
+//***************************************************************************
+
+template < typename Graph, typename MateMap > struct greedy_matching
+{
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+
+ static void find_matching(const Graph& g, MateMap mate)
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(mate, *vi, graph_traits< Graph >::null_vertex());
+
+ edge_iterator_t ei, ei_end;
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_descriptor_t e = *ei;
+ vertex_descriptor_t u = source(e, g);
+ vertex_descriptor_t v = target(e, g);
+
+ if (u != v && get(mate, u) == get(mate, v))
+ // only way equality can hold is if
+ // mate[u] == mate[v] == null_vertex
+ {
+ put(mate, u, v);
+ put(mate, v, u);
+ }
+ }
+ }
+};
+
+template < typename Graph, typename MateMap > struct extra_greedy_matching
+{
+ // The "extra greedy matching" is formed by repeating the
+ // following procedure as many times as possible: Choose the
+ // unmatched vertex v of minimum non-zero degree. Choose the
+ // neighbor w of v which is unmatched and has minimum degree over
+ // all of v's neighbors. Add (u,v) to the matching. Ties for
+ // either choice are broken arbitrarily. This procedure takes time
+ // O(m log n), where m is the number of edges in the graph and n
+ // is the number of vertices.
+
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+ typedef std::pair< vertex_descriptor_t, vertex_descriptor_t > vertex_pair_t;
+
+ struct select_first
+ {
+ inline static vertex_descriptor_t select_vertex(const vertex_pair_t p)
+ {
+ return p.first;
+ }
+ };
+
+ struct select_second
+ {
+ inline static vertex_descriptor_t select_vertex(const vertex_pair_t p)
+ {
+ return p.second;
+ }
+ };
+
+ template < class PairSelector > class less_than_by_degree
+ {
+ public:
+ less_than_by_degree(const Graph& g) : m_g(g) {}
+ bool operator()(const vertex_pair_t x, const vertex_pair_t y)
+ {
+ return out_degree(PairSelector::select_vertex(x), m_g)
+ < out_degree(PairSelector::select_vertex(y), m_g);
+ }
+
+ private:
+ const Graph& m_g;
+ };
+
+ static void find_matching(const Graph& g, MateMap mate)
+ {
+ typedef std::vector<
+ std::pair< vertex_descriptor_t, vertex_descriptor_t > >
+ directed_edges_vector_t;
+
+ directed_edges_vector_t edge_list;
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(mate, *vi, graph_traits< Graph >::null_vertex());
+
+ edge_iterator_t ei, ei_end;
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_descriptor_t e = *ei;
+ vertex_descriptor_t u = source(e, g);
+ vertex_descriptor_t v = target(e, g);
+ if (u == v)
+ continue;
+ edge_list.push_back(std::make_pair(u, v));
+ edge_list.push_back(std::make_pair(v, u));
+ }
+
+ // sort the edges by the degree of the target, then (using a
+ // stable sort) by degree of the source
+ std::sort(edge_list.begin(), edge_list.end(),
+ less_than_by_degree< select_second >(g));
+ std::stable_sort(edge_list.begin(), edge_list.end(),
+ less_than_by_degree< select_first >(g));
+
+ // construct the extra greedy matching
+ for (typename directed_edges_vector_t::const_iterator itr
+ = edge_list.begin();
+ itr != edge_list.end(); ++itr)
+ {
+ if (get(mate, itr->first) == get(mate, itr->second))
+ // only way equality can hold is if mate[itr->first] ==
+ // mate[itr->second] == null_vertex
+ {
+ put(mate, itr->first, itr->second);
+ put(mate, itr->second, itr->first);
+ }
+ }
+ }
+};
+
+template < typename Graph, typename MateMap > struct empty_matching
+{
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+
+ static void find_matching(const Graph& g, MateMap mate)
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(mate, *vi, graph_traits< Graph >::null_vertex());
+ }
+};
+
+//***************************************************************************
+//***************************************************************************
+// Matching Verifiers
+//***************************************************************************
+//***************************************************************************
+
+namespace detail
+{
+
+ template < typename SizeType >
+ class odd_components_counter : public dfs_visitor<>
+ // This depth-first search visitor will count the number of connected
+ // components with an odd number of vertices. It's used by
+ // maximum_matching_verifier.
+ {
+ public:
+ odd_components_counter(SizeType& c_count) : m_count(c_count)
+ {
+ m_count = 0;
+ }
+
+ template < class Vertex, class Graph > void start_vertex(Vertex, Graph&)
+ {
+ m_parity = false;
+ }
+
+ template < class Vertex, class Graph >
+ void discover_vertex(Vertex, Graph&)
+ {
+ m_parity = !m_parity;
+ m_parity ? ++m_count : --m_count;
+ }
+
+ protected:
+ SizeType& m_count;
+
+ private:
+ bool m_parity;
+ };
+
+} // namespace detail
+
+template < typename Graph, typename MateMap,
+ typename VertexIndexMap = dummy_property_map >
+struct no_matching_verifier
+{
+ inline static bool verify_matching(const Graph&, MateMap, VertexIndexMap)
+ {
+ return true;
+ }
+};
+
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+struct maximum_cardinality_matching_verifier
+{
+
+ template < typename X > struct map_vertex_to_
+ {
+ typedef boost::iterator_property_map<
+ typename std::vector< X >::iterator, VertexIndexMap >
+ type;
+ };
+
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename map_vertex_to_< int >::type vertex_to_int_map_t;
+ typedef typename map_vertex_to_< vertex_descriptor_t >::type
+ vertex_to_vertex_map_t;
+
+ template < typename VertexStateMap > struct non_odd_vertex
+ {
+ // this predicate is used to create a filtered graph that
+ // excludes vertices labeled "graph::detail::V_ODD"
+ non_odd_vertex() : vertex_state(0) {}
+
+ non_odd_vertex(VertexStateMap* arg_vertex_state)
+ : vertex_state(arg_vertex_state)
+ {
+ }
+
+ template < typename Vertex > bool operator()(const Vertex& v) const
+ {
+ BOOST_ASSERT(vertex_state);
+ return get(*vertex_state, v) != graph::detail::V_ODD;
+ }
+
+ VertexStateMap* vertex_state;
+ };
+
+ static bool verify_matching(const Graph& g, MateMap mate, VertexIndexMap vm)
+ {
+ // For any graph G, let o(G) be the number of connected
+ // components in G of odd size. For a subset S of G's vertex set
+ // V(G), let (G - S) represent the subgraph of G induced by
+ // removing all vertices in S from G. Let M(G) be the size of the
+ // maximum cardinality matching in G. Then the Tutte-Berge
+ // formula guarantees that
+ //
+ // 2 * M(G) = min ( |V(G)| + |U| + o(G - U) )
+ //
+ // where the minimum is taken over all subsets U of
+ // V(G). Edmonds' algorithm finds a set U that achieves the
+ // minimum in the above formula, namely the vertices labeled
+ //"ODD." This function runs one iteration of Edmonds' algorithm
+ // to find U, then verifies that the size of the matching given
+ // by mate satisfies the Tutte-Berge formula.
+
+ // first, make sure it's a valid matching
+ if (!is_a_matching(g, mate, vm))
+ return false;
+
+ // We'll try to augment the matching once. This serves two
+ // purposes: first, if we find some augmenting path, the matching
+ // is obviously non-maximum. Second, running edmonds' algorithm
+ // on a graph with no augmenting path will create the
+ // Edmonds-Gallai decomposition that we need as a certificate of
+ // maximality - we can get it by looking at the vertex_state map
+ // that results.
+ edmonds_augmenting_path_finder< Graph, MateMap, VertexIndexMap >
+ augmentor(g, mate, vm);
+ if (augmentor.augment_matching())
+ return false;
+
+ std::vector< int > vertex_state_vector(num_vertices(g));
+ vertex_to_int_map_t vertex_state(vertex_state_vector.begin(), vm);
+ augmentor.get_vertex_state_map(vertex_state);
+
+ // count the number of graph::detail::V_ODD vertices
+ v_size_t num_odd_vertices = 0;
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ if (vertex_state[*vi] == graph::detail::V_ODD)
+ ++num_odd_vertices;
+
+ // count the number of connected components with odd cardinality
+ // in the graph without graph::detail::V_ODD vertices
+ non_odd_vertex< vertex_to_int_map_t > filter(&vertex_state);
+ filtered_graph< Graph, keep_all, non_odd_vertex< vertex_to_int_map_t > >
+ fg(g, keep_all(), filter);
+
+ v_size_t num_odd_components;
+ detail::odd_components_counter< v_size_t > occ(num_odd_components);
+ depth_first_search(fg, visitor(occ).vertex_index_map(vm));
+
+ if (2 * matching_size(g, mate, vm)
+ == num_vertices(g) + num_odd_vertices - num_odd_components)
+ return true;
+ else
+ return false;
+ }
+};
+
+template < typename Graph, typename MateMap, typename VertexIndexMap,
+ template < typename, typename, typename > class AugmentingPathFinder,
+ template < typename, typename > class InitialMatchingFinder,
+ template < typename, typename, typename > class MatchingVerifier >
+bool matching(const Graph& g, MateMap mate, VertexIndexMap vm)
+{
+
+ InitialMatchingFinder< Graph, MateMap >::find_matching(g, mate);
+
+ AugmentingPathFinder< Graph, MateMap, VertexIndexMap > augmentor(
+ g, mate, vm);
+ bool not_maximum_yet = true;
+ while (not_maximum_yet)
+ {
+ not_maximum_yet = augmentor.augment_matching();
+ }
+ augmentor.get_current_matching(mate);
+
+ return MatchingVerifier< Graph, MateMap, VertexIndexMap >::verify_matching(
+ g, mate, vm);
+}
+
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+inline bool checked_edmonds_maximum_cardinality_matching(
+ const Graph& g, MateMap mate, VertexIndexMap vm)
+{
+ return matching< Graph, MateMap, VertexIndexMap,
+ edmonds_augmenting_path_finder, extra_greedy_matching,
+ maximum_cardinality_matching_verifier >(g, mate, vm);
+}
+
+template < typename Graph, typename MateMap >
+inline bool checked_edmonds_maximum_cardinality_matching(
+ const Graph& g, MateMap mate)
+{
+ return checked_edmonds_maximum_cardinality_matching(
+ g, mate, get(vertex_index, g));
+}
+
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+inline void edmonds_maximum_cardinality_matching(
+ const Graph& g, MateMap mate, VertexIndexMap vm)
+{
+ matching< Graph, MateMap, VertexIndexMap, edmonds_augmenting_path_finder,
+ extra_greedy_matching, no_matching_verifier >(g, mate, vm);
+}
+
+template < typename Graph, typename MateMap >
+inline void edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate)
+{
+ edmonds_maximum_cardinality_matching(g, mate, get(vertex_index, g));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/maximum_adjacency_search.hpp b/contrib/restricted/boost/graph/include/boost/graph/maximum_adjacency_search.hpp
new file mode 100644
index 0000000000..ed4b5578d1
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/maximum_adjacency_search.hpp
@@ -0,0 +1,399 @@
+//
+//=======================================================================
+// Copyright 2012 Fernando Vilas
+// 2010 Daniel Trebbien
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+
+// The maximum adjacency search algorithm was originally part of the
+// Stoer-Wagner min cut implementation by Daniel Trebbien. It has been
+// broken out into its own file to be a public search algorithm, with
+// visitor concepts.
+#ifndef BOOST_GRAPH_MAXIMUM_ADJACENCY_SEARCH_H
+#define BOOST_GRAPH_MAXIMUM_ADJACENCY_SEARCH_H
+
+/**
+ * This is an implementation of the maximum adjacency search on an
+ * undirected graph. It allows a visitor object to perform some
+ * operation on each vertex as that vertex is visited.
+ *
+ * The algorithm runs as follows:
+ *
+ * Initialize all nodes to be unvisited (reach count = 0)
+ * and call vis.initialize_vertex
+ * For i = number of nodes in graph downto 1
+ * Select the unvisited node with the highest reach count
+ * The user provides the starting node to break the first tie,
+ * but future ties are broken arbitrarily
+ * Visit the node by calling vis.start_vertex
+ * Increment the reach count for all unvisited neighbors
+ * and call vis.examine_edge for each of these edges
+ * Mark the node as visited and call vis.finish_vertex
+ *
+ */
+
+#include <boost/concept_check.hpp>
+#include <boost/concept/assert.hpp>
+#include <boost/graph/buffer_concepts.hpp>
+#include <boost/graph/exception.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#include <set>
+
+namespace boost
+{
+template < class Visitor, class Graph > struct MASVisitorConcept
+{
+ void constraints()
+ {
+ boost::function_requires<
+ boost::CopyConstructibleConcept< Visitor > >();
+ vis.initialize_vertex(u, g);
+ vis.start_vertex(u, g);
+ vis.examine_edge(e, g);
+ vis.finish_vertex(u, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename boost::graph_traits< Graph >::vertex_descriptor u;
+ typename boost::graph_traits< Graph >::edge_descriptor e;
+};
+
+template < class Visitors = null_visitor > class mas_visitor
+{
+public:
+ mas_visitor() {}
+ mas_visitor(Visitors vis) : m_vis(vis) {}
+
+ template < class Vertex, class Graph >
+ void initialize_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
+ }
+
+ template < class Vertex, class Graph > void start_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, ::boost::on_start_vertex());
+ }
+
+ template < class Edge, class Graph > void examine_edge(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, ::boost::on_examine_edge());
+ }
+
+ template < class Vertex, class Graph >
+ void finish_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
+ }
+
+ BOOST_GRAPH_EVENT_STUB(on_initialize_vertex, mas)
+ BOOST_GRAPH_EVENT_STUB(on_start_vertex, mas)
+ BOOST_GRAPH_EVENT_STUB(on_examine_edge, mas)
+ BOOST_GRAPH_EVENT_STUB(on_finish_vertex, mas)
+
+protected:
+ Visitors m_vis;
+};
+template < class Visitors >
+mas_visitor< Visitors > make_mas_visitor(Visitors vis)
+{
+ return mas_visitor< Visitors >(vis);
+}
+typedef mas_visitor<> default_mas_visitor;
+
+namespace detail
+{
+ template < class Graph, class WeightMap, class MASVisitor,
+ class VertexAssignmentMap, class KeyedUpdatablePriorityQueue >
+ void maximum_adjacency_search(const Graph& g, WeightMap weights,
+ MASVisitor vis,
+ const typename boost::graph_traits< Graph >::vertex_descriptor start,
+ VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue pq)
+ {
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+ typedef typename boost::property_traits< WeightMap >::value_type
+ weight_type;
+
+ std::set< vertex_descriptor > assignedVertices;
+
+ // initialize `assignments` (all vertices are initially
+ // assigned to themselves)
+ BGL_FORALL_VERTICES_T(v, g, Graph) { put(assignments, v, v); }
+
+ typename KeyedUpdatablePriorityQueue::key_map keys = pq.keys();
+
+ // set number of visited neighbors for all vertices to 0
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ if (v == get(assignments, v))
+ { // foreach u \in V do
+ put(keys, v, weight_type(0));
+ vis.initialize_vertex(v, g);
+
+ pq.push(v);
+ }
+ }
+ BOOST_ASSERT(pq.size() >= 2);
+
+ // Give the starting vertex high priority
+ put(keys, start, get(keys, start) + num_vertices(g) + 1);
+ pq.update(start);
+
+ // start traversing the graph
+ // vertex_descriptor s, t;
+ // weight_type w;
+ while (!pq.empty())
+ { // while PQ \neq {} do
+ const vertex_descriptor u = pq.top(); // u = extractmax(PQ)
+ /* weight_type w = */ get(keys, u);
+ vis.start_vertex(u, g);
+ pq.pop(); // vis.start_vertex(u, g);
+
+ BGL_FORALL_OUTEDGES_T(u, e, g, Graph)
+ { // foreach (u, v) \in E do
+ vis.examine_edge(e, g);
+
+ const vertex_descriptor v = get(assignments, target(e, g));
+
+ if (pq.contains(v))
+ { // if v \in PQ then
+ put(keys, v,
+ get(keys, v)
+ + get(weights,
+ e)); // increasekey(PQ, v, wA(v) + w(u, v))
+ pq.update(v);
+ }
+ }
+
+ typename std::set< vertex_descriptor >::const_iterator
+ assignedVertexIt,
+ assignedVertexEnd = assignedVertices.end();
+ for (assignedVertexIt = assignedVertices.begin();
+ assignedVertexIt != assignedVertexEnd; ++assignedVertexIt)
+ {
+ const vertex_descriptor uPrime = *assignedVertexIt;
+
+ if (get(assignments, uPrime) == u)
+ {
+ BGL_FORALL_OUTEDGES_T(uPrime, e, g, Graph)
+ { // foreach (u, v) \in E do
+ vis.examine_edge(e, g);
+
+ const vertex_descriptor v
+ = get(assignments, target(e, g));
+
+ if (pq.contains(v))
+ { // if v \in PQ then
+ put(keys, v,
+ get(keys, v)
+ + get(weights, e)); // increasekey(PQ, v,
+ // wA(v) + w(u, v))
+ pq.update(v);
+ }
+ }
+ }
+ }
+ vis.finish_vertex(u, g);
+ }
+ }
+} // end namespace detail
+
+template < class Graph, class WeightMap, class MASVisitor,
+ class VertexAssignmentMap, class KeyedUpdatablePriorityQueue >
+void maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis,
+ const typename boost::graph_traits< Graph >::vertex_descriptor start,
+ VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue pq)
+{
+ BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept< Graph >));
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+ typedef typename boost::graph_traits< Graph >::vertices_size_type
+ vertices_size_type;
+ typedef
+ typename boost::graph_traits< Graph >::edge_descriptor edge_descriptor;
+ BOOST_CONCEPT_ASSERT((boost::Convertible<
+ typename boost::graph_traits< Graph >::directed_category,
+ boost::undirected_tag >));
+ BOOST_CONCEPT_ASSERT(
+ (boost::ReadablePropertyMapConcept< WeightMap, edge_descriptor >));
+ // typedef typename boost::property_traits<WeightMap>::value_type
+ // weight_type;
+ boost::function_requires< MASVisitorConcept< MASVisitor, Graph > >();
+ BOOST_CONCEPT_ASSERT(
+ (boost::ReadWritePropertyMapConcept< VertexAssignmentMap,
+ vertex_descriptor >));
+ BOOST_CONCEPT_ASSERT((boost::Convertible< vertex_descriptor,
+ typename boost::property_traits< VertexAssignmentMap >::value_type >));
+ BOOST_CONCEPT_ASSERT(
+ (boost::KeyedUpdatableQueueConcept< KeyedUpdatablePriorityQueue >));
+
+ vertices_size_type n = num_vertices(g);
+ if (n < 2)
+ throw boost::bad_graph(
+ "the input graph must have at least two vertices.");
+ else if (!pq.empty())
+ throw std::invalid_argument(
+ "the max-priority queue must be empty initially.");
+
+ detail::maximum_adjacency_search(g, weights, vis, start, assignments, pq);
+}
+
+namespace graph
+{
+ namespace detail
+ {
+ template < typename WeightMap > struct mas_dispatch
+ {
+ typedef void result_type;
+ template < typename Graph, typename ArgPack >
+ static result_type apply(const Graph& g,
+ // const bgl_named_params<P,T,R>& params,
+ const ArgPack& params, WeightMap w)
+ {
+
+ using namespace boost::graph::keywords;
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+ typedef typename WeightMap::value_type weight_type;
+
+ typedef boost::detail::make_priority_queue_from_arg_pack_gen<
+ boost::graph::keywords::tag::max_priority_queue,
+ weight_type, vertex_descriptor,
+ std::greater< weight_type > >
+ default_pq_gen_type;
+
+ default_pq_gen_type pq_gen(
+ choose_param(get_param(params, boost::distance_zero_t()),
+ weight_type(0)));
+
+ typename boost::result_of< default_pq_gen_type(
+ const Graph&, const ArgPack&) >::type pq
+ = pq_gen(g, params);
+
+ boost::null_visitor null_vis;
+ boost::mas_visitor< boost::null_visitor > default_visitor(
+ null_vis);
+ vertex_descriptor v = vertex_descriptor();
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::vertex_assignment_map,
+ vertex_descriptor >
+ map_gen(v);
+ typename boost::detail::map_maker< Graph, ArgPack,
+ boost::graph::keywords::tag::vertex_assignment_map,
+ vertex_descriptor >::map_type default_map
+ = map_gen(g, params);
+ boost::maximum_adjacency_search(g, w,
+ params[_visitor | default_visitor],
+ params[_root_vertex | *vertices(g).first],
+ params[_vertex_assignment_map | default_map], pq);
+ }
+ };
+
+ template <> struct mas_dispatch< boost::param_not_found >
+ {
+ typedef void result_type;
+
+ template < typename Graph, typename ArgPack >
+ static result_type apply(
+ const Graph& g, const ArgPack& params, param_not_found)
+ {
+
+ using namespace boost::graph::keywords;
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor;
+
+ // get edge_weight_t as the weight type
+ typedef typename boost::property_map< Graph, edge_weight_t >
+ WeightMap;
+ typedef typename WeightMap::value_type weight_type;
+
+ typedef boost::detail::make_priority_queue_from_arg_pack_gen<
+ boost::graph::keywords::tag::max_priority_queue,
+ weight_type, vertex_descriptor,
+ std::greater< weight_type > >
+ default_pq_gen_type;
+
+ default_pq_gen_type pq_gen(
+ choose_param(get_param(params, boost::distance_zero_t()),
+ weight_type(0)));
+
+ typename boost::result_of< default_pq_gen_type(
+ const Graph&, const ArgPack&) >::type pq
+ = pq_gen(g, params);
+
+ boost::null_visitor null_vis;
+ boost::mas_visitor< boost::null_visitor > default_visitor(
+ null_vis);
+ vertex_descriptor v = vertex_descriptor();
+ boost::detail::make_property_map_from_arg_pack_gen<
+ boost::graph::keywords::tag::vertex_assignment_map,
+ vertex_descriptor >
+ map_gen(v);
+ typename boost::detail::map_maker< Graph, ArgPack,
+ boost::graph::keywords::tag::vertex_assignment_map,
+ vertex_descriptor >::map_type default_map
+ = map_gen(g, params);
+ boost::maximum_adjacency_search(g, get(edge_weight, g),
+ params[_visitor | default_visitor],
+ params[_root_vertex | *vertices(g).first],
+ params[_vertex_assignment_map | default_map], pq);
+ }
+ };
+ } // end namespace detail
+} // end namespace graph
+
+// Named parameter interface
+// BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(maximum_adjacency_search, 1)
+template < typename Graph, typename P, typename T, typename R >
+void maximum_adjacency_search(
+ const Graph& g, const bgl_named_params< P, T, R >& params)
+{
+
+ typedef bgl_named_params< P, T, R > params_type;
+ BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params)
+
+ // do the dispatch based on WeightMap
+ typedef typename get_param_type< edge_weight_t,
+ bgl_named_params< P, T, R > >::type W;
+ graph::detail::mas_dispatch< W >::apply(
+ g, arg_pack, get_param(params, edge_weight));
+}
+
+namespace graph
+{
+ namespace detail
+ {
+ template < typename Graph > struct maximum_adjacency_search_impl
+ {
+ typedef void result_type;
+
+ template < typename ArgPack >
+ void operator()(const Graph& g, const ArgPack& arg_pack) const
+ {
+ // call the function that does the dispatching
+ typedef
+ typename get_param_type< edge_weight_t, ArgPack >::type W;
+ graph::detail::mas_dispatch< W >::apply(
+ g, arg_pack, get_param(arg_pack, edge_weight));
+ }
+ };
+ } // end namespace detail
+ BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(maximum_adjacency_search, 1, 5)
+} // end namespace graph
+
+} // end namespace boost
+
+#include <boost/graph/iteration_macros_undef.hpp>
+
+#endif // BOOST_GRAPH_MAXIMUM_ADJACENCY_SEARCH_H
diff --git a/contrib/restricted/boost/graph/include/boost/graph/maximum_weighted_matching.hpp b/contrib/restricted/boost/graph/include/boost/graph/maximum_weighted_matching.hpp
new file mode 100644
index 0000000000..098a9c2aa7
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/maximum_weighted_matching.hpp
@@ -0,0 +1,1313 @@
+//=======================================================================
+// Copyright (c) 2018 Yi Ji
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//=======================================================================
+
+#ifndef BOOST_GRAPH_MAXIMUM_WEIGHTED_MATCHING_HPP
+#define BOOST_GRAPH_MAXIMUM_WEIGHTED_MATCHING_HPP
+
+#include <algorithm> // for std::iter_swap
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/graph/max_cardinality_matching.hpp>
+
+namespace boost
+{
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+typename property_traits<
+ typename property_map< Graph, edge_weight_t >::type >::value_type
+matching_weight_sum(const Graph& g, MateMap mate, VertexIndexMap vm)
+{
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename property_traits< typename property_map< Graph,
+ edge_weight_t >::type >::value_type edge_property_t;
+
+ edge_property_t weight_sum = 0;
+ vertex_iterator_t vi, vi_end;
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t v = *vi;
+ if (get(mate, v) != graph_traits< Graph >::null_vertex()
+ && get(vm, v) < get(vm, get(mate, v)))
+ weight_sum += get(edge_weight, g, edge(v, mate[v], g).first);
+ }
+ return weight_sum;
+}
+
+template < typename Graph, typename MateMap >
+inline typename property_traits<
+ typename property_map< Graph, edge_weight_t >::type >::value_type
+matching_weight_sum(const Graph& g, MateMap mate)
+{
+ return matching_weight_sum(g, mate, get(vertex_index, g));
+}
+
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+class weighted_augmenting_path_finder
+{
+public:
+ template < typename T > struct map_vertex_to_
+ {
+ typedef boost::iterator_property_map<
+ typename std::vector< T >::iterator, VertexIndexMap >
+ type;
+ };
+ typedef typename graph::detail::VERTEX_STATE vertex_state_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename std::vector< vertex_descriptor_t >::const_iterator
+ vertex_vec_iter_t;
+ typedef
+ typename graph_traits< Graph >::out_edge_iterator out_edge_iterator_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+ typedef typename property_traits< typename property_map< Graph,
+ edge_weight_t >::type >::value_type edge_property_t;
+ typedef std::deque< vertex_descriptor_t > vertex_list_t;
+ typedef std::vector< edge_descriptor_t > edge_list_t;
+ typedef typename map_vertex_to_< vertex_descriptor_t >::type
+ vertex_to_vertex_map_t;
+ typedef
+ typename map_vertex_to_< edge_property_t >::type vertex_to_weight_map_t;
+ typedef typename map_vertex_to_< bool >::type vertex_to_bool_map_t;
+ typedef typename map_vertex_to_< std::pair< vertex_descriptor_t,
+ vertex_descriptor_t > >::type vertex_to_pair_map_t;
+ typedef
+ typename map_vertex_to_< std::pair< edge_descriptor_t, bool > >::type
+ vertex_to_edge_map_t;
+ typedef typename map_vertex_to_< vertex_to_edge_map_t >::type
+ vertex_pair_to_edge_map_t;
+
+ class blossom
+ {
+ public:
+ typedef boost::shared_ptr< blossom > blossom_ptr_t;
+ std::vector< blossom_ptr_t > sub_blossoms;
+ edge_property_t dual_var;
+ blossom_ptr_t father;
+
+ blossom() : dual_var(0), father(blossom_ptr_t()) {}
+
+ // get the base vertex of a blossom by recursively getting
+ // its base sub-blossom, which is always the first one in
+ // sub_blossoms because of how we create and maintain blossoms
+ virtual vertex_descriptor_t get_base() const
+ {
+ const blossom* b = this;
+ while (!b->sub_blossoms.empty())
+ b = b->sub_blossoms[0].get();
+ return b->get_base();
+ }
+
+ // set a sub-blossom as a blossom's base by exchanging it
+ // with its first sub-blossom
+ void set_base(const blossom_ptr_t& sub)
+ {
+ for (blossom_iterator_t bi = sub_blossoms.begin();
+ bi != sub_blossoms.end(); ++bi)
+ {
+ if (sub.get() == bi->get())
+ {
+ std::iter_swap(sub_blossoms.begin(), bi);
+ break;
+ }
+ }
+ }
+
+ // get all vertices inside recursively
+ virtual std::vector< vertex_descriptor_t > vertices() const
+ {
+ std::vector< vertex_descriptor_t > all_vertices;
+ for (typename std::vector< blossom_ptr_t >::const_iterator bi
+ = sub_blossoms.begin();
+ bi != sub_blossoms.end(); ++bi)
+ {
+ std::vector< vertex_descriptor_t > some_vertices
+ = (*bi)->vertices();
+ all_vertices.insert(all_vertices.end(), some_vertices.begin(),
+ some_vertices.end());
+ }
+ return all_vertices;
+ }
+ };
+
+ // a trivial_blossom only has one vertex and no sub-blossom;
+ // for each vertex v, in_blossom[v] is the trivial_blossom that contains it
+ // directly
+ class trivial_blossom : public blossom
+ {
+ public:
+ trivial_blossom(vertex_descriptor_t v) : trivial_vertex(v) {}
+ virtual vertex_descriptor_t get_base() const { return trivial_vertex; }
+
+ virtual std::vector< vertex_descriptor_t > vertices() const
+ {
+ std::vector< vertex_descriptor_t > all_vertices;
+ all_vertices.push_back(trivial_vertex);
+ return all_vertices;
+ }
+
+ private:
+ vertex_descriptor_t trivial_vertex;
+ };
+
+ typedef boost::shared_ptr< blossom > blossom_ptr_t;
+ typedef typename std::vector< blossom_ptr_t >::iterator blossom_iterator_t;
+ typedef
+ typename map_vertex_to_< blossom_ptr_t >::type vertex_to_blossom_map_t;
+
+ weighted_augmenting_path_finder(
+ const Graph& arg_g, MateMap arg_mate, VertexIndexMap arg_vm)
+ : g(arg_g)
+ , vm(arg_vm)
+ , null_edge(std::pair< edge_descriptor_t, bool >(
+ num_edges(g) == 0 ? edge_descriptor_t() : *edges(g).first, false))
+ , mate_vector(num_vertices(g))
+ , label_S_vector(num_vertices(g), graph_traits< Graph >::null_vertex())
+ , label_T_vector(num_vertices(g), graph_traits< Graph >::null_vertex())
+ , outlet_vector(num_vertices(g), graph_traits< Graph >::null_vertex())
+ , tau_idx_vector(num_vertices(g), graph_traits< Graph >::null_vertex())
+ , dual_var_vector(std::vector< edge_property_t >(
+ num_vertices(g), std::numeric_limits< edge_property_t >::min()))
+ , pi_vector(std::vector< edge_property_t >(
+ num_vertices(g), std::numeric_limits< edge_property_t >::max()))
+ , gamma_vector(std::vector< edge_property_t >(
+ num_vertices(g), std::numeric_limits< edge_property_t >::max()))
+ , tau_vector(std::vector< edge_property_t >(
+ num_vertices(g), std::numeric_limits< edge_property_t >::max()))
+ , in_blossom_vector(num_vertices(g))
+ , old_label_vector(num_vertices(g))
+ , critical_edge_vectors(num_vertices(g),
+ std::vector< std::pair< edge_descriptor_t, bool > >(
+ num_vertices(g), null_edge))
+ ,
+
+ mate(mate_vector.begin(), vm)
+ , label_S(label_S_vector.begin(), vm)
+ , label_T(label_T_vector.begin(), vm)
+ , outlet(outlet_vector.begin(), vm)
+ , tau_idx(tau_idx_vector.begin(), vm)
+ , dual_var(dual_var_vector.begin(), vm)
+ , pi(pi_vector.begin(), vm)
+ , gamma(gamma_vector.begin(), vm)
+ , tau(tau_vector.begin(), vm)
+ , in_blossom(in_blossom_vector.begin(), vm)
+ , old_label(old_label_vector.begin(), vm)
+ {
+ vertex_iterator_t vi, vi_end;
+ edge_iterator_t ei, ei_end;
+
+ edge_property_t max_weight
+ = std::numeric_limits< edge_property_t >::min();
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ max_weight = std::max(max_weight, get(edge_weight, g, *ei));
+
+ typename std::vector<
+ std::vector< std::pair< edge_descriptor_t, bool > > >::iterator vei;
+
+ for (boost::tie(vi, vi_end) = vertices(g),
+ vei = critical_edge_vectors.begin();
+ vi != vi_end; ++vi, ++vei)
+ {
+ vertex_descriptor_t u = *vi;
+ mate[u] = get(arg_mate, u);
+ dual_var[u] = 2 * max_weight;
+ in_blossom[u] = boost::make_shared< trivial_blossom >(u);
+ outlet[u] = u;
+ critical_edge_vector.push_back(
+ vertex_to_edge_map_t(vei->begin(), vm));
+ }
+
+ critical_edge
+ = vertex_pair_to_edge_map_t(critical_edge_vector.begin(), vm);
+
+ init();
+ }
+
+ // return the top blossom where v is contained inside
+ blossom_ptr_t in_top_blossom(vertex_descriptor_t v) const
+ {
+ blossom_ptr_t b = in_blossom[v];
+ while (b->father != blossom_ptr_t())
+ b = b->father;
+ return b;
+ }
+
+ // check if vertex v is in blossom b
+ bool is_in_blossom(blossom_ptr_t b, vertex_descriptor_t v) const
+ {
+ if (v == graph_traits< Graph >::null_vertex())
+ return false;
+ blossom_ptr_t vb = in_blossom[v]->father;
+ while (vb != blossom_ptr_t())
+ {
+ if (vb.get() == b.get())
+ return true;
+ vb = vb->father;
+ }
+ return false;
+ }
+
+ // return the base vertex of the top blossom that contains v
+ inline vertex_descriptor_t base_vertex(vertex_descriptor_t v) const
+ {
+ return in_top_blossom(v)->get_base();
+ }
+
+ // add an existed top blossom of base vertex v into new top
+ // blossom b as its sub-blossom
+ void add_sub_blossom(blossom_ptr_t b, vertex_descriptor_t v)
+ {
+ blossom_ptr_t sub = in_top_blossom(v);
+ sub->father = b;
+ b->sub_blossoms.push_back(sub);
+ if (sub->sub_blossoms.empty())
+ return;
+ for (blossom_iterator_t bi = top_blossoms.begin();
+ bi != top_blossoms.end(); ++bi)
+ {
+ if (bi->get() == sub.get())
+ {
+ top_blossoms.erase(bi);
+ break;
+ }
+ }
+ }
+
+ // when a top blossom is created or its base vertex getting an S-label,
+ // add all edges incident to this blossom into even_edges
+ void bloom(blossom_ptr_t b)
+ {
+ std::vector< vertex_descriptor_t > vertices_of_b = b->vertices();
+ vertex_vec_iter_t vi;
+ for (vi = vertices_of_b.begin(); vi != vertices_of_b.end(); ++vi)
+ {
+ out_edge_iterator_t oei, oei_end;
+ for (boost::tie(oei, oei_end) = out_edges(*vi, g); oei != oei_end;
+ ++oei)
+ {
+ if (target(*oei, g) != *vi && mate[*vi] != target(*oei, g))
+ even_edges.push_back(*oei);
+ }
+ }
+ }
+
+ // assigning a T-label to a non S-vertex, along with outlet and updating pi
+ // value if updated pi[v] equals zero, augment the matching from its mate
+ // vertex
+ void put_T_label(vertex_descriptor_t v, vertex_descriptor_t T_label,
+ vertex_descriptor_t outlet_v, edge_property_t pi_v)
+ {
+ if (label_S[v] != graph_traits< Graph >::null_vertex())
+ return;
+
+ label_T[v] = T_label;
+ outlet[v] = outlet_v;
+ pi[v] = pi_v;
+
+ vertex_descriptor_t v_mate = mate[v];
+ if (pi[v] == 0)
+ {
+ label_T[v_mate] = graph_traits< Graph >::null_vertex();
+ label_S[v_mate] = v;
+ bloom(in_top_blossom(v_mate));
+ }
+ }
+
+ // get the missing T-label for a to-be-expanded base vertex
+ // the missing T-label is the last vertex of the path from outlet[v] to v
+ std::pair< vertex_descriptor_t, vertex_descriptor_t > missing_label(
+ vertex_descriptor_t b_base)
+ {
+ vertex_descriptor_t missing_outlet = outlet[b_base];
+
+ if (outlet[b_base] == b_base)
+ return std::make_pair(
+ graph_traits< Graph >::null_vertex(), missing_outlet);
+
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ old_label[*vi] = std::make_pair(label_T[*vi], outlet[*vi]);
+
+ std::pair< vertex_descriptor_t, vertex_state_t > child(
+ outlet[b_base], graph::detail::V_EVEN);
+ blossom_ptr_t b = in_blossom[child.first];
+ for (; b->father->father != blossom_ptr_t(); b = b->father)
+ ;
+ child.first = b->get_base();
+
+ if (child.first == b_base)
+ return std::make_pair(
+ graph_traits< Graph >::null_vertex(), missing_outlet);
+
+ while (true)
+ {
+ std::pair< vertex_descriptor_t, vertex_state_t > child_parent
+ = parent(child, true);
+
+ for (b = in_blossom[child_parent.first];
+ b->father->father != blossom_ptr_t(); b = b->father)
+ ;
+ missing_outlet = child_parent.first;
+ child_parent.first = b->get_base();
+
+ if (child_parent.first == b_base)
+ break;
+ else
+ child = child_parent;
+ }
+ return std::make_pair(child.first, missing_outlet);
+ }
+
+ // expand a top blossom, put all its non-trivial sub-blossoms into
+ // top_blossoms
+ blossom_iterator_t expand_blossom(
+ blossom_iterator_t bi, std::vector< blossom_ptr_t >& new_ones)
+ {
+ blossom_ptr_t b = *bi;
+ for (blossom_iterator_t i = b->sub_blossoms.begin();
+ i != b->sub_blossoms.end(); ++i)
+ {
+ blossom_ptr_t sub_blossom = *i;
+ vertex_descriptor_t sub_base = sub_blossom->get_base();
+ label_S[sub_base] = label_T[sub_base]
+ = graph_traits< Graph >::null_vertex();
+ outlet[sub_base] = sub_base;
+ sub_blossom->father = blossom_ptr_t();
+ // new top blossoms cannot be pushed back into top_blossoms
+ // immediately, because push_back() may cause reallocation and then
+ // invalid iterators
+ if (!sub_blossom->sub_blossoms.empty())
+ new_ones.push_back(sub_blossom);
+ }
+ return top_blossoms.erase(bi);
+ }
+
+ // when expanding a T-blossom with base v, it requires more operations:
+ // supply the missing T-labels for new base vertices by picking the minimum
+ // tau from vertices of each corresponding new top-blossoms; when label_T[v]
+ // is null or we have a smaller tau from missing_label(v), replace T-label
+ // and outlet of v (but don't bloom v)
+ blossom_iterator_t expand_T_blossom(
+ blossom_iterator_t bi, std::vector< blossom_ptr_t >& new_ones)
+ {
+ blossom_ptr_t b = *bi;
+
+ vertex_descriptor_t b_base = b->get_base();
+ std::pair< vertex_descriptor_t, vertex_descriptor_t > T_and_outlet
+ = missing_label(b_base);
+
+ blossom_iterator_t next_bi = expand_blossom(bi, new_ones);
+
+ for (blossom_iterator_t i = b->sub_blossoms.begin();
+ i != b->sub_blossoms.end(); ++i)
+ {
+ blossom_ptr_t sub_blossom = *i;
+ vertex_descriptor_t sub_base = sub_blossom->get_base();
+ vertex_descriptor_t min_tau_v
+ = graph_traits< Graph >::null_vertex();
+ edge_property_t min_tau
+ = std::numeric_limits< edge_property_t >::max();
+
+ std::vector< vertex_descriptor_t > sub_vertices
+ = sub_blossom->vertices();
+ for (vertex_vec_iter_t v = sub_vertices.begin();
+ v != sub_vertices.end(); ++v)
+ {
+ if (tau[*v] < min_tau)
+ {
+ min_tau = tau[*v];
+ min_tau_v = *v;
+ }
+ }
+
+ if (min_tau < std::numeric_limits< edge_property_t >::max())
+ put_T_label(
+ sub_base, tau_idx[min_tau_v], min_tau_v, tau[min_tau_v]);
+ }
+
+ if (label_T[b_base] == graph_traits< Graph >::null_vertex()
+ || tau[old_label[b_base].second] < pi[b_base])
+ boost::tie(label_T[b_base], outlet[b_base]) = T_and_outlet;
+
+ return next_bi;
+ }
+
+ // when vertices v and w are matched to each other by augmenting,
+ // we must set v/w as base vertex of any blossom who contains v/w and
+ // is a sub-blossom of their lowest (smallest) common blossom
+ void adjust_blossom(vertex_descriptor_t v, vertex_descriptor_t w)
+ {
+ blossom_ptr_t vb = in_blossom[v], wb = in_blossom[w],
+ lowest_common_blossom;
+ std::vector< blossom_ptr_t > v_ancestors, w_ancestors;
+
+ while (vb->father != blossom_ptr_t())
+ {
+ v_ancestors.push_back(vb->father);
+ vb = vb->father;
+ }
+ while (wb->father != blossom_ptr_t())
+ {
+ w_ancestors.push_back(wb->father);
+ wb = wb->father;
+ }
+
+ typename std::vector< blossom_ptr_t >::reverse_iterator i, j;
+ i = v_ancestors.rbegin();
+ j = w_ancestors.rbegin();
+ while (i != v_ancestors.rend() && j != w_ancestors.rend()
+ && i->get() == j->get())
+ {
+ lowest_common_blossom = *i;
+ ++i;
+ ++j;
+ }
+
+ vb = in_blossom[v];
+ wb = in_blossom[w];
+ while (vb->father != lowest_common_blossom)
+ {
+ vb->father->set_base(vb);
+ vb = vb->father;
+ }
+ while (wb->father != lowest_common_blossom)
+ {
+ wb->father->set_base(wb);
+ wb = wb->father;
+ }
+ }
+
+ // every edge weight is multiplied by 4 to ensure integer weights
+ // throughout the algorithm if all input weights are integers
+ inline edge_property_t slack(const edge_descriptor_t& e) const
+ {
+ vertex_descriptor_t v, w;
+ v = source(e, g);
+ w = target(e, g);
+ return dual_var[v] + dual_var[w] - 4 * get(edge_weight, g, e);
+ }
+
+ // backtrace one step on vertex v along the augmenting path
+ // by its labels and its vertex state;
+ // boolean parameter "use_old" means whether we are updating labels,
+ // if we are, then we use old labels to backtrace and also we
+ // don't jump to its base vertex when we reach an odd vertex
+ std::pair< vertex_descriptor_t, vertex_state_t > parent(
+ std::pair< vertex_descriptor_t, vertex_state_t > v,
+ bool use_old = false) const
+ {
+ if (v.second == graph::detail::V_EVEN)
+ {
+ // a paranoid check: label_S shoule be the same as mate in
+ // backtracing
+ if (label_S[v.first] == graph_traits< Graph >::null_vertex())
+ label_S[v.first] = mate[v.first];
+ return std::make_pair(label_S[v.first], graph::detail::V_ODD);
+ }
+ else if (v.second == graph::detail::V_ODD)
+ {
+ vertex_descriptor_t w = use_old ? old_label[v.first].first
+ : base_vertex(label_T[v.first]);
+ return std::make_pair(w, graph::detail::V_EVEN);
+ }
+ return std::make_pair(v.first, graph::detail::V_UNREACHED);
+ }
+
+ // backtrace from vertices v and w to their free (unmatched) ancesters,
+ // return the nearest common ancestor (null_vertex if none) of v and w
+ vertex_descriptor_t nearest_common_ancestor(vertex_descriptor_t v,
+ vertex_descriptor_t w, vertex_descriptor_t& v_free_ancestor,
+ vertex_descriptor_t& w_free_ancestor) const
+ {
+ std::pair< vertex_descriptor_t, vertex_state_t > v_up(
+ v, graph::detail::V_EVEN);
+ std::pair< vertex_descriptor_t, vertex_state_t > w_up(
+ w, graph::detail::V_EVEN);
+ vertex_descriptor_t nca;
+ nca = w_free_ancestor = v_free_ancestor
+ = graph_traits< Graph >::null_vertex();
+
+ std::vector< bool > ancestor_of_w_vector(num_vertices(g), false);
+ std::vector< bool > ancestor_of_v_vector(num_vertices(g), false);
+ vertex_to_bool_map_t ancestor_of_w(ancestor_of_w_vector.begin(), vm);
+ vertex_to_bool_map_t ancestor_of_v(ancestor_of_v_vector.begin(), vm);
+
+ while (nca == graph_traits< Graph >::null_vertex()
+ && (v_free_ancestor == graph_traits< Graph >::null_vertex()
+ || w_free_ancestor == graph_traits< Graph >::null_vertex()))
+ {
+ ancestor_of_w[w_up.first] = true;
+ ancestor_of_v[v_up.first] = true;
+
+ if (w_free_ancestor == graph_traits< Graph >::null_vertex())
+ w_up = parent(w_up);
+ if (v_free_ancestor == graph_traits< Graph >::null_vertex())
+ v_up = parent(v_up);
+
+ if (mate[v_up.first] == graph_traits< Graph >::null_vertex())
+ v_free_ancestor = v_up.first;
+ if (mate[w_up.first] == graph_traits< Graph >::null_vertex())
+ w_free_ancestor = w_up.first;
+
+ if (ancestor_of_w[v_up.first] == true || v_up.first == w_up.first)
+ nca = v_up.first;
+ else if (ancestor_of_v[w_up.first] == true)
+ nca = w_up.first;
+ else if (v_free_ancestor == w_free_ancestor
+ && v_free_ancestor != graph_traits< Graph >::null_vertex())
+ nca = v_up.first;
+ }
+
+ return nca;
+ }
+
+ // when a new top blossom b is created by connecting (v, w), we add
+ // sub-blossoms into b along backtracing from v_prime and w_prime to
+ // stop_vertex (the base vertex); also, we set labels and outlet for each
+ // base vertex we pass by
+ void make_blossom(blossom_ptr_t b, vertex_descriptor_t w_prime,
+ vertex_descriptor_t v_prime, vertex_descriptor_t stop_vertex)
+ {
+ std::pair< vertex_descriptor_t, vertex_state_t > u(
+ v_prime, graph::detail::V_ODD);
+ std::pair< vertex_descriptor_t, vertex_state_t > u_up(
+ w_prime, graph::detail::V_EVEN);
+
+ for (; u_up.first != stop_vertex; u = u_up, u_up = parent(u))
+ {
+ if (u_up.second == graph::detail::V_EVEN)
+ {
+ if (!in_top_blossom(u_up.first)->sub_blossoms.empty())
+ outlet[u_up.first] = label_T[u.first];
+ label_T[u_up.first] = outlet[u.first];
+ }
+ else if (u_up.second == graph::detail::V_ODD)
+ label_S[u_up.first] = u.first;
+
+ add_sub_blossom(b, u_up.first);
+ }
+ }
+
+ // the design of recursively expanding augmenting path in
+ // (reversed_)retrieve_augmenting_path functions is inspired by same
+ // functions in max_cardinality_matching.hpp; except that in weighted
+ // matching, we use "outlet" vertices instead of "bridge" vertex pairs: if
+ // blossom b is the smallest non-trivial blossom that contains its base
+ // vertex v, then v and outlet[v] are where augmenting path enters and
+ // leaves b
+ void retrieve_augmenting_path(
+ vertex_descriptor_t v, vertex_descriptor_t w, vertex_state_t v_state)
+ {
+ if (v == w)
+ aug_path.push_back(v);
+ else if (v_state == graph::detail::V_EVEN)
+ {
+ aug_path.push_back(v);
+ retrieve_augmenting_path(label_S[v], w, graph::detail::V_ODD);
+ }
+ else if (v_state == graph::detail::V_ODD)
+ {
+ if (outlet[v] == v)
+ aug_path.push_back(v);
+ else
+ reversed_retrieve_augmenting_path(
+ outlet[v], v, graph::detail::V_EVEN);
+ retrieve_augmenting_path(label_T[v], w, graph::detail::V_EVEN);
+ }
+ }
+
+ void reversed_retrieve_augmenting_path(
+ vertex_descriptor_t v, vertex_descriptor_t w, vertex_state_t v_state)
+ {
+ if (v == w)
+ aug_path.push_back(v);
+ else if (v_state == graph::detail::V_EVEN)
+ {
+ reversed_retrieve_augmenting_path(
+ label_S[v], w, graph::detail::V_ODD);
+ aug_path.push_back(v);
+ }
+ else if (v_state == graph::detail::V_ODD)
+ {
+ reversed_retrieve_augmenting_path(
+ label_T[v], w, graph::detail::V_EVEN);
+ if (outlet[v] != v)
+ retrieve_augmenting_path(outlet[v], v, graph::detail::V_EVEN);
+ else
+ aug_path.push_back(v);
+ }
+ }
+
+ // correct labels for vertices in the augmenting path
+ void relabel(vertex_descriptor_t v)
+ {
+ blossom_ptr_t b = in_blossom[v]->father;
+
+ if (!is_in_blossom(b, mate[v]))
+ { // if v is a new base vertex
+ std::pair< vertex_descriptor_t, vertex_state_t > u(
+ v, graph::detail::V_EVEN);
+ while (label_S[u.first] != u.first
+ && is_in_blossom(b, label_S[u.first]))
+ u = parent(u, true);
+
+ vertex_descriptor_t old_base = u.first;
+ if (label_S[old_base] != old_base)
+ { // if old base is not exposed
+ label_T[v] = label_S[old_base];
+ outlet[v] = old_base;
+ }
+ else
+ { // if old base is exposed then new label_T[v] is not in b,
+ // we must (i) make b2 the smallest blossom containing v but not
+ // as base vertex (ii) backtrace from b2's new base vertex to b
+ label_T[v] = graph_traits< Graph >::null_vertex();
+ for (b = b->father; b != blossom_ptr_t() && b->get_base() == v;
+ b = b->father)
+ ;
+ if (b != blossom_ptr_t())
+ {
+ u = std::make_pair(b->get_base(), graph::detail::V_ODD);
+ while (!is_in_blossom(
+ in_blossom[v]->father, old_label[u.first].first))
+ u = parent(u, true);
+ label_T[v] = u.first;
+ outlet[v] = old_label[u.first].first;
+ }
+ }
+ }
+ else if (label_S[v] == v || !is_in_blossom(b, label_S[v]))
+ { // if v is an old base vertex
+ // let u be the new base vertex; backtrace from u's old T-label
+ std::pair< vertex_descriptor_t, vertex_state_t > u(
+ b->get_base(), graph::detail::V_ODD);
+ while (
+ old_label[u.first].first != graph_traits< Graph >::null_vertex()
+ && old_label[u.first].first != v)
+ u = parent(u, true);
+ label_T[v] = old_label[u.first].second;
+ outlet[v] = v;
+ }
+ else // if v is neither a new nor an old base vertex
+ label_T[v] = label_S[v];
+ }
+
+ void augmenting(vertex_descriptor_t v, vertex_descriptor_t v_free_ancestor,
+ vertex_descriptor_t w, vertex_descriptor_t w_free_ancestor)
+ {
+ vertex_iterator_t vi, vi_end;
+
+ // retrieve the augmenting path and put it in aug_path
+ reversed_retrieve_augmenting_path(
+ v, v_free_ancestor, graph::detail::V_EVEN);
+ retrieve_augmenting_path(w, w_free_ancestor, graph::detail::V_EVEN);
+
+ // augment the matching along aug_path
+ vertex_descriptor_t a, b;
+ vertex_list_t reversed_aug_path;
+ while (!aug_path.empty())
+ {
+ a = aug_path.front();
+ aug_path.pop_front();
+ reversed_aug_path.push_back(a);
+ b = aug_path.front();
+ aug_path.pop_front();
+ reversed_aug_path.push_back(b);
+
+ mate[a] = b;
+ mate[b] = a;
+
+ // reset base vertex for every blossom in augment path
+ adjust_blossom(a, b);
+ }
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ old_label[*vi] = std::make_pair(label_T[*vi], outlet[*vi]);
+
+ // correct labels for in-blossom vertices along aug_path
+ while (!reversed_aug_path.empty())
+ {
+ a = reversed_aug_path.front();
+ reversed_aug_path.pop_front();
+
+ if (in_blossom[a]->father != blossom_ptr_t())
+ relabel(a);
+ }
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t u = *vi;
+ if (mate[u] != graph_traits< Graph >::null_vertex())
+ label_S[u] = mate[u];
+ }
+
+ // expand blossoms with zero dual variables
+ std::vector< blossom_ptr_t > new_top_blossoms;
+ for (blossom_iterator_t bi = top_blossoms.begin();
+ bi != top_blossoms.end();)
+ {
+ if ((*bi)->dual_var <= 0)
+ bi = expand_blossom(bi, new_top_blossoms);
+ else
+ ++bi;
+ }
+ top_blossoms.insert(top_blossoms.end(), new_top_blossoms.begin(),
+ new_top_blossoms.end());
+ init();
+ }
+
+ // create a new blossom and set labels for vertices inside
+ void blossoming(vertex_descriptor_t v, vertex_descriptor_t v_prime,
+ vertex_descriptor_t w, vertex_descriptor_t w_prime,
+ vertex_descriptor_t nca)
+ {
+ vertex_iterator_t vi, vi_end;
+
+ std::vector< bool > is_old_base_vector(num_vertices(g));
+ vertex_to_bool_map_t is_old_base(is_old_base_vector.begin(), vm);
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ if (*vi == base_vertex(*vi))
+ is_old_base[*vi] = true;
+ }
+
+ blossom_ptr_t b = boost::make_shared< blossom >();
+ add_sub_blossom(b, nca);
+
+ label_T[w_prime] = v;
+ label_T[v_prime] = w;
+ outlet[w_prime] = w;
+ outlet[v_prime] = v;
+
+ make_blossom(b, w_prime, v_prime, nca);
+ make_blossom(b, v_prime, w_prime, nca);
+
+ label_T[nca] = graph_traits< Graph >::null_vertex();
+ outlet[nca] = nca;
+
+ top_blossoms.push_back(b);
+ bloom(b);
+
+ // set gamma[b_base] = min_slack{critical_edge(b_base, other_base)}
+ // where each critical edge is updated before, by
+ // argmin{slack(old_bases_in_b, other_base)};
+ vertex_vec_iter_t i, j;
+ std::vector< vertex_descriptor_t > b_vertices = b->vertices(),
+ old_base_in_b, other_base;
+ vertex_descriptor_t b_base = b->get_base();
+ for (i = b_vertices.begin(); i != b_vertices.end(); ++i)
+ {
+ if (is_old_base[*i])
+ old_base_in_b.push_back(*i);
+ }
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ if (*vi != b_base && *vi == base_vertex(*vi))
+ other_base.push_back(*vi);
+ }
+ for (i = other_base.begin(); i != other_base.end(); ++i)
+ {
+ edge_property_t min_slack
+ = std::numeric_limits< edge_property_t >::max();
+ std::pair< edge_descriptor_t, bool > b_vi = null_edge;
+ for (j = old_base_in_b.begin(); j != old_base_in_b.end(); ++j)
+ {
+ if (critical_edge[*j][*i] != null_edge
+ && min_slack > slack(critical_edge[*j][*i].first))
+ {
+ min_slack = slack(critical_edge[*j][*i].first);
+ b_vi = critical_edge[*j][*i];
+ }
+ }
+ critical_edge[b_base][*i] = critical_edge[*i][b_base] = b_vi;
+ }
+ gamma[b_base] = std::numeric_limits< edge_property_t >::max();
+ for (i = other_base.begin(); i != other_base.end(); ++i)
+ {
+ if (critical_edge[b_base][*i] != null_edge)
+ gamma[b_base] = std::min(
+ gamma[b_base], slack(critical_edge[b_base][*i].first));
+ }
+ }
+
+ void init()
+ {
+ even_edges.clear();
+
+ vertex_iterator_t vi, vi_end;
+ typename std::vector<
+ std::vector< std::pair< edge_descriptor_t, bool > > >::iterator vei;
+
+ for (boost::tie(vi, vi_end) = vertices(g),
+ vei = critical_edge_vectors.begin();
+ vi != vi_end; ++vi, ++vei)
+ {
+ vertex_descriptor_t u = *vi;
+ out_edge_iterator_t ei, ei_end;
+
+ gamma[u] = tau[u] = pi[u]
+ = std::numeric_limits< edge_property_t >::max();
+ std::fill(vei->begin(), vei->end(), null_edge);
+
+ if (base_vertex(u) != u)
+ continue;
+
+ label_S[u] = label_T[u] = graph_traits< Graph >::null_vertex();
+ outlet[u] = u;
+
+ if (mate[u] == graph_traits< Graph >::null_vertex())
+ {
+ label_S[u] = u;
+ bloom(in_top_blossom(u));
+ }
+ }
+ }
+
+ bool augment_matching()
+ {
+ vertex_descriptor_t v, w, w_free_ancestor, v_free_ancestor;
+ v = w = w_free_ancestor = v_free_ancestor
+ = graph_traits< Graph >::null_vertex();
+ bool found_alternating_path = false;
+
+ // note that we only use edges of zero slack value for augmenting
+ while (!even_edges.empty() && !found_alternating_path)
+ {
+ // search for augmenting paths depth-first
+ edge_descriptor_t current_edge = even_edges.back();
+ even_edges.pop_back();
+
+ v = source(current_edge, g);
+ w = target(current_edge, g);
+
+ vertex_descriptor_t v_prime = base_vertex(v);
+ vertex_descriptor_t w_prime = base_vertex(w);
+
+ // w_prime == v_prime implies that we get an edge that has been
+ // shrunk into a blossom
+ if (v_prime == w_prime)
+ continue;
+
+ // a paranoid check
+ if (label_S[v_prime] == graph_traits< Graph >::null_vertex())
+ {
+ std::swap(v_prime, w_prime);
+ std::swap(v, w);
+ }
+
+ // w_prime may be unlabeled or have a T-label; replace the existed
+ // T-label if the edge slack is smaller than current pi[w_prime] and
+ // update it. Note that a T-label is "deserved" only when pi equals
+ // zero. also update tau and tau_idx so that tau_idx becomes T-label
+ // when a T-blossom is expanded
+ if (label_S[w_prime] == graph_traits< Graph >::null_vertex())
+ {
+ if (slack(current_edge) < pi[w_prime])
+ put_T_label(w_prime, v, w, slack(current_edge));
+ if (slack(current_edge) < tau[w])
+ {
+ if (in_blossom[w]->father == blossom_ptr_t()
+ || label_T[w_prime] == v
+ || label_T[w_prime]
+ == graph_traits< Graph >::null_vertex()
+ || nearest_common_ancestor(v_prime, label_T[w_prime],
+ v_free_ancestor, w_free_ancestor)
+ == graph_traits< Graph >::null_vertex())
+ {
+ tau[w] = slack(current_edge);
+ tau_idx[w] = v;
+ }
+ }
+ }
+
+ else
+ {
+ if (slack(current_edge) > 0)
+ {
+ // update gamma and critical_edges when we have a smaller
+ // edge slack
+ gamma[v_prime]
+ = std::min(gamma[v_prime], slack(current_edge));
+ gamma[w_prime]
+ = std::min(gamma[w_prime], slack(current_edge));
+ if (critical_edge[v_prime][w_prime] == null_edge
+ || slack(critical_edge[v_prime][w_prime].first)
+ > slack(current_edge))
+ {
+ critical_edge[v_prime][w_prime]
+ = std::pair< edge_descriptor_t, bool >(
+ current_edge, true);
+ critical_edge[w_prime][v_prime]
+ = std::pair< edge_descriptor_t, bool >(
+ current_edge, true);
+ }
+ continue;
+ }
+ else if (slack(current_edge) == 0)
+ {
+ // if nca is null_vertex then we have an augmenting path;
+ // otherwise we have a new top blossom with nca as its base
+ // vertex
+ vertex_descriptor_t nca = nearest_common_ancestor(
+ v_prime, w_prime, v_free_ancestor, w_free_ancestor);
+
+ if (nca == graph_traits< Graph >::null_vertex())
+ found_alternating_path
+ = true; // to break out of the loop
+ else
+ blossoming(v, v_prime, w, w_prime, nca);
+ }
+ }
+ }
+
+ if (!found_alternating_path)
+ return false;
+
+ augmenting(v, v_free_ancestor, w, w_free_ancestor);
+ return true;
+ }
+
+ // slack the vertex and blossom dual variables when there is no augmenting
+ // path found according to the primal-dual method
+ bool adjust_dual()
+ {
+ edge_property_t delta1, delta2, delta3, delta4, delta;
+ delta1 = delta2 = delta3 = delta4
+ = std::numeric_limits< edge_property_t >::max();
+
+ vertex_iterator_t vi, vi_end;
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ delta1 = std::min(delta1, dual_var[*vi]);
+ delta4 = pi[*vi] > 0 ? std::min(delta4, pi[*vi]) : delta4;
+ if (*vi == base_vertex(*vi))
+ delta3 = std::min(delta3, gamma[*vi] / 2);
+ }
+
+ for (blossom_iterator_t bi = top_blossoms.begin();
+ bi != top_blossoms.end(); ++bi)
+ {
+ vertex_descriptor_t b_base = (*bi)->get_base();
+ if (label_T[b_base] != graph_traits< Graph >::null_vertex()
+ && pi[b_base] == 0)
+ delta2 = std::min(delta2, (*bi)->dual_var / 2);
+ }
+
+ delta = std::min(std::min(delta1, delta2), std::min(delta3, delta4));
+
+ // start updating dual variables, note that the order is important
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t v = *vi, v_prime = base_vertex(v);
+
+ if (label_S[v_prime] != graph_traits< Graph >::null_vertex())
+ dual_var[v] -= delta;
+ else if (label_T[v_prime] != graph_traits< Graph >::null_vertex()
+ && pi[v_prime] == 0)
+ dual_var[v] += delta;
+
+ if (v == v_prime)
+ gamma[v] -= 2 * delta;
+ }
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t v_prime = base_vertex(*vi);
+ if (pi[v_prime] > 0)
+ tau[*vi] -= delta;
+ }
+
+ for (blossom_iterator_t bi = top_blossoms.begin();
+ bi != top_blossoms.end(); ++bi)
+ {
+ vertex_descriptor_t b_base = (*bi)->get_base();
+ if (label_T[b_base] != graph_traits< Graph >::null_vertex()
+ && pi[b_base] == 0)
+ (*bi)->dual_var -= 2 * delta;
+ if (label_S[b_base] != graph_traits< Graph >::null_vertex())
+ (*bi)->dual_var += 2 * delta;
+ }
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t v = *vi;
+ if (pi[v] > 0)
+ pi[v] -= delta;
+
+ // when some T-vertices have zero pi value, bloom their mates so
+ // that matching can be further augmented
+ if (label_T[v] != graph_traits< Graph >::null_vertex()
+ && pi[v] == 0)
+ put_T_label(v, label_T[v], outlet[v], pi[v]);
+ }
+
+ // optimal solution reached, halt
+ if (delta == delta1)
+ return false;
+
+ // expand odd blossoms with zero dual variables and zero pi value of
+ // their base vertices
+ if (delta == delta2 && delta != delta3)
+ {
+ std::vector< blossom_ptr_t > new_top_blossoms;
+ for (blossom_iterator_t bi = top_blossoms.begin();
+ bi != top_blossoms.end();)
+ {
+ const blossom_ptr_t b = *bi;
+ vertex_descriptor_t b_base = b->get_base();
+ if (b->dual_var == 0
+ && label_T[b_base] != graph_traits< Graph >::null_vertex()
+ && pi[b_base] == 0)
+ bi = expand_T_blossom(bi, new_top_blossoms);
+ else
+ ++bi;
+ }
+ top_blossoms.insert(top_blossoms.end(), new_top_blossoms.begin(),
+ new_top_blossoms.end());
+ }
+
+ while (true)
+ {
+ // find a zero-slack critical edge (v, w) of zero gamma values
+ std::pair< edge_descriptor_t, bool > best_edge = null_edge;
+ std::vector< vertex_descriptor_t > base_nodes;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ if (*vi == base_vertex(*vi))
+ base_nodes.push_back(*vi);
+ }
+ for (vertex_vec_iter_t i = base_nodes.begin();
+ i != base_nodes.end(); ++i)
+ {
+ if (gamma[*i] == 0)
+ {
+ for (vertex_vec_iter_t j = base_nodes.begin();
+ j != base_nodes.end(); ++j)
+ {
+ if (critical_edge[*i][*j] != null_edge
+ && slack(critical_edge[*i][*j].first) == 0)
+ best_edge = critical_edge[*i][*j];
+ }
+ }
+ }
+
+ // if not found, continue finding other augment matching
+ if (best_edge == null_edge)
+ {
+ bool augmented = augment_matching();
+ return augmented || delta != delta1;
+ }
+ // if found, determine either augmenting or blossoming
+ vertex_descriptor_t v = source(best_edge.first, g),
+ w = target(best_edge.first, g);
+ vertex_descriptor_t v_prime = base_vertex(v),
+ w_prime = base_vertex(w), v_free_ancestor,
+ w_free_ancestor;
+ vertex_descriptor_t nca = nearest_common_ancestor(
+ v_prime, w_prime, v_free_ancestor, w_free_ancestor);
+ if (nca == graph_traits< Graph >::null_vertex())
+ {
+ augmenting(v, v_free_ancestor, w, w_free_ancestor);
+ return true;
+ }
+ else
+ blossoming(v, v_prime, w, w_prime, nca);
+ }
+
+ return false;
+ }
+
+ template < typename PropertyMap > void get_current_matching(PropertyMap pm)
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(pm, *vi, mate[*vi]);
+ }
+
+private:
+ const Graph& g;
+ VertexIndexMap vm;
+ const std::pair< edge_descriptor_t, bool > null_edge;
+
+ // storage for the property maps below
+ std::vector< vertex_descriptor_t > mate_vector;
+ std::vector< vertex_descriptor_t > label_S_vector, label_T_vector;
+ std::vector< vertex_descriptor_t > outlet_vector;
+ std::vector< vertex_descriptor_t > tau_idx_vector;
+ std::vector< edge_property_t > dual_var_vector;
+ std::vector< edge_property_t > pi_vector, gamma_vector, tau_vector;
+ std::vector< blossom_ptr_t > in_blossom_vector;
+ std::vector< std::pair< vertex_descriptor_t, vertex_descriptor_t > >
+ old_label_vector;
+ std::vector< vertex_to_edge_map_t > critical_edge_vector;
+ std::vector< std::vector< std::pair< edge_descriptor_t, bool > > >
+ critical_edge_vectors;
+
+ // iterator property maps
+ vertex_to_vertex_map_t mate;
+ vertex_to_vertex_map_t label_S; // v has an S-label -> v can be an even
+ // vertex, label_S[v] is its mate
+ vertex_to_vertex_map_t
+ label_T; // v has a T-label -> v can be an odd vertex, label_T[v] is its
+ // predecessor in aug_path
+ vertex_to_vertex_map_t outlet;
+ vertex_to_vertex_map_t tau_idx;
+ vertex_to_weight_map_t dual_var;
+ vertex_to_weight_map_t pi, gamma, tau;
+ vertex_to_blossom_map_t
+ in_blossom; // map any vertex v to the trivial blossom containing v
+ vertex_to_pair_map_t old_label; // <old T-label, old outlet> before
+ // relabeling or expanding T-blossoms
+ vertex_pair_to_edge_map_t
+ critical_edge; // an not matched edge (v, w) is critical if v and w
+ // belongs to different S-blossoms
+
+ vertex_list_t aug_path;
+ edge_list_t even_edges;
+ std::vector< blossom_ptr_t > top_blossoms;
+};
+
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+void maximum_weighted_matching(const Graph& g, MateMap mate, VertexIndexMap vm)
+{
+ empty_matching< Graph, MateMap >::find_matching(g, mate);
+ weighted_augmenting_path_finder< Graph, MateMap, VertexIndexMap > augmentor(
+ g, mate, vm);
+
+ // can have |V| times augmenting at most
+ for (std::size_t t = 0; t < num_vertices(g); ++t)
+ {
+ bool augmented = false;
+ while (!augmented)
+ {
+ augmented = augmentor.augment_matching();
+ if (!augmented)
+ {
+ // halt if adjusting dual variables can't bring potential
+ // augment
+ if (!augmentor.adjust_dual())
+ break;
+ }
+ }
+ if (!augmented)
+ break;
+ }
+
+ augmentor.get_current_matching(mate);
+}
+
+template < typename Graph, typename MateMap >
+inline void maximum_weighted_matching(const Graph& g, MateMap mate)
+{
+ maximum_weighted_matching(g, mate, get(vertex_index, g));
+}
+
+// brute-force matcher searches all possible combinations of matched edges to
+// get the maximum weighted matching which can be used for testing on small
+// graphs (within dozens vertices)
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+class brute_force_matching
+{
+public:
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef
+ typename std::vector< vertex_descriptor_t >::iterator vertex_vec_iter_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+ typedef boost::iterator_property_map< vertex_vec_iter_t, VertexIndexMap >
+ vertex_to_vertex_map_t;
+
+ brute_force_matching(
+ const Graph& arg_g, MateMap arg_mate, VertexIndexMap arg_vm)
+ : g(arg_g)
+ , vm(arg_vm)
+ , mate_vector(num_vertices(g))
+ , best_mate_vector(num_vertices(g))
+ , mate(mate_vector.begin(), vm)
+ , best_mate(best_mate_vector.begin(), vm)
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ best_mate[*vi] = mate[*vi] = get(arg_mate, *vi);
+ }
+
+ template < typename PropertyMap > void find_matching(PropertyMap pm)
+ {
+ edge_iterator_t ei;
+ boost::tie(ei, ei_end) = edges(g);
+ select_edge(ei);
+
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(pm, *vi, best_mate[*vi]);
+ }
+
+private:
+ const Graph& g;
+ VertexIndexMap vm;
+ std::vector< vertex_descriptor_t > mate_vector, best_mate_vector;
+ vertex_to_vertex_map_t mate, best_mate;
+ edge_iterator_t ei_end;
+
+ void select_edge(edge_iterator_t ei)
+ {
+ if (ei == ei_end)
+ {
+ if (matching_weight_sum(g, mate)
+ > matching_weight_sum(g, best_mate))
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ best_mate[*vi] = mate[*vi];
+ }
+ return;
+ }
+
+ vertex_descriptor_t v, w;
+ v = source(*ei, g);
+ w = target(*ei, g);
+
+ select_edge(++ei);
+
+ if (mate[v] == graph_traits< Graph >::null_vertex()
+ && mate[w] == graph_traits< Graph >::null_vertex())
+ {
+ mate[v] = w;
+ mate[w] = v;
+ select_edge(ei);
+ mate[v] = mate[w] = graph_traits< Graph >::null_vertex();
+ }
+ }
+};
+
+template < typename Graph, typename MateMap, typename VertexIndexMap >
+void brute_force_maximum_weighted_matching(
+ const Graph& g, MateMap mate, VertexIndexMap vm)
+{
+ empty_matching< Graph, MateMap >::find_matching(g, mate);
+ brute_force_matching< Graph, MateMap, VertexIndexMap > brute_force_matcher(
+ g, mate, vm);
+ brute_force_matcher.find_matching(mate);
+}
+
+template < typename Graph, typename MateMap >
+inline void brute_force_maximum_weighted_matching(const Graph& g, MateMap mate)
+{
+ brute_force_maximum_weighted_matching(g, mate, get(vertex_index, g));
+}
+
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/mcgregor_common_subgraphs.hpp b/contrib/restricted/boost/graph/include/boost/graph/mcgregor_common_subgraphs.hpp
new file mode 100644
index 0000000000..9c2b4b980d
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/mcgregor_common_subgraphs.hpp
@@ -0,0 +1,1117 @@
+//=======================================================================
+// Copyright 2009 Trustees of Indiana University.
+// Authors: Michael Hansen, Andrew Lumsdaine
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_MCGREGOR_COMMON_SUBGRAPHS_HPP
+#define BOOST_GRAPH_MCGREGOR_COMMON_SUBGRAPHS_HPP
+
+#include <algorithm>
+#include <vector>
+#include <stack>
+
+#include <boost/make_shared.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/filtered_graph.hpp>
+#include <boost/graph/graph_utility.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/property_map/shared_array_property_map.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ // Traits associated with common subgraphs, used mainly to keep a
+ // consistent type for the correspondence maps.
+ template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond >
+ struct mcgregor_common_subgraph_traits
+ {
+ typedef typename graph_traits< GraphFirst >::vertex_descriptor
+ vertex_first_type;
+ typedef typename graph_traits< GraphSecond >::vertex_descriptor
+ vertex_second_type;
+
+ typedef shared_array_property_map< vertex_second_type,
+ VertexIndexMapFirst >
+ correspondence_map_first_to_second_type;
+
+ typedef shared_array_property_map< vertex_first_type,
+ VertexIndexMapSecond >
+ correspondence_map_second_to_first_type;
+ };
+
+} // namespace detail
+
+// ==========================================================================
+
+// Binary function object that returns true if the values for item1
+// in property_map1 and item2 in property_map2 are equivalent.
+template < typename PropertyMapFirst, typename PropertyMapSecond >
+struct property_map_equivalent
+{
+
+ property_map_equivalent(const PropertyMapFirst property_map1,
+ const PropertyMapSecond property_map2)
+ : m_property_map1(property_map1), m_property_map2(property_map2)
+ {
+ }
+
+ template < typename ItemFirst, typename ItemSecond >
+ bool operator()(const ItemFirst item1, const ItemSecond item2)
+ {
+ return (get(m_property_map1, item1) == get(m_property_map2, item2));
+ }
+
+private:
+ const PropertyMapFirst m_property_map1;
+ const PropertyMapSecond m_property_map2;
+};
+
+// Returns a property_map_equivalent object that compares the values
+// of property_map1 and property_map2.
+template < typename PropertyMapFirst, typename PropertyMapSecond >
+property_map_equivalent< PropertyMapFirst, PropertyMapSecond >
+make_property_map_equivalent(
+ const PropertyMapFirst property_map1, const PropertyMapSecond property_map2)
+{
+
+ return (property_map_equivalent< PropertyMapFirst, PropertyMapSecond >(
+ property_map1, property_map2));
+}
+
+// Binary function object that always returns true. Used when
+// vertices or edges are always equivalent (i.e. have no labels).
+struct always_equivalent
+{
+
+ template < typename ItemFirst, typename ItemSecond >
+ bool operator()(const ItemFirst&, const ItemSecond&)
+ {
+ return (true);
+ }
+};
+
+// ==========================================================================
+
+namespace detail
+{
+
+ // Return true if new_vertex1 and new_vertex2 can extend the
+ // subgraph represented by correspondence_map_1_to_2 and
+ // correspondence_map_2_to_1. The vertices_equivalent and
+ // edges_equivalent predicates are used to test vertex and edge
+ // equivalency between the two graphs.
+ template < typename GraphFirst, typename GraphSecond,
+ typename CorrespondenceMapFirstToSecond,
+ typename CorrespondenceMapSecondToFirst,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate >
+ bool can_extend_graph(const GraphFirst& graph1, const GraphSecond& graph2,
+ CorrespondenceMapFirstToSecond correspondence_map_1_to_2,
+ CorrespondenceMapSecondToFirst /*correspondence_map_2_to_1*/,
+ typename graph_traits< GraphFirst >::vertices_size_type subgraph_size,
+ typename graph_traits< GraphFirst >::vertex_descriptor new_vertex1,
+ typename graph_traits< GraphSecond >::vertex_descriptor new_vertex2,
+ EdgeEquivalencePredicate edges_equivalent,
+ VertexEquivalencePredicate vertices_equivalent,
+ bool only_connected_subgraphs)
+ {
+ typedef typename graph_traits< GraphSecond >::vertex_descriptor
+ VertexSecond;
+
+ typedef typename graph_traits< GraphFirst >::edge_descriptor EdgeFirst;
+ typedef
+ typename graph_traits< GraphSecond >::edge_descriptor EdgeSecond;
+
+ // Check vertex equality
+ if (!vertices_equivalent(new_vertex1, new_vertex2))
+ {
+ return (false);
+ }
+
+ // Vertices match and graph is empty, so we can extend the subgraph
+ if (subgraph_size == 0)
+ {
+ return (true);
+ }
+
+ bool has_one_edge = false;
+
+ // Verify edges with existing sub-graph
+ BGL_FORALL_VERTICES_T(existing_vertex1, graph1, GraphFirst)
+ {
+
+ VertexSecond existing_vertex2
+ = get(correspondence_map_1_to_2, existing_vertex1);
+
+ // Skip unassociated vertices
+ if (existing_vertex2 == graph_traits< GraphSecond >::null_vertex())
+ {
+ continue;
+ }
+
+ // NOTE: This will not work with parallel edges, since the
+ // first matching edge is always chosen.
+ EdgeFirst edge_to_new1, edge_from_new1;
+ bool edge_to_new_exists1 = false, edge_from_new_exists1 = false;
+
+ EdgeSecond edge_to_new2, edge_from_new2;
+ bool edge_to_new_exists2 = false, edge_from_new_exists2 = false;
+
+ // Search for edge from existing to new vertex (graph1)
+ BGL_FORALL_OUTEDGES_T(existing_vertex1, edge1, graph1, GraphFirst)
+ {
+ if (target(edge1, graph1) == new_vertex1)
+ {
+ edge_to_new1 = edge1;
+ edge_to_new_exists1 = true;
+ break;
+ }
+ }
+
+ // Search for edge from existing to new vertex (graph2)
+ BGL_FORALL_OUTEDGES_T(existing_vertex2, edge2, graph2, GraphSecond)
+ {
+ if (target(edge2, graph2) == new_vertex2)
+ {
+ edge_to_new2 = edge2;
+ edge_to_new_exists2 = true;
+ break;
+ }
+ }
+
+ // Make sure edges from existing to new vertices are equivalent
+ if ((edge_to_new_exists1 != edge_to_new_exists2)
+ || ((edge_to_new_exists1 && edge_to_new_exists2)
+ && !edges_equivalent(edge_to_new1, edge_to_new2)))
+ {
+
+ return (false);
+ }
+
+ bool is_undirected1 = is_undirected(graph1),
+ is_undirected2 = is_undirected(graph2);
+
+ if (is_undirected1 && is_undirected2)
+ {
+
+ // Edge in both graphs exists and both graphs are undirected
+ if (edge_to_new_exists1 && edge_to_new_exists2)
+ {
+ has_one_edge = true;
+ }
+
+ continue;
+ }
+ else
+ {
+
+ if (!is_undirected1)
+ {
+
+ // Search for edge from new to existing vertex (graph1)
+ BGL_FORALL_OUTEDGES_T(
+ new_vertex1, edge1, graph1, GraphFirst)
+ {
+ if (target(edge1, graph1) == existing_vertex1)
+ {
+ edge_from_new1 = edge1;
+ edge_from_new_exists1 = true;
+ break;
+ }
+ }
+ }
+
+ if (!is_undirected2)
+ {
+
+ // Search for edge from new to existing vertex (graph2)
+ BGL_FORALL_OUTEDGES_T(
+ new_vertex2, edge2, graph2, GraphSecond)
+ {
+ if (target(edge2, graph2) == existing_vertex2)
+ {
+ edge_from_new2 = edge2;
+ edge_from_new_exists2 = true;
+ break;
+ }
+ }
+ }
+
+ // Make sure edges from new to existing vertices are equivalent
+ if ((edge_from_new_exists1 != edge_from_new_exists2)
+ || ((edge_from_new_exists1 && edge_from_new_exists2)
+ && !edges_equivalent(edge_from_new1, edge_from_new2)))
+ {
+
+ return (false);
+ }
+
+ if ((edge_from_new_exists1 && edge_from_new_exists2)
+ || (edge_to_new_exists1 && edge_to_new_exists2))
+ {
+ has_one_edge = true;
+ }
+
+ } // else
+
+ } // BGL_FORALL_VERTICES_T
+
+ // Make sure new vertices are connected to the existing subgraph
+ if (only_connected_subgraphs && !has_one_edge)
+ {
+ return (false);
+ }
+
+ return (true);
+ }
+
+ // Recursive method that does a depth-first search in the space of
+ // potential subgraphs. At each level, every new vertex pair from
+ // both graphs is tested to see if it can extend the current
+ // subgraph. If so, the subgraph is output to subgraph_callback
+ // in the form of two correspondence maps (one for each graph).
+ // Returning false from subgraph_callback will terminate the
+ // search. Function returns true if the entire search space was
+ // explored.
+ template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond,
+ typename CorrespondenceMapFirstToSecond,
+ typename CorrespondenceMapSecondToFirst, typename VertexStackFirst,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename SubGraphInternalCallback >
+ bool mcgregor_common_subgraphs_internal(const GraphFirst& graph1,
+ const GraphSecond& graph2, const VertexIndexMapFirst& vindex_map1,
+ const VertexIndexMapSecond& vindex_map2,
+ CorrespondenceMapFirstToSecond correspondence_map_1_to_2,
+ CorrespondenceMapSecondToFirst correspondence_map_2_to_1,
+ VertexStackFirst& vertex_stack1,
+ EdgeEquivalencePredicate edges_equivalent,
+ VertexEquivalencePredicate vertices_equivalent,
+ bool only_connected_subgraphs,
+ SubGraphInternalCallback subgraph_callback)
+ {
+ typedef
+ typename graph_traits< GraphFirst >::vertex_descriptor VertexFirst;
+ typedef typename graph_traits< GraphSecond >::vertex_descriptor
+ VertexSecond;
+ typedef typename graph_traits< GraphFirst >::vertices_size_type
+ VertexSizeFirst;
+
+ // Get iterators for vertices from both graphs
+ typename graph_traits< GraphFirst >::vertex_iterator vertex1_iter,
+ vertex1_end;
+
+ typename graph_traits< GraphSecond >::vertex_iterator vertex2_begin,
+ vertex2_end, vertex2_iter;
+
+ boost::tie(vertex1_iter, vertex1_end) = vertices(graph1);
+ boost::tie(vertex2_begin, vertex2_end) = vertices(graph2);
+ vertex2_iter = vertex2_begin;
+
+ // Iterate until all vertices have been visited
+ BGL_FORALL_VERTICES_T(new_vertex1, graph1, GraphFirst)
+ {
+
+ VertexSecond existing_vertex2
+ = get(correspondence_map_1_to_2, new_vertex1);
+
+ // Skip already matched vertices in first graph
+ if (existing_vertex2 != graph_traits< GraphSecond >::null_vertex())
+ {
+ continue;
+ }
+
+ BGL_FORALL_VERTICES_T(new_vertex2, graph2, GraphSecond)
+ {
+
+ VertexFirst existing_vertex1
+ = get(correspondence_map_2_to_1, new_vertex2);
+
+ // Skip already matched vertices in second graph
+ if (existing_vertex1
+ != graph_traits< GraphFirst >::null_vertex())
+ {
+ continue;
+ }
+
+ // Check if current sub-graph can be extended with the matched
+ // vertex pair
+ if (can_extend_graph(graph1, graph2, correspondence_map_1_to_2,
+ correspondence_map_2_to_1,
+ (VertexSizeFirst)vertex_stack1.size(), new_vertex1,
+ new_vertex2, edges_equivalent, vertices_equivalent,
+ only_connected_subgraphs))
+ {
+
+ // Keep track of old graph size for restoring later
+ VertexSizeFirst old_graph_size
+ = (VertexSizeFirst)vertex_stack1.size(),
+ new_graph_size = old_graph_size + 1;
+
+ // Extend subgraph
+ put(correspondence_map_1_to_2, new_vertex1, new_vertex2);
+ put(correspondence_map_2_to_1, new_vertex2, new_vertex1);
+ vertex_stack1.push(new_vertex1);
+
+ // Returning false from the callback will cancel iteration
+ if (!subgraph_callback(correspondence_map_1_to_2,
+ correspondence_map_2_to_1, new_graph_size))
+ {
+ return (false);
+ }
+
+ // Depth-first search into the state space of possible
+ // sub-graphs
+ bool continue_iteration
+ = mcgregor_common_subgraphs_internal(graph1, graph2,
+ vindex_map1, vindex_map2, correspondence_map_1_to_2,
+ correspondence_map_2_to_1, vertex_stack1,
+ edges_equivalent, vertices_equivalent,
+ only_connected_subgraphs, subgraph_callback);
+
+ if (!continue_iteration)
+ {
+ return (false);
+ }
+
+ // Restore previous state
+ if (vertex_stack1.size() > old_graph_size)
+ {
+
+ VertexFirst stack_vertex1 = vertex_stack1.top();
+ VertexSecond stack_vertex2
+ = get(correspondence_map_1_to_2, stack_vertex1);
+
+ // Contract subgraph
+ put(correspondence_map_1_to_2, stack_vertex1,
+ graph_traits< GraphSecond >::null_vertex());
+
+ put(correspondence_map_2_to_1, stack_vertex2,
+ graph_traits< GraphFirst >::null_vertex());
+
+ vertex_stack1.pop();
+ }
+
+ } // if can_extend_graph
+
+ } // BGL_FORALL_VERTICES_T (graph2)
+
+ } // BGL_FORALL_VERTICES_T (graph1)
+
+ return (true);
+ }
+
+ // Internal method that initializes blank correspondence maps and
+ // a vertex stack for use in mcgregor_common_subgraphs_internal.
+ template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename SubGraphInternalCallback >
+ inline void mcgregor_common_subgraphs_internal_init(
+ const GraphFirst& graph1, const GraphSecond& graph2,
+ const VertexIndexMapFirst vindex_map1,
+ const VertexIndexMapSecond vindex_map2,
+ EdgeEquivalencePredicate edges_equivalent,
+ VertexEquivalencePredicate vertices_equivalent,
+ bool only_connected_subgraphs,
+ SubGraphInternalCallback subgraph_callback)
+ {
+ typedef mcgregor_common_subgraph_traits< GraphFirst, GraphSecond,
+ VertexIndexMapFirst, VertexIndexMapSecond >
+ SubGraphTraits;
+
+ typename SubGraphTraits::correspondence_map_first_to_second_type
+ correspondence_map_1_to_2(num_vertices(graph1), vindex_map1);
+
+ BGL_FORALL_VERTICES_T(vertex1, graph1, GraphFirst)
+ {
+ put(correspondence_map_1_to_2, vertex1,
+ graph_traits< GraphSecond >::null_vertex());
+ }
+
+ typename SubGraphTraits::correspondence_map_second_to_first_type
+ correspondence_map_2_to_1(num_vertices(graph2), vindex_map2);
+
+ BGL_FORALL_VERTICES_T(vertex2, graph2, GraphSecond)
+ {
+ put(correspondence_map_2_to_1, vertex2,
+ graph_traits< GraphFirst >::null_vertex());
+ }
+
+ typedef
+ typename graph_traits< GraphFirst >::vertex_descriptor VertexFirst;
+
+ std::stack< VertexFirst > vertex_stack1;
+
+ mcgregor_common_subgraphs_internal(graph1, graph2, vindex_map1,
+ vindex_map2, correspondence_map_1_to_2, correspondence_map_2_to_1,
+ vertex_stack1, edges_equivalent, vertices_equivalent,
+ only_connected_subgraphs, subgraph_callback);
+ }
+
+} // namespace detail
+
+// ==========================================================================
+
+// Enumerates all common subgraphs present in graph1 and graph2.
+// Continues until the search space has been fully explored or false
+// is returned from user_callback.
+template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename SubGraphCallback >
+void mcgregor_common_subgraphs(const GraphFirst& graph1,
+ const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1,
+ const VertexIndexMapSecond vindex_map2,
+ EdgeEquivalencePredicate edges_equivalent,
+ VertexEquivalencePredicate vertices_equivalent,
+ bool only_connected_subgraphs, SubGraphCallback user_callback)
+{
+
+ detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, vindex_map1,
+ vindex_map2, edges_equivalent, vertices_equivalent,
+ only_connected_subgraphs, user_callback);
+}
+
+// Variant of mcgregor_common_subgraphs with all default parameters
+template < typename GraphFirst, typename GraphSecond,
+ typename SubGraphCallback >
+void mcgregor_common_subgraphs(const GraphFirst& graph1,
+ const GraphSecond& graph2, bool only_connected_subgraphs,
+ SubGraphCallback user_callback)
+{
+
+ detail::mcgregor_common_subgraphs_internal_init(graph1, graph2,
+ get(vertex_index, graph1), get(vertex_index, graph2),
+ always_equivalent(), always_equivalent(), only_connected_subgraphs,
+ user_callback);
+}
+
+// Named parameter variant of mcgregor_common_subgraphs
+template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback,
+ typename Param, typename Tag, typename Rest >
+void mcgregor_common_subgraphs(const GraphFirst& graph1,
+ const GraphSecond& graph2, bool only_connected_subgraphs,
+ SubGraphCallback user_callback,
+ const bgl_named_params< Param, Tag, Rest >& params)
+{
+
+ detail::mcgregor_common_subgraphs_internal_init(graph1, graph2,
+ choose_const_pmap(
+ get_param(params, vertex_index1), graph1, vertex_index),
+ choose_const_pmap(
+ get_param(params, vertex_index2), graph2, vertex_index),
+ choose_param(
+ get_param(params, edges_equivalent_t()), always_equivalent()),
+ choose_param(
+ get_param(params, vertices_equivalent_t()), always_equivalent()),
+ only_connected_subgraphs, user_callback);
+}
+
+// ==========================================================================
+
+namespace detail
+{
+
+ // Binary function object that intercepts subgraphs from
+ // mcgregor_common_subgraphs_internal and maintains a cache of
+ // unique subgraphs. The user callback is invoked for each unique
+ // subgraph.
+ template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond,
+ typename SubGraphCallback >
+ struct unique_subgraph_interceptor
+ {
+
+ typedef typename graph_traits< GraphFirst >::vertices_size_type
+ VertexSizeFirst;
+
+ typedef mcgregor_common_subgraph_traits< GraphFirst, GraphSecond,
+ VertexIndexMapFirst, VertexIndexMapSecond >
+ SubGraphTraits;
+
+ typedef typename SubGraphTraits::correspondence_map_first_to_second_type
+ CachedCorrespondenceMapFirstToSecond;
+
+ typedef typename SubGraphTraits::correspondence_map_second_to_first_type
+ CachedCorrespondenceMapSecondToFirst;
+
+ typedef std::pair< VertexSizeFirst,
+ std::pair< CachedCorrespondenceMapFirstToSecond,
+ CachedCorrespondenceMapSecondToFirst > >
+ SubGraph;
+
+ typedef std::vector< SubGraph > SubGraphList;
+
+ unique_subgraph_interceptor(const GraphFirst& graph1,
+ const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1,
+ const VertexIndexMapSecond vindex_map2,
+ SubGraphCallback user_callback)
+ : m_graph1(graph1)
+ , m_graph2(graph2)
+ , m_vindex_map1(vindex_map1)
+ , m_vindex_map2(vindex_map2)
+ , m_subgraphs(make_shared< SubGraphList >())
+ , m_user_callback(user_callback)
+ {
+ }
+
+ template < typename CorrespondenceMapFirstToSecond,
+ typename CorrespondenceMapSecondToFirst >
+ bool operator()(
+ CorrespondenceMapFirstToSecond correspondence_map_1_to_2,
+ CorrespondenceMapSecondToFirst correspondence_map_2_to_1,
+ VertexSizeFirst subgraph_size)
+ {
+
+ for (typename SubGraphList::const_iterator subgraph_iter
+ = m_subgraphs->begin();
+ subgraph_iter != m_subgraphs->end(); ++subgraph_iter)
+ {
+
+ SubGraph subgraph_cached = *subgraph_iter;
+
+ // Compare subgraph sizes
+ if (subgraph_size != subgraph_cached.first)
+ {
+ continue;
+ }
+
+ if (!are_property_maps_different(correspondence_map_1_to_2,
+ subgraph_cached.second.first, m_graph1))
+ {
+
+ // New subgraph is a duplicate
+ return (true);
+ }
+ }
+
+ // Subgraph is unique, so make a cached copy
+ CachedCorrespondenceMapFirstToSecond new_subgraph_1_to_2
+ = CachedCorrespondenceMapFirstToSecond(
+ num_vertices(m_graph1), m_vindex_map1);
+
+ CachedCorrespondenceMapSecondToFirst new_subgraph_2_to_1
+ = CorrespondenceMapSecondToFirst(
+ num_vertices(m_graph2), m_vindex_map2);
+
+ BGL_FORALL_VERTICES_T(vertex1, m_graph1, GraphFirst)
+ {
+ put(new_subgraph_1_to_2, vertex1,
+ get(correspondence_map_1_to_2, vertex1));
+ }
+
+ BGL_FORALL_VERTICES_T(vertex2, m_graph2, GraphFirst)
+ {
+ put(new_subgraph_2_to_1, vertex2,
+ get(correspondence_map_2_to_1, vertex2));
+ }
+
+ m_subgraphs->push_back(std::make_pair(subgraph_size,
+ std::make_pair(new_subgraph_1_to_2, new_subgraph_2_to_1)));
+
+ return (m_user_callback(correspondence_map_1_to_2,
+ correspondence_map_2_to_1, subgraph_size));
+ }
+
+ private:
+ const GraphFirst& m_graph1;
+ const GraphFirst& m_graph2;
+ const VertexIndexMapFirst m_vindex_map1;
+ const VertexIndexMapSecond m_vindex_map2;
+ shared_ptr< SubGraphList > m_subgraphs;
+ SubGraphCallback m_user_callback;
+ };
+
+} // namespace detail
+
+// Enumerates all unique common subgraphs between graph1 and graph2.
+// The user callback is invoked for each unique subgraph as they are
+// discovered.
+template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename SubGraphCallback >
+void mcgregor_common_subgraphs_unique(const GraphFirst& graph1,
+ const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1,
+ const VertexIndexMapSecond vindex_map2,
+ EdgeEquivalencePredicate edges_equivalent,
+ VertexEquivalencePredicate vertices_equivalent,
+ bool only_connected_subgraphs, SubGraphCallback user_callback)
+{
+ detail::unique_subgraph_interceptor< GraphFirst, GraphSecond,
+ VertexIndexMapFirst, VertexIndexMapSecond, SubGraphCallback >
+ unique_callback(
+ graph1, graph2, vindex_map1, vindex_map2, user_callback);
+
+ detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, vindex_map1,
+ vindex_map2, edges_equivalent, vertices_equivalent,
+ only_connected_subgraphs, unique_callback);
+}
+
+// Variant of mcgregor_common_subgraphs_unique with all default
+// parameters.
+template < typename GraphFirst, typename GraphSecond,
+ typename SubGraphCallback >
+void mcgregor_common_subgraphs_unique(const GraphFirst& graph1,
+ const GraphSecond& graph2, bool only_connected_subgraphs,
+ SubGraphCallback user_callback)
+{
+ mcgregor_common_subgraphs_unique(graph1, graph2, get(vertex_index, graph1),
+ get(vertex_index, graph2), always_equivalent(), always_equivalent(),
+ only_connected_subgraphs, user_callback);
+}
+
+// Named parameter variant of mcgregor_common_subgraphs_unique
+template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback,
+ typename Param, typename Tag, typename Rest >
+void mcgregor_common_subgraphs_unique(const GraphFirst& graph1,
+ const GraphSecond& graph2, bool only_connected_subgraphs,
+ SubGraphCallback user_callback,
+ const bgl_named_params< Param, Tag, Rest >& params)
+{
+ mcgregor_common_subgraphs_unique(graph1, graph2,
+ choose_const_pmap(
+ get_param(params, vertex_index1), graph1, vertex_index),
+ choose_const_pmap(
+ get_param(params, vertex_index2), graph2, vertex_index),
+ choose_param(
+ get_param(params, edges_equivalent_t()), always_equivalent()),
+ choose_param(
+ get_param(params, vertices_equivalent_t()), always_equivalent()),
+ only_connected_subgraphs, user_callback);
+}
+
+// ==========================================================================
+
+namespace detail
+{
+
+ // Binary function object that intercepts subgraphs from
+ // mcgregor_common_subgraphs_internal and maintains a cache of the
+ // largest subgraphs.
+ template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond,
+ typename SubGraphCallback >
+ struct maximum_subgraph_interceptor
+ {
+
+ typedef typename graph_traits< GraphFirst >::vertices_size_type
+ VertexSizeFirst;
+
+ typedef mcgregor_common_subgraph_traits< GraphFirst, GraphSecond,
+ VertexIndexMapFirst, VertexIndexMapSecond >
+ SubGraphTraits;
+
+ typedef typename SubGraphTraits::correspondence_map_first_to_second_type
+ CachedCorrespondenceMapFirstToSecond;
+
+ typedef typename SubGraphTraits::correspondence_map_second_to_first_type
+ CachedCorrespondenceMapSecondToFirst;
+
+ typedef std::pair< VertexSizeFirst,
+ std::pair< CachedCorrespondenceMapFirstToSecond,
+ CachedCorrespondenceMapSecondToFirst > >
+ SubGraph;
+
+ typedef std::vector< SubGraph > SubGraphList;
+
+ maximum_subgraph_interceptor(const GraphFirst& graph1,
+ const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1,
+ const VertexIndexMapSecond vindex_map2,
+ SubGraphCallback user_callback)
+ : m_graph1(graph1)
+ , m_graph2(graph2)
+ , m_vindex_map1(vindex_map1)
+ , m_vindex_map2(vindex_map2)
+ , m_subgraphs(make_shared< SubGraphList >())
+ , m_largest_size_so_far(make_shared< VertexSizeFirst >(0))
+ , m_user_callback(user_callback)
+ {
+ }
+
+ template < typename CorrespondenceMapFirstToSecond,
+ typename CorrespondenceMapSecondToFirst >
+ bool operator()(
+ CorrespondenceMapFirstToSecond correspondence_map_1_to_2,
+ CorrespondenceMapSecondToFirst correspondence_map_2_to_1,
+ VertexSizeFirst subgraph_size)
+ {
+
+ if (subgraph_size > *m_largest_size_so_far)
+ {
+ m_subgraphs->clear();
+ *m_largest_size_so_far = subgraph_size;
+ }
+
+ if (subgraph_size == *m_largest_size_so_far)
+ {
+
+ // Make a cached copy
+ CachedCorrespondenceMapFirstToSecond new_subgraph_1_to_2
+ = CachedCorrespondenceMapFirstToSecond(
+ num_vertices(m_graph1), m_vindex_map1);
+
+ CachedCorrespondenceMapSecondToFirst new_subgraph_2_to_1
+ = CachedCorrespondenceMapSecondToFirst(
+ num_vertices(m_graph2), m_vindex_map2);
+
+ BGL_FORALL_VERTICES_T(vertex1, m_graph1, GraphFirst)
+ {
+ put(new_subgraph_1_to_2, vertex1,
+ get(correspondence_map_1_to_2, vertex1));
+ }
+
+ BGL_FORALL_VERTICES_T(vertex2, m_graph2, GraphFirst)
+ {
+ put(new_subgraph_2_to_1, vertex2,
+ get(correspondence_map_2_to_1, vertex2));
+ }
+
+ m_subgraphs->push_back(std::make_pair(subgraph_size,
+ std::make_pair(new_subgraph_1_to_2, new_subgraph_2_to_1)));
+ }
+
+ return (true);
+ }
+
+ void output_subgraphs()
+ {
+ for (typename SubGraphList::const_iterator subgraph_iter
+ = m_subgraphs->begin();
+ subgraph_iter != m_subgraphs->end(); ++subgraph_iter)
+ {
+
+ SubGraph subgraph_cached = *subgraph_iter;
+ m_user_callback(subgraph_cached.second.first,
+ subgraph_cached.second.second, subgraph_cached.first);
+ }
+ }
+
+ private:
+ const GraphFirst& m_graph1;
+ const GraphFirst& m_graph2;
+ const VertexIndexMapFirst m_vindex_map1;
+ const VertexIndexMapSecond m_vindex_map2;
+ shared_ptr< SubGraphList > m_subgraphs;
+ shared_ptr< VertexSizeFirst > m_largest_size_so_far;
+ SubGraphCallback m_user_callback;
+ };
+
+} // namespace detail
+
+// Enumerates the largest common subgraphs found between graph1
+// and graph2. Note that the ENTIRE search space is explored before
+// user_callback is actually invoked.
+template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename SubGraphCallback >
+void mcgregor_common_subgraphs_maximum(const GraphFirst& graph1,
+ const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1,
+ const VertexIndexMapSecond vindex_map2,
+ EdgeEquivalencePredicate edges_equivalent,
+ VertexEquivalencePredicate vertices_equivalent,
+ bool only_connected_subgraphs, SubGraphCallback user_callback)
+{
+ detail::maximum_subgraph_interceptor< GraphFirst, GraphSecond,
+ VertexIndexMapFirst, VertexIndexMapSecond, SubGraphCallback >
+ max_interceptor(
+ graph1, graph2, vindex_map1, vindex_map2, user_callback);
+
+ detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, vindex_map1,
+ vindex_map2, edges_equivalent, vertices_equivalent,
+ only_connected_subgraphs, max_interceptor);
+
+ // Only output the largest subgraphs
+ max_interceptor.output_subgraphs();
+}
+
+// Variant of mcgregor_common_subgraphs_maximum with all default
+// parameters.
+template < typename GraphFirst, typename GraphSecond,
+ typename SubGraphCallback >
+void mcgregor_common_subgraphs_maximum(const GraphFirst& graph1,
+ const GraphSecond& graph2, bool only_connected_subgraphs,
+ SubGraphCallback user_callback)
+{
+ mcgregor_common_subgraphs_maximum(graph1, graph2, get(vertex_index, graph1),
+ get(vertex_index, graph2), always_equivalent(), always_equivalent(),
+ only_connected_subgraphs, user_callback);
+}
+
+// Named parameter variant of mcgregor_common_subgraphs_maximum
+template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback,
+ typename Param, typename Tag, typename Rest >
+void mcgregor_common_subgraphs_maximum(const GraphFirst& graph1,
+ const GraphSecond& graph2, bool only_connected_subgraphs,
+ SubGraphCallback user_callback,
+ const bgl_named_params< Param, Tag, Rest >& params)
+{
+ mcgregor_common_subgraphs_maximum(graph1, graph2,
+ choose_const_pmap(
+ get_param(params, vertex_index1), graph1, vertex_index),
+ choose_const_pmap(
+ get_param(params, vertex_index2), graph2, vertex_index),
+ choose_param(
+ get_param(params, edges_equivalent_t()), always_equivalent()),
+ choose_param(
+ get_param(params, vertices_equivalent_t()), always_equivalent()),
+ only_connected_subgraphs, user_callback);
+}
+
+// ==========================================================================
+
+namespace detail
+{
+
+ // Binary function object that intercepts subgraphs from
+ // mcgregor_common_subgraphs_internal and maintains a cache of the
+ // largest, unique subgraphs.
+ template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond,
+ typename SubGraphCallback >
+ struct unique_maximum_subgraph_interceptor
+ {
+
+ typedef typename graph_traits< GraphFirst >::vertices_size_type
+ VertexSizeFirst;
+
+ typedef mcgregor_common_subgraph_traits< GraphFirst, GraphSecond,
+ VertexIndexMapFirst, VertexIndexMapSecond >
+ SubGraphTraits;
+
+ typedef typename SubGraphTraits::correspondence_map_first_to_second_type
+ CachedCorrespondenceMapFirstToSecond;
+
+ typedef typename SubGraphTraits::correspondence_map_second_to_first_type
+ CachedCorrespondenceMapSecondToFirst;
+
+ typedef std::pair< VertexSizeFirst,
+ std::pair< CachedCorrespondenceMapFirstToSecond,
+ CachedCorrespondenceMapSecondToFirst > >
+ SubGraph;
+
+ typedef std::vector< SubGraph > SubGraphList;
+
+ unique_maximum_subgraph_interceptor(const GraphFirst& graph1,
+ const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1,
+ const VertexIndexMapSecond vindex_map2,
+ SubGraphCallback user_callback)
+ : m_graph1(graph1)
+ , m_graph2(graph2)
+ , m_vindex_map1(vindex_map1)
+ , m_vindex_map2(vindex_map2)
+ , m_subgraphs(make_shared< SubGraphList >())
+ , m_largest_size_so_far(make_shared< VertexSizeFirst >(0))
+ , m_user_callback(user_callback)
+ {
+ }
+
+ template < typename CorrespondenceMapFirstToSecond,
+ typename CorrespondenceMapSecondToFirst >
+ bool operator()(
+ CorrespondenceMapFirstToSecond correspondence_map_1_to_2,
+ CorrespondenceMapSecondToFirst correspondence_map_2_to_1,
+ VertexSizeFirst subgraph_size)
+ {
+
+ if (subgraph_size > *m_largest_size_so_far)
+ {
+ m_subgraphs->clear();
+ *m_largest_size_so_far = subgraph_size;
+ }
+
+ if (subgraph_size == *m_largest_size_so_far)
+ {
+
+ // Check if subgraph is unique
+ for (typename SubGraphList::const_iterator subgraph_iter
+ = m_subgraphs->begin();
+ subgraph_iter != m_subgraphs->end(); ++subgraph_iter)
+ {
+
+ SubGraph subgraph_cached = *subgraph_iter;
+
+ if (!are_property_maps_different(correspondence_map_1_to_2,
+ subgraph_cached.second.first, m_graph1))
+ {
+
+ // New subgraph is a duplicate
+ return (true);
+ }
+ }
+
+ // Subgraph is unique, so make a cached copy
+ CachedCorrespondenceMapFirstToSecond new_subgraph_1_to_2
+ = CachedCorrespondenceMapFirstToSecond(
+ num_vertices(m_graph1), m_vindex_map1);
+
+ CachedCorrespondenceMapSecondToFirst new_subgraph_2_to_1
+ = CachedCorrespondenceMapSecondToFirst(
+ num_vertices(m_graph2), m_vindex_map2);
+
+ BGL_FORALL_VERTICES_T(vertex1, m_graph1, GraphFirst)
+ {
+ put(new_subgraph_1_to_2, vertex1,
+ get(correspondence_map_1_to_2, vertex1));
+ }
+
+ BGL_FORALL_VERTICES_T(vertex2, m_graph2, GraphFirst)
+ {
+ put(new_subgraph_2_to_1, vertex2,
+ get(correspondence_map_2_to_1, vertex2));
+ }
+
+ m_subgraphs->push_back(std::make_pair(subgraph_size,
+ std::make_pair(new_subgraph_1_to_2, new_subgraph_2_to_1)));
+ }
+
+ return (true);
+ }
+
+ void output_subgraphs()
+ {
+ for (typename SubGraphList::const_iterator subgraph_iter
+ = m_subgraphs->begin();
+ subgraph_iter != m_subgraphs->end(); ++subgraph_iter)
+ {
+
+ SubGraph subgraph_cached = *subgraph_iter;
+ m_user_callback(subgraph_cached.second.first,
+ subgraph_cached.second.second, subgraph_cached.first);
+ }
+ }
+
+ private:
+ const GraphFirst& m_graph1;
+ const GraphFirst& m_graph2;
+ const VertexIndexMapFirst m_vindex_map1;
+ const VertexIndexMapSecond m_vindex_map2;
+ shared_ptr< SubGraphList > m_subgraphs;
+ shared_ptr< VertexSizeFirst > m_largest_size_so_far;
+ SubGraphCallback m_user_callback;
+ };
+
+} // namespace detail
+
+// Enumerates the largest, unique common subgraphs found between
+// graph1 and graph2. Note that the ENTIRE search space is explored
+// before user_callback is actually invoked.
+template < typename GraphFirst, typename GraphSecond,
+ typename VertexIndexMapFirst, typename VertexIndexMapSecond,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename SubGraphCallback >
+void mcgregor_common_subgraphs_maximum_unique(const GraphFirst& graph1,
+ const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1,
+ const VertexIndexMapSecond vindex_map2,
+ EdgeEquivalencePredicate edges_equivalent,
+ VertexEquivalencePredicate vertices_equivalent,
+ bool only_connected_subgraphs, SubGraphCallback user_callback)
+{
+ detail::unique_maximum_subgraph_interceptor< GraphFirst, GraphSecond,
+ VertexIndexMapFirst, VertexIndexMapSecond, SubGraphCallback >
+ unique_max_interceptor(
+ graph1, graph2, vindex_map1, vindex_map2, user_callback);
+
+ detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, vindex_map1,
+ vindex_map2, edges_equivalent, vertices_equivalent,
+ only_connected_subgraphs, unique_max_interceptor);
+
+ // Only output the largest, unique subgraphs
+ unique_max_interceptor.output_subgraphs();
+}
+
+// Variant of mcgregor_common_subgraphs_maximum_unique with all default
+// parameters
+template < typename GraphFirst, typename GraphSecond,
+ typename SubGraphCallback >
+void mcgregor_common_subgraphs_maximum_unique(const GraphFirst& graph1,
+ const GraphSecond& graph2, bool only_connected_subgraphs,
+ SubGraphCallback user_callback)
+{
+
+ mcgregor_common_subgraphs_maximum_unique(graph1, graph2,
+ get(vertex_index, graph1), get(vertex_index, graph2),
+ always_equivalent(), always_equivalent(), only_connected_subgraphs,
+ user_callback);
+}
+
+// Named parameter variant of
+// mcgregor_common_subgraphs_maximum_unique
+template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback,
+ typename Param, typename Tag, typename Rest >
+void mcgregor_common_subgraphs_maximum_unique(const GraphFirst& graph1,
+ const GraphSecond& graph2, bool only_connected_subgraphs,
+ SubGraphCallback user_callback,
+ const bgl_named_params< Param, Tag, Rest >& params)
+{
+ mcgregor_common_subgraphs_maximum_unique(graph1, graph2,
+ choose_const_pmap(
+ get_param(params, vertex_index1), graph1, vertex_index),
+ choose_const_pmap(
+ get_param(params, vertex_index2), graph2, vertex_index),
+ choose_param(
+ get_param(params, edges_equivalent_t()), always_equivalent()),
+ choose_param(
+ get_param(params, vertices_equivalent_t()), always_equivalent()),
+ only_connected_subgraphs, user_callback);
+}
+
+// ==========================================================================
+
+// Fills a membership map (vertex -> bool) using the information
+// present in correspondence_map_1_to_2. Every vertex in a
+// membership map will have a true value only if it is not
+// associated with a null vertex in the correspondence map.
+template < typename GraphSecond, typename GraphFirst,
+ typename CorrespondenceMapFirstToSecond, typename MembershipMapFirst >
+void fill_membership_map(const GraphFirst& graph1,
+ const CorrespondenceMapFirstToSecond correspondence_map_1_to_2,
+ MembershipMapFirst membership_map1)
+{
+
+ BGL_FORALL_VERTICES_T(vertex1, graph1, GraphFirst)
+ {
+ put(membership_map1, vertex1,
+ get(correspondence_map_1_to_2, vertex1)
+ != graph_traits< GraphSecond >::null_vertex());
+ }
+}
+
+// Traits associated with a membership map filtered graph. Provided
+// for convenience to access graph and vertex filter types.
+template < typename Graph, typename MembershipMap >
+struct membership_filtered_graph_traits
+{
+ typedef property_map_filter< MembershipMap > vertex_filter_type;
+ typedef filtered_graph< Graph, keep_all, vertex_filter_type > graph_type;
+};
+
+// Returns a filtered sub-graph of graph whose edge and vertex
+// inclusion is dictated by membership_map.
+template < typename Graph, typename MembershipMap >
+typename membership_filtered_graph_traits< Graph, MembershipMap >::graph_type
+make_membership_filtered_graph(
+ const Graph& graph, MembershipMap& membership_map)
+{
+
+ typedef membership_filtered_graph_traits< Graph, MembershipMap > MFGTraits;
+ typedef typename MFGTraits::graph_type MembershipFilteredGraph;
+
+ typename MFGTraits::vertex_filter_type v_filter(membership_map);
+
+ return (MembershipFilteredGraph(graph, keep_all(), v_filter));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_MCGREGOR_COMMON_SUBGRAPHS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/mesh_graph_generator.hpp b/contrib/restricted/boost/graph/include/boost/graph/mesh_graph_generator.hpp
new file mode 100644
index 0000000000..0dcba2adad
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/mesh_graph_generator.hpp
@@ -0,0 +1,184 @@
+// Copyright 2004, 2005 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Nick Edmonds
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_MESH_GENERATOR_HPP
+#define BOOST_GRAPH_MESH_GENERATOR_HPP
+
+#include <iterator>
+#include <utility>
+#include <boost/assert.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost
+{
+
+template < typename Graph > class mesh_iterator
+{
+ typedef typename graph_traits< Graph >::directed_category directed_category;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+
+ BOOST_STATIC_CONSTANT(bool,
+ is_undirected
+ = (is_base_and_derived< undirected_tag, directed_category >::value
+ || is_same< undirected_tag, directed_category >::value));
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< vertices_size_type, vertices_size_type > value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef void difference_type;
+
+ mesh_iterator() : x(0), y(0), done(true) {}
+
+ // Vertices are numbered in row-major order
+ // Assumes directed
+ mesh_iterator(
+ vertices_size_type x, vertices_size_type y, bool toroidal = true)
+ : x(x)
+ , y(y)
+ , n(x * y)
+ , source(0)
+ , target(1)
+ , current(0, 1)
+ , toroidal(toroidal)
+ , done(false)
+ {
+ BOOST_ASSERT(x > 1 && y > 1);
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return &current; }
+
+ mesh_iterator& operator++()
+ {
+ if (is_undirected)
+ {
+ if (!toroidal)
+ {
+ if (target == source + 1)
+ if (source < x * (y - 1))
+ target = source + x;
+ else
+ {
+ source++;
+ target = (source % x) < x - 1 ? source + 1 : source + x;
+ if (target > n)
+ done = true;
+ }
+ else if (target == source + x)
+ {
+ source++;
+ target = (source % x) < x - 1 ? source + 1 : source + x;
+ }
+ }
+ else
+ {
+ if (target == source + 1 || target == source - (source % x))
+ target = (source + x) % n;
+ else if (target == (source + x) % n)
+ {
+ if (source == n - 1)
+ done = true;
+ else
+ {
+ source++;
+ target = (source % x) < (x - 1) ? source + 1
+ : source - (source % x);
+ }
+ }
+ }
+ }
+ else
+ { // Directed
+ if (!toroidal)
+ {
+ if (target == source - x)
+ target = source % x > 0 ? source - 1 : source + 1;
+ else if (target == source - 1)
+ if ((source % x) < (x - 1))
+ target = source + 1;
+ else if (source < x * (y - 1))
+ target = source + x;
+ else
+ {
+ done = true;
+ }
+ else if (target == source + 1)
+ if (source < x * (y - 1))
+ target = source + x;
+ else
+ {
+ source++;
+ target = source - x;
+ }
+ else if (target == source + x)
+ {
+ source++;
+ target = (source >= x) ? source - x : source - 1;
+ }
+ }
+ else
+ {
+ if (source == n - 1 && target == (source + x) % n)
+ done = true;
+ else if (target == source - 1 || target == source + x - 1)
+ target = (source + x) % n;
+ else if (target == source + 1
+ || target == source - (source % x))
+ target = (source - x + n) % n;
+ else if (target == (source - x + n) % n)
+ target = (source % x > 0) ? source - 1 : source + x - 1;
+ else if (target == (source + x) % n)
+ {
+ source++;
+ target = (source % x) < (x - 1) ? source + 1
+ : source - (source % x);
+ }
+ }
+ }
+
+ current.first = source;
+ current.second = target;
+
+ return *this;
+ }
+
+ mesh_iterator operator++(int)
+ {
+ mesh_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const mesh_iterator& other) const
+ {
+ return done == other.done;
+ }
+
+ bool operator!=(const mesh_iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ vertices_size_type x, y;
+ vertices_size_type n;
+ vertices_size_type source;
+ vertices_size_type target;
+ value_type current;
+ bool toroidal;
+ bool done;
+};
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_MESH_GENERATOR_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/metis.hpp b/contrib/restricted/boost/graph/include/boost/graph/metis.hpp
new file mode 100644
index 0000000000..e6567c999a
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/metis.hpp
@@ -0,0 +1,369 @@
+// Copyright 2005 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_METIS_HPP
+#define BOOST_GRAPH_METIS_HPP
+
+#ifdef BOOST_GRAPH_METIS_NO_INLINE
+#define BOOST_GRAPH_METIS_INLINE_KEYWORD
+#else
+#define BOOST_GRAPH_METIS_INLINE_KEYWORD inline
+#endif
+
+#include <string>
+#include <iostream>
+#include <iterator>
+#include <utility>
+#include <sstream>
+#include <exception>
+#include <vector>
+#include <algorithm>
+
+#include <boost/throw_exception.hpp>
+
+namespace boost
+{
+namespace graph
+{
+
+ class BOOST_SYMBOL_VISIBLE metis_exception : public std::exception
+ {
+ };
+ class BOOST_SYMBOL_VISIBLE metis_input_exception : public metis_exception
+ {
+ };
+
+ class metis_reader
+ {
+ public:
+ typedef std::size_t vertices_size_type;
+ typedef std::size_t edges_size_type;
+ typedef double vertex_weight_type;
+ typedef double edge_weight_type;
+
+ class edge_iterator
+ {
+ public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< vertices_size_type, vertices_size_type >
+ value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef std::ptrdiff_t difference_type;
+
+ private:
+ class postincrement_proxy
+ {
+ postincrement_proxy(const value_type& value) : value(value) {}
+
+ public:
+ reference operator*() const { return value; }
+
+ private:
+ value_type value;
+ friend class edge_iterator;
+ };
+
+ public:
+ edge_iterator& operator++();
+ postincrement_proxy operator++(int);
+
+ reference operator*() const { return self->edge; }
+ pointer operator->() const { return &self->edge; }
+
+ // Default copy constructor and assignment operator are okay
+
+ private:
+ edge_iterator(metis_reader* self);
+ void advance(bool skip_initial_read);
+
+ metis_reader* self;
+
+ friend class metis_reader;
+ friend bool operator==(edge_iterator, edge_iterator);
+ friend bool operator!=(edge_iterator, edge_iterator);
+ };
+ friend class edge_iterator;
+
+ class edge_weight_iterator
+ {
+ public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef edge_weight_type value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+
+ // Default copy constructor and assignment operator are okay
+
+ reference operator*() const { return self->edge_weight; }
+ pointer operator->() const { return &self->edge_weight; }
+
+ edge_weight_iterator& operator++() { return *this; }
+ edge_weight_iterator operator++(int) { return *this; }
+
+ private:
+ edge_weight_iterator(metis_reader* self) : self(self) {}
+
+ metis_reader* self;
+
+ friend class metis_reader;
+ };
+
+ metis_reader(std::istream& in) : in(in), edge_weight(1.0) { start(); }
+
+ edge_iterator begin();
+ edge_iterator end();
+ edge_weight_iterator weight_begin();
+
+ vertices_size_type num_vertices() const { return n_vertices; }
+ edges_size_type num_edges() const { return n_edges; }
+
+ std::size_t num_vertex_weights() const { return n_vertex_weights; }
+
+ vertex_weight_type vertex_weight(vertices_size_type v, std::size_t n)
+ {
+ return vertex_weights[v * num_vertex_weights() + n];
+ }
+
+ bool has_edge_weights() const { return edge_weights; }
+
+ private:
+ void start();
+
+ // Configuration information
+ std::istream& in;
+
+ // Information about the current METIS file
+ vertices_size_type n_vertices;
+ edges_size_type n_edges;
+ std::size_t n_vertex_weights;
+ bool edge_weights;
+
+ // Information about the current edge/vertex
+ std::istringstream line_in;
+ std::pair< vertices_size_type, vertices_size_type > edge;
+ std::vector< vertex_weight_type > vertex_weights;
+ edge_weight_type edge_weight;
+
+ friend bool operator==(edge_iterator, edge_iterator);
+ friend bool operator!=(edge_iterator, edge_iterator);
+ };
+
+ class metis_distribution
+ {
+ public:
+ typedef int process_id_type;
+ typedef std::size_t size_type;
+ typedef std::vector< process_id_type >::iterator iterator;
+
+ metis_distribution(std::istream& in, process_id_type my_id);
+
+ size_type block_size(process_id_type id, size_type) const;
+ process_id_type operator()(size_type n) const { return vertices[n]; }
+ size_type local(size_type n) const;
+ size_type global(size_type n) const { return global(my_id, n); }
+ size_type global(process_id_type id, size_type n) const;
+
+ iterator begin() { return vertices.begin(); }
+ iterator end() { return vertices.end(); }
+
+ private:
+ process_id_type my_id;
+ std::vector< process_id_type > vertices;
+ };
+
+#if !defined(BOOST_GRAPH_METIS_NO_INLINE) || defined(BOOST_GRAPH_METIS_SOURCE)
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ bool operator==(
+ metis_reader::edge_iterator x, metis_reader::edge_iterator y)
+ {
+ return (x.self == y.self
+ || (x.self && x.self->edge.first == x.self->num_vertices())
+ || (y.self && y.self->edge.first == y.self->num_vertices()));
+ }
+
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ bool operator!=(
+ metis_reader::edge_iterator x, metis_reader::edge_iterator y)
+ {
+ return !(x == y);
+ }
+
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ metis_reader::edge_iterator::edge_iterator(metis_reader* self) : self(self)
+ {
+ if (self)
+ advance(true);
+ }
+
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ metis_reader::edge_iterator& metis_reader::edge_iterator::operator++()
+ {
+ advance(false);
+ return *this;
+ }
+
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ void metis_reader::edge_iterator::advance(bool skip_initial_read)
+ {
+ do
+ {
+
+ if (!skip_initial_read)
+ {
+ // Try to read the next edge
+ if (self->line_in >> std::ws >> self->edge.second)
+ {
+ --self->edge.second;
+ if (self->has_edge_weights())
+ {
+ if (!(self->line_in >> self->edge_weight))
+ boost::throw_exception(metis_input_exception());
+ }
+ return;
+ }
+
+ // Check if we're done
+ ++self->edge.first;
+ if (self->edge.first == self->num_vertices())
+ return;
+ }
+
+ // Find the next line
+ std::string line;
+ while (getline(self->in, line) && !line.empty() && line[0] == '%')
+ {
+ /* Keep reading lines in the loop header... */
+ }
+ if (!self->in)
+ boost::throw_exception(metis_input_exception());
+ self->line_in.str(line);
+ self->line_in.clear();
+
+ // Read the next line
+ std::size_t weights_left = self->n_vertex_weights;
+ vertex_weight_type weight;
+ while (weights_left > 0)
+ {
+ if (self->line_in >> weight)
+ self->vertex_weights.push_back(weight);
+ else
+ boost::throw_exception(metis_input_exception());
+ --weights_left;
+ }
+
+ // Successive iterations will pick up edges for this vertex.
+ skip_initial_read = false;
+ } while (true);
+ }
+
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ metis_reader::edge_iterator::postincrement_proxy
+ metis_reader::edge_iterator::operator++(int)
+ {
+ postincrement_proxy result(**this);
+ ++(*this);
+ return result;
+ }
+
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ metis_reader::edge_iterator metis_reader::begin()
+ {
+ if (edge.first != 0)
+ start();
+ return edge_iterator(this);
+ }
+
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ metis_reader::edge_iterator metis_reader::end() { return edge_iterator(0); }
+
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ metis_reader::edge_weight_iterator metis_reader::weight_begin()
+ {
+ return edge_weight_iterator(this);
+ }
+
+ BOOST_GRAPH_METIS_INLINE_KEYWORD
+ void metis_reader::start()
+ {
+ in.seekg(0, std::ios::beg);
+ std::string line;
+ while (getline(in, line) && !line.empty() && line[0] == '%')
+ {
+ /* Keep getting lines in loop header. */
+ }
+
+ if (!in || line.empty())
+ boost::throw_exception(metis_input_exception());
+
+ // Determine number of vertices and edges in the graph
+ line_in.str(line);
+ if (!(line_in >> n_vertices >> n_edges))
+ boost::throw_exception(metis_input_exception());
+
+ // Determine whether vertex or edge weights are included in the graph
+ int fmt = 0;
+ line_in >> fmt;
+ n_vertex_weights = fmt / 10;
+ edge_weights = (fmt % 10 == 1);
+
+ // Determine how many (if any!) vertex weights are included
+ if (n_vertex_weights)
+ line_in >> n_vertex_weights;
+
+ // Setup the iteration data structures
+ edge_weight = 1.0;
+ edge.first = 0;
+ edge.second = 0;
+ vertex_weights.reserve(n_vertex_weights * num_vertices());
+ }
+
+ metis_distribution::metis_distribution(
+ std::istream& in, process_id_type my_id)
+ : my_id(my_id)
+ , vertices(std::istream_iterator< process_id_type >(in),
+ std::istream_iterator< process_id_type >())
+ {
+ }
+
+ metis_distribution::size_type metis_distribution::block_size(
+ process_id_type id, size_type) const
+ {
+ return std::count(vertices.begin(), vertices.end(), id);
+ }
+
+ metis_distribution::size_type metis_distribution::local(size_type n) const
+ {
+ return std::count(vertices.begin(), vertices.begin() + n, vertices[n]);
+ }
+
+ metis_distribution::size_type metis_distribution::global(
+ process_id_type id, size_type n) const
+ {
+ std::vector< process_id_type >::const_iterator i = vertices.begin();
+ while (*i != id)
+ ++i;
+
+ while (n > 0)
+ {
+ do
+ {
+ ++i;
+ } while (*i != id);
+ --n;
+ }
+
+ return i - vertices.begin();
+ }
+
+#endif
+
+}
+} // end namespace boost::graph
+
+#endif // BOOST_GRAPH_METIS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/metric_tsp_approx.hpp b/contrib/restricted/boost/graph/include/boost/graph/metric_tsp_approx.hpp
new file mode 100644
index 0000000000..38eaf6fa61
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/metric_tsp_approx.hpp
@@ -0,0 +1,316 @@
+
+//=======================================================================
+// Copyright 2008
+// Author: Matyas W Egyhazy
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_METRIC_TSP_APPROX_HPP
+#define BOOST_GRAPH_METRIC_TSP_APPROX_HPP
+
+// metric_tsp_approx
+// Generates an approximate tour solution for the traveling salesperson
+// problem in polynomial time. The current algorithm guarantees a tour with a
+// length at most as long as 2x optimal solution. The graph should have
+// 'natural' (metric) weights such that the triangle inequality is maintained.
+// Graphs must be fully interconnected.
+
+// TODO:
+// There are a couple of improvements that could be made.
+// 1) Change implementation to lower uppper bound Christofides heuristic
+// 2) Implement a less restrictive TSP heuristic (one that does not rely on
+// triangle inequality).
+// 3) Determine if the algorithm can be implemented without creating a new
+// graph.
+
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_as_tree.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/prim_minimum_spanning_tree.hpp>
+#include <boost/graph/lookup_edge.hpp>
+#include <boost/throw_exception.hpp>
+
+namespace boost
+{
+// Define a concept for the concept-checking library.
+template < typename Visitor, typename Graph > struct TSPVertexVisitorConcept
+{
+private:
+ Visitor vis_;
+
+public:
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+
+ BOOST_CONCEPT_USAGE(TSPVertexVisitorConcept)
+ {
+ Visitor vis(vis_); // require copy construction
+ Graph g(1);
+ Vertex v(*vertices(g).first);
+ vis.visit_vertex(v, g); // require visit_vertex
+ }
+};
+
+// Tree visitor that keeps track of a preorder traversal of a tree
+// TODO: Consider migrating this to the graph_as_tree header.
+// TODO: Parameterize the underlying stores so it doesn't have to be a vector.
+template < typename Node, typename Tree > class PreorderTraverser
+{
+private:
+ std::vector< Node >& path_;
+
+public:
+ typedef typename std::vector< Node >::const_iterator const_iterator;
+
+ PreorderTraverser(std::vector< Node >& p) : path_(p) {}
+
+ void preorder(Node n, const Tree&) { path_.push_back(n); }
+
+ void inorder(Node, const Tree&) const {}
+ void postorder(Node, const Tree&) const {}
+
+ const_iterator begin() const { return path_.begin(); }
+ const_iterator end() const { return path_.end(); }
+};
+
+// Forward declarations
+template < typename > class tsp_tour_visitor;
+template < typename, typename, typename, typename > class tsp_tour_len_visitor;
+
+template < typename VertexListGraph, typename OutputIterator >
+void metric_tsp_approx_tour(VertexListGraph& g, OutputIterator o)
+{
+ metric_tsp_approx_from_vertex(g, *vertices(g).first, get(edge_weight, g),
+ get(vertex_index, g), tsp_tour_visitor< OutputIterator >(o));
+}
+
+template < typename VertexListGraph, typename WeightMap,
+ typename OutputIterator >
+void metric_tsp_approx_tour(VertexListGraph& g, WeightMap w, OutputIterator o)
+{
+ metric_tsp_approx_from_vertex(
+ g, *vertices(g).first, w, tsp_tour_visitor< OutputIterator >(o));
+}
+
+template < typename VertexListGraph, typename OutputIterator >
+void metric_tsp_approx_tour_from_vertex(VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor start,
+ OutputIterator o)
+{
+ metric_tsp_approx_from_vertex(g, start, get(edge_weight, g),
+ get(vertex_index, g), tsp_tour_visitor< OutputIterator >(o));
+}
+
+template < typename VertexListGraph, typename WeightMap,
+ typename OutputIterator >
+void metric_tsp_approx_tour_from_vertex(VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor start,
+ WeightMap w, OutputIterator o)
+{
+ metric_tsp_approx_from_vertex(g, start, w, get(vertex_index, g),
+ tsp_tour_visitor< OutputIterator >(o));
+}
+
+template < typename VertexListGraph, typename TSPVertexVisitor >
+void metric_tsp_approx(VertexListGraph& g, TSPVertexVisitor vis)
+{
+ metric_tsp_approx_from_vertex(
+ g, *vertices(g).first, get(edge_weight, g), get(vertex_index, g), vis);
+}
+
+template < typename VertexListGraph, typename Weightmap,
+ typename VertexIndexMap, typename TSPVertexVisitor >
+void metric_tsp_approx(VertexListGraph& g, Weightmap w, TSPVertexVisitor vis)
+{
+ metric_tsp_approx_from_vertex(
+ g, *vertices(g).first, w, get(vertex_index, g), vis);
+}
+
+template < typename VertexListGraph, typename WeightMap,
+ typename VertexIndexMap, typename TSPVertexVisitor >
+void metric_tsp_approx(
+ VertexListGraph& g, WeightMap w, VertexIndexMap id, TSPVertexVisitor vis)
+{
+ metric_tsp_approx_from_vertex(g, *vertices(g).first, w, id, vis);
+}
+
+template < typename VertexListGraph, typename WeightMap,
+ typename TSPVertexVisitor >
+void metric_tsp_approx_from_vertex(VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor start,
+ WeightMap w, TSPVertexVisitor vis)
+{
+ metric_tsp_approx_from_vertex(g, start, w, get(vertex_index, g), vis);
+}
+
+template < typename VertexListGraph, typename WeightMap,
+ typename VertexIndexMap, typename TSPVertexVisitor >
+void metric_tsp_approx_from_vertex(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor start,
+ WeightMap weightmap, VertexIndexMap indexmap, TSPVertexVisitor vis)
+{
+ using namespace boost;
+ using namespace std;
+
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< VertexListGraph >));
+ BOOST_CONCEPT_ASSERT(
+ (TSPVertexVisitorConcept< TSPVertexVisitor, VertexListGraph >));
+
+ // Types related to the input graph (GVertex is a template parameter).
+ typedef typename graph_traits< VertexListGraph >::vertex_descriptor GVertex;
+ typedef typename graph_traits< VertexListGraph >::vertex_iterator GVItr;
+
+ // We build a custom graph in this algorithm.
+ typedef adjacency_list< vecS, vecS, directedS, no_property, no_property >
+ MSTImpl;
+ typedef graph_traits< MSTImpl >::vertex_descriptor Vertex;
+ typedef graph_traits< MSTImpl >::vertex_iterator VItr;
+
+ // And then re-cast it as a tree.
+ typedef iterator_property_map< vector< Vertex >::iterator,
+ property_map< MSTImpl, vertex_index_t >::type >
+ ParentMap;
+ typedef graph_as_tree< MSTImpl, ParentMap > Tree;
+ typedef tree_traits< Tree >::node_descriptor Node;
+
+ // A predecessor map.
+ typedef vector< GVertex > PredMap;
+ typedef iterator_property_map< typename PredMap::iterator, VertexIndexMap >
+ PredPMap;
+
+ PredMap preds(num_vertices(g));
+ PredPMap pred_pmap(preds.begin(), indexmap);
+
+ // Compute a spanning tree over the in put g.
+ prim_minimum_spanning_tree(g, pred_pmap,
+ root_vertex(start).vertex_index_map(indexmap).weight_map(weightmap));
+
+ // Build a MST using the predecessor map from prim mst
+ MSTImpl mst(num_vertices(g));
+ std::size_t cnt = 0;
+ pair< VItr, VItr > mst_verts(vertices(mst));
+ for (typename PredMap::iterator vi(preds.begin()); vi != preds.end();
+ ++vi, ++cnt)
+ {
+ if (indexmap[*vi] != cnt)
+ {
+ add_edge(*next(mst_verts.first, indexmap[*vi]),
+ *next(mst_verts.first, cnt), mst);
+ }
+ }
+
+ // Build a tree abstraction over the MST.
+ vector< Vertex > parent(num_vertices(mst));
+ Tree t(mst, *vertices(mst).first,
+ make_iterator_property_map(parent.begin(), get(vertex_index, mst)));
+
+ // Create tour using a preorder traversal of the mst
+ vector< Node > tour;
+ PreorderTraverser< Node, Tree > tvis(tour);
+ traverse_tree(indexmap[start], t, tvis);
+
+ pair< GVItr, GVItr > g_verts(vertices(g));
+ for (PreorderTraverser< Node, Tree >::const_iterator curr(tvis.begin());
+ curr != tvis.end(); ++curr)
+ {
+ // TODO: This is will be O(n^2) if vertex storage of g != vecS.
+ GVertex v = *next(g_verts.first, get(vertex_index, mst)[*curr]);
+ vis.visit_vertex(v, g);
+ }
+
+ // Connect back to the start of the tour
+ vis.visit_vertex(start, g);
+}
+
+// Default tsp tour visitor that puts the tour in an OutputIterator
+template < typename OutItr > class tsp_tour_visitor
+{
+ OutItr itr_;
+
+public:
+ tsp_tour_visitor(OutItr itr) : itr_(itr) {}
+
+ template < typename Vertex, typename Graph >
+ void visit_vertex(Vertex v, const Graph&)
+ {
+ BOOST_CONCEPT_ASSERT((OutputIterator< OutItr, Vertex >));
+ *itr_++ = v;
+ }
+};
+
+// Tsp tour visitor that adds the total tour length.
+template < typename Graph, typename WeightMap, typename OutIter,
+ typename Length >
+class tsp_tour_len_visitor
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT((OutputIterator< OutIter, Vertex >));
+
+ OutIter iter_;
+ Length& tourlen_;
+ WeightMap& wmap_;
+ Vertex previous_;
+
+ // Helper function for getting the null vertex.
+ Vertex null() { return graph_traits< Graph >::null_vertex(); }
+
+public:
+ tsp_tour_len_visitor(Graph const&, OutIter iter, Length& l, WeightMap& map)
+ : iter_(iter), tourlen_(l), wmap_(map), previous_(null())
+ {
+ }
+
+ void visit_vertex(Vertex v, const Graph& g)
+ {
+ typedef typename graph_traits< Graph >::edge_descriptor Edge;
+
+ // If it is not the start, then there is a
+ // previous vertex
+ if (previous_ != null())
+ {
+ // NOTE: For non-adjacency matrix graphs g, this bit of code
+ // will be linear in the degree of previous_ or v. A better
+ // solution would be to visit edges of the graph, but that
+ // would require revisiting the core algorithm.
+ Edge e;
+ bool found;
+ boost::tie(e, found) = lookup_edge(previous_, v, g);
+ if (!found)
+ {
+ BOOST_THROW_EXCEPTION(not_complete());
+ }
+
+ tourlen_ += wmap_[e];
+ }
+
+ previous_ = v;
+ *iter_++ = v;
+ }
+};
+
+// Object generator(s)
+template < typename OutIter >
+inline tsp_tour_visitor< OutIter > make_tsp_tour_visitor(OutIter iter)
+{
+ return tsp_tour_visitor< OutIter >(iter);
+}
+
+template < typename Graph, typename WeightMap, typename OutIter,
+ typename Length >
+inline tsp_tour_len_visitor< Graph, WeightMap, OutIter, Length >
+make_tsp_tour_len_visitor(
+ Graph const& g, OutIter iter, Length& l, WeightMap map)
+{
+ return tsp_tour_len_visitor< Graph, WeightMap, OutIter, Length >(
+ g, iter, l, map);
+}
+
+} // boost
+
+#endif // BOOST_GRAPH_METRIC_TSP_APPROX_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/minimum_degree_ordering.hpp b/contrib/restricted/boost/graph/include/boost/graph/minimum_degree_ordering.hpp
new file mode 100644
index 0000000000..2630831f5e
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/minimum_degree_ordering.hpp
@@ -0,0 +1,760 @@
+//-*-c++-*-
+//=======================================================================
+// Copyright 1997-2001 University of Notre Dame.
+// Authors: Lie-Quan Lee, Jeremy Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_MINIMUM_DEGREE_ORDERING_HPP
+#define BOOST_GRAPH_MINIMUM_DEGREE_ORDERING_HPP
+
+#include <vector>
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/pending/bucket_sorter.hpp>
+#include <boost/detail/numeric_traits.hpp> // for integer_traits
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ //
+ // Given a set of n integers (where the integer values range from
+ // zero to n-1), we want to keep track of a collection of stacks
+ // of integers. It so happens that an integer will appear in at
+ // most one stack at a time, so the stacks form disjoint sets.
+ // Because of these restrictions, we can use one big array to
+ // store all the stacks, intertwined with one another.
+ // No allocation/deallocation happens in the push()/pop() methods
+ // so this is faster than using std::stack's.
+ //
+ template < class SignedInteger > class Stacks
+ {
+ typedef SignedInteger value_type;
+ typedef typename std::vector< value_type >::size_type size_type;
+
+ public:
+ Stacks(size_type n) : data(n) {}
+
+ //: stack
+ class stack
+ {
+ typedef typename std::vector< value_type >::iterator Iterator;
+
+ public:
+ stack(Iterator _data, const value_type& head)
+ : data(_data), current(head)
+ {
+ }
+
+ // did not use default argument here to avoid internal compiler
+ // error in g++.
+ stack(Iterator _data)
+ : data(_data), current(-(std::numeric_limits< value_type >::max)())
+ {
+ }
+
+ void pop()
+ {
+ BOOST_ASSERT(!empty());
+ current = data[current];
+ }
+ void push(value_type v)
+ {
+ data[v] = current;
+ current = v;
+ }
+ bool empty()
+ {
+ return current == -(std::numeric_limits< value_type >::max)();
+ }
+ value_type& top() { return current; }
+
+ private:
+ Iterator data;
+ value_type current;
+ };
+
+ // To return a stack object
+ stack make_stack() { return stack(data.begin()); }
+
+ protected:
+ std::vector< value_type > data;
+ };
+
+ // marker class, a generalization of coloring.
+ //
+ // This class is to provide a generalization of coloring which has
+ // complexity of amortized constant time to set all vertices' color
+ // back to be untagged. It implemented by increasing a tag.
+ //
+ // The colors are:
+ // not tagged
+ // tagged
+ // multiple_tagged
+ // done
+ //
+ template < class SignedInteger, class Vertex, class VertexIndexMap >
+ class Marker
+ {
+ typedef SignedInteger value_type;
+ typedef typename std::vector< value_type >::size_type size_type;
+
+ static value_type done()
+ {
+ return (std::numeric_limits< value_type >::max)() / 2;
+ }
+
+ public:
+ Marker(size_type _num, VertexIndexMap index_map)
+ : tag(1 - (std::numeric_limits< value_type >::max)())
+ , data(_num, -(std::numeric_limits< value_type >::max)())
+ , id(index_map)
+ {
+ }
+
+ void mark_done(Vertex node) { data[get(id, node)] = done(); }
+
+ bool is_done(Vertex node) { return data[get(id, node)] == done(); }
+
+ void mark_tagged(Vertex node) { data[get(id, node)] = tag; }
+
+ void mark_multiple_tagged(Vertex node)
+ {
+ data[get(id, node)] = multiple_tag;
+ }
+
+ bool is_tagged(Vertex node) const { return data[get(id, node)] >= tag; }
+
+ bool is_not_tagged(Vertex node) const
+ {
+ return data[get(id, node)] < tag;
+ }
+
+ bool is_multiple_tagged(Vertex node) const
+ {
+ return data[get(id, node)] >= multiple_tag;
+ }
+
+ void increment_tag()
+ {
+ const size_type num = data.size();
+ ++tag;
+ if (tag >= done())
+ {
+ tag = 1 - (std::numeric_limits< value_type >::max)();
+ for (size_type i = 0; i < num; ++i)
+ if (data[i] < done())
+ data[i] = -(std::numeric_limits< value_type >::max)();
+ }
+ }
+
+ void set_multiple_tag(value_type mdeg0)
+ {
+ const size_type num = data.size();
+ multiple_tag = tag + mdeg0;
+
+ if (multiple_tag >= done())
+ {
+ tag = 1 - (std::numeric_limits< value_type >::max)();
+
+ for (size_type i = 0; i < num; i++)
+ if (data[i] < done())
+ data[i] = -(std::numeric_limits< value_type >::max)();
+
+ multiple_tag = tag + mdeg0;
+ }
+ }
+
+ void set_tag_as_multiple_tag() { tag = multiple_tag; }
+
+ protected:
+ value_type tag;
+ value_type multiple_tag;
+ std::vector< value_type > data;
+ VertexIndexMap id;
+ };
+
+ template < class Iterator, class SignedInteger, class Vertex,
+ class VertexIndexMap, int offset = 1 >
+ class Numbering
+ {
+ typedef SignedInteger number_type;
+ number_type num; // start from 1 instead of zero
+ Iterator data;
+ number_type max_num;
+ VertexIndexMap id;
+
+ public:
+ Numbering(Iterator _data, number_type _max_num, VertexIndexMap id)
+ : num(1), data(_data), max_num(_max_num), id(id)
+ {
+ }
+ void operator()(Vertex node) { data[get(id, node)] = -num; }
+ bool all_done(number_type i = 0) const { return num + i > max_num; }
+ void increment(number_type i = 1) { num += i; }
+ bool is_numbered(Vertex node) const { return data[get(id, node)] < 0; }
+ void indistinguishable(Vertex i, Vertex j)
+ {
+ data[get(id, i)] = -(get(id, j) + offset);
+ }
+ };
+
+ template < class SignedInteger, class Vertex, class VertexIndexMap >
+ class degreelists_marker
+ {
+ public:
+ typedef SignedInteger value_type;
+ typedef typename std::vector< value_type >::size_type size_type;
+ degreelists_marker(size_type n, VertexIndexMap id) : marks(n, 0), id(id)
+ {
+ }
+ void mark_need_update(Vertex i) { marks[get(id, i)] = 1; }
+ bool need_update(Vertex i) { return marks[get(id, i)] == 1; }
+ bool outmatched_or_done(Vertex i) { return marks[get(id, i)] == -1; }
+ void mark(Vertex i) { marks[get(id, i)] = -1; }
+ void unmark(Vertex i) { marks[get(id, i)] = 0; }
+
+ private:
+ std::vector< value_type > marks;
+ VertexIndexMap id;
+ };
+
+ // Helper function object for edge removal
+ template < class Graph, class MarkerP, class NumberD, class Stack,
+ class VertexIndexMap >
+ class predicateRemoveEdge1
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+
+ public:
+ predicateRemoveEdge1(Graph& _g, MarkerP& _marker, NumberD _numbering,
+ Stack& n_e, VertexIndexMap id)
+ : g(&_g)
+ , marker(&_marker)
+ , numbering(_numbering)
+ , neighbor_elements(&n_e)
+ , id(id)
+ {
+ }
+
+ bool operator()(edge_t e)
+ {
+ vertex_t dist = target(e, *g);
+ if (marker->is_tagged(dist))
+ return true;
+ marker->mark_tagged(dist);
+ if (numbering.is_numbered(dist))
+ {
+ neighbor_elements->push(get(id, dist));
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ Graph* g;
+ MarkerP* marker;
+ NumberD numbering;
+ Stack* neighbor_elements;
+ VertexIndexMap id;
+ };
+
+ // Helper function object for edge removal
+ template < class Graph, class MarkerP > class predicate_remove_tagged_edges
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+
+ public:
+ predicate_remove_tagged_edges(Graph& _g, MarkerP& _marker)
+ : g(&_g), marker(&_marker)
+ {
+ }
+
+ bool operator()(edge_t e)
+ {
+ vertex_t dist = target(e, *g);
+ if (marker->is_tagged(dist))
+ return true;
+ return false;
+ }
+
+ private:
+ Graph* g;
+ MarkerP* marker;
+ };
+
+ template < class Graph, class DegreeMap, class InversePermutationMap,
+ class PermutationMap, class SuperNodeMap, class VertexIndexMap >
+ class mmd_impl
+ {
+ // Typedefs
+ typedef graph_traits< Graph > Traits;
+ typedef typename Traits::vertices_size_type size_type;
+ typedef typename detail::integer_traits< size_type >::difference_type
+ diff_t;
+ typedef typename Traits::vertex_descriptor vertex_t;
+ typedef typename Traits::adjacency_iterator adj_iter;
+ typedef iterator_property_map< vertex_t*, identity_property_map,
+ vertex_t, vertex_t& >
+ IndexVertexMap;
+ typedef detail::Stacks< diff_t > Workspace;
+ typedef bucket_sorter< size_type, vertex_t, DegreeMap, VertexIndexMap >
+ DegreeLists;
+ typedef Numbering< InversePermutationMap, diff_t, vertex_t,
+ VertexIndexMap >
+ NumberingD;
+ typedef degreelists_marker< diff_t, vertex_t, VertexIndexMap >
+ DegreeListsMarker;
+ typedef Marker< diff_t, vertex_t, VertexIndexMap > MarkerP;
+
+ // Data Members
+ bool has_no_edges;
+
+ // input parameters
+ Graph& G;
+ int delta;
+ DegreeMap degree;
+ InversePermutationMap inverse_perm;
+ PermutationMap perm;
+ SuperNodeMap supernode_size;
+ VertexIndexMap vertex_index_map;
+
+ // internal data-structures
+ std::vector< vertex_t > index_vertex_vec;
+ size_type n;
+ IndexVertexMap index_vertex_map;
+ DegreeLists degreelists;
+ NumberingD numbering;
+ DegreeListsMarker degree_lists_marker;
+ MarkerP marker;
+ Workspace work_space;
+
+ public:
+ mmd_impl(Graph& g, size_type n_, int delta, DegreeMap degree,
+ InversePermutationMap inverse_perm, PermutationMap perm,
+ SuperNodeMap supernode_size, VertexIndexMap id)
+ : has_no_edges(true)
+ , G(g)
+ , delta(delta)
+ , degree(degree)
+ , inverse_perm(inverse_perm)
+ , perm(perm)
+ , supernode_size(supernode_size)
+ , vertex_index_map(id)
+ , index_vertex_vec(n_)
+ , n(n_)
+ , degreelists(n_ + 1, n_, degree, id)
+ , numbering(inverse_perm, n_, vertex_index_map)
+ , degree_lists_marker(n_, vertex_index_map)
+ , marker(n_, vertex_index_map)
+ , work_space(n_)
+ {
+ typename graph_traits< Graph >::vertex_iterator v, vend;
+ size_type vid = 0;
+ for (boost::tie(v, vend) = vertices(G); v != vend; ++v, ++vid)
+ index_vertex_vec[vid] = *v;
+ index_vertex_map = IndexVertexMap(&index_vertex_vec[0]);
+
+ // Initialize degreelists. Degreelists organizes the nodes
+ // according to their degree.
+ for (boost::tie(v, vend) = vertices(G); v != vend; ++v)
+ {
+ typename Traits::degree_size_type d = out_degree(*v, G);
+ put(degree, *v, d);
+ if (0 < d)
+ has_no_edges = false;
+ degreelists.push(*v);
+ }
+ }
+
+ void do_mmd()
+ {
+ // Eliminate the isolated nodes -- these are simply the nodes
+ // with no neighbors, which are accessible as a list (really, a
+ // stack) at location 0. Since these don't affect any other
+ // nodes, we can eliminate them without doing degree updates.
+ typename DegreeLists::stack list_isolated = degreelists[0];
+ while (!list_isolated.empty())
+ {
+ vertex_t node = list_isolated.top();
+ marker.mark_done(node);
+ numbering(node);
+ numbering.increment();
+ list_isolated.pop();
+ }
+
+ if (has_no_edges)
+ {
+ return;
+ }
+
+ size_type min_degree = 1;
+ typename DegreeLists::stack list_min_degree
+ = degreelists[min_degree];
+
+ while (list_min_degree.empty())
+ {
+ ++min_degree;
+ list_min_degree = degreelists[min_degree];
+ }
+
+ // check if the whole eliminating process is done
+ while (!numbering.all_done())
+ {
+
+ size_type min_degree_limit = min_degree + delta; // WARNING
+ typename Workspace::stack llist = work_space.make_stack();
+
+ // multiple elimination
+ while (delta >= 0)
+ {
+
+ // Find the next non-empty degree
+ for (list_min_degree = degreelists[min_degree];
+ list_min_degree.empty()
+ && min_degree <= min_degree_limit;
+ ++min_degree,
+ list_min_degree = degreelists[min_degree])
+ ;
+ if (min_degree > min_degree_limit)
+ break;
+
+ const vertex_t node = list_min_degree.top();
+ const size_type node_id = get(vertex_index_map, node);
+ list_min_degree.pop();
+ numbering(node);
+
+ // check if node is the last one
+ if (numbering.all_done(supernode_size[node]))
+ {
+ numbering.increment(supernode_size[node]);
+ break;
+ }
+ marker.increment_tag();
+ marker.mark_tagged(node);
+
+ this->eliminate(node);
+
+ numbering.increment(supernode_size[node]);
+ llist.push(node_id);
+ } // multiple elimination
+
+ if (numbering.all_done())
+ break;
+
+ this->update(llist, min_degree);
+ }
+
+ } // do_mmd()
+
+ void eliminate(vertex_t node)
+ {
+ typename Workspace::stack element_neighbor
+ = work_space.make_stack();
+
+ // Create two function objects for edge removal
+ typedef typename Workspace::stack WorkStack;
+ predicateRemoveEdge1< Graph, MarkerP, NumberingD, WorkStack,
+ VertexIndexMap >
+ p(G, marker, numbering, element_neighbor, vertex_index_map);
+
+ predicate_remove_tagged_edges< Graph, MarkerP > p2(G, marker);
+
+ // Reconstruct the adjacent node list, push element neighbor in a
+ // List.
+ remove_out_edge_if(node, p, G);
+ // during removal element neighbors are collected.
+
+ while (!element_neighbor.empty())
+ {
+ // element absorb
+ size_type e_id = element_neighbor.top();
+ vertex_t element = get(index_vertex_map, e_id);
+ adj_iter i, i_end;
+ for (boost::tie(i, i_end) = adjacent_vertices(element, G);
+ i != i_end; ++i)
+ {
+ vertex_t i_node = *i;
+ if (!marker.is_tagged(i_node)
+ && !numbering.is_numbered(i_node))
+ {
+ marker.mark_tagged(i_node);
+ add_edge(node, i_node, G);
+ }
+ }
+ element_neighbor.pop();
+ }
+ adj_iter v, ve;
+ for (boost::tie(v, ve) = adjacent_vertices(node, G); v != ve; ++v)
+ {
+ vertex_t v_node = *v;
+ if (!degree_lists_marker.need_update(v_node)
+ && !degree_lists_marker.outmatched_or_done(v_node))
+ {
+ degreelists.remove(v_node);
+ }
+ // update out edges of v_node
+ remove_out_edge_if(v_node, p2, G);
+
+ if (out_degree(v_node, G) == 0)
+ { // indistinguishable nodes
+ supernode_size[node] += supernode_size[v_node];
+ supernode_size[v_node] = 0;
+ numbering.indistinguishable(v_node, node);
+ marker.mark_done(v_node);
+ degree_lists_marker.mark(v_node);
+ }
+ else
+ { // not indistinguishable nodes
+ add_edge(v_node, node, G);
+ degree_lists_marker.mark_need_update(v_node);
+ }
+ }
+ } // eliminate()
+
+ template < class Stack > void update(Stack llist, size_type& min_degree)
+ {
+ size_type min_degree0 = min_degree + delta + 1;
+
+ while (!llist.empty())
+ {
+ size_type deg, deg0 = 0;
+
+ marker.set_multiple_tag(min_degree0);
+ typename Workspace::stack q2list = work_space.make_stack();
+ typename Workspace::stack qxlist = work_space.make_stack();
+
+ vertex_t current = get(index_vertex_map, llist.top());
+ adj_iter i, ie;
+ for (boost::tie(i, ie) = adjacent_vertices(current, G); i != ie;
+ ++i)
+ {
+ vertex_t i_node = *i;
+ const size_type i_id = get(vertex_index_map, i_node);
+ if (supernode_size[i_node] != 0)
+ {
+ deg0 += supernode_size[i_node];
+ marker.mark_multiple_tagged(i_node);
+ if (degree_lists_marker.need_update(i_node))
+ {
+ if (out_degree(i_node, G) == 2)
+ q2list.push(i_id);
+ else
+ qxlist.push(i_id);
+ }
+ }
+ }
+
+ while (!q2list.empty())
+ {
+ const size_type u_id = q2list.top();
+ vertex_t u_node = get(index_vertex_map, u_id);
+ // if u_id is outmatched by others, no need to update degree
+ if (degree_lists_marker.outmatched_or_done(u_node))
+ {
+ q2list.pop();
+ continue;
+ }
+ marker.increment_tag();
+ deg = deg0;
+
+ adj_iter nu = adjacent_vertices(u_node, G).first;
+ vertex_t neighbor = *nu;
+ if (neighbor == u_node)
+ {
+ ++nu;
+ neighbor = *nu;
+ }
+ if (numbering.is_numbered(neighbor))
+ {
+ adj_iter i, ie;
+ for (boost::tie(i, ie) = adjacent_vertices(neighbor, G);
+ i != ie; ++i)
+ {
+ const vertex_t i_node = *i;
+ if (i_node == u_node || supernode_size[i_node] == 0)
+ continue;
+ if (marker.is_tagged(i_node))
+ {
+ if (degree_lists_marker.need_update(i_node))
+ {
+ if (out_degree(i_node, G) == 2)
+ { // is indistinguishable
+ supernode_size[u_node]
+ += supernode_size[i_node];
+ supernode_size[i_node] = 0;
+ numbering.indistinguishable(
+ i_node, u_node);
+ marker.mark_done(i_node);
+ degree_lists_marker.mark(i_node);
+ }
+ else // is outmatched
+ degree_lists_marker.mark(i_node);
+ }
+ }
+ else
+ {
+ marker.mark_tagged(i_node);
+ deg += supernode_size[i_node];
+ }
+ }
+ }
+ else
+ deg += supernode_size[neighbor];
+
+ deg -= supernode_size[u_node];
+ degree[u_node] = deg; // update degree
+ degreelists[deg].push(u_node);
+ // u_id has been pushed back into degreelists
+ degree_lists_marker.unmark(u_node);
+ if (min_degree > deg)
+ min_degree = deg;
+ q2list.pop();
+ } // while (!q2list.empty())
+
+ while (!qxlist.empty())
+ {
+ const size_type u_id = qxlist.top();
+ const vertex_t u_node = get(index_vertex_map, u_id);
+
+ // if u_id is outmatched by others, no need to update degree
+ if (degree_lists_marker.outmatched_or_done(u_node))
+ {
+ qxlist.pop();
+ continue;
+ }
+ marker.increment_tag();
+ deg = deg0;
+ adj_iter i, ie;
+ for (boost::tie(i, ie) = adjacent_vertices(u_node, G);
+ i != ie; ++i)
+ {
+ vertex_t i_node = *i;
+ if (marker.is_tagged(i_node))
+ continue;
+ marker.mark_tagged(i_node);
+
+ if (numbering.is_numbered(i_node))
+ {
+ adj_iter j, je;
+ for (boost::tie(j, je)
+ = adjacent_vertices(i_node, G);
+ j != je; ++j)
+ {
+ const vertex_t j_node = *j;
+ if (marker.is_not_tagged(j_node))
+ {
+ marker.mark_tagged(j_node);
+ deg += supernode_size[j_node];
+ }
+ }
+ }
+ else
+ deg += supernode_size[i_node];
+ } // for adjacent vertices of u_node
+ deg -= supernode_size[u_node];
+ degree[u_node] = deg;
+ degreelists[deg].push(u_node);
+ // u_id has been pushed back into degreelists
+ degree_lists_marker.unmark(u_node);
+ if (min_degree > deg)
+ min_degree = deg;
+ qxlist.pop();
+ } // while (!qxlist.empty()) {
+
+ marker.set_tag_as_multiple_tag();
+ llist.pop();
+ } // while (! llist.empty())
+
+ } // update()
+
+ void build_permutation(InversePermutationMap next, PermutationMap prev)
+ {
+ // collect the permutation info
+ size_type i;
+ for (i = 0; i < n; ++i)
+ {
+ diff_t size = supernode_size[get(index_vertex_map, i)];
+ if (size <= 0)
+ {
+ prev[i] = next[i];
+ supernode_size[get(index_vertex_map, i)]
+ = next[i] + 1; // record the supernode info
+ }
+ else
+ prev[i] = -next[i];
+ }
+ for (i = 1; i < n + 1; ++i)
+ {
+ if (prev[i - 1] > 0)
+ continue;
+ diff_t parent = i;
+ while (prev[parent - 1] < 0)
+ {
+ parent = -prev[parent - 1];
+ }
+
+ diff_t root = parent;
+ diff_t num = prev[root - 1] + 1;
+ next[i - 1] = -num;
+ prev[root - 1] = num;
+
+ parent = i;
+ diff_t next_node = -prev[parent - 1];
+ while (next_node > 0)
+ {
+ prev[parent - 1] = -root;
+ parent = next_node;
+ next_node = -prev[parent - 1];
+ }
+ }
+ for (i = 0; i < n; i++)
+ {
+ diff_t num = -next[i] - 1;
+ next[i] = num;
+ prev[num] = i;
+ }
+ } // build_permutation()
+ };
+
+} // namespace detail
+
+// MMD algorithm
+//
+// The implementation presently includes the enhancements for mass
+// elimination, incomplete degree update, multiple elimination, and
+// external degree.
+//
+// Important Note: This implementation requires the BGL graph to be
+// directed. Therefore, nonzero entry (i, j) in a symmetrical matrix
+// A coresponds to two directed edges (i->j and j->i).
+//
+// see Alan George and Joseph W. H. Liu, The Evolution of the Minimum
+// Degree Ordering Algorithm, SIAM Review, 31, 1989, Page 1-19
+template < class Graph, class DegreeMap, class InversePermutationMap,
+ class PermutationMap, class SuperNodeMap, class VertexIndexMap >
+void minimum_degree_ordering(Graph& G, DegreeMap degree,
+ InversePermutationMap inverse_perm, PermutationMap perm,
+ SuperNodeMap supernode_size, int delta, VertexIndexMap vertex_index_map)
+{
+ detail::mmd_impl< Graph, DegreeMap, InversePermutationMap, PermutationMap,
+ SuperNodeMap, VertexIndexMap >
+ impl(G, num_vertices(G), delta, degree, inverse_perm, perm,
+ supernode_size, vertex_index_map);
+ impl.do_mmd();
+ impl.build_permutation(inverse_perm, perm);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_MINIMUM_DEGREE_ORDERING_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/neighbor_bfs.hpp b/contrib/restricted/boost/graph/include/boost/graph/neighbor_bfs.hpp
new file mode 100644
index 0000000000..bfe87a998b
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/neighbor_bfs.hpp
@@ -0,0 +1,326 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
+#define BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
+
+/*
+ Neighbor Breadth First Search
+ Like BFS, but traverses in-edges as well as out-edges.
+ (for directed graphs only. use normal BFS for undirected graphs)
+*/
+#include <boost/config.hpp>
+#include <boost/ref.hpp>
+#include <vector>
+#include <boost/pending/queue.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+
+template < class Visitor, class Graph > struct NeighborBFSVisitorConcept
+{
+ void constraints()
+ {
+ BOOST_CONCEPT_ASSERT((CopyConstructibleConcept< Visitor >));
+ vis.initialize_vertex(u, g);
+ vis.discover_vertex(u, g);
+ vis.examine_vertex(u, g);
+ vis.examine_out_edge(e, g);
+ vis.examine_in_edge(e, g);
+ vis.tree_out_edge(e, g);
+ vis.tree_in_edge(e, g);
+ vis.non_tree_out_edge(e, g);
+ vis.non_tree_in_edge(e, g);
+ vis.gray_target(e, g);
+ vis.black_target(e, g);
+ vis.gray_source(e, g);
+ vis.black_source(e, g);
+ vis.finish_vertex(u, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename graph_traits< Graph >::vertex_descriptor u;
+ typename graph_traits< Graph >::edge_descriptor e;
+};
+
+template < class Visitors = null_visitor > class neighbor_bfs_visitor
+{
+public:
+ neighbor_bfs_visitor(Visitors vis = Visitors()) : m_vis(vis) {}
+
+ template < class Vertex, class Graph >
+ void initialize_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, on_initialize_vertex());
+ }
+ template < class Vertex, class Graph >
+ void discover_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, on_discover_vertex());
+ }
+ template < class Vertex, class Graph >
+ void examine_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, on_examine_vertex());
+ }
+ template < class Edge, class Graph > void examine_out_edge(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_examine_edge());
+ }
+ template < class Edge, class Graph > void tree_out_edge(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_tree_edge());
+ }
+ template < class Edge, class Graph >
+ void non_tree_out_edge(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_non_tree_edge());
+ }
+ template < class Edge, class Graph > void gray_target(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_gray_target());
+ }
+ template < class Edge, class Graph > void black_target(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_black_target());
+ }
+ template < class Edge, class Graph > void examine_in_edge(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_examine_edge());
+ }
+ template < class Edge, class Graph > void tree_in_edge(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_tree_edge());
+ }
+ template < class Edge, class Graph > void non_tree_in_edge(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_non_tree_edge());
+ }
+ template < class Edge, class Graph > void gray_source(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_gray_target());
+ }
+ template < class Edge, class Graph > void black_source(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, on_black_target());
+ }
+ template < class Vertex, class Graph >
+ void finish_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, on_finish_vertex());
+ }
+
+protected:
+ Visitors m_vis;
+};
+
+template < class Visitors >
+neighbor_bfs_visitor< Visitors > make_neighbor_bfs_visitor(Visitors vis)
+{
+ return neighbor_bfs_visitor< Visitors >(vis);
+}
+
+namespace detail
+{
+
+ template < class BidirectionalGraph, class Buffer, class BFSVisitor,
+ class ColorMap >
+ void neighbor_bfs_impl(const BidirectionalGraph& g,
+ typename graph_traits< BidirectionalGraph >::vertex_descriptor s,
+ Buffer& Q, BFSVisitor vis, ColorMap color)
+
+ {
+ BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< BidirectionalGraph >));
+ typedef graph_traits< BidirectionalGraph > GTraits;
+ typedef typename GTraits::vertex_descriptor Vertex;
+ typedef typename GTraits::edge_descriptor Edge;
+ BOOST_CONCEPT_ASSERT(
+ (NeighborBFSVisitorConcept< BFSVisitor, BidirectionalGraph >));
+ BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< ColorMap, Vertex >));
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+
+ put(color, s, Color::gray());
+ vis.discover_vertex(s, g);
+ Q.push(s);
+ while (!Q.empty())
+ {
+ Vertex u = Q.top();
+ Q.pop(); // pop before push to avoid problem if Q is priority_queue.
+ vis.examine_vertex(u, g);
+
+ typename GTraits::out_edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
+ {
+ Edge e = *ei;
+ vis.examine_out_edge(e, g);
+ Vertex v = target(e, g);
+ ColorValue v_color = get(color, v);
+ if (v_color == Color::white())
+ {
+ vis.tree_out_edge(e, g);
+ put(color, v, Color::gray());
+ vis.discover_vertex(v, g);
+ Q.push(v);
+ }
+ else
+ {
+ vis.non_tree_out_edge(e, g);
+ if (v_color == Color::gray())
+ vis.gray_target(e, g);
+ else
+ vis.black_target(e, g);
+ }
+ } // for out-edges
+
+ typename GTraits::in_edge_iterator in_ei, in_ei_end;
+ for (boost::tie(in_ei, in_ei_end) = in_edges(u, g);
+ in_ei != in_ei_end; ++in_ei)
+ {
+ Edge e = *in_ei;
+ vis.examine_in_edge(e, g);
+ Vertex v = source(e, g);
+ ColorValue v_color = get(color, v);
+ if (v_color == Color::white())
+ {
+ vis.tree_in_edge(e, g);
+ put(color, v, Color::gray());
+ vis.discover_vertex(v, g);
+ Q.push(v);
+ }
+ else
+ {
+ vis.non_tree_in_edge(e, g);
+ if (v_color == Color::gray())
+ vis.gray_source(e, g);
+ else
+ vis.black_source(e, g);
+ }
+ } // for in-edges
+
+ put(color, u, Color::black());
+ vis.finish_vertex(u, g);
+ } // while
+ }
+
+ template < class VertexListGraph, class ColorMap, class BFSVisitor, class P,
+ class T, class R >
+ void neighbor_bfs_helper(VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ ColorMap color, BFSVisitor vis,
+ const bgl_named_params< P, T, R >& params)
+ {
+ typedef graph_traits< VertexListGraph > Traits;
+ // Buffer default
+ typedef typename Traits::vertex_descriptor Vertex;
+ typedef boost::queue< Vertex > queue_t;
+ queue_t Q;
+ // Initialization
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+ typename boost::graph_traits< VertexListGraph >::vertex_iterator i,
+ i_end;
+ for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i)
+ {
+ put(color, *i, Color::white());
+ vis.initialize_vertex(*i, g);
+ }
+ neighbor_bfs_impl(g, s,
+ choose_param(get_param(params, buffer_param_t()), boost::ref(Q))
+ .get(),
+ vis, color);
+ }
+
+ //-------------------------------------------------------------------------
+ // Choose between default color and color parameters. Using
+ // function dispatching so that we don't require vertex index if
+ // the color default is not being used.
+
+ template < class ColorMap > struct neighbor_bfs_dispatch
+ {
+ template < class VertexListGraph, class P, class T, class R >
+ static void apply(VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ const bgl_named_params< P, T, R >& params, ColorMap color)
+ {
+ neighbor_bfs_helper(g, s, color,
+ choose_param(get_param(params, graph_visitor),
+ make_neighbor_bfs_visitor(null_visitor())),
+ params);
+ }
+ };
+
+ template <> struct neighbor_bfs_dispatch< param_not_found >
+ {
+ template < class VertexListGraph, class P, class T, class R >
+ static void apply(VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ const bgl_named_params< P, T, R >& params, param_not_found)
+ {
+ std::vector< default_color_type > color_vec(num_vertices(g));
+ null_visitor null_vis;
+
+ neighbor_bfs_helper(g, s,
+ make_iterator_property_map(color_vec.begin(),
+ choose_const_pmap(
+ get_param(params, vertex_index), g, vertex_index),
+ color_vec[0]),
+ choose_param(get_param(params, graph_visitor),
+ make_neighbor_bfs_visitor(null_vis)),
+ params);
+ }
+ };
+
+} // namespace detail
+
+// Named Parameter Variant
+template < class VertexListGraph, class P, class T, class R >
+void neighbor_breadth_first_search(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ const bgl_named_params< P, T, R >& params)
+{
+ // The graph is passed by *const* reference so that graph adaptors
+ // (temporaries) can be passed into this function. However, the
+ // graph is not really const since we may write to property maps
+ // of the graph.
+ VertexListGraph& ng = const_cast< VertexListGraph& >(g);
+ typedef typename get_param_type< vertex_color_t,
+ bgl_named_params< P, T, R > >::type C;
+ detail::neighbor_bfs_dispatch< C >::apply(
+ ng, s, params, get_param(params, vertex_color));
+}
+
+// This version does not initialize colors, user has to.
+
+template < class IncidenceGraph, class P, class T, class R >
+void neighbor_breadth_first_visit(IncidenceGraph& g,
+ typename graph_traits< IncidenceGraph >::vertex_descriptor s,
+ const bgl_named_params< P, T, R >& params)
+{
+ typedef graph_traits< IncidenceGraph > Traits;
+ // Buffer default
+ typedef boost::queue< typename Traits::vertex_descriptor > queue_t;
+ queue_t Q;
+
+ detail::neighbor_bfs_impl(g, s,
+ choose_param(get_param(params, buffer_param_t()), boost::ref(Q)).get(),
+ choose_param(get_param(params, graph_visitor),
+ make_neighbor_bfs_visitor(null_visitor())),
+ choose_pmap(get_param(params, vertex_color), g, vertex_color));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/one_bit_color_map.hpp b/contrib/restricted/boost/graph/include/boost/graph/one_bit_color_map.hpp
new file mode 100644
index 0000000000..b11f16f684
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/one_bit_color_map.hpp
@@ -0,0 +1,104 @@
+// Copyright (C) 2005-2010 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jeremiah Willcock
+// Douglas Gregor
+// Andrew Lumsdaine
+
+// One bit per color property map (gray and black are the same, green is not
+// supported)
+
+#ifndef BOOST_ONE_BIT_COLOR_MAP_HPP
+#define BOOST_ONE_BIT_COLOR_MAP_HPP
+
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/detail/mpi_include.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <algorithm>
+#include <limits>
+
+namespace boost
+{
+
+enum one_bit_color_type
+{
+ one_bit_white = 0,
+ one_bit_not_white = 1
+};
+
+template <> struct color_traits< one_bit_color_type >
+{
+ static one_bit_color_type white() { return one_bit_white; }
+ static one_bit_color_type gray() { return one_bit_not_white; }
+ static one_bit_color_type black() { return one_bit_not_white; }
+};
+
+template < typename IndexMap = identity_property_map > struct one_bit_color_map
+{
+ BOOST_STATIC_CONSTANT(
+ int, bits_per_char = std::numeric_limits< unsigned char >::digits);
+ std::size_t n;
+ IndexMap index;
+ shared_array< unsigned char > data;
+
+ typedef typename property_traits< IndexMap >::key_type key_type;
+ typedef one_bit_color_type value_type;
+ typedef void reference;
+ typedef read_write_property_map_tag category;
+
+ explicit one_bit_color_map(
+ std::size_t n, const IndexMap& index = IndexMap())
+ : n(n)
+ , index(index)
+ , data(new unsigned char[(n + bits_per_char - 1) / bits_per_char]())
+ {
+ }
+};
+
+template < typename IndexMap >
+inline one_bit_color_type get(const one_bit_color_map< IndexMap >& pm,
+ typename property_traits< IndexMap >::key_type key)
+{
+ BOOST_STATIC_CONSTANT(
+ int, bits_per_char = one_bit_color_map< IndexMap >::bits_per_char);
+ typename property_traits< IndexMap >::value_type i = get(pm.index, key);
+ BOOST_ASSERT((std::size_t)i < pm.n);
+ return one_bit_color_type(
+ (pm.data.get()[i / bits_per_char] >> (i % bits_per_char)) & 1);
+}
+
+template < typename IndexMap >
+inline void put(const one_bit_color_map< IndexMap >& pm,
+ typename property_traits< IndexMap >::key_type key,
+ one_bit_color_type value)
+{
+ BOOST_STATIC_CONSTANT(
+ int, bits_per_char = one_bit_color_map< IndexMap >::bits_per_char);
+ typename property_traits< IndexMap >::value_type i = get(pm.index, key);
+ BOOST_ASSERT((std::size_t)i < pm.n);
+ BOOST_ASSERT(value >= 0 && value < 2);
+ std::size_t byte_num = i / bits_per_char;
+ std::size_t bit_position = (i % bits_per_char);
+ pm.data.get()[byte_num]
+ = (unsigned char)((pm.data.get()[byte_num] & ~(1 << bit_position))
+ | (value << bit_position));
+}
+
+template < typename IndexMap >
+inline one_bit_color_map< IndexMap > make_one_bit_color_map(
+ std::size_t n, const IndexMap& index_map)
+{
+ return one_bit_color_map< IndexMap >(n, index_map);
+}
+
+} // end namespace boost
+
+
+
+#endif // BOOST_ONE_BIT_COLOR_MAP_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/page_rank.hpp b/contrib/restricted/boost/graph/include/boost/graph/page_rank.hpp
new file mode 100644
index 0000000000..94ae0f3409
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/page_rank.hpp
@@ -0,0 +1,179 @@
+// Copyright 2004-5 The Trustees of Indiana University.
+// Copyright 2002 Brad King and Douglas Gregor
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+
+#ifndef BOOST_GRAPH_PAGE_RANK_HPP
+#define BOOST_GRAPH_PAGE_RANK_HPP
+
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/overloading.hpp>
+#include <boost/graph/detail/mpi_include.hpp>
+#include <vector>
+
+namespace boost
+{
+namespace graph
+{
+
+ struct n_iterations
+ {
+ explicit n_iterations(std::size_t n) : n(n) {}
+
+ template < typename RankMap, typename Graph >
+ bool operator()(const RankMap&, const Graph&)
+ {
+ return n-- == 0;
+ }
+
+ private:
+ std::size_t n;
+ };
+
+ namespace detail
+ {
+ template < typename Graph, typename RankMap, typename RankMap2 >
+ void page_rank_step(const Graph& g, RankMap from_rank, RankMap2 to_rank,
+ typename property_traits< RankMap >::value_type damping,
+ incidence_graph_tag)
+ {
+ typedef typename property_traits< RankMap >::value_type rank_type;
+
+ // Set new rank maps
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ put(to_rank, v, rank_type(1 - damping));
+
+ BGL_FORALL_VERTICES_T(u, g, Graph)
+ {
+ rank_type u_rank_out
+ = damping * get(from_rank, u) / out_degree(u, g);
+ BGL_FORALL_ADJ_T(u, v, g, Graph)
+ put(to_rank, v, get(to_rank, v) + u_rank_out);
+ }
+ }
+
+ template < typename Graph, typename RankMap, typename RankMap2 >
+ void page_rank_step(const Graph& g, RankMap from_rank, RankMap2 to_rank,
+ typename property_traits< RankMap >::value_type damping,
+ bidirectional_graph_tag)
+ {
+ typedef
+ typename property_traits< RankMap >::value_type damping_type;
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ typename property_traits< RankMap >::value_type rank(0);
+ BGL_FORALL_INEDGES_T(v, e, g, Graph)
+ rank += get(from_rank, source(e, g))
+ / out_degree(source(e, g), g);
+ put(to_rank, v, (damping_type(1) - damping) + damping * rank);
+ }
+ }
+ } // end namespace detail
+
+ template < typename Graph, typename RankMap, typename Done,
+ typename RankMap2 >
+ void page_rank(const Graph& g, RankMap rank_map, Done done,
+ typename property_traits< RankMap >::value_type damping,
+ typename graph_traits< Graph >::vertices_size_type n,
+ RankMap2 rank_map2 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(
+ Graph, vertex_list_graph_tag))
+ {
+ typedef typename property_traits< RankMap >::value_type rank_type;
+
+ rank_type initial_rank = rank_type(rank_type(1) / n);
+ BGL_FORALL_VERTICES_T(v, g, Graph) put(rank_map, v, initial_rank);
+
+ bool to_map_2 = true;
+ while ((to_map_2 && !done(rank_map, g))
+ || (!to_map_2 && !done(rank_map2, g)))
+ {
+ typedef typename graph_traits< Graph >::traversal_category category;
+
+ if (to_map_2)
+ {
+ detail::page_rank_step(
+ g, rank_map, rank_map2, damping, category());
+ }
+ else
+ {
+ detail::page_rank_step(
+ g, rank_map2, rank_map, damping, category());
+ }
+ to_map_2 = !to_map_2;
+ }
+
+ if (!to_map_2)
+ {
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ put(rank_map, v, get(rank_map2, v));
+ }
+ }
+
+ template < typename Graph, typename RankMap, typename Done >
+ void page_rank(const Graph& g, RankMap rank_map, Done done,
+ typename property_traits< RankMap >::value_type damping,
+ typename graph_traits< Graph >::vertices_size_type n)
+ {
+ typedef typename property_traits< RankMap >::value_type rank_type;
+
+ std::vector< rank_type > ranks2(num_vertices(g));
+ page_rank(g, rank_map, done, damping, n,
+ make_iterator_property_map(ranks2.begin(), get(vertex_index, g)));
+ }
+
+ template < typename Graph, typename RankMap, typename Done >
+ inline void page_rank(const Graph& g, RankMap rank_map, Done done,
+ typename property_traits< RankMap >::value_type damping = 0.85)
+ {
+ page_rank(g, rank_map, done, damping, num_vertices(g));
+ }
+
+ template < typename Graph, typename RankMap >
+ inline void page_rank(const Graph& g, RankMap rank_map)
+ {
+ page_rank(g, rank_map, n_iterations(20));
+ }
+
+ // TBD: this could be _much_ more efficient, using a queue to store
+ // the vertices that should be reprocessed and keeping track of which
+ // vertices are in the queue with a property map. Baah, this only
+ // applies when we have a bidirectional graph.
+ template < typename MutableGraph >
+ void remove_dangling_links(
+ MutableGraph& g BOOST_GRAPH_ENABLE_IF_MODELS_PARM(
+ MutableGraph, vertex_list_graph_tag))
+ {
+ typename graph_traits< MutableGraph >::vertices_size_type old_n;
+ do
+ {
+ old_n = num_vertices(g);
+
+ typename graph_traits< MutableGraph >::vertex_iterator vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end;
+ /* in loop */)
+ {
+ typename graph_traits< MutableGraph >::vertex_descriptor v
+ = *vi++;
+ if (out_degree(v, g) == 0)
+ {
+ clear_vertex(v, g);
+ remove_vertex(v, g);
+ }
+ }
+ } while (num_vertices(g) < old_n);
+ }
+
+}
+} // end namespace boost::graph
+
+
+
+#endif // BOOST_GRAPH_PAGE_RANK_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/planar_canonical_ordering.hpp b/contrib/restricted/boost/graph/include/boost/graph/planar_canonical_ordering.hpp
new file mode 100644
index 0000000000..61f2797a14
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/planar_canonical_ordering.hpp
@@ -0,0 +1,205 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef __PLANAR_CANONICAL_ORDERING_HPP__
+#define __PLANAR_CANONICAL_ORDERING_HPP__
+
+#include <vector>
+#include <list>
+#include <boost/config.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+ enum planar_canonical_ordering_state
+ {
+ PCO_PROCESSED,
+ PCO_UNPROCESSED,
+ PCO_ONE_NEIGHBOR_PROCESSED,
+ PCO_READY_TO_BE_PROCESSED
+ };
+}
+
+template < typename Graph, typename PlanarEmbedding, typename OutputIterator,
+ typename VertexIndexMap >
+void planar_canonical_ordering(const Graph& g, PlanarEmbedding embedding,
+ OutputIterator ordering, VertexIndexMap vm)
+{
+
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef
+ typename graph_traits< Graph >::adjacency_iterator adjacency_iterator_t;
+ typedef typename property_traits< PlanarEmbedding >::value_type
+ embedding_value_t;
+ typedef typename embedding_value_t::const_iterator embedding_iterator_t;
+ typedef iterator_property_map< typename std::vector< vertex_t >::iterator,
+ VertexIndexMap >
+ vertex_to_vertex_map_t;
+ typedef iterator_property_map<
+ typename std::vector< std::size_t >::iterator, VertexIndexMap >
+ vertex_to_size_t_map_t;
+
+ std::vector< vertex_t > processed_neighbor_vector(num_vertices(g));
+ vertex_to_vertex_map_t processed_neighbor(
+ processed_neighbor_vector.begin(), vm);
+
+ std::vector< std::size_t > status_vector(
+ num_vertices(g), detail::PCO_UNPROCESSED);
+ vertex_to_size_t_map_t status(status_vector.begin(), vm);
+
+ std::list< vertex_t > ready_to_be_processed;
+
+ vertex_t first_vertex = *vertices(g).first;
+ vertex_t second_vertex = first_vertex;
+ adjacency_iterator_t ai, ai_end;
+ for (boost::tie(ai, ai_end) = adjacent_vertices(first_vertex, g);
+ ai != ai_end; ++ai)
+ {
+ if (*ai == first_vertex)
+ continue;
+ second_vertex = *ai;
+ break;
+ }
+
+ ready_to_be_processed.push_back(first_vertex);
+ status[first_vertex] = detail::PCO_READY_TO_BE_PROCESSED;
+ ready_to_be_processed.push_back(second_vertex);
+ status[second_vertex] = detail::PCO_READY_TO_BE_PROCESSED;
+
+ while (!ready_to_be_processed.empty())
+ {
+ vertex_t u = ready_to_be_processed.front();
+ ready_to_be_processed.pop_front();
+
+ if (status[u] != detail::PCO_READY_TO_BE_PROCESSED
+ && u != second_vertex)
+ continue;
+
+ embedding_iterator_t ei, ei_start, ei_end;
+ embedding_iterator_t next_edge_itr, prior_edge_itr;
+
+ ei_start = embedding[u].begin();
+ ei_end = embedding[u].end();
+ prior_edge_itr = prior(ei_end);
+ while (source(*prior_edge_itr, g) == target(*prior_edge_itr, g))
+ prior_edge_itr = prior(prior_edge_itr);
+
+ for (ei = ei_start; ei != ei_end; ++ei)
+ {
+
+ edge_t e(*ei); // e = (u,v)
+ next_edge_itr
+ = boost::next(ei) == ei_end ? ei_start : boost::next(ei);
+ vertex_t v = source(e, g) == u ? target(e, g) : source(e, g);
+
+ vertex_t prior_vertex = source(*prior_edge_itr, g) == u
+ ? target(*prior_edge_itr, g)
+ : source(*prior_edge_itr, g);
+ vertex_t next_vertex = source(*next_edge_itr, g) == u
+ ? target(*next_edge_itr, g)
+ : source(*next_edge_itr, g);
+
+ // Need prior_vertex, u, v, and next_vertex to all be
+ // distinct. This is possible, since the input graph is
+ // triangulated. It'll be true all the time in a simple
+ // graph, but loops and parallel edges cause some complications.
+ if (prior_vertex == v || prior_vertex == u)
+ {
+ prior_edge_itr = ei;
+ continue;
+ }
+
+ // Skip any self-loops
+ if (u == v)
+ continue;
+
+ // Move next_edge_itr (and next_vertex) forwards
+ // past any loops or parallel edges
+ while (next_vertex == v || next_vertex == u)
+ {
+ next_edge_itr = boost::next(next_edge_itr) == ei_end
+ ? ei_start
+ : boost::next(next_edge_itr);
+ next_vertex = source(*next_edge_itr, g) == u
+ ? target(*next_edge_itr, g)
+ : source(*next_edge_itr, g);
+ }
+
+ if (status[v] == detail::PCO_UNPROCESSED)
+ {
+ status[v] = detail::PCO_ONE_NEIGHBOR_PROCESSED;
+ processed_neighbor[v] = u;
+ }
+ else if (status[v] == detail::PCO_ONE_NEIGHBOR_PROCESSED)
+ {
+ vertex_t x = processed_neighbor[v];
+ // are edges (v,u) and (v,x) adjacent in the planar
+ // embedding? if so, set status[v] = 1. otherwise, set
+ // status[v] = 2.
+
+ if ((next_vertex == x
+ && !(first_vertex == u && second_vertex == x))
+ || (prior_vertex == x
+ && !(first_vertex == x && second_vertex == u)))
+ {
+ status[v] = detail::PCO_READY_TO_BE_PROCESSED;
+ }
+ else
+ {
+ status[v] = detail::PCO_READY_TO_BE_PROCESSED + 1;
+ }
+ }
+ else if (status[v] > detail::PCO_ONE_NEIGHBOR_PROCESSED)
+ {
+ // check the two edges before and after (v,u) in the planar
+ // embedding, and update status[v] accordingly
+
+ bool processed_before = false;
+ if (status[prior_vertex] == detail::PCO_PROCESSED)
+ processed_before = true;
+
+ bool processed_after = false;
+ if (status[next_vertex] == detail::PCO_PROCESSED)
+ processed_after = true;
+
+ if (!processed_before && !processed_after)
+ ++status[v];
+
+ else if (processed_before && processed_after)
+ --status[v];
+ }
+
+ if (status[v] == detail::PCO_READY_TO_BE_PROCESSED)
+ ready_to_be_processed.push_back(v);
+
+ prior_edge_itr = ei;
+ }
+
+ status[u] = detail::PCO_PROCESSED;
+ *ordering = u;
+ ++ordering;
+ }
+}
+
+template < typename Graph, typename PlanarEmbedding, typename OutputIterator >
+void planar_canonical_ordering(
+ const Graph& g, PlanarEmbedding embedding, OutputIterator ordering)
+{
+ planar_canonical_ordering(g, embedding, ordering, get(vertex_index, g));
+}
+
+} // namespace boost
+
+#endif //__PLANAR_CANONICAL_ORDERING_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/planar_detail/add_edge_visitors.hpp b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/add_edge_visitors.hpp
new file mode 100644
index 0000000000..7ea34f479d
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/add_edge_visitors.hpp
@@ -0,0 +1,54 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef __ADD_EDGE_VISITORS_HPP__
+#define __ADD_EDGE_VISITORS_HPP__
+
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+
+struct default_add_edge_visitor
+{
+
+ template < typename Graph, typename Vertex >
+ void visit_vertex_pair(Vertex u, Vertex v, Graph& g)
+ {
+ add_edge(u, v, g);
+ }
+};
+
+template < typename EdgeIndexMap > struct edge_index_update_visitor
+{
+
+ typedef
+ typename property_traits< EdgeIndexMap >::value_type edge_index_value_t;
+
+ edge_index_update_visitor(
+ EdgeIndexMap em, edge_index_value_t next_index_available)
+ : m_em(em), m_next_index(next_index_available)
+ {
+ }
+
+ template < typename Graph, typename Vertex >
+ void visit_vertex_pair(Vertex u, Vertex v, Graph& g)
+ {
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ std::pair< edge_t, bool > return_value = add_edge(u, v, g);
+ if (return_value.second)
+ put(m_em, return_value.first, m_next_index++);
+ }
+
+private:
+ EdgeIndexMap m_em;
+ edge_index_value_t m_next_index;
+};
+
+} // namespace boost
+
+#endif //__ADD_EDGE_VISITORS_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp
new file mode 100644
index 0000000000..c2797c1d81
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp
@@ -0,0 +1,1813 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef __BOYER_MYRVOLD_IMPL_HPP__
+#define __BOYER_MYRVOLD_IMPL_HPP__
+
+#include <vector>
+#include <list>
+#include <boost/next_prior.hpp>
+#include <boost/config.hpp> //for std::min macros
+#include <boost/shared_ptr.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/planar_detail/face_handles.hpp>
+#include <boost/graph/planar_detail/face_iterators.hpp>
+#include <boost/graph/planar_detail/bucket_sort.hpp>
+
+namespace boost
+{
+namespace detail
+{
+ enum bm_case_t
+ {
+ BM_NO_CASE_CHOSEN,
+ BM_CASE_A,
+ BM_CASE_B,
+ BM_CASE_C,
+ BM_CASE_D,
+ BM_CASE_E
+ };
+}
+
+template < typename LowPointMap, typename DFSParentMap, typename DFSNumberMap,
+ typename LeastAncestorMap, typename DFSParentEdgeMap, typename SizeType >
+struct planar_dfs_visitor : public dfs_visitor<>
+{
+ planar_dfs_visitor(LowPointMap lpm, DFSParentMap dfs_p, DFSNumberMap dfs_n,
+ LeastAncestorMap lam, DFSParentEdgeMap dfs_edge)
+ : low(lpm)
+ , parent(dfs_p)
+ , df_number(dfs_n)
+ , least_ancestor(lam)
+ , df_edge(dfs_edge)
+ , count(0)
+ {
+ }
+
+ template < typename Vertex, typename Graph >
+ void start_vertex(const Vertex& u, Graph&)
+ {
+ put(parent, u, u);
+ put(least_ancestor, u, count);
+ }
+
+ template < typename Vertex, typename Graph >
+ void discover_vertex(const Vertex& u, Graph&)
+ {
+ put(low, u, count);
+ put(df_number, u, count);
+ ++count;
+ }
+
+ template < typename Edge, typename Graph >
+ void tree_edge(const Edge& e, Graph& g)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ vertex_t s(source(e, g));
+ vertex_t t(target(e, g));
+
+ put(parent, t, s);
+ put(df_edge, t, e);
+ put(least_ancestor, t, get(df_number, s));
+ }
+
+ template < typename Edge, typename Graph >
+ void back_edge(const Edge& e, Graph& g)
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+
+ vertex_t s(source(e, g));
+ vertex_t t(target(e, g));
+ BOOST_USING_STD_MIN();
+
+ if (t != get(parent, s))
+ {
+ v_size_t s_low_df_number = get(low, s);
+ v_size_t t_df_number = get(df_number, t);
+ v_size_t s_least_ancestor_df_number = get(least_ancestor, s);
+
+ put(low, s,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ s_low_df_number, t_df_number));
+
+ put(least_ancestor, s,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ s_least_ancestor_df_number, t_df_number));
+ }
+ }
+
+ template < typename Vertex, typename Graph >
+ void finish_vertex(const Vertex& u, Graph&)
+ {
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+
+ Vertex u_parent = get(parent, u);
+ v_size_t u_parent_lowpoint = get(low, u_parent);
+ v_size_t u_lowpoint = get(low, u);
+ BOOST_USING_STD_MIN();
+
+ if (u_parent != u)
+ {
+ put(low, u_parent,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ u_lowpoint, u_parent_lowpoint));
+ }
+ }
+
+ LowPointMap low;
+ DFSParentMap parent;
+ DFSNumberMap df_number;
+ LeastAncestorMap least_ancestor;
+ DFSParentEdgeMap df_edge;
+ SizeType count;
+};
+
+template < typename Graph, typename VertexIndexMap,
+ typename StoreOldHandlesPolicy = graph::detail::store_old_handles,
+ typename StoreEmbeddingPolicy = graph::detail::recursive_lazy_list >
+class boyer_myrvold_impl
+{
+
+ typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+ typedef
+ typename graph_traits< Graph >::out_edge_iterator out_edge_iterator_t;
+ typedef graph::detail::face_handle< Graph, StoreOldHandlesPolicy,
+ StoreEmbeddingPolicy >
+ face_handle_t;
+ typedef std::vector< vertex_t > vertex_vector_t;
+ typedef std::vector< edge_t > edge_vector_t;
+ typedef std::list< vertex_t > vertex_list_t;
+ typedef std::list< face_handle_t > face_handle_list_t;
+ typedef boost::shared_ptr< face_handle_list_t > face_handle_list_ptr_t;
+ typedef boost::shared_ptr< vertex_list_t > vertex_list_ptr_t;
+ typedef boost::tuple< vertex_t, bool, bool > merge_stack_frame_t;
+ typedef std::vector< merge_stack_frame_t > merge_stack_t;
+
+ template < typename T > struct map_vertex_to_
+ {
+ typedef iterator_property_map< typename std::vector< T >::iterator,
+ VertexIndexMap >
+ type;
+ };
+
+ typedef typename map_vertex_to_< v_size_t >::type vertex_to_v_size_map_t;
+ typedef typename map_vertex_to_< vertex_t >::type vertex_to_vertex_map_t;
+ typedef typename map_vertex_to_< edge_t >::type vertex_to_edge_map_t;
+ typedef typename map_vertex_to_< vertex_list_ptr_t >::type
+ vertex_to_vertex_list_ptr_map_t;
+ typedef typename map_vertex_to_< edge_vector_t >::type
+ vertex_to_edge_vector_map_t;
+ typedef typename map_vertex_to_< bool >::type vertex_to_bool_map_t;
+ typedef typename map_vertex_to_< face_handle_t >::type
+ vertex_to_face_handle_map_t;
+ typedef typename map_vertex_to_< face_handle_list_ptr_t >::type
+ vertex_to_face_handle_list_ptr_map_t;
+ typedef typename map_vertex_to_< typename vertex_list_t::iterator >::type
+ vertex_to_separated_node_map_t;
+
+ template < typename BicompSideToTraverse = single_side,
+ typename VisitorType = lead_visitor, typename Time = current_iteration >
+ struct face_vertex_iterator
+ {
+ typedef face_iterator< Graph, vertex_to_face_handle_map_t, vertex_t,
+ BicompSideToTraverse, VisitorType, Time >
+ type;
+ };
+
+ template < typename BicompSideToTraverse = single_side,
+ typename Time = current_iteration >
+ struct face_edge_iterator
+ {
+ typedef face_iterator< Graph, vertex_to_face_handle_map_t, edge_t,
+ BicompSideToTraverse, lead_visitor, Time >
+ type;
+ };
+
+public:
+ boyer_myrvold_impl(const Graph& arg_g, VertexIndexMap arg_vm)
+ : g(arg_g)
+ , vm(arg_vm)
+ ,
+
+ low_point_vector(num_vertices(g))
+ , dfs_parent_vector(num_vertices(g))
+ , dfs_number_vector(num_vertices(g))
+ , least_ancestor_vector(num_vertices(g))
+ , pertinent_roots_vector(num_vertices(g))
+ , backedge_flag_vector(num_vertices(g), num_vertices(g) + 1)
+ , visited_vector(num_vertices(g), num_vertices(g) + 1)
+ , face_handles_vector(num_vertices(g))
+ , dfs_child_handles_vector(num_vertices(g))
+ , separated_dfs_child_list_vector(num_vertices(g))
+ , separated_node_in_parent_list_vector(num_vertices(g))
+ , canonical_dfs_child_vector(num_vertices(g))
+ , flipped_vector(num_vertices(g), false)
+ , backedges_vector(num_vertices(g))
+ , dfs_parent_edge_vector(num_vertices(g))
+ ,
+
+ vertices_by_dfs_num(num_vertices(g))
+ ,
+
+ low_point(low_point_vector.begin(), vm)
+ , dfs_parent(dfs_parent_vector.begin(), vm)
+ , dfs_number(dfs_number_vector.begin(), vm)
+ , least_ancestor(least_ancestor_vector.begin(), vm)
+ , pertinent_roots(pertinent_roots_vector.begin(), vm)
+ , backedge_flag(backedge_flag_vector.begin(), vm)
+ , visited(visited_vector.begin(), vm)
+ , face_handles(face_handles_vector.begin(), vm)
+ , dfs_child_handles(dfs_child_handles_vector.begin(), vm)
+ , separated_dfs_child_list(separated_dfs_child_list_vector.begin(), vm)
+ , separated_node_in_parent_list(
+ separated_node_in_parent_list_vector.begin(), vm)
+ , canonical_dfs_child(canonical_dfs_child_vector.begin(), vm)
+ , flipped(flipped_vector.begin(), vm)
+ , backedges(backedges_vector.begin(), vm)
+ , dfs_parent_edge(dfs_parent_edge_vector.begin(), vm)
+
+ {
+
+ planar_dfs_visitor< vertex_to_v_size_map_t, vertex_to_vertex_map_t,
+ vertex_to_v_size_map_t, vertex_to_v_size_map_t,
+ vertex_to_edge_map_t, v_size_t >
+ vis(low_point, dfs_parent, dfs_number, least_ancestor,
+ dfs_parent_edge);
+
+ // Perform a depth-first search to find each vertex's low point, least
+ // ancestor, and dfs tree information
+ depth_first_search(g, visitor(vis).vertex_index_map(vm));
+
+ // Sort vertices by their lowpoint - need this later in the constructor
+ vertex_vector_t vertices_by_lowpoint(num_vertices(g));
+ std::copy(vertices(g).first, vertices(g).second,
+ vertices_by_lowpoint.begin());
+ bucket_sort(vertices_by_lowpoint.begin(), vertices_by_lowpoint.end(),
+ low_point, num_vertices(g));
+
+ // Sort vertices by their dfs number - need this to iterate by reverse
+ // DFS number in the main loop.
+ std::copy(
+ vertices(g).first, vertices(g).second, vertices_by_dfs_num.begin());
+ bucket_sort(vertices_by_dfs_num.begin(), vertices_by_dfs_num.end(),
+ dfs_number, num_vertices(g));
+
+ // Initialize face handles. A face handle is an abstraction that serves
+ // two uses in our implementation - it allows us to efficiently move
+ // along the outer face of embedded bicomps in a partially embedded
+ // graph, and it provides storage for the planar embedding. Face
+ // handles are implemented by a sequence of edges and are associated
+ // with a particular vertex - the sequence of edges represents the
+ // current embedding of edges around that vertex, and the first and
+ // last edges in the sequence represent the pair of edges on the outer
+ // face that are adjacent to the associated vertex. This lets us embed
+ // edges in the graph by just pushing them on the front or back of the
+ // sequence of edges held by the face handles.
+ //
+ // Our algorithm starts with a DFS tree of edges (where every vertex is
+ // an articulation point and every edge is a singleton bicomp) and
+ // repeatedly merges bicomps by embedding additional edges. Note that
+ // any bicomp at any point in the algorithm can be associated with a
+ // unique edge connecting the vertex of that bicomp with the lowest DFS
+ // number (which we refer to as the "root" of the bicomp) with its DFS
+ // child in the bicomp: the existence of two such edges would contradict
+ // the properties of a DFS tree. We refer to the DFS child of the root
+ // of a bicomp as the "canonical DFS child" of the bicomp. Note that a
+ // vertex can be the root of more than one bicomp.
+ //
+ // We move around the external faces of a bicomp using a few property
+ // maps, which we'll initialize presently:
+ //
+ // - face_handles: maps a vertex to a face handle that can be used to
+ // move "up" a bicomp. For a vertex that isn't an articulation point,
+ // this holds the face handles that can be used to move around that
+ // vertex's unique bicomp. For a vertex that is an articulation point,
+ // this holds the face handles associated with the unique bicomp that
+ // the vertex is NOT the root of. These handles can therefore be used
+ // to move from any point on the outer face of the tree of bicomps
+ // around the current outer face towards the root of the DFS tree.
+ //
+ // - dfs_child_handles: these are used to hold face handles for
+ // vertices that are articulation points - dfs_child_handles[v] holds
+ // the face handles corresponding to vertex u in the bicomp with root
+ // u and canonical DFS child v.
+ //
+ // - canonical_dfs_child: this property map allows one to determine the
+ // canonical DFS child of a bicomp while traversing the outer face.
+ // This property map is only valid when applied to one of the two
+ // vertices adjacent to the root of the bicomp on the outer face. To
+ // be more precise, if v is the canonical DFS child of a bicomp,
+ // canonical_dfs_child[dfs_child_handles[v].first_vertex()] == v and
+ // canonical_dfs_child[dfs_child_handles[v].second_vertex()] == v.
+ //
+ // - pertinent_roots: given a vertex v, pertinent_roots[v] contains a
+ // list of face handles pointing to the top of bicomps that need to
+ // be visited by the current walkdown traversal (since they lead to
+ // backedges that need to be embedded). These lists are populated by
+ // the walkup and consumed by the walkdown.
+
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+ vertex_t parent = dfs_parent[v];
+
+ if (parent != v)
+ {
+ edge_t parent_edge = dfs_parent_edge[v];
+ add_to_embedded_edges(parent_edge, StoreOldHandlesPolicy());
+ face_handles[v] = face_handle_t(v, parent_edge, g);
+ dfs_child_handles[v] = face_handle_t(parent, parent_edge, g);
+ }
+ else
+ {
+ face_handles[v] = face_handle_t(v);
+ dfs_child_handles[v] = face_handle_t(parent);
+ }
+
+ canonical_dfs_child[v] = v;
+ pertinent_roots[v] = face_handle_list_ptr_t(new face_handle_list_t);
+ separated_dfs_child_list[v] = vertex_list_ptr_t(new vertex_list_t);
+ }
+
+ // We need to create a list of not-yet-merged depth-first children for
+ // each vertex that will be updated as bicomps get merged. We sort each
+ // list by ascending lowpoint, which allows the externally_active
+ // function to run in constant time, and we keep a pointer to each
+ // vertex's representation in its parent's list, which allows merging
+ // in constant time.
+
+ for (typename vertex_vector_t::iterator itr
+ = vertices_by_lowpoint.begin();
+ itr != vertices_by_lowpoint.end(); ++itr)
+ {
+ vertex_t v(*itr);
+ vertex_t parent(dfs_parent[v]);
+ if (v != parent)
+ {
+ separated_node_in_parent_list[v]
+ = separated_dfs_child_list[parent]->insert(
+ separated_dfs_child_list[parent]->end(), v);
+ }
+ }
+
+ // The merge stack holds path information during a walkdown iteration
+ merge_stack.reserve(num_vertices(g));
+ }
+
+ bool is_planar()
+ {
+
+ // This is the main algorithm: starting with a DFS tree of embedded
+ // edges (which, since it's a tree, is planar), iterate through all
+ // vertices by reverse DFS number, attempting to embed all backedges
+ // connecting the current vertex to vertices with higher DFS numbers.
+ //
+ // The walkup is a procedure that examines all such backedges and sets
+ // up the required data structures so that they can be searched by the
+ // walkdown in linear time. The walkdown does the actual work of
+ // embedding edges and flipping bicomps, and can identify when it has
+ // come across a kuratowski subgraph.
+ //
+ // store_old_face_handles caches face handles from the previous
+ // iteration - this is used only for the kuratowski subgraph isolation,
+ // and is therefore dispatched based on the StoreOldHandlesPolicy.
+ //
+ // clean_up_embedding does some clean-up and fills in values that have
+ // to be computed lazily during the actual execution of the algorithm
+ // (for instance, whether or not a bicomp is flipped in the final
+ // embedding). It's dispatched on the the StoreEmbeddingPolicy, since
+ // it's not needed if an embedding isn't desired.
+
+ typename vertex_vector_t::reverse_iterator vi, vi_end;
+
+ vi_end = vertices_by_dfs_num.rend();
+ for (vi = vertices_by_dfs_num.rbegin(); vi != vi_end; ++vi)
+ {
+
+ store_old_face_handles(StoreOldHandlesPolicy());
+
+ vertex_t v(*vi);
+
+ walkup(v);
+
+ if (!walkdown(v))
+ return false;
+ }
+
+ clean_up_embedding(StoreEmbeddingPolicy());
+
+ return true;
+ }
+
+private:
+ void walkup(vertex_t v)
+ {
+
+ // The point of the walkup is to follow all backedges from v to
+ // vertices with higher DFS numbers, and update pertinent_roots
+ // for the bicomp roots on the path from backedge endpoints up
+ // to v. This will set the stage for the walkdown to efficiently
+ // traverse the graph of bicomps down from v.
+
+ typedef
+ typename face_vertex_iterator< both_sides >::type walkup_iterator_t;
+
+ out_edge_iterator_t oi, oi_end;
+ for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi)
+ {
+ edge_t e(*oi);
+ vertex_t e_source(source(e, g));
+ vertex_t e_target(target(e, g));
+
+ if (e_source == e_target)
+ {
+ self_loops.push_back(e);
+ continue;
+ }
+
+ vertex_t w(e_source == v ? e_target : e_source);
+
+ // continue if not a back edge or already embedded
+ if (dfs_number[w] < dfs_number[v] || e == dfs_parent_edge[w])
+ continue;
+
+ backedges[w].push_back(e);
+
+ v_size_t timestamp = dfs_number[v];
+ backedge_flag[w] = timestamp;
+
+ walkup_iterator_t walkup_itr(w, face_handles);
+ walkup_iterator_t walkup_end;
+ vertex_t lead_vertex = w;
+
+ while (true)
+ {
+
+ // Move to the root of the current bicomp or the first visited
+ // vertex on the bicomp by going up each side in parallel
+
+ while (walkup_itr != walkup_end
+ && visited[*walkup_itr] != timestamp)
+ {
+ lead_vertex = *walkup_itr;
+ visited[lead_vertex] = timestamp;
+ ++walkup_itr;
+ }
+
+ // If we've found the root of a bicomp through a path we haven't
+ // seen before, update pertinent_roots with a handle to the
+ // current bicomp. Otherwise, we've just seen a path we've been
+ // up before, so break out of the main while loop.
+
+ if (walkup_itr == walkup_end)
+ {
+ vertex_t dfs_child = canonical_dfs_child[lead_vertex];
+ vertex_t parent = dfs_parent[dfs_child];
+
+ visited[dfs_child_handles[dfs_child].first_vertex()]
+ = timestamp;
+ visited[dfs_child_handles[dfs_child].second_vertex()]
+ = timestamp;
+
+ if (low_point[dfs_child] < dfs_number[v]
+ || least_ancestor[dfs_child] < dfs_number[v])
+ {
+ pertinent_roots[parent]->push_back(
+ dfs_child_handles[dfs_child]);
+ }
+ else
+ {
+ pertinent_roots[parent]->push_front(
+ dfs_child_handles[dfs_child]);
+ }
+
+ if (parent != v && visited[parent] != timestamp)
+ {
+ walkup_itr = walkup_iterator_t(parent, face_handles);
+ lead_vertex = parent;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ bool walkdown(vertex_t v)
+ {
+ // This procedure is where all of the action is - pertinent_roots
+ // has already been set up by the walkup, so we just need to move
+ // down bicomps from v until we find vertices that have been
+ // labeled as backedge endpoints. Once we find such a vertex, we
+ // embed the corresponding edge and glue together the bicomps on
+ // the path connecting the two vertices in the edge. This may
+ // involve flipping bicomps along the way.
+
+ vertex_t w; // the other endpoint of the edge we're embedding
+
+ while (!pertinent_roots[v]->empty())
+ {
+
+ face_handle_t root_face_handle = pertinent_roots[v]->front();
+ face_handle_t curr_face_handle = root_face_handle;
+ pertinent_roots[v]->pop_front();
+
+ merge_stack.clear();
+
+ while (true)
+ {
+
+ typename face_vertex_iterator<>::type first_face_itr,
+ second_face_itr, face_end;
+ vertex_t first_side_vertex
+ = graph_traits< Graph >::null_vertex();
+ vertex_t second_side_vertex
+ = graph_traits< Graph >::null_vertex();
+ vertex_t first_tail, second_tail;
+
+ first_tail = second_tail = curr_face_handle.get_anchor();
+ first_face_itr = typename face_vertex_iterator<>::type(
+ curr_face_handle, face_handles, first_side());
+ second_face_itr = typename face_vertex_iterator<>::type(
+ curr_face_handle, face_handles, second_side());
+
+ for (; first_face_itr != face_end; ++first_face_itr)
+ {
+ vertex_t face_vertex(*first_face_itr);
+ if (pertinent(face_vertex, v)
+ || externally_active(face_vertex, v))
+ {
+ first_side_vertex = face_vertex;
+ second_side_vertex = face_vertex;
+ break;
+ }
+ first_tail = face_vertex;
+ }
+
+ if (first_side_vertex == graph_traits< Graph >::null_vertex()
+ || first_side_vertex == curr_face_handle.get_anchor())
+ break;
+
+ for (; second_face_itr != face_end; ++second_face_itr)
+ {
+ vertex_t face_vertex(*second_face_itr);
+ if (pertinent(face_vertex, v)
+ || externally_active(face_vertex, v))
+ {
+ second_side_vertex = face_vertex;
+ break;
+ }
+ second_tail = face_vertex;
+ }
+
+ vertex_t chosen;
+ bool chose_first_upper_path;
+ if (internally_active(first_side_vertex, v))
+ {
+ chosen = first_side_vertex;
+ chose_first_upper_path = true;
+ }
+ else if (internally_active(second_side_vertex, v))
+ {
+ chosen = second_side_vertex;
+ chose_first_upper_path = false;
+ }
+ else if (pertinent(first_side_vertex, v))
+ {
+ chosen = first_side_vertex;
+ chose_first_upper_path = true;
+ }
+ else if (pertinent(second_side_vertex, v))
+ {
+ chosen = second_side_vertex;
+ chose_first_upper_path = false;
+ }
+ else
+ {
+
+ // If there's a pertinent vertex on the lower face
+ // between the first_face_itr and the second_face_itr,
+ // this graph isn't planar.
+ for (; *first_face_itr != second_side_vertex;
+ ++first_face_itr)
+ {
+ vertex_t p(*first_face_itr);
+ if (pertinent(p, v))
+ {
+ // Found a Kuratowski subgraph
+ kuratowski_v = v;
+ kuratowski_x = first_side_vertex;
+ kuratowski_y = second_side_vertex;
+ return false;
+ }
+ }
+
+ // Otherwise, the fact that we didn't find a pertinent
+ // vertex on this face is fine - we should set the
+ // short-circuit edges and break out of this loop to
+ // start looking at a different pertinent root.
+
+ if (first_side_vertex == second_side_vertex)
+ {
+ if (first_tail != v)
+ {
+ vertex_t first
+ = face_handles[first_tail].first_vertex();
+ vertex_t second
+ = face_handles[first_tail].second_vertex();
+ boost::tie(first_side_vertex, first_tail)
+ = make_tuple(first_tail,
+ first == first_side_vertex ? second
+ : first);
+ }
+ else if (second_tail != v)
+ {
+ vertex_t first
+ = face_handles[second_tail].first_vertex();
+ vertex_t second
+ = face_handles[second_tail].second_vertex();
+ boost::tie(second_side_vertex, second_tail)
+ = make_tuple(second_tail,
+ first == second_side_vertex ? second
+ : first);
+ }
+ else
+ break;
+ }
+
+ canonical_dfs_child[first_side_vertex]
+ = canonical_dfs_child[root_face_handle.first_vertex()];
+ canonical_dfs_child[second_side_vertex]
+ = canonical_dfs_child[root_face_handle.second_vertex()];
+ root_face_handle.set_first_vertex(first_side_vertex);
+ root_face_handle.set_second_vertex(second_side_vertex);
+
+ if (face_handles[first_side_vertex].first_vertex()
+ == first_tail)
+ face_handles[first_side_vertex].set_first_vertex(v);
+ else
+ face_handles[first_side_vertex].set_second_vertex(v);
+
+ if (face_handles[second_side_vertex].first_vertex()
+ == second_tail)
+ face_handles[second_side_vertex].set_first_vertex(v);
+ else
+ face_handles[second_side_vertex].set_second_vertex(v);
+
+ break;
+ }
+
+ // When we unwind the stack, we need to know which direction
+ // we came down from on the top face handle
+
+ bool chose_first_lower_path
+ = (chose_first_upper_path
+ && face_handles[chosen].first_vertex() == first_tail)
+ || (!chose_first_upper_path
+ && face_handles[chosen].first_vertex() == second_tail);
+
+ // If there's a backedge at the chosen vertex, embed it now
+ if (backedge_flag[chosen] == dfs_number[v])
+ {
+ w = chosen;
+
+ backedge_flag[chosen] = num_vertices(g) + 1;
+ add_to_merge_points(chosen, StoreOldHandlesPolicy());
+
+ typename edge_vector_t::iterator ei, ei_end;
+ ei_end = backedges[chosen].end();
+ for (ei = backedges[chosen].begin(); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ add_to_embedded_edges(e, StoreOldHandlesPolicy());
+
+ if (chose_first_lower_path)
+ face_handles[chosen].push_first(e, g);
+ else
+ face_handles[chosen].push_second(e, g);
+ }
+ }
+ else
+ {
+ merge_stack.push_back(make_tuple(chosen,
+ chose_first_upper_path, chose_first_lower_path));
+ curr_face_handle = *pertinent_roots[chosen]->begin();
+ continue;
+ }
+
+ // Unwind the merge stack to the root, merging all bicomps
+
+ bool bottom_path_follows_first;
+ bool top_path_follows_first;
+ bool next_bottom_follows_first = chose_first_upper_path;
+
+ vertex_t merge_point = chosen;
+
+ while (!merge_stack.empty())
+ {
+
+ bottom_path_follows_first = next_bottom_follows_first;
+ boost::tie(merge_point, next_bottom_follows_first,
+ top_path_follows_first)
+ = merge_stack.back();
+ merge_stack.pop_back();
+
+ face_handle_t top_handle(face_handles[merge_point]);
+ face_handle_t bottom_handle(
+ *pertinent_roots[merge_point]->begin());
+
+ vertex_t bottom_dfs_child = canonical_dfs_child
+ [pertinent_roots[merge_point]->begin()->first_vertex()];
+
+ remove_vertex_from_separated_dfs_child_list(
+ canonical_dfs_child[pertinent_roots[merge_point]
+ ->begin()
+ ->first_vertex()]);
+
+ pertinent_roots[merge_point]->pop_front();
+
+ add_to_merge_points(
+ top_handle.get_anchor(), StoreOldHandlesPolicy());
+
+ if (top_path_follows_first && bottom_path_follows_first)
+ {
+ bottom_handle.flip();
+ top_handle.glue_first_to_second(bottom_handle);
+ }
+ else if (!top_path_follows_first
+ && bottom_path_follows_first)
+ {
+ flipped[bottom_dfs_child] = true;
+ top_handle.glue_second_to_first(bottom_handle);
+ }
+ else if (top_path_follows_first
+ && !bottom_path_follows_first)
+ {
+ flipped[bottom_dfs_child] = true;
+ top_handle.glue_first_to_second(bottom_handle);
+ }
+ else //! top_path_follows_first &&
+ //! !bottom_path_follows_first
+ {
+ bottom_handle.flip();
+ top_handle.glue_second_to_first(bottom_handle);
+ }
+ }
+
+ // Finally, embed all edges (v,w) at their upper end points
+ canonical_dfs_child[w]
+ = canonical_dfs_child[root_face_handle.first_vertex()];
+
+ add_to_merge_points(
+ root_face_handle.get_anchor(), StoreOldHandlesPolicy());
+
+ typename edge_vector_t::iterator ei, ei_end;
+ ei_end = backedges[chosen].end();
+ for (ei = backedges[chosen].begin(); ei != ei_end; ++ei)
+ {
+ if (next_bottom_follows_first)
+ root_face_handle.push_first(*ei, g);
+ else
+ root_face_handle.push_second(*ei, g);
+ }
+
+ backedges[chosen].clear();
+ curr_face_handle = root_face_handle;
+
+ } // while(true)
+
+ } // while(!pertinent_roots[v]->empty())
+
+ return true;
+ }
+
+ void store_old_face_handles(graph::detail::no_old_handles) {}
+
+ void store_old_face_handles(graph::detail::store_old_handles)
+ {
+ for (typename std::vector< vertex_t >::iterator mp_itr
+ = current_merge_points.begin();
+ mp_itr != current_merge_points.end(); ++mp_itr)
+ {
+ face_handles[*mp_itr].store_old_face_handles();
+ }
+ current_merge_points.clear();
+ }
+
+ void add_to_merge_points(vertex_t, graph::detail::no_old_handles) {}
+
+ void add_to_merge_points(vertex_t v, graph::detail::store_old_handles)
+ {
+ current_merge_points.push_back(v);
+ }
+
+ void add_to_embedded_edges(edge_t, graph::detail::no_old_handles) {}
+
+ void add_to_embedded_edges(edge_t e, graph::detail::store_old_handles)
+ {
+ embedded_edges.push_back(e);
+ }
+
+ void clean_up_embedding(graph::detail::no_embedding) {}
+
+ void clean_up_embedding(graph::detail::store_embedding)
+ {
+
+ // If the graph isn't biconnected, we'll still have entries
+ // in the separated_dfs_child_list for some vertices. Since
+ // these represent articulation points, we can obtain a
+ // planar embedding no matter what order we embed them in.
+
+ vertex_iterator_t xi, xi_end;
+ for (boost::tie(xi, xi_end) = vertices(g); xi != xi_end; ++xi)
+ {
+ if (!separated_dfs_child_list[*xi]->empty())
+ {
+ typename vertex_list_t::iterator yi, yi_end;
+ yi_end = separated_dfs_child_list[*xi]->end();
+ for (yi = separated_dfs_child_list[*xi]->begin(); yi != yi_end;
+ ++yi)
+ {
+ dfs_child_handles[*yi].flip();
+ face_handles[*xi].glue_first_to_second(
+ dfs_child_handles[*yi]);
+ }
+ }
+ }
+
+ // Up until this point, we've flipped bicomps lazily by setting
+ // flipped[v] to true if the bicomp rooted at v was flipped (the
+ // lazy aspect of this flip is that all descendents of that vertex
+ // need to have their orientations reversed as well). Now, we
+ // traverse the DFS tree by DFS number and perform the actual
+ // flipping as needed
+
+ typedef typename vertex_vector_t::iterator vertex_vector_itr_t;
+ vertex_vector_itr_t vi_end = vertices_by_dfs_num.end();
+ for (vertex_vector_itr_t vi = vertices_by_dfs_num.begin(); vi != vi_end;
+ ++vi)
+ {
+ vertex_t v(*vi);
+ bool v_flipped = flipped[v];
+ bool p_flipped = flipped[dfs_parent[v]];
+ if (v_flipped && !p_flipped)
+ {
+ face_handles[v].flip();
+ }
+ else if (p_flipped && !v_flipped)
+ {
+ face_handles[v].flip();
+ flipped[v] = true;
+ }
+ else
+ {
+ flipped[v] = false;
+ }
+ }
+
+ // If there are any self-loops in the graph, they were flagged
+ // during the walkup, and we should add them to the embedding now.
+ // Adding a self loop anywhere in the embedding could never
+ // invalidate the embedding, but they would complicate the traversal
+ // if they were added during the walkup/walkdown.
+
+ typename edge_vector_t::iterator ei, ei_end;
+ ei_end = self_loops.end();
+ for (ei = self_loops.begin(); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ face_handles[source(e, g)].push_second(e, g);
+ }
+ }
+
+ bool pertinent(vertex_t w, vertex_t v)
+ {
+ // w is pertinent with respect to v if there is a backedge (v,w) or if
+ // w is the root of a bicomp that contains a pertinent vertex.
+
+ return backedge_flag[w] == dfs_number[v]
+ || !pertinent_roots[w]->empty();
+ }
+
+ bool externally_active(vertex_t w, vertex_t v)
+ {
+ // Let a be any proper depth-first search ancestor of v. w is externally
+ // active with respect to v if there exists a backedge (a,w) or a
+ // backedge (a,w_0) for some w_0 in a descendent bicomp of w.
+
+ v_size_t dfs_number_of_v = dfs_number[v];
+ return (least_ancestor[w] < dfs_number_of_v)
+ || (!separated_dfs_child_list[w]->empty()
+ && low_point[separated_dfs_child_list[w]->front()]
+ < dfs_number_of_v);
+ }
+
+ bool internally_active(vertex_t w, vertex_t v)
+ {
+ return pertinent(w, v) && !externally_active(w, v);
+ }
+
+ void remove_vertex_from_separated_dfs_child_list(vertex_t v)
+ {
+ typename vertex_list_t::iterator to_delete
+ = separated_node_in_parent_list[v];
+ garbage.splice(garbage.end(), *separated_dfs_child_list[dfs_parent[v]],
+ to_delete, boost::next(to_delete));
+ }
+
+ // End of the implementation of the basic Boyer-Myrvold Algorithm. The rest
+ // of the code below implements the isolation of a Kuratowski subgraph in
+ // the case that the input graph is not planar. This is by far the most
+ // complicated part of the implementation.
+
+public:
+ template < typename EdgeToBoolPropertyMap, typename EdgeContainer >
+ vertex_t kuratowski_walkup(vertex_t v, EdgeToBoolPropertyMap forbidden_edge,
+ EdgeToBoolPropertyMap goal_edge, EdgeToBoolPropertyMap is_embedded,
+ EdgeContainer& path_edges)
+ {
+ vertex_t current_endpoint;
+ bool seen_goal_edge = false;
+ out_edge_iterator_t oi, oi_end;
+
+ for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi)
+ forbidden_edge[*oi] = true;
+
+ for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi)
+ {
+ path_edges.clear();
+
+ edge_t e(*oi);
+ current_endpoint
+ = target(*oi, g) == v ? source(*oi, g) : target(*oi, g);
+
+ if (dfs_number[current_endpoint] < dfs_number[v] || is_embedded[e]
+ || v == current_endpoint // self-loop
+ )
+ {
+ // Not a backedge
+ continue;
+ }
+
+ path_edges.push_back(e);
+ if (goal_edge[e])
+ {
+ return current_endpoint;
+ }
+
+ typedef typename face_edge_iterator<>::type walkup_itr_t;
+
+ walkup_itr_t walkup_itr(
+ current_endpoint, face_handles, first_side());
+ walkup_itr_t walkup_end;
+
+ seen_goal_edge = false;
+
+ while (true)
+ {
+
+ if (walkup_itr != walkup_end && forbidden_edge[*walkup_itr])
+ break;
+
+ while (walkup_itr != walkup_end && !goal_edge[*walkup_itr]
+ && !forbidden_edge[*walkup_itr])
+ {
+ edge_t f(*walkup_itr);
+ forbidden_edge[f] = true;
+ path_edges.push_back(f);
+ current_endpoint = source(f, g) == current_endpoint
+ ? target(f, g)
+ : source(f, g);
+ ++walkup_itr;
+ }
+
+ if (walkup_itr != walkup_end && goal_edge[*walkup_itr])
+ {
+ path_edges.push_back(*walkup_itr);
+ seen_goal_edge = true;
+ break;
+ }
+
+ walkup_itr = walkup_itr_t(
+ current_endpoint, face_handles, first_side());
+ }
+
+ if (seen_goal_edge)
+ break;
+ }
+
+ if (seen_goal_edge)
+ return current_endpoint;
+ else
+ return graph_traits< Graph >::null_vertex();
+ }
+
+ template < typename OutputIterator, typename EdgeIndexMap >
+ void extract_kuratowski_subgraph(OutputIterator o_itr, EdgeIndexMap em)
+ {
+
+ // If the main algorithm has failed to embed one of the back-edges from
+ // a vertex v, we can use the current state of the algorithm to isolate
+ // a Kuratowksi subgraph. The isolation process breaks down into five
+ // cases, A - E. The general configuration of all five cases is shown in
+ // figure 1. There is a vertex v from which the planar
+ // v embedding process could not proceed. This means that
+ // | there exists some bicomp containing three vertices
+ // ----- x,y, and z as shown such that x and y are externally
+ // | | active with respect to v (which means that there are
+ // x y two vertices x_0 and y_0 such that (1) both x_0 and
+ // | | y_0 are proper depth-first search ancestors of v and
+ // --z-- (2) there are two disjoint paths, one connecting x
+ // and x_0 and one connecting y and y_0, both
+ // consisting
+ // fig. 1 entirely of unembedded edges). Furthermore, there
+ // exists a vertex z_0 such that z is a depth-first
+ // search ancestor of z_0 and (v,z_0) is an unembedded back-edge from v.
+ // x,y and z all exist on the same bicomp, which consists entirely of
+ // embedded edges. The five subcases break down as follows, and are
+ // handled by the algorithm logically in the order A-E: First, if v is
+ // not on the same bicomp as x,y, and z, a K_3_3 can be isolated - this
+ // is case A. So, we'll assume that v is on the same bicomp as x,y, and
+ // z. If z_0 is on a different bicomp than x,y, and z, a K_3_3 can also
+ // be isolated - this is a case B - so we'll assume from now on that v
+ // is on the same bicomp as x, y, and z=z_0. In this case, one can use
+ // properties of the Boyer-Myrvold algorithm to show the existence of an
+ // "x-y path" connecting some vertex on the "left side" of the x,y,z
+ // bicomp with some vertex on the "right side" of the bicomp (where the
+ // left and right are split by a line drawn through v and z.If either of
+ // the endpoints of the x-y path is above x or y on the bicomp, a K_3_3
+ // can be isolated - this is a case C. Otherwise, both endpoints are at
+ // or below x and y on the bicomp. If there is a vertex alpha on the x-y
+ // path such that alpha is not x or y and there's a path from alpha to v
+ // that's disjoint from any of the edges on the bicomp and the x-y path,
+ // a K_3_3 can be isolated - this is a case D. Otherwise, properties of
+ // the Boyer-Myrvold algorithm can be used to show that another vertex
+ // w exists on the lower half of the bicomp such that w is externally
+ // active with respect to v. w can then be used to isolate a K_5 - this
+ // is the configuration of case E.
+
+ vertex_iterator_t vi, vi_end;
+ edge_iterator_t ei, ei_end;
+ out_edge_iterator_t oei, oei_end;
+ typename std::vector< edge_t >::iterator xi, xi_end;
+
+ // Clear the short-circuit edges - these are needed for the planar
+ // testing/embedding algorithm to run in linear time, but they'll
+ // complicate the kuratowski subgraph isolation
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ face_handles[*vi].reset_vertex_cache();
+ dfs_child_handles[*vi].reset_vertex_cache();
+ }
+
+ vertex_t v = kuratowski_v;
+ vertex_t x = kuratowski_x;
+ vertex_t y = kuratowski_y;
+
+ typedef iterator_property_map< typename std::vector< bool >::iterator,
+ EdgeIndexMap >
+ edge_to_bool_map_t;
+
+ std::vector< bool > is_in_subgraph_vector(num_edges(g), false);
+ edge_to_bool_map_t is_in_subgraph(is_in_subgraph_vector.begin(), em);
+
+ std::vector< bool > is_embedded_vector(num_edges(g), false);
+ edge_to_bool_map_t is_embedded(is_embedded_vector.begin(), em);
+
+ typename std::vector< edge_t >::iterator embedded_itr, embedded_end;
+ embedded_end = embedded_edges.end();
+ for (embedded_itr = embedded_edges.begin();
+ embedded_itr != embedded_end; ++embedded_itr)
+ is_embedded[*embedded_itr] = true;
+
+ // upper_face_vertex is true for x,y, and all vertices above x and y in
+ // the bicomp
+ std::vector< bool > upper_face_vertex_vector(num_vertices(g), false);
+ vertex_to_bool_map_t upper_face_vertex(
+ upper_face_vertex_vector.begin(), vm);
+
+ std::vector< bool > lower_face_vertex_vector(num_vertices(g), false);
+ vertex_to_bool_map_t lower_face_vertex(
+ lower_face_vertex_vector.begin(), vm);
+
+ // These next few variable declarations are all things that we need
+ // to find.
+ vertex_t z = graph_traits< Graph >::null_vertex();
+ vertex_t bicomp_root;
+ vertex_t w = graph_traits< Graph >::null_vertex();
+ face_handle_t w_handle;
+ face_handle_t v_dfchild_handle;
+ vertex_t first_x_y_path_endpoint = graph_traits< Graph >::null_vertex();
+ vertex_t second_x_y_path_endpoint
+ = graph_traits< Graph >::null_vertex();
+ vertex_t w_ancestor = v;
+
+ detail::bm_case_t chosen_case = detail::BM_NO_CASE_CHOSEN;
+
+ std::vector< edge_t > x_external_path;
+ std::vector< edge_t > y_external_path;
+ std::vector< edge_t > case_d_edges;
+
+ std::vector< edge_t > z_v_path;
+ std::vector< edge_t > w_path;
+
+ // first, use a walkup to find a path from V that starts with a
+ // backedge from V, then goes up until it hits either X or Y
+ //(but doesn't find X or Y as the root of a bicomp)
+
+ typename face_vertex_iterator<>::type x_upper_itr(
+ x, face_handles, first_side());
+ typename face_vertex_iterator<>::type x_lower_itr(
+ x, face_handles, second_side());
+ typename face_vertex_iterator<>::type face_itr, face_end;
+
+ // Don't know which path from x is the upper or lower path -
+ // we'll find out here
+ for (face_itr = x_upper_itr; face_itr != face_end; ++face_itr)
+ {
+ if (*face_itr == y)
+ {
+ std::swap(x_upper_itr, x_lower_itr);
+ break;
+ }
+ }
+
+ upper_face_vertex[x] = true;
+
+ vertex_t current_vertex = x;
+ vertex_t previous_vertex;
+ for (face_itr = x_upper_itr; face_itr != face_end; ++face_itr)
+ {
+ previous_vertex = current_vertex;
+ current_vertex = *face_itr;
+ upper_face_vertex[current_vertex] = true;
+ }
+
+ v_dfchild_handle
+ = dfs_child_handles[canonical_dfs_child[previous_vertex]];
+
+ for (face_itr = x_lower_itr; *face_itr != y; ++face_itr)
+ {
+ vertex_t current_vertex(*face_itr);
+ lower_face_vertex[current_vertex] = true;
+
+ typename face_handle_list_t::iterator roots_itr, roots_end;
+
+ if (w == graph_traits< Graph >::null_vertex()) // haven't found a w
+ // yet
+ {
+ roots_end = pertinent_roots[current_vertex]->end();
+ for (roots_itr = pertinent_roots[current_vertex]->begin();
+ roots_itr != roots_end; ++roots_itr)
+ {
+ if (low_point
+ [canonical_dfs_child[roots_itr->first_vertex()]]
+ < dfs_number[v])
+ {
+ w = current_vertex;
+ w_handle = *roots_itr;
+ break;
+ }
+ }
+ }
+ }
+
+ for (; face_itr != face_end; ++face_itr)
+ {
+ vertex_t current_vertex(*face_itr);
+ upper_face_vertex[current_vertex] = true;
+ bicomp_root = current_vertex;
+ }
+
+ typedef typename face_edge_iterator<>::type walkup_itr_t;
+
+ std::vector< bool > outer_face_edge_vector(num_edges(g), false);
+ edge_to_bool_map_t outer_face_edge(outer_face_edge_vector.begin(), em);
+
+ walkup_itr_t walkup_end;
+ for (walkup_itr_t walkup_itr(x, face_handles, first_side());
+ walkup_itr != walkup_end; ++walkup_itr)
+ {
+ outer_face_edge[*walkup_itr] = true;
+ is_in_subgraph[*walkup_itr] = true;
+ }
+
+ for (walkup_itr_t walkup_itr(x, face_handles, second_side());
+ walkup_itr != walkup_end; ++walkup_itr)
+ {
+ outer_face_edge[*walkup_itr] = true;
+ is_in_subgraph[*walkup_itr] = true;
+ }
+
+ std::vector< bool > forbidden_edge_vector(num_edges(g), false);
+ edge_to_bool_map_t forbidden_edge(forbidden_edge_vector.begin(), em);
+
+ std::vector< bool > goal_edge_vector(num_edges(g), false);
+ edge_to_bool_map_t goal_edge(goal_edge_vector.begin(), em);
+
+ // Find external path to x and to y
+
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ goal_edge[e] = !outer_face_edge[e]
+ && (source(e, g) == x || target(e, g) == x);
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+ }
+
+ vertex_t x_ancestor = v;
+ vertex_t x_endpoint = graph_traits< Graph >::null_vertex();
+
+ while (x_endpoint == graph_traits< Graph >::null_vertex())
+ {
+ x_ancestor = dfs_parent[x_ancestor];
+ x_endpoint = kuratowski_walkup(x_ancestor, forbidden_edge,
+ goal_edge, is_embedded, x_external_path);
+ }
+
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ goal_edge[e] = !outer_face_edge[e]
+ && (source(e, g) == y || target(e, g) == y);
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+ }
+
+ vertex_t y_ancestor = v;
+ vertex_t y_endpoint = graph_traits< Graph >::null_vertex();
+
+ while (y_endpoint == graph_traits< Graph >::null_vertex())
+ {
+ y_ancestor = dfs_parent[y_ancestor];
+ y_endpoint = kuratowski_walkup(y_ancestor, forbidden_edge,
+ goal_edge, is_embedded, y_external_path);
+ }
+
+ vertex_t parent, child;
+
+ // If v isn't on the same bicomp as x and y, it's a case A
+ if (bicomp_root != v)
+ {
+ chosen_case = detail::BM_CASE_A;
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ if (lower_face_vertex[*vi])
+ for (boost::tie(oei, oei_end) = out_edges(*vi, g);
+ oei != oei_end; ++oei)
+ if (!outer_face_edge[*oei])
+ goal_edge[*oei] = true;
+
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+
+ z = kuratowski_walkup(
+ v, forbidden_edge, goal_edge, is_embedded, z_v_path);
+ }
+ else if (w != graph_traits< Graph >::null_vertex())
+ {
+ chosen_case = detail::BM_CASE_B;
+
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ goal_edge[e] = false;
+ forbidden_edge[e] = outer_face_edge[e];
+ }
+
+ goal_edge[w_handle.first_edge()] = true;
+ goal_edge[w_handle.second_edge()] = true;
+
+ z = kuratowski_walkup(
+ v, forbidden_edge, goal_edge, is_embedded, z_v_path);
+
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+ }
+
+ typename std::vector< edge_t >::iterator pi, pi_end;
+ pi_end = z_v_path.end();
+ for (pi = z_v_path.begin(); pi != pi_end; ++pi)
+ {
+ goal_edge[*pi] = true;
+ }
+
+ w_ancestor = v;
+ vertex_t w_endpoint = graph_traits< Graph >::null_vertex();
+
+ while (w_endpoint == graph_traits< Graph >::null_vertex())
+ {
+ w_ancestor = dfs_parent[w_ancestor];
+ w_endpoint = kuratowski_walkup(
+ w_ancestor, forbidden_edge, goal_edge, is_embedded, w_path);
+ }
+
+ // We really want both the w walkup and the z walkup to finish on
+ // exactly the same edge, but for convenience (since we don't have
+ // control over which side of a bicomp a walkup moves up) we've
+ // defined the walkup to either end at w_handle.first_edge() or
+ // w_handle.second_edge(). If both walkups ended at different edges,
+ // we'll do a little surgery on the w walkup path to make it follow
+ // the other side of the final bicomp.
+
+ if ((w_path.back() == w_handle.first_edge()
+ && z_v_path.back() == w_handle.second_edge())
+ || (w_path.back() == w_handle.second_edge()
+ && z_v_path.back() == w_handle.first_edge()))
+ {
+ walkup_itr_t wi, wi_end;
+ edge_t final_edge = w_path.back();
+ vertex_t anchor = source(final_edge, g) == w_handle.get_anchor()
+ ? target(final_edge, g)
+ : source(final_edge, g);
+ if (face_handles[anchor].first_edge() == final_edge)
+ wi = walkup_itr_t(anchor, face_handles, second_side());
+ else
+ wi = walkup_itr_t(anchor, face_handles, first_side());
+
+ w_path.pop_back();
+
+ for (; wi != wi_end; ++wi)
+ {
+ edge_t e(*wi);
+ if (w_path.back() == e)
+ w_path.pop_back();
+ else
+ w_path.push_back(e);
+ }
+ }
+ }
+ else
+ {
+
+ // We need to find a valid z, since the x-y path re-defines the
+ // lower face, and the z we found earlier may now be on the upper
+ // face.
+
+ chosen_case = detail::BM_CASE_E;
+
+ // The z we've used so far is just an externally active vertex on
+ // the lower face path, but may not be the z we need for a case C,
+ // D, or E subgraph. the z we need now is any externally active
+ // vertex on the lower face path with both old_face_handles edges on
+ // the outer face. Since we know an x-y path exists, such a z must
+ // also exist.
+
+ // TODO: find this z in the first place.
+
+ // find the new z
+
+ for (face_itr = x_lower_itr; *face_itr != y; ++face_itr)
+ {
+ vertex_t possible_z(*face_itr);
+ if (pertinent(possible_z, v)
+ && outer_face_edge[face_handles[possible_z]
+ .old_first_edge()]
+ && outer_face_edge[face_handles[possible_z]
+ .old_second_edge()])
+ {
+ z = possible_z;
+ break;
+ }
+ }
+
+ // find x-y path, and a w if one exists.
+
+ if (externally_active(z, v))
+ w = z;
+
+ typedef typename face_edge_iterator< single_side,
+ previous_iteration >::type old_face_iterator_t;
+
+ old_face_iterator_t first_old_face_itr(
+ z, face_handles, first_side());
+ old_face_iterator_t second_old_face_itr(
+ z, face_handles, second_side());
+ old_face_iterator_t old_face_itr, old_face_end;
+
+ std::vector< old_face_iterator_t > old_face_iterators;
+ old_face_iterators.push_back(first_old_face_itr);
+ old_face_iterators.push_back(second_old_face_itr);
+
+ std::vector< bool > x_y_path_vertex_vector(num_vertices(g), false);
+ vertex_to_bool_map_t x_y_path_vertex(
+ x_y_path_vertex_vector.begin(), vm);
+
+ typename std::vector< old_face_iterator_t >::iterator of_itr,
+ of_itr_end;
+ of_itr_end = old_face_iterators.end();
+ for (of_itr = old_face_iterators.begin(); of_itr != of_itr_end;
+ ++of_itr)
+ {
+
+ old_face_itr = *of_itr;
+
+ vertex_t previous_vertex;
+ bool seen_x_or_y = false;
+ vertex_t current_vertex = z;
+ for (; old_face_itr != old_face_end; ++old_face_itr)
+ {
+ edge_t e(*old_face_itr);
+ previous_vertex = current_vertex;
+ current_vertex = source(e, g) == current_vertex
+ ? target(e, g)
+ : source(e, g);
+
+ if (current_vertex == x || current_vertex == y)
+ seen_x_or_y = true;
+
+ if (w == graph_traits< Graph >::null_vertex()
+ && externally_active(current_vertex, v)
+ && outer_face_edge[e]
+ && outer_face_edge[*boost::next(old_face_itr)]
+ && !seen_x_or_y)
+ {
+ w = current_vertex;
+ }
+
+ if (!outer_face_edge[e])
+ {
+ if (!upper_face_vertex[current_vertex]
+ && !lower_face_vertex[current_vertex])
+ {
+ x_y_path_vertex[current_vertex] = true;
+ }
+
+ is_in_subgraph[e] = true;
+ if (upper_face_vertex[source(e, g)]
+ || lower_face_vertex[source(e, g)])
+ {
+ if (first_x_y_path_endpoint
+ == graph_traits< Graph >::null_vertex())
+ first_x_y_path_endpoint = source(e, g);
+ else
+ second_x_y_path_endpoint = source(e, g);
+ }
+ if (upper_face_vertex[target(e, g)]
+ || lower_face_vertex[target(e, g)])
+ {
+ if (first_x_y_path_endpoint
+ == graph_traits< Graph >::null_vertex())
+ first_x_y_path_endpoint = target(e, g);
+ else
+ second_x_y_path_endpoint = target(e, g);
+ }
+ }
+ else if (previous_vertex == x || previous_vertex == y)
+ {
+ chosen_case = detail::BM_CASE_C;
+ }
+ }
+ }
+
+ // Look for a case D - one of v's embedded edges will connect to the
+ // x-y path along an inner face path.
+
+ // First, get a list of all of v's embedded child edges
+
+ out_edge_iterator_t v_edge_itr, v_edge_end;
+ for (boost::tie(v_edge_itr, v_edge_end) = out_edges(v, g);
+ v_edge_itr != v_edge_end; ++v_edge_itr)
+ {
+ edge_t embedded_edge(*v_edge_itr);
+
+ if (!is_embedded[embedded_edge]
+ || embedded_edge == dfs_parent_edge[v])
+ continue;
+
+ case_d_edges.push_back(embedded_edge);
+
+ vertex_t current_vertex = source(embedded_edge, g) == v
+ ? target(embedded_edge, g)
+ : source(embedded_edge, g);
+
+ typename face_edge_iterator<>::type internal_face_itr,
+ internal_face_end;
+ if (face_handles[current_vertex].first_vertex() == v)
+ {
+ internal_face_itr = typename face_edge_iterator<>::type(
+ current_vertex, face_handles, second_side());
+ }
+ else
+ {
+ internal_face_itr = typename face_edge_iterator<>::type(
+ current_vertex, face_handles, first_side());
+ }
+
+ while (internal_face_itr != internal_face_end
+ && !outer_face_edge[*internal_face_itr]
+ && !x_y_path_vertex[current_vertex])
+ {
+ edge_t e(*internal_face_itr);
+ case_d_edges.push_back(e);
+ current_vertex = source(e, g) == current_vertex
+ ? target(e, g)
+ : source(e, g);
+ ++internal_face_itr;
+ }
+
+ if (x_y_path_vertex[current_vertex])
+ {
+ chosen_case = detail::BM_CASE_D;
+ break;
+ }
+ else
+ {
+ case_d_edges.clear();
+ }
+ }
+ }
+
+ if (chosen_case != detail::BM_CASE_B
+ && chosen_case != detail::BM_CASE_A)
+ {
+
+ // Finding z and w.
+
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ goal_edge[e] = !outer_face_edge[e]
+ && (source(e, g) == z || target(e, g) == z);
+ forbidden_edge[e] = outer_face_edge[e];
+ }
+
+ kuratowski_walkup(
+ v, forbidden_edge, goal_edge, is_embedded, z_v_path);
+
+ if (chosen_case == detail::BM_CASE_E)
+ {
+
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+ goal_edge[*ei] = !outer_face_edge[*ei]
+ && (source(*ei, g) == w || target(*ei, g) == w);
+ }
+
+ for (boost::tie(oei, oei_end) = out_edges(w, g); oei != oei_end;
+ ++oei)
+ {
+ if (!outer_face_edge[*oei])
+ goal_edge[*oei] = true;
+ }
+
+ typename std::vector< edge_t >::iterator pi, pi_end;
+ pi_end = z_v_path.end();
+ for (pi = z_v_path.begin(); pi != pi_end; ++pi)
+ {
+ goal_edge[*pi] = true;
+ }
+
+ w_ancestor = v;
+ vertex_t w_endpoint = graph_traits< Graph >::null_vertex();
+
+ while (w_endpoint == graph_traits< Graph >::null_vertex())
+ {
+ w_ancestor = dfs_parent[w_ancestor];
+ w_endpoint = kuratowski_walkup(w_ancestor, forbidden_edge,
+ goal_edge, is_embedded, w_path);
+ }
+ }
+ }
+
+ // We're done isolating the Kuratowski subgraph at this point -
+ // but there's still some cleaning up to do.
+
+ // Update is_in_subgraph with the paths we just found
+
+ xi_end = x_external_path.end();
+ for (xi = x_external_path.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ xi_end = y_external_path.end();
+ for (xi = y_external_path.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ xi_end = z_v_path.end();
+ for (xi = z_v_path.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ xi_end = case_d_edges.end();
+ for (xi = case_d_edges.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ xi_end = w_path.end();
+ for (xi = w_path.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ child = bicomp_root;
+ parent = dfs_parent[child];
+ while (child != parent)
+ {
+ is_in_subgraph[dfs_parent_edge[child]] = true;
+ boost::tie(parent, child)
+ = std::make_pair(dfs_parent[parent], parent);
+ }
+
+ // At this point, we've already isolated the Kuratowski subgraph and
+ // collected all of the edges that compose it in the is_in_subgraph
+ // property map. But we want the verification of such a subgraph to be
+ // a deterministic process, and we can simplify the function
+ // is_kuratowski_subgraph by cleaning up some edges here.
+
+ if (chosen_case == detail::BM_CASE_B)
+ {
+ is_in_subgraph[dfs_parent_edge[v]] = false;
+ }
+ else if (chosen_case == detail::BM_CASE_C)
+ {
+ // In a case C subgraph, at least one of the x-y path endpoints
+ // (call it alpha) is above either x or y on the outer face. The
+ // other endpoint may be attached at x or y OR above OR below. In
+ // any of these three cases, we can form a K_3_3 by removing the
+ // edge attached to v on the outer face that is NOT on the path to
+ // alpha.
+
+ typename face_vertex_iterator< single_side, follow_visitor >::type
+ face_itr,
+ face_end;
+ if (face_handles[v_dfchild_handle.first_vertex()].first_edge()
+ == v_dfchild_handle.first_edge())
+ {
+ face_itr = typename face_vertex_iterator< single_side,
+ follow_visitor >::type(v_dfchild_handle.first_vertex(),
+ face_handles, second_side());
+ }
+ else
+ {
+ face_itr = typename face_vertex_iterator< single_side,
+ follow_visitor >::type(v_dfchild_handle.first_vertex(),
+ face_handles, first_side());
+ }
+
+ for (; true; ++face_itr)
+ {
+ vertex_t current_vertex(*face_itr);
+ if (current_vertex == x || current_vertex == y)
+ {
+ is_in_subgraph[v_dfchild_handle.first_edge()] = false;
+ break;
+ }
+ else if (current_vertex == first_x_y_path_endpoint
+ || current_vertex == second_x_y_path_endpoint)
+ {
+ is_in_subgraph[v_dfchild_handle.second_edge()] = false;
+ break;
+ }
+ }
+ }
+ else if (chosen_case == detail::BM_CASE_D)
+ {
+ // Need to remove both of the edges adjacent to v on the outer face.
+ // remove the connecting edges from v to bicomp, then
+ // is_kuratowski_subgraph will shrink vertices of degree 1
+ // automatically...
+
+ is_in_subgraph[v_dfchild_handle.first_edge()] = false;
+ is_in_subgraph[v_dfchild_handle.second_edge()] = false;
+ }
+ else if (chosen_case == detail::BM_CASE_E)
+ {
+ // Similarly to case C, if the endpoints of the x-y path are both
+ // below x and y, we should remove an edge to allow the subgraph to
+ // contract to a K_3_3.
+
+ if ((first_x_y_path_endpoint != x && first_x_y_path_endpoint != y)
+ || (second_x_y_path_endpoint != x
+ && second_x_y_path_endpoint != y))
+ {
+ is_in_subgraph[dfs_parent_edge[v]] = false;
+
+ vertex_t deletion_endpoint, other_endpoint;
+ if (lower_face_vertex[first_x_y_path_endpoint])
+ {
+ deletion_endpoint = second_x_y_path_endpoint;
+ other_endpoint = first_x_y_path_endpoint;
+ }
+ else
+ {
+ deletion_endpoint = first_x_y_path_endpoint;
+ other_endpoint = second_x_y_path_endpoint;
+ }
+
+ typename face_edge_iterator<>::type face_itr, face_end;
+
+ bool found_other_endpoint = false;
+ for (face_itr = typename face_edge_iterator<>::type(
+ deletion_endpoint, face_handles, first_side());
+ face_itr != face_end; ++face_itr)
+ {
+ edge_t e(*face_itr);
+ if (source(e, g) == other_endpoint
+ || target(e, g) == other_endpoint)
+ {
+ found_other_endpoint = true;
+ break;
+ }
+ }
+
+ if (found_other_endpoint)
+ {
+ is_in_subgraph[face_handles[deletion_endpoint].first_edge()]
+ = false;
+ }
+ else
+ {
+ is_in_subgraph[face_handles[deletion_endpoint]
+ .second_edge()]
+ = false;
+ }
+ }
+ }
+
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ if (is_in_subgraph[*ei])
+ *o_itr = *ei;
+ }
+
+ template < typename EdgePermutation >
+ void make_edge_permutation(EdgePermutation perm)
+ {
+ vertex_iterator_t vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+ perm[v].clear();
+ face_handles[v].get_list(std::back_inserter(perm[v]));
+ }
+ }
+
+private:
+ const Graph& g;
+ VertexIndexMap vm;
+
+ vertex_t kuratowski_v;
+ vertex_t kuratowski_x;
+ vertex_t kuratowski_y;
+
+ vertex_list_t garbage; // we delete items from linked lists by
+ // splicing them into garbage
+
+ // only need these two for kuratowski subgraph isolation
+ std::vector< vertex_t > current_merge_points;
+ std::vector< edge_t > embedded_edges;
+
+ // property map storage
+ std::vector< v_size_t > low_point_vector;
+ std::vector< vertex_t > dfs_parent_vector;
+ std::vector< v_size_t > dfs_number_vector;
+ std::vector< v_size_t > least_ancestor_vector;
+ std::vector< face_handle_list_ptr_t > pertinent_roots_vector;
+ std::vector< v_size_t > backedge_flag_vector;
+ std::vector< v_size_t > visited_vector;
+ std::vector< face_handle_t > face_handles_vector;
+ std::vector< face_handle_t > dfs_child_handles_vector;
+ std::vector< vertex_list_ptr_t > separated_dfs_child_list_vector;
+ std::vector< typename vertex_list_t::iterator >
+ separated_node_in_parent_list_vector;
+ std::vector< vertex_t > canonical_dfs_child_vector;
+ std::vector< bool > flipped_vector;
+ std::vector< edge_vector_t > backedges_vector;
+ edge_vector_t self_loops;
+ std::vector< edge_t > dfs_parent_edge_vector;
+ vertex_vector_t vertices_by_dfs_num;
+
+ // property maps
+ vertex_to_v_size_map_t low_point;
+ vertex_to_vertex_map_t dfs_parent;
+ vertex_to_v_size_map_t dfs_number;
+ vertex_to_v_size_map_t least_ancestor;
+ vertex_to_face_handle_list_ptr_map_t pertinent_roots;
+ vertex_to_v_size_map_t backedge_flag;
+ vertex_to_v_size_map_t visited;
+ vertex_to_face_handle_map_t face_handles;
+ vertex_to_face_handle_map_t dfs_child_handles;
+ vertex_to_vertex_list_ptr_map_t separated_dfs_child_list;
+ vertex_to_separated_node_map_t separated_node_in_parent_list;
+ vertex_to_vertex_map_t canonical_dfs_child;
+ vertex_to_bool_map_t flipped;
+ vertex_to_edge_vector_map_t backedges;
+ vertex_to_edge_map_t dfs_parent_edge; // only need for kuratowski
+
+ merge_stack_t merge_stack;
+};
+
+} // namespace boost
+
+#endif //__BOYER_MYRVOLD_IMPL_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/planar_detail/bucket_sort.hpp b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/bucket_sort.hpp
new file mode 100644
index 0000000000..15b932b9fd
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/bucket_sort.hpp
@@ -0,0 +1,118 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef __BUCKET_SORT_HPP__
+#define __BUCKET_SORT_HPP__
+
+#include <vector>
+#include <algorithm>
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+
+template < typename ItemToRankMap > struct rank_comparison
+{
+ rank_comparison(ItemToRankMap arg_itrm) : itrm(arg_itrm) {}
+
+ template < typename Item > bool operator()(Item x, Item y) const
+ {
+ return get(itrm, x) < get(itrm, y);
+ }
+
+private:
+ ItemToRankMap itrm;
+};
+
+template < typename TupleType, int N,
+ typename PropertyMapWrapper = identity_property_map >
+struct property_map_tuple_adaptor
+: public put_get_helper< typename PropertyMapWrapper::value_type,
+ property_map_tuple_adaptor< TupleType, N, PropertyMapWrapper > >
+{
+ typedef typename PropertyMapWrapper::reference reference;
+ typedef typename PropertyMapWrapper::value_type value_type;
+ typedef TupleType key_type;
+ typedef readable_property_map_tag category;
+
+ property_map_tuple_adaptor() {}
+
+ property_map_tuple_adaptor(PropertyMapWrapper wrapper_map)
+ : m_wrapper_map(wrapper_map)
+ {
+ }
+
+ inline value_type operator[](const key_type& x) const
+ {
+ return get(m_wrapper_map, get< n >(x));
+ }
+
+ static const int n = N;
+ PropertyMapWrapper m_wrapper_map;
+};
+
+// This function sorts a sequence of n items by their ranks in linear time,
+// given that all ranks are in the range [0, range). This sort is stable.
+template < typename ForwardIterator, typename ItemToRankMap, typename SizeType >
+void bucket_sort(ForwardIterator begin, ForwardIterator end, ItemToRankMap rank,
+ SizeType range = 0)
+{
+#ifdef BOOST_GRAPH_PREFER_STD_LIB
+ std::stable_sort(begin, end, rank_comparison< ItemToRankMap >(rank));
+#else
+ typedef std::vector<
+ typename boost::property_traits< ItemToRankMap >::key_type >
+ vector_of_values_t;
+ typedef std::vector< vector_of_values_t > vector_of_vectors_t;
+
+ if (!range)
+ {
+ rank_comparison< ItemToRankMap > cmp(rank);
+ ForwardIterator max_by_rank = std::max_element(begin, end, cmp);
+ if (max_by_rank == end)
+ return;
+ range = get(rank, *max_by_rank) + 1;
+ }
+
+ vector_of_vectors_t temp_values(range);
+
+ for (ForwardIterator itr = begin; itr != end; ++itr)
+ {
+ temp_values[get(rank, *itr)].push_back(*itr);
+ }
+
+ ForwardIterator orig_seq_itr = begin;
+ typename vector_of_vectors_t::iterator itr_end = temp_values.end();
+ for (typename vector_of_vectors_t::iterator itr = temp_values.begin();
+ itr != itr_end; ++itr)
+ {
+ typename vector_of_values_t::iterator jtr_end = itr->end();
+ for (typename vector_of_values_t::iterator jtr = itr->begin();
+ jtr != jtr_end; ++jtr)
+ {
+ *orig_seq_itr = *jtr;
+ ++orig_seq_itr;
+ }
+ }
+#endif
+}
+
+template < typename ForwardIterator, typename ItemToRankMap >
+void bucket_sort(ForwardIterator begin, ForwardIterator end, ItemToRankMap rank)
+{
+ bucket_sort(begin, end, rank, 0);
+}
+
+template < typename ForwardIterator >
+void bucket_sort(ForwardIterator begin, ForwardIterator end)
+{
+ bucket_sort(begin, end, identity_property_map());
+}
+
+} // namespace boost
+
+#endif //__BUCKET_SORT_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/planar_detail/face_handles.hpp b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/face_handles.hpp
new file mode 100644
index 0000000000..1ea7efcb46
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/face_handles.hpp
@@ -0,0 +1,453 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef __FACE_HANDLES_HPP__
+#define __FACE_HANDLES_HPP__
+
+#include <list>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/shared_ptr.hpp>
+
+// A "face handle" is an optimization meant to serve two purposes in
+// the implementation of the Boyer-Myrvold planarity test: (1) it holds
+// the partial planar embedding of a particular vertex as it's being
+// constructed, and (2) it allows for efficient traversal around the
+// outer face of the partial embedding at that particular vertex. A face
+// handle is lightweight, just a shared pointer to the actual implementation,
+// since it is passed around/copied liberally in the algorithm. It consists
+// of an "anchor" (the actual vertex it's associated with) as well as a
+// sequence of edges. The functions first_vertex/second_vertex and
+// first_edge/second_edge allow fast access to the beginning and end of the
+// stored sequence, which allows one to traverse the outer face of the partial
+// planar embedding as it's being created.
+//
+// There are some policies below that define the contents of the face handles:
+// in the case no embedding is needed (for example, if one just wants to use
+// the Boyer-Myrvold algorithm as a true/false test for planarity, the
+// no_embedding class can be passed as the StoreEmbedding policy. Otherwise,
+// either std_list (which uses as std::list) or recursive_lazy_list can be
+// passed as this policy. recursive_lazy_list has the best theoretical
+// performance (O(n) for a sequence of interleaved concatenations and reversals
+// of the underlying list), but I've noticed little difference between std_list
+// and recursive_lazy_list in my tests, even though using std_list changes
+// the worst-case complexity of the planarity test to O(n^2)
+//
+// Another policy is StoreOldHandlesPolicy, which specifies whether or not
+// to keep a record of the previous first/second vertex/edge - this is needed
+// if a Kuratowski subgraph needs to be isolated.
+
+namespace boost
+{
+namespace graph
+{
+ namespace detail
+ {
+
+ // face handle policies
+
+ // EmbeddingStorage policy
+ struct store_embedding
+ {
+ };
+ struct recursive_lazy_list : public store_embedding
+ {
+ };
+ struct std_list : public store_embedding
+ {
+ };
+ struct no_embedding
+ {
+ };
+
+ // StoreOldHandlesPolicy
+ struct store_old_handles
+ {
+ };
+ struct no_old_handles
+ {
+ };
+
+ template < typename DataType > struct lazy_list_node
+ {
+ typedef shared_ptr< lazy_list_node< DataType > > ptr_t;
+
+ lazy_list_node(const DataType& data)
+ : m_reversed(false), m_data(data), m_has_data(true)
+ {
+ }
+
+ lazy_list_node(ptr_t left_child, ptr_t right_child)
+ : m_reversed(false)
+ , m_has_data(false)
+ , m_left_child(left_child)
+ , m_right_child(right_child)
+ {
+ }
+
+ bool m_reversed;
+ DataType m_data;
+ bool m_has_data;
+ shared_ptr< lazy_list_node > m_left_child;
+ shared_ptr< lazy_list_node > m_right_child;
+ };
+
+ template < typename StoreOldHandlesPolicy, typename Vertex,
+ typename Edge >
+ struct old_handles_storage;
+
+ template < typename Vertex, typename Edge >
+ struct old_handles_storage< store_old_handles, Vertex, Edge >
+ {
+ Vertex first_vertex;
+ Vertex second_vertex;
+ Edge first_edge;
+ Edge second_edge;
+ };
+
+ template < typename Vertex, typename Edge >
+ struct old_handles_storage< no_old_handles, Vertex, Edge >
+ {
+ };
+
+ template < typename StoreEmbeddingPolicy, typename Edge >
+ struct edge_list_storage;
+
+ template < typename Edge >
+ struct edge_list_storage< no_embedding, Edge >
+ {
+ typedef void type;
+
+ void push_back(Edge) {}
+ void push_front(Edge) {}
+ void reverse() {}
+ void concat_front(edge_list_storage< no_embedding, Edge >) {}
+ void concat_back(edge_list_storage< no_embedding, Edge >) {}
+ template < typename OutputIterator > void get_list(OutputIterator)
+ {
+ }
+ };
+
+ template < typename Edge >
+ struct edge_list_storage< recursive_lazy_list, Edge >
+ {
+ typedef lazy_list_node< Edge > node_type;
+ typedef shared_ptr< node_type > type;
+ type value;
+
+ void push_back(Edge e)
+ {
+ type new_node(new node_type(e));
+ value = type(new node_type(value, new_node));
+ }
+
+ void push_front(Edge e)
+ {
+ type new_node(new node_type(e));
+ value = type(new node_type(new_node, value));
+ }
+
+ void reverse() { value->m_reversed = !value->m_reversed; }
+
+ void concat_front(
+ edge_list_storage< recursive_lazy_list, Edge > other)
+ {
+ value = type(new node_type(other.value, value));
+ }
+
+ void concat_back(
+ edge_list_storage< recursive_lazy_list, Edge > other)
+ {
+ value = type(new node_type(value, other.value));
+ }
+
+ template < typename OutputIterator >
+ void get_list(OutputIterator out)
+ {
+ get_list_helper(out, value);
+ }
+
+ private:
+ template < typename OutputIterator >
+ void get_list_helper(
+ OutputIterator o_itr, type root, bool flipped = false)
+ {
+ if (!root)
+ return;
+
+ if (root->m_has_data)
+ *o_itr = root->m_data;
+
+ if ((flipped && !root->m_reversed)
+ || (!flipped && root->m_reversed))
+ {
+ get_list_helper(o_itr, root->m_right_child, true);
+ get_list_helper(o_itr, root->m_left_child, true);
+ }
+ else
+ {
+ get_list_helper(o_itr, root->m_left_child, false);
+ get_list_helper(o_itr, root->m_right_child, false);
+ }
+ }
+ };
+
+ template < typename Edge > struct edge_list_storage< std_list, Edge >
+ {
+ typedef std::list< Edge > type;
+ type value;
+
+ void push_back(Edge e) { value.push_back(e); }
+
+ void push_front(Edge e) { value.push_front(e); }
+
+ void reverse() { value.reverse(); }
+
+ void concat_front(edge_list_storage< std_list, Edge > other)
+ {
+ value.splice(value.begin(), other.value);
+ }
+
+ void concat_back(edge_list_storage< std_list, Edge > other)
+ {
+ value.splice(value.end(), other.value);
+ }
+
+ template < typename OutputIterator >
+ void get_list(OutputIterator out)
+ {
+ std::copy(value.begin(), value.end(), out);
+ }
+ };
+
+ template < typename Graph, typename StoreOldHandlesPolicy,
+ typename StoreEmbeddingPolicy >
+ struct face_handle_impl
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef
+ typename edge_list_storage< StoreEmbeddingPolicy, edge_t >::type
+ edge_list_storage_t;
+
+ face_handle_impl()
+ : cached_first_vertex(graph_traits< Graph >::null_vertex())
+ , cached_second_vertex(graph_traits< Graph >::null_vertex())
+ , true_first_vertex(graph_traits< Graph >::null_vertex())
+ , true_second_vertex(graph_traits< Graph >::null_vertex())
+ , anchor(graph_traits< Graph >::null_vertex())
+ {
+ initialize_old_vertices_dispatch(StoreOldHandlesPolicy());
+ }
+
+ void initialize_old_vertices_dispatch(store_old_handles)
+ {
+ old_handles.first_vertex = graph_traits< Graph >::null_vertex();
+ old_handles.second_vertex
+ = graph_traits< Graph >::null_vertex();
+ }
+
+ void initialize_old_vertices_dispatch(no_old_handles) {}
+
+ vertex_t cached_first_vertex;
+ vertex_t cached_second_vertex;
+ vertex_t true_first_vertex;
+ vertex_t true_second_vertex;
+ vertex_t anchor;
+ edge_t cached_first_edge;
+ edge_t cached_second_edge;
+
+ edge_list_storage< StoreEmbeddingPolicy, edge_t > edge_list;
+ old_handles_storage< StoreOldHandlesPolicy, vertex_t, edge_t >
+ old_handles;
+ };
+
+ template < typename Graph,
+ typename StoreOldHandlesPolicy = store_old_handles,
+ typename StoreEmbeddingPolicy = recursive_lazy_list >
+ class face_handle
+ {
+ public:
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef face_handle_impl< Graph, StoreOldHandlesPolicy,
+ StoreEmbeddingPolicy >
+ impl_t;
+ typedef face_handle< Graph, StoreOldHandlesPolicy,
+ StoreEmbeddingPolicy >
+ self_t;
+
+ face_handle(vertex_t anchor = graph_traits< Graph >::null_vertex())
+ : pimpl(new impl_t())
+ {
+ pimpl->anchor = anchor;
+ }
+
+ face_handle(vertex_t anchor, edge_t initial_edge, const Graph& g)
+ : pimpl(new impl_t())
+ {
+ vertex_t s(source(initial_edge, g));
+ vertex_t t(target(initial_edge, g));
+ vertex_t other_vertex = s == anchor ? t : s;
+ pimpl->anchor = anchor;
+ pimpl->cached_first_edge = initial_edge;
+ pimpl->cached_second_edge = initial_edge;
+ pimpl->cached_first_vertex = other_vertex;
+ pimpl->cached_second_vertex = other_vertex;
+ pimpl->true_first_vertex = other_vertex;
+ pimpl->true_second_vertex = other_vertex;
+
+ pimpl->edge_list.push_back(initial_edge);
+ store_old_face_handles_dispatch(StoreOldHandlesPolicy());
+ }
+
+ // default copy construction, assignment okay.
+
+ void push_first(edge_t e, const Graph& g)
+ {
+ pimpl->edge_list.push_front(e);
+ pimpl->cached_first_vertex = pimpl->true_first_vertex
+ = source(e, g) == pimpl->anchor ? target(e, g)
+ : source(e, g);
+ pimpl->cached_first_edge = e;
+ }
+
+ void push_second(edge_t e, const Graph& g)
+ {
+ pimpl->edge_list.push_back(e);
+ pimpl->cached_second_vertex = pimpl->true_second_vertex
+ = source(e, g) == pimpl->anchor ? target(e, g)
+ : source(e, g);
+ pimpl->cached_second_edge = e;
+ }
+
+ inline void store_old_face_handles()
+ {
+ store_old_face_handles_dispatch(StoreOldHandlesPolicy());
+ }
+
+ inline vertex_t first_vertex() const
+ {
+ return pimpl->cached_first_vertex;
+ }
+
+ inline vertex_t second_vertex() const
+ {
+ return pimpl->cached_second_vertex;
+ }
+
+ inline vertex_t true_first_vertex() const
+ {
+ return pimpl->true_first_vertex;
+ }
+
+ inline vertex_t true_second_vertex() const
+ {
+ return pimpl->true_second_vertex;
+ }
+
+ inline vertex_t old_first_vertex() const
+ {
+ return pimpl->old_handles.first_vertex;
+ }
+
+ inline vertex_t old_second_vertex() const
+ {
+ return pimpl->old_handles.second_vertex;
+ }
+
+ inline edge_t old_first_edge() const
+ {
+ return pimpl->old_handles.first_edge;
+ }
+
+ inline edge_t old_second_edge() const
+ {
+ return pimpl->old_handles.second_edge;
+ }
+
+ inline edge_t first_edge() const
+ {
+ return pimpl->cached_first_edge;
+ }
+
+ inline edge_t second_edge() const
+ {
+ return pimpl->cached_second_edge;
+ }
+
+ inline vertex_t get_anchor() const { return pimpl->anchor; }
+
+ void glue_first_to_second(face_handle< Graph, StoreOldHandlesPolicy,
+ StoreEmbeddingPolicy >& bottom)
+ {
+ pimpl->edge_list.concat_front(bottom.pimpl->edge_list);
+ pimpl->true_first_vertex = bottom.pimpl->true_first_vertex;
+ pimpl->cached_first_vertex = bottom.pimpl->cached_first_vertex;
+ pimpl->cached_first_edge = bottom.pimpl->cached_first_edge;
+ }
+
+ void glue_second_to_first(face_handle< Graph, StoreOldHandlesPolicy,
+ StoreEmbeddingPolicy >& bottom)
+ {
+ pimpl->edge_list.concat_back(bottom.pimpl->edge_list);
+ pimpl->true_second_vertex = bottom.pimpl->true_second_vertex;
+ pimpl->cached_second_vertex
+ = bottom.pimpl->cached_second_vertex;
+ pimpl->cached_second_edge = bottom.pimpl->cached_second_edge;
+ }
+
+ void flip()
+ {
+ pimpl->edge_list.reverse();
+ std::swap(pimpl->true_first_vertex, pimpl->true_second_vertex);
+ std::swap(
+ pimpl->cached_first_vertex, pimpl->cached_second_vertex);
+ std::swap(pimpl->cached_first_edge, pimpl->cached_second_edge);
+ }
+
+ template < typename OutputIterator >
+ void get_list(OutputIterator o_itr)
+ {
+ pimpl->edge_list.get_list(o_itr);
+ }
+
+ void reset_vertex_cache()
+ {
+ pimpl->cached_first_vertex = pimpl->true_first_vertex;
+ pimpl->cached_second_vertex = pimpl->true_second_vertex;
+ }
+
+ inline void set_first_vertex(vertex_t v)
+ {
+ pimpl->cached_first_vertex = v;
+ }
+
+ inline void set_second_vertex(vertex_t v)
+ {
+ pimpl->cached_second_vertex = v;
+ }
+
+ private:
+ void store_old_face_handles_dispatch(store_old_handles)
+ {
+ pimpl->old_handles.first_vertex = pimpl->true_first_vertex;
+ pimpl->old_handles.second_vertex = pimpl->true_second_vertex;
+ pimpl->old_handles.first_edge = pimpl->cached_first_edge;
+ pimpl->old_handles.second_edge = pimpl->cached_second_edge;
+ }
+
+ void store_old_face_handles_dispatch(no_old_handles) {}
+
+ boost::shared_ptr< impl_t > pimpl;
+ };
+
+ } /* namespace detail */
+} /* namespace graph */
+} /* namespace boost */
+
+#endif //__FACE_HANDLES_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/planar_detail/face_iterators.hpp b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/face_iterators.hpp
new file mode 100644
index 0000000000..f1a1c333ce
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/planar_detail/face_iterators.hpp
@@ -0,0 +1,332 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef __FACE_ITERATORS_HPP__
+#define __FACE_ITERATORS_HPP__
+
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/graph/graph_traits.hpp>
+
+namespace boost
+{
+
+// tags for defining traversal properties
+
+// VisitorType
+struct lead_visitor
+{
+};
+struct follow_visitor
+{
+};
+
+// TraversalType
+struct single_side
+{
+};
+struct both_sides
+{
+};
+
+// TraversalSubType
+struct first_side
+{
+}; // for single_side
+struct second_side
+{
+}; // for single_side
+struct alternating
+{
+}; // for both_sides
+
+// Time
+struct current_iteration
+{
+};
+struct previous_iteration
+{
+};
+
+// Why TraversalType AND TraversalSubType? TraversalSubType is a function
+// template parameter passed in to the constructor of the face iterator,
+// whereas TraversalType is a class template parameter. This lets us decide
+// at runtime whether to move along the first or second side of a bicomp (by
+// assigning a face_iterator that has been constructed with TraversalSubType
+// = first_side or second_side to a face_iterator variable) without any of
+// the virtual function overhead that comes with implementing this
+// functionality as a more structured form of type erasure. It also allows
+// a single face_iterator to be the end iterator of two iterators traversing
+// both sides of a bicomp.
+
+// ValueType is either graph_traits<Graph>::vertex_descriptor
+// or graph_traits<Graph>::edge_descriptor
+
+// forward declaration (defining defaults)
+template < typename Graph, typename FaceHandlesMap, typename ValueType,
+ typename BicompSideToTraverse = single_side,
+ typename VisitorType = lead_visitor, typename Time = current_iteration >
+class face_iterator;
+
+template < typename Graph, bool StoreEdge > struct edge_storage
+{
+};
+
+template < typename Graph > struct edge_storage< Graph, true >
+{
+ typename graph_traits< Graph >::edge_descriptor value;
+};
+
+// specialization for TraversalType = traverse_vertices
+template < typename Graph, typename FaceHandlesMap, typename ValueType,
+ typename TraversalType, typename VisitorType, typename Time >
+
+class face_iterator : public boost::iterator_facade<
+ face_iterator< Graph, FaceHandlesMap, ValueType,
+ TraversalType, VisitorType, Time >,
+ ValueType, boost::forward_traversal_tag, ValueType >
+{
+public:
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef face_iterator< Graph, FaceHandlesMap, ValueType, TraversalType,
+ VisitorType, Time >
+ self;
+ typedef typename FaceHandlesMap::value_type face_handle_t;
+
+ face_iterator()
+ : m_lead(graph_traits< Graph >::null_vertex())
+ , m_follow(graph_traits< Graph >::null_vertex())
+ {
+ }
+
+ template < typename TraversalSubType >
+ face_iterator(face_handle_t anchor_handle, FaceHandlesMap face_handles,
+ TraversalSubType traversal_type)
+ : m_follow(anchor_handle.get_anchor()), m_face_handles(face_handles)
+ {
+ set_lead_dispatch(anchor_handle, traversal_type);
+ }
+
+ template < typename TraversalSubType >
+ face_iterator(vertex_t anchor, FaceHandlesMap face_handles,
+ TraversalSubType traversal_type)
+ : m_follow(anchor), m_face_handles(face_handles)
+ {
+ set_lead_dispatch(m_face_handles[anchor], traversal_type);
+ }
+
+private:
+ friend class boost::iterator_core_access;
+
+ inline vertex_t get_first_vertex(
+ face_handle_t anchor_handle, current_iteration)
+ {
+ return anchor_handle.first_vertex();
+ }
+
+ inline vertex_t get_second_vertex(
+ face_handle_t anchor_handle, current_iteration)
+ {
+ return anchor_handle.second_vertex();
+ }
+
+ inline vertex_t get_first_vertex(
+ face_handle_t anchor_handle, previous_iteration)
+ {
+ return anchor_handle.old_first_vertex();
+ }
+
+ inline vertex_t get_second_vertex(
+ face_handle_t anchor_handle, previous_iteration)
+ {
+ return anchor_handle.old_second_vertex();
+ }
+
+ inline void set_lead_dispatch(face_handle_t anchor_handle, first_side)
+ {
+ m_lead = get_first_vertex(anchor_handle, Time());
+ set_edge_to_first_dispatch(anchor_handle, ValueType(), Time());
+ }
+
+ inline void set_lead_dispatch(face_handle_t anchor_handle, second_side)
+ {
+ m_lead = get_second_vertex(anchor_handle, Time());
+ set_edge_to_second_dispatch(anchor_handle, ValueType(), Time());
+ }
+
+ inline void set_edge_to_first_dispatch(
+ face_handle_t anchor_handle, edge_t, current_iteration)
+ {
+ m_edge.value = anchor_handle.first_edge();
+ }
+
+ inline void set_edge_to_second_dispatch(
+ face_handle_t anchor_handle, edge_t, current_iteration)
+ {
+ m_edge.value = anchor_handle.second_edge();
+ }
+
+ inline void set_edge_to_first_dispatch(
+ face_handle_t anchor_handle, edge_t, previous_iteration)
+ {
+ m_edge.value = anchor_handle.old_first_edge();
+ }
+
+ inline void set_edge_to_second_dispatch(
+ face_handle_t anchor_handle, edge_t, previous_iteration)
+ {
+ m_edge.value = anchor_handle.old_second_edge();
+ }
+
+ template < typename T >
+ inline void set_edge_to_first_dispatch(face_handle_t, vertex_t, T)
+ {
+ }
+
+ template < typename T >
+ inline void set_edge_to_second_dispatch(face_handle_t, vertex_t, T)
+ {
+ }
+
+ void increment()
+ {
+ face_handle_t curr_face_handle(m_face_handles[m_lead]);
+ vertex_t first = get_first_vertex(curr_face_handle, Time());
+ vertex_t second = get_second_vertex(curr_face_handle, Time());
+ if (first == m_follow)
+ {
+ m_follow = m_lead;
+ set_edge_to_second_dispatch(curr_face_handle, ValueType(), Time());
+ m_lead = second;
+ }
+ else if (second == m_follow)
+ {
+ m_follow = m_lead;
+ set_edge_to_first_dispatch(curr_face_handle, ValueType(), Time());
+ m_lead = first;
+ }
+ else
+ m_lead = m_follow = graph_traits< Graph >::null_vertex();
+ }
+
+ bool equal(self const& other) const
+ {
+ return m_lead == other.m_lead && m_follow == other.m_follow;
+ }
+
+ ValueType dereference() const
+ {
+ return dereference_dispatch(VisitorType(), ValueType());
+ }
+
+ inline ValueType dereference_dispatch(lead_visitor, vertex_t) const
+ {
+ return m_lead;
+ }
+
+ inline ValueType dereference_dispatch(follow_visitor, vertex_t) const
+ {
+ return m_follow;
+ }
+
+ inline ValueType dereference_dispatch(lead_visitor, edge_t) const
+ {
+ return m_edge.value;
+ }
+
+ inline ValueType dereference_dispatch(follow_visitor, edge_t) const
+ {
+ return m_edge.value;
+ }
+
+ vertex_t m_lead;
+ vertex_t m_follow;
+ edge_storage< Graph, boost::is_same< ValueType, edge_t >::value > m_edge;
+ FaceHandlesMap m_face_handles;
+};
+
+template < typename Graph, typename FaceHandlesMap, typename ValueType,
+ typename VisitorType, typename Time >
+class face_iterator< Graph, FaceHandlesMap, ValueType, both_sides, VisitorType,
+ Time >
+: public boost::iterator_facade< face_iterator< Graph, FaceHandlesMap,
+ ValueType, both_sides, VisitorType, Time >,
+ ValueType, boost::forward_traversal_tag, ValueType >
+{
+public:
+ typedef face_iterator< Graph, FaceHandlesMap, ValueType, both_sides,
+ VisitorType, Time >
+ self;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename FaceHandlesMap::value_type face_handle_t;
+
+ face_iterator() {}
+
+ face_iterator(face_handle_t anchor_handle, FaceHandlesMap face_handles)
+ : first_itr(anchor_handle, face_handles, first_side())
+ , second_itr(anchor_handle, face_handles, second_side())
+ , first_is_active(true)
+ , first_increment(true)
+ {
+ }
+
+ face_iterator(vertex_t anchor, FaceHandlesMap face_handles)
+ : first_itr(face_handles[anchor], face_handles, first_side())
+ , second_itr(face_handles[anchor], face_handles, second_side())
+ , first_is_active(true)
+ , first_increment(true)
+ {
+ }
+
+private:
+ friend class boost::iterator_core_access;
+
+ typedef face_iterator< Graph, FaceHandlesMap, ValueType, single_side,
+ follow_visitor, Time >
+ inner_itr_t;
+
+ void increment()
+ {
+ if (first_increment)
+ {
+ ++first_itr;
+ ++second_itr;
+ first_increment = false;
+ }
+ else if (first_is_active)
+ ++first_itr;
+ else
+ ++second_itr;
+ first_is_active = !first_is_active;
+ }
+
+ bool equal(self const& other) const
+ {
+ // Want this iterator to be equal to the "end" iterator when at least
+ // one of the iterators has reached the root of the current bicomp.
+ // This isn't ideal, but it works.
+
+ return (first_itr == other.first_itr || second_itr == other.second_itr);
+ }
+
+ ValueType dereference() const
+ {
+ return first_is_active ? *first_itr : *second_itr;
+ }
+
+ inner_itr_t first_itr;
+ inner_itr_t second_itr;
+ inner_itr_t face_end;
+ bool first_is_active;
+ bool first_increment;
+};
+
+} /* namespace boost */
+
+#endif //__FACE_ITERATORS_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/planar_face_traversal.hpp b/contrib/restricted/boost/graph/include/boost/graph/planar_face_traversal.hpp
new file mode 100644
index 0000000000..00e5b3895a
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/planar_face_traversal.hpp
@@ -0,0 +1,178 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef __PLANAR_FACE_TRAVERSAL_HPP__
+#define __PLANAR_FACE_TRAVERSAL_HPP__
+
+#include <vector>
+#include <set>
+#include <map>
+#include <boost/next_prior.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+
+namespace boost
+{
+
+struct planar_face_traversal_visitor
+{
+ void begin_traversal() {}
+
+ void begin_face() {}
+
+ template < typename Edge > void next_edge(Edge) {}
+
+ template < typename Vertex > void next_vertex(Vertex) {}
+
+ void end_face() {}
+
+ void end_traversal() {}
+};
+
+template < typename Graph, typename PlanarEmbedding, typename Visitor,
+ typename EdgeIndexMap >
+void planar_face_traversal(const Graph& g, PlanarEmbedding embedding,
+ Visitor& visitor, EdgeIndexMap em)
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+ typedef typename property_traits< PlanarEmbedding >::value_type
+ embedding_value_t;
+ typedef typename embedding_value_t::const_iterator embedding_iterator_t;
+
+ typedef typename std::vector< std::set< vertex_t > >
+ distinguished_edge_storage_t;
+ typedef typename std::vector< std::map< vertex_t, edge_t > >
+ distinguished_edge_to_edge_storage_t;
+
+ typedef typename boost::iterator_property_map<
+ typename distinguished_edge_storage_t::iterator, EdgeIndexMap >
+ distinguished_edge_map_t;
+
+ typedef typename boost::iterator_property_map<
+ typename distinguished_edge_to_edge_storage_t::iterator, EdgeIndexMap >
+ distinguished_edge_to_edge_map_t;
+
+ distinguished_edge_storage_t visited_vector(num_edges(g));
+ distinguished_edge_to_edge_storage_t next_edge_vector(num_edges(g));
+
+ distinguished_edge_map_t visited(visited_vector.begin(), em);
+ distinguished_edge_to_edge_map_t next_edge(next_edge_vector.begin(), em);
+
+ vertex_iterator_t vi, vi_end;
+ typename std::vector< edge_t >::iterator ei, ei_end;
+ edge_iterator_t fi, fi_end;
+ embedding_iterator_t pi, pi_begin, pi_end;
+
+ visitor.begin_traversal();
+
+ // Initialize the next_edge property map. This map is initialized from the
+ // PlanarEmbedding so that get(next_edge, e)[v] is the edge that comes
+ // after e in the clockwise embedding around vertex v.
+
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+ pi_begin = embedding[v].begin();
+ pi_end = embedding[v].end();
+ for (pi = pi_begin; pi != pi_end; ++pi)
+ {
+ edge_t e(*pi);
+ std::map< vertex_t, edge_t > m = get(next_edge, e);
+ m[v] = boost::next(pi) == pi_end ? *pi_begin : *boost::next(pi);
+ put(next_edge, e, m);
+ }
+ }
+
+ // Take a copy of the edges in the graph here, since we want to accomodate
+ // face traversals that add edges to the graph (for triangulation, in
+ // particular) and don't want to use invalidated edge iterators.
+ // Also, while iterating over all edges in the graph, we single out
+ // any self-loops, which need some special treatment in the face traversal.
+
+ std::vector< edge_t > self_loops;
+ std::vector< edge_t > edges_cache;
+ std::vector< vertex_t > vertices_in_edge;
+
+ for (boost::tie(fi, fi_end) = edges(g); fi != fi_end; ++fi)
+ {
+ edge_t e(*fi);
+ edges_cache.push_back(e);
+ if (source(e, g) == target(e, g))
+ self_loops.push_back(e);
+ }
+
+ // Iterate over all edges in the graph
+ ei_end = edges_cache.end();
+ for (ei = edges_cache.begin(); ei != ei_end; ++ei)
+ {
+
+ edge_t e(*ei);
+ vertices_in_edge.clear();
+ vertices_in_edge.push_back(source(e, g));
+ vertices_in_edge.push_back(target(e, g));
+
+ typename std::vector< vertex_t >::iterator vi, vi_end;
+ vi_end = vertices_in_edge.end();
+
+ // Iterate over both vertices in the current edge
+ for (vi = vertices_in_edge.begin(); vi != vi_end; ++vi)
+ {
+
+ vertex_t v(*vi);
+ std::set< vertex_t > e_visited = get(visited, e);
+ typename std::set< vertex_t >::iterator e_visited_found
+ = e_visited.find(v);
+
+ if (e_visited_found == e_visited.end())
+ visitor.begin_face();
+
+ while (e_visited.find(v) == e_visited.end())
+ {
+ visitor.next_vertex(v);
+ visitor.next_edge(e);
+ e_visited.insert(v);
+ put(visited, e, e_visited);
+ v = source(e, g) == v ? target(e, g) : source(e, g);
+ e = get(next_edge, e)[v];
+ e_visited = get(visited, e);
+ }
+
+ if (e_visited_found == e_visited.end())
+ visitor.end_face();
+ }
+ }
+
+ // Iterate over all self-loops, visiting them once separately
+ // (they've already been visited once, this visitation is for
+ // the "inside" of the self-loop)
+
+ ei_end = self_loops.end();
+ for (ei = self_loops.begin(); ei != ei_end; ++ei)
+ {
+ visitor.begin_face();
+ visitor.next_edge(*ei);
+ visitor.next_vertex(source(*ei, g));
+ visitor.end_face();
+ }
+
+ visitor.end_traversal();
+}
+
+template < typename Graph, typename PlanarEmbedding, typename Visitor >
+inline void planar_face_traversal(
+ const Graph& g, PlanarEmbedding embedding, Visitor& visitor)
+{
+ planar_face_traversal(g, embedding, visitor, get(edge_index, g));
+}
+
+} // namespace boost
+
+#endif //__PLANAR_FACE_TRAVERSAL_HPP__
diff --git a/contrib/restricted/boost/graph/include/boost/graph/plod_generator.hpp b/contrib/restricted/boost/graph/include/boost/graph/plod_generator.hpp
new file mode 100644
index 0000000000..1f22d39190
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/plod_generator.hpp
@@ -0,0 +1,275 @@
+// Copyright 2004-2006 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_PLOD_GENERATOR_HPP
+#define BOOST_GRAPH_PLOD_GENERATOR_HPP
+
+#include <iterator>
+#include <utility>
+#include <boost/random/uniform_int.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <vector>
+#include <map>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/mpl/if.hpp>
+
+namespace boost
+{
+template < typename RandomGenerator > class out_directed_plod_iterator
+{
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::pair< std::size_t, std::size_t > value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef std::ptrdiff_t difference_type;
+
+ out_directed_plod_iterator() : gen(0), at_end(true) {}
+
+ out_directed_plod_iterator(RandomGenerator& gen, std::size_t n,
+ double alpha, double beta, bool allow_self_loops)
+ : gen(&gen)
+ , n(n)
+ , alpha(alpha)
+ , beta(beta)
+ , allow_self_loops(allow_self_loops)
+ , at_end(false)
+ , degree(0)
+ , current(0, 0)
+ {
+ using std::pow;
+
+ uniform_int< std::size_t > x(0, n - 1);
+ std::size_t xv = x(gen);
+ degree = (xv == 0 ? 0 : std::size_t(beta * pow(xv, -alpha)));
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return &current; }
+
+ out_directed_plod_iterator& operator++()
+ {
+ using std::pow;
+
+ uniform_int< std::size_t > x(0, n - 1);
+
+ // Continue stepping through source nodes until the
+ // (out)degree is > 0
+ while (degree == 0)
+ {
+ // Step to the next source node. If we've gone past the
+ // number of nodes we're responsible for, we're done.
+ if (++current.first >= n)
+ {
+ at_end = true;
+ return *this;
+ }
+
+ std::size_t xv = x(*gen);
+ degree = (xv == 0 ? 0 : std::size_t(beta * pow(xv, -alpha)));
+ }
+
+ do
+ {
+ current.second = x(*gen);
+ } while (current.first == current.second && !allow_self_loops);
+ --degree;
+
+ return *this;
+ }
+
+ out_directed_plod_iterator operator++(int)
+ {
+ out_directed_plod_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const out_directed_plod_iterator& other) const
+ {
+ return at_end == other.at_end;
+ }
+
+ bool operator!=(const out_directed_plod_iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ RandomGenerator* gen;
+ std::size_t n;
+ double alpha;
+ double beta;
+ bool allow_self_loops;
+ bool at_end;
+ std::size_t degree;
+ value_type current;
+};
+
+template < typename RandomGenerator > class undirected_plod_iterator
+{
+ typedef std::vector< std::pair< std::size_t, std::size_t > > out_degrees_t;
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< std::size_t, std::size_t > value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef std::ptrdiff_t difference_type;
+
+ undirected_plod_iterator()
+ : gen(0), out_degrees(), degrees_left(0), allow_self_loops(false)
+ {
+ }
+
+ undirected_plod_iterator(RandomGenerator& gen, std::size_t n, double alpha,
+ double beta, bool allow_self_loops = false)
+ : gen(&gen)
+ , n(n)
+ , out_degrees(new out_degrees_t)
+ , degrees_left(0)
+ , allow_self_loops(allow_self_loops)
+ {
+ using std::pow;
+
+ uniform_int< std::size_t > x(0, n - 1);
+ for (std::size_t i = 0; i != n; ++i)
+ {
+ std::size_t xv = x(gen);
+ std::size_t degree
+ = (xv == 0 ? 0 : std::size_t(beta * pow(xv, -alpha)));
+ if (degree == 0)
+ degree = 1;
+ else if (degree >= n)
+ degree = n - 1;
+ out_degrees->push_back(std::make_pair(i, degree));
+ degrees_left += degree;
+ }
+
+ next();
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return &current; }
+
+ undirected_plod_iterator& operator++()
+ {
+ next();
+ return *this;
+ }
+
+ undirected_plod_iterator operator++(int)
+ {
+ undirected_plod_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const undirected_plod_iterator& other) const
+ {
+ return degrees_left == other.degrees_left;
+ }
+
+ bool operator!=(const undirected_plod_iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ void next()
+ {
+ std::size_t source, target;
+ while (true)
+ {
+ /* We may get to the point where we can't actually find any
+ new edges, so we just add some random edge and set the
+ degrees left = 0 to signal termination. */
+ if (out_degrees->size() < 2)
+ {
+ uniform_int< std::size_t > x(0, n - 1);
+ current.first = x(*gen);
+ do
+ {
+ current.second = x(*gen);
+ } while (current.first == current.second && !allow_self_loops);
+ degrees_left = 0;
+ out_degrees->clear();
+ return;
+ }
+
+ uniform_int< std::size_t > x(0, out_degrees->size() - 1);
+
+ // Select source vertex
+ source = x(*gen);
+ if ((*out_degrees)[source].second == 0)
+ {
+ (*out_degrees)[source] = out_degrees->back();
+ out_degrees->pop_back();
+ continue;
+ }
+
+ // Select target vertex
+ target = x(*gen);
+ if ((*out_degrees)[target].second == 0)
+ {
+ (*out_degrees)[target] = out_degrees->back();
+ out_degrees->pop_back();
+ continue;
+ }
+ else if (source != target
+ || (allow_self_loops && (*out_degrees)[source].second > 2))
+ {
+ break;
+ }
+ }
+
+ // Update degree counts
+ --(*out_degrees)[source].second;
+ --degrees_left;
+ --(*out_degrees)[target].second;
+ --degrees_left;
+ current.first = (*out_degrees)[source].first;
+ current.second = (*out_degrees)[target].first;
+ }
+
+ RandomGenerator* gen;
+ std::size_t n;
+ shared_ptr< out_degrees_t > out_degrees;
+ std::size_t degrees_left;
+ bool allow_self_loops;
+ value_type current;
+};
+
+template < typename RandomGenerator, typename Graph >
+class plod_iterator
+: public mpl::if_<
+ is_convertible< typename graph_traits< Graph >::directed_category,
+ directed_tag >,
+ out_directed_plod_iterator< RandomGenerator >,
+ undirected_plod_iterator< RandomGenerator > >::type
+{
+ typedef typename mpl::if_<
+ is_convertible< typename graph_traits< Graph >::directed_category,
+ directed_tag >,
+ out_directed_plod_iterator< RandomGenerator >,
+ undirected_plod_iterator< RandomGenerator > >::type inherited;
+
+public:
+ plod_iterator() : inherited() {}
+
+ plod_iterator(RandomGenerator& gen, std::size_t n, double alpha,
+ double beta, bool allow_self_loops = false)
+ : inherited(gen, n, alpha, beta, allow_self_loops)
+ {
+ }
+};
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_PLOD_GENERATOR_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/point_traits.hpp b/contrib/restricted/boost/graph/include/boost/graph/point_traits.hpp
new file mode 100644
index 0000000000..c81b9ed6f5
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/point_traits.hpp
@@ -0,0 +1,31 @@
+// Copyright 2004, 2005 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_POINT_TRAITS_HPP
+#define BOOST_GRAPH_POINT_TRAITS_HPP
+
+#include <cstddef>
+
+namespace boost
+{
+namespace graph
+{
+
+ template < typename Point > struct point_traits
+ {
+ // The type of each component of the point
+ typedef typename Point::component_type component_type;
+
+ // The number of dimensions in the point
+ static std::size_t dimensions(const Point& point);
+ };
+
+}
+} // end namespace boost::graph
+
+#endif // BOOST_GRAPH_POINT_TRAITS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/prim_minimum_spanning_tree.hpp b/contrib/restricted/boost/graph/include/boost/graph/prim_minimum_spanning_tree.hpp
new file mode 100644
index 0000000000..1f26f2ef54
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/prim_minimum_spanning_tree.hpp
@@ -0,0 +1,84 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_MST_PRIM_HPP
+#define BOOST_GRAPH_MST_PRIM_HPP
+
+#include <functional>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+ // this should be somewhere else in boost...
+ template < class U, class V > struct _project2nd
+ {
+ V operator()(U, V v) const { return v; }
+ };
+}
+
+namespace detail
+{
+
+ // This is Prim's algorithm to calculate the Minimum Spanning Tree
+ // for an undirected graph with weighted edges.
+
+ template < class Graph, class P, class T, class R, class Weight >
+ inline void prim_mst_impl(const Graph& G,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ const bgl_named_params< P, T, R >& params, Weight)
+ {
+ typedef typename property_traits< Weight >::value_type W;
+ std::less< W > compare;
+ detail::_project2nd< W, W > combine;
+ dijkstra_shortest_paths(
+ G, s, params.distance_compare(compare).distance_combine(combine));
+ }
+} // namespace detail
+
+template < class VertexListGraph, class DijkstraVisitor, class PredecessorMap,
+ class DistanceMap, class WeightMap, class IndexMap >
+inline void prim_minimum_spanning_tree(const VertexListGraph& g,
+ typename graph_traits< VertexListGraph >::vertex_descriptor s,
+ PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
+ IndexMap index_map, DijkstraVisitor vis)
+{
+ typedef typename property_traits< WeightMap >::value_type W;
+ std::less< W > compare;
+ detail::_project2nd< W, W > combine;
+ dijkstra_shortest_paths(g, s, predecessor, distance, weight, index_map,
+ compare, combine, (std::numeric_limits< W >::max)(), 0, vis);
+}
+
+template < class VertexListGraph, class PredecessorMap, class P, class T,
+ class R >
+inline void prim_minimum_spanning_tree(const VertexListGraph& g,
+ PredecessorMap p_map, const bgl_named_params< P, T, R >& params)
+{
+ detail::prim_mst_impl(g,
+ choose_param(get_param(params, root_vertex_t()), *vertices(g).first),
+ params.predecessor_map(p_map),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight));
+}
+
+template < class VertexListGraph, class PredecessorMap >
+inline void prim_minimum_spanning_tree(
+ const VertexListGraph& g, PredecessorMap p_map)
+{
+ detail::prim_mst_impl(g, *vertices(g).first,
+ predecessor_map(p_map).weight_map(get(edge_weight, g)),
+ get(edge_weight, g));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_MST_PRIM_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/profile.hpp b/contrib/restricted/boost/graph/include/boost/graph/profile.hpp
new file mode 100644
index 0000000000..c06200cb71
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/profile.hpp
@@ -0,0 +1,44 @@
+//
+//=======================================================================
+// Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch)
+// ETH Zurich, Center of Structure Technologies
+// (https://web.archive.org/web/20050307090307/http://www.structures.ethz.ch/)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_PROFILE_HPP
+#define BOOST_GRAPH_PROFILE_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/detail/numeric_traits.hpp>
+#include <boost/graph/bandwidth.hpp>
+
+namespace boost
+{
+
+template < typename Graph, typename VertexIndexMap >
+typename graph_traits< Graph >::vertices_size_type profile(
+ const Graph& g, VertexIndexMap index)
+{
+ typename graph_traits< Graph >::vertices_size_type b = 0;
+ typename graph_traits< Graph >::vertex_iterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ {
+ b += ith_bandwidth(*i, g, index) + 1;
+ }
+
+ return b;
+}
+
+template < typename Graph >
+typename graph_traits< Graph >::vertices_size_type profile(const Graph& g)
+{
+ return profile(g, get(vertex_index, g));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_PROFILE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/property_iter_range.hpp b/contrib/restricted/boost/graph/include/boost/graph/property_iter_range.hpp
new file mode 100644
index 0000000000..aa8780b37d
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/property_iter_range.hpp
@@ -0,0 +1,120 @@
+
+// (C) Copyright Francois Faure, iMAGIS-GRAVIR / UJF, 2001.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Revision History:
+// 03 May 2001 Jeremy Siek
+// Generalized the property map iterator and moved that
+// part to boost/property_map.hpp. Also modified to
+// differentiate between const/mutable graphs and
+// added a workaround to avoid partial specialization.
+
+// 02 May 2001 Francois Faure
+// Initial version.
+
+#ifndef BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP
+#define BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP
+
+#include <boost/property_map/property_map_iterator.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/same_traits.hpp>
+
+namespace boost
+{
+
+//======================================================================
+// graph property iterator range
+
+template < class Graph, class PropertyTag > class graph_property_iter_range
+{
+ typedef typename property_map< Graph, PropertyTag >::type map_type;
+ typedef
+ typename property_map< Graph, PropertyTag >::const_type const_map_type;
+ typedef typename property_kind< PropertyTag >::type Kind;
+ typedef typename mpl::if_c< is_same< Kind, vertex_property_tag >::value,
+ typename graph_traits< Graph >::vertex_iterator,
+ typename graph_traits< Graph >::edge_iterator >::type iter;
+
+public:
+ typedef typename property_map_iterator_generator< map_type, iter >::type
+ iterator;
+ typedef
+ typename property_map_iterator_generator< const_map_type, iter >::type
+ const_iterator;
+ typedef std::pair< iterator, iterator > type;
+ typedef std::pair< const_iterator, const_iterator > const_type;
+};
+
+namespace detail
+{
+
+ template < class Graph, class Tag >
+ typename graph_property_iter_range< Graph, Tag >::type
+ get_property_iter_range_kind(
+ Graph& graph, const Tag& tag, const vertex_property_tag&)
+ {
+ typedef typename graph_property_iter_range< Graph, Tag >::iterator iter;
+ return std::make_pair(iter(vertices(graph).first, get(tag, graph)),
+ iter(vertices(graph).second, get(tag, graph)));
+ }
+
+ template < class Graph, class Tag >
+ typename graph_property_iter_range< Graph, Tag >::const_type
+ get_property_iter_range_kind(
+ const Graph& graph, const Tag& tag, const vertex_property_tag&)
+ {
+ typedef typename graph_property_iter_range< Graph, Tag >::const_iterator
+ iter;
+ return std::make_pair(iter(vertices(graph).first, get(tag, graph)),
+ iter(vertices(graph).second, get(tag, graph)));
+ }
+
+ template < class Graph, class Tag >
+ typename graph_property_iter_range< Graph, Tag >::type
+ get_property_iter_range_kind(
+ Graph& graph, const Tag& tag, const edge_property_tag&)
+ {
+ typedef typename graph_property_iter_range< Graph, Tag >::iterator iter;
+ return std::make_pair(iter(edges(graph).first, get(tag, graph)),
+ iter(edges(graph).second, get(tag, graph)));
+ }
+
+ template < class Graph, class Tag >
+ typename graph_property_iter_range< Graph, Tag >::const_type
+ get_property_iter_range_kind(
+ const Graph& graph, const Tag& tag, const edge_property_tag&)
+ {
+ typedef typename graph_property_iter_range< Graph, Tag >::const_iterator
+ iter;
+ return std::make_pair(iter(edges(graph).first, get(tag, graph)),
+ iter(edges(graph).second, get(tag, graph)));
+ }
+
+} // namespace detail
+
+//======================================================================
+// get an iterator range of properties
+
+template < class Graph, class Tag >
+typename graph_property_iter_range< Graph, Tag >::type get_property_iter_range(
+ Graph& graph, const Tag& tag)
+{
+ typedef typename property_kind< Tag >::type Kind;
+ return detail::get_property_iter_range_kind(graph, tag, Kind());
+}
+
+template < class Graph, class Tag >
+typename graph_property_iter_range< Graph, Tag >::const_type
+get_property_iter_range(const Graph& graph, const Tag& tag)
+{
+ typedef typename property_kind< Tag >::type Kind;
+ return detail::get_property_iter_range_kind(graph, tag, Kind());
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/property_maps/container_property_map.hpp b/contrib/restricted/boost/graph/include/boost/graph/property_maps/container_property_map.hpp
new file mode 100644
index 0000000000..6a565c2e9d
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/property_maps/container_property_map.hpp
@@ -0,0 +1,70 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_CONTAINER_PROPERTY_MAP_HPP
+#define BOOST_GRAPH_CONTAINER_PROPERTY_MAP_HPP
+
+#include <boost/graph/detail/index.hpp>
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+// This is an adapter built over the iterator property map with
+// more useful uniform construction semantics. Specifically, this
+// requires the container rather than the iterator and the graph
+// rather than the optional index map.
+template < typename Graph, typename Key, typename Container >
+struct container_property_map
+: public boost::put_get_helper<
+ typename iterator_property_map< typename Container::iterator,
+ typename property_map< Graph,
+ typename detail::choose_indexer< Graph,
+ Key >::index_type >::type >::reference,
+ container_property_map< Graph, Key, Container > >
+{
+ typedef typename detail::choose_indexer< Graph, Key >::indexer_type
+ indexer_type;
+ typedef typename indexer_type::index_type index_type;
+ typedef iterator_property_map< typename Container::iterator,
+ typename property_map< Graph, index_type >::type >
+ map_type;
+ typedef typename map_type::key_type key_type;
+ typedef typename map_type::value_type value_type;
+ typedef typename map_type::reference reference;
+ typedef typename map_type::category category;
+
+ // The default constructor will *probably* crash if its actually
+ // used for referencing vertices since the underlying iterator
+ // map points past the end of an unknown container.
+ inline container_property_map() : m_map() {}
+
+ // This is the preferred constructor. It is invoked over the container
+ // and the graph explicitly. This requires that the underlying iterator
+ // map use the indices of the vertices in g rather than the default
+ // identity map.
+ //
+ // Note the const-cast this ensures the reference type of the
+ // vertex index map is non-const, which happens to be an
+ // artifact of passing const graph references.
+ inline container_property_map(Container& c, const Graph& g)
+ : m_map(c.begin(), indexer_type::index_map(const_cast< Graph& >(g)))
+ {
+ }
+
+ // Typical copy constructor.
+ inline container_property_map(const container_property_map& x)
+ : m_map(x.m_map)
+ {
+ }
+
+ // The [] operator delegates to the underlying map/
+ inline reference operator[](const key_type& k) const { return m_map[k]; }
+
+ map_type m_map;
+};
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/property_maps/matrix_property_map.hpp b/contrib/restricted/boost/graph/include/boost/graph/property_maps/matrix_property_map.hpp
new file mode 100644
index 0000000000..f33f137464
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/property_maps/matrix_property_map.hpp
@@ -0,0 +1,68 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_MATRIX_PROPERTY_MAP_HPP
+#define BOOST_GRAPH_MATRIX_PROPERTY_MAP_HPP
+
+#include <boost/graph/property_maps/container_property_map.hpp>
+
+namespace boost
+{
+// This property map is built specifically for property maps over
+// matrices. Like the basic property map over a container, this builds
+// the property abstraction over a matrix (usually a vector of vectors)
+// and returns property maps over the nested containers.
+template < typename Graph, typename Key, typename Matrix >
+struct matrix_property_map
+: boost::put_get_helper<
+ container_property_map< Graph, Key, typename Matrix::value_type >,
+ matrix_property_map< Graph, Key, Matrix > >
+{
+ // abstract the indexing keys
+ typedef typename detail::choose_indexer< Graph, Key >::indexer_type
+ indexer_type;
+
+ // aliases for the nested container and its corresponding map
+ typedef typename Matrix::value_type container_type;
+ typedef container_property_map< Graph, Key, container_type > map_type;
+
+ typedef Key key_type;
+
+ // This property map doesn't really provide access to nested containers,
+ // but returns property maps over them. Since property maps are all
+ // copy-constructible (or should be anyways), we never return references.
+ // As such, this property is only readable, but not writable. Curiously,
+ // the inner property map is actually an lvalue pmap.
+ typedef map_type value_type;
+ typedef map_type reference;
+ typedef readable_property_map_tag category;
+
+ matrix_property_map() : m_matrix(0), m_graph(0) {}
+
+ matrix_property_map(Matrix& m, const Graph& g)
+ : m_matrix(&m), m_graph(const_cast< Graph* >(&g))
+ {
+ }
+
+ matrix_property_map(const matrix_property_map& x)
+ : m_matrix(x.m_matrix), m_graph(x.m_graph)
+ {
+ }
+
+ inline reference operator[](key_type k) const
+ {
+ typedef typename indexer_type::value_type Index;
+ Index x = indexer_type::index(k, *m_graph);
+ return map_type((*m_matrix)[x], *m_graph);
+ }
+
+private:
+ mutable Matrix* m_matrix;
+ mutable Graph* m_graph;
+};
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/push_relabel_max_flow.hpp b/contrib/restricted/boost/graph/include/boost/graph/push_relabel_max_flow.hpp
new file mode 100644
index 0000000000..a243f56487
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/push_relabel_max_flow.hpp
@@ -0,0 +1,860 @@
+//=======================================================================
+// Copyright 2000 University of Notre Dame.
+// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#ifndef BOOST_PUSH_RELABEL_MAX_FLOW_HPP
+#define BOOST_PUSH_RELABEL_MAX_FLOW_HPP
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <vector>
+#include <list>
+#include <iosfwd>
+#include <algorithm> // for std::min and std::max
+
+#include <boost/pending/queue.hpp>
+#include <boost/limits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ // This implementation is based on Goldberg's
+ // "On Implementing Push-Relabel Method for the Maximum Flow Problem"
+ // by B.V. Cherkassky and A.V. Goldberg, IPCO '95, pp. 157--171
+ // and on the h_prf.c and hi_pr.c code written by the above authors.
+
+ // This implements the highest-label version of the push-relabel method
+ // with the global relabeling and gap relabeling heuristics.
+
+ // The terms "rank", "distance", "height" are synonyms in
+ // Goldberg's implementation, paper and in the CLR. A "layer" is a
+ // group of vertices with the same distance. The vertices in each
+ // layer are categorized as active or inactive. An active vertex
+ // has positive excess flow and its distance is less than n (it is
+ // not blocked).
+
+ template < class Vertex > struct preflow_layer
+ {
+ std::list< Vertex > active_vertices;
+ std::list< Vertex > inactive_vertices;
+ };
+
+ template < class Graph,
+ class EdgeCapacityMap, // integer value type
+ class ResidualCapacityEdgeMap, class ReverseEdgeMap,
+ class VertexIndexMap, // vertex_descriptor -> integer
+ class FlowValue >
+ class push_relabel
+ {
+ public:
+ typedef graph_traits< Graph > Traits;
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::edge_descriptor edge_descriptor;
+ typedef typename Traits::vertex_iterator vertex_iterator;
+ typedef typename Traits::out_edge_iterator out_edge_iterator;
+ typedef typename Traits::vertices_size_type vertices_size_type;
+ typedef typename Traits::edges_size_type edges_size_type;
+
+ typedef preflow_layer< vertex_descriptor > Layer;
+ typedef std::vector< Layer > LayerArray;
+ typedef typename LayerArray::iterator layer_iterator;
+ typedef typename LayerArray::size_type distance_size_type;
+
+ typedef color_traits< default_color_type > ColorTraits;
+
+ //=======================================================================
+ // Some helper predicates
+
+ inline bool is_admissible(vertex_descriptor u, vertex_descriptor v)
+ {
+ return get(distance, u) == get(distance, v) + 1;
+ }
+ inline bool is_residual_edge(edge_descriptor a)
+ {
+ return 0 < get(residual_capacity, a);
+ }
+ inline bool is_saturated(edge_descriptor a)
+ {
+ return get(residual_capacity, a) == 0;
+ }
+
+ //=======================================================================
+ // Layer List Management Functions
+
+ typedef typename std::list< vertex_descriptor >::iterator list_iterator;
+
+ void add_to_active_list(vertex_descriptor u, Layer& layer)
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ layer.active_vertices.push_front(u);
+ max_active = max BOOST_PREVENT_MACRO_SUBSTITUTION(
+ get(distance, u), max_active);
+ min_active = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ get(distance, u), min_active);
+ layer_list_ptr[u] = layer.active_vertices.begin();
+ }
+ void remove_from_active_list(vertex_descriptor u)
+ {
+ layers[get(distance, u)].active_vertices.erase(layer_list_ptr[u]);
+ }
+
+ void add_to_inactive_list(vertex_descriptor u, Layer& layer)
+ {
+ layer.inactive_vertices.push_front(u);
+ layer_list_ptr[u] = layer.inactive_vertices.begin();
+ }
+ void remove_from_inactive_list(vertex_descriptor u)
+ {
+ layers[get(distance, u)].inactive_vertices.erase(layer_list_ptr[u]);
+ }
+
+ //=======================================================================
+ // initialization
+ push_relabel(Graph& g_, EdgeCapacityMap cap,
+ ResidualCapacityEdgeMap res, ReverseEdgeMap rev,
+ vertex_descriptor src_, vertex_descriptor sink_, VertexIndexMap idx)
+ : g(g_)
+ , n(num_vertices(g_))
+ , capacity(cap)
+ , src(src_)
+ , sink(sink_)
+ , index(idx)
+ , excess_flow_data(num_vertices(g_))
+ , excess_flow(excess_flow_data.begin(), idx)
+ , current_data(num_vertices(g_), out_edges(*vertices(g_).first, g_))
+ , current(current_data.begin(), idx)
+ , distance_data(num_vertices(g_))
+ , distance(distance_data.begin(), idx)
+ , color_data(num_vertices(g_))
+ , color(color_data.begin(), idx)
+ , reverse_edge(rev)
+ , residual_capacity(res)
+ , layers(num_vertices(g_))
+ , layer_list_ptr_data(
+ num_vertices(g_), layers.front().inactive_vertices.end())
+ , layer_list_ptr(layer_list_ptr_data.begin(), idx)
+ , push_count(0)
+ , update_count(0)
+ , relabel_count(0)
+ , gap_count(0)
+ , gap_node_count(0)
+ , work_since_last_update(0)
+ {
+ vertex_iterator u_iter, u_end;
+ // Don't count the reverse edges
+ edges_size_type m = num_edges(g) / 2;
+ nm = alpha() * n + m;
+
+ // Initialize flow to zero which means initializing
+ // the residual capacity to equal the capacity.
+ out_edge_iterator ei, e_end;
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end;
+ ++ei)
+ {
+ put(residual_capacity, *ei, get(capacity, *ei));
+ }
+
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ {
+ vertex_descriptor u = *u_iter;
+ put(excess_flow, u, 0);
+ current[u] = out_edges(u, g);
+ }
+
+ bool overflow_detected = false;
+ FlowValue test_excess = 0;
+
+ out_edge_iterator a_iter, a_end;
+ for (boost::tie(a_iter, a_end) = out_edges(src, g); a_iter != a_end;
+ ++a_iter)
+ if (target(*a_iter, g) != src)
+ test_excess += get(residual_capacity, *a_iter);
+ if (test_excess > (std::numeric_limits< FlowValue >::max)())
+ overflow_detected = true;
+
+ if (overflow_detected)
+ put(excess_flow, src,
+ (std::numeric_limits< FlowValue >::max)());
+ else
+ {
+ put(excess_flow, src, 0);
+ for (boost::tie(a_iter, a_end) = out_edges(src, g);
+ a_iter != a_end; ++a_iter)
+ {
+ edge_descriptor a = *a_iter;
+ vertex_descriptor tgt = target(a, g);
+ if (tgt != src)
+ {
+ ++push_count;
+ FlowValue delta = get(residual_capacity, a);
+ put(residual_capacity, a,
+ get(residual_capacity, a) - delta);
+ edge_descriptor rev = get(reverse_edge, a);
+ put(residual_capacity, rev,
+ get(residual_capacity, rev) + delta);
+ put(excess_flow, tgt, get(excess_flow, tgt) + delta);
+ }
+ }
+ }
+ max_distance = num_vertices(g) - 1;
+ max_active = 0;
+ min_active = n;
+
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ {
+ vertex_descriptor u = *u_iter;
+ if (u == sink)
+ {
+ put(distance, u, 0);
+ continue;
+ }
+ else if (u == src && !overflow_detected)
+ put(distance, u, n);
+ else
+ put(distance, u, 1);
+
+ if (get(excess_flow, u) > 0)
+ add_to_active_list(u, layers[1]);
+ else if (get(distance, u) < n)
+ add_to_inactive_list(u, layers[1]);
+ }
+
+ } // push_relabel constructor
+
+ //=======================================================================
+ // This is a breadth-first search over the residual graph
+ // (well, actually the reverse of the residual graph).
+ // Would be cool to have a graph view adaptor for hiding certain
+ // edges, like the saturated (non-residual) edges in this case.
+ // Goldberg's implementation abused "distance" for the coloring.
+ void global_distance_update()
+ {
+ BOOST_USING_STD_MAX();
+ ++update_count;
+ vertex_iterator u_iter, u_end;
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ {
+ put(color, *u_iter, ColorTraits::white());
+ put(distance, *u_iter, n);
+ }
+ put(color, sink, ColorTraits::gray());
+ put(distance, sink, 0);
+
+ for (distance_size_type l = 0; l <= max_distance; ++l)
+ {
+ layers[l].active_vertices.clear();
+ layers[l].inactive_vertices.clear();
+ }
+
+ max_distance = max_active = 0;
+ min_active = n;
+
+ Q.push(sink);
+ while (!Q.empty())
+ {
+ vertex_descriptor u = Q.top();
+ Q.pop();
+ distance_size_type d_v = get(distance, u) + 1;
+
+ out_edge_iterator ai, a_end;
+ for (boost::tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai)
+ {
+ edge_descriptor a = *ai;
+ vertex_descriptor v = target(a, g);
+ if (get(color, v) == ColorTraits::white()
+ && is_residual_edge(get(reverse_edge, a)))
+ {
+ put(distance, v, d_v);
+ put(color, v, ColorTraits::gray());
+ current[v] = out_edges(v, g);
+ max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(
+ d_v, max_distance);
+
+ if (get(excess_flow, v) > 0)
+ add_to_active_list(v, layers[d_v]);
+ else
+ add_to_inactive_list(v, layers[d_v]);
+
+ Q.push(v);
+ }
+ }
+ }
+ } // global_distance_update()
+
+ //=======================================================================
+ // This function is called "push" in Goldberg's h_prf implementation,
+ // but it is called "discharge" in the paper and in hi_pr.c.
+ void discharge(vertex_descriptor u)
+ {
+ BOOST_ASSERT(get(excess_flow, u) > 0);
+ while (1)
+ {
+ out_edge_iterator ai, ai_end;
+ for (boost::tie(ai, ai_end) = current[u]; ai != ai_end; ++ai)
+ {
+ edge_descriptor a = *ai;
+ if (is_residual_edge(a))
+ {
+ vertex_descriptor v = target(a, g);
+ if (is_admissible(u, v))
+ {
+ ++push_count;
+ if (v != sink && get(excess_flow, v) == 0)
+ {
+ remove_from_inactive_list(v);
+ add_to_active_list(v, layers[get(distance, v)]);
+ }
+ push_flow(a);
+ if (get(excess_flow, u) == 0)
+ break;
+ }
+ }
+ } // for out_edges of i starting from current
+
+ Layer& layer = layers[get(distance, u)];
+ distance_size_type du = get(distance, u);
+
+ if (ai == ai_end)
+ { // i must be relabeled
+ relabel_distance(u);
+ if (layer.active_vertices.empty()
+ && layer.inactive_vertices.empty())
+ gap(du);
+ if (get(distance, u) == n)
+ break;
+ }
+ else
+ { // i is no longer active
+ current[u].first = ai;
+ add_to_inactive_list(u, layer);
+ break;
+ }
+ } // while (1)
+ } // discharge()
+
+ //=======================================================================
+ // This corresponds to the "push" update operation of the paper,
+ // not the "push" function in Goldberg's h_prf.c implementation.
+ // The idea is to push the excess flow from from vertex u to v.
+ void push_flow(edge_descriptor u_v)
+ {
+ vertex_descriptor u = source(u_v, g), v = target(u_v, g);
+
+ BOOST_USING_STD_MIN();
+ FlowValue flow_delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ get(excess_flow, u), get(residual_capacity, u_v));
+
+ put(residual_capacity, u_v,
+ get(residual_capacity, u_v) - flow_delta);
+ edge_descriptor rev = get(reverse_edge, u_v);
+ put(residual_capacity, rev,
+ get(residual_capacity, rev) + flow_delta);
+
+ put(excess_flow, u, get(excess_flow, u) - flow_delta);
+ put(excess_flow, v, get(excess_flow, v) + flow_delta);
+ } // push_flow()
+
+ //=======================================================================
+ // The main purpose of this routine is to set distance[v]
+ // to the smallest value allowed by the valid labeling constraints,
+ // which are:
+ // distance[t] = 0
+ // distance[u] <= distance[v] + 1 for every residual edge (u,v)
+ //
+ distance_size_type relabel_distance(vertex_descriptor u)
+ {
+ BOOST_USING_STD_MAX();
+ ++relabel_count;
+ work_since_last_update += beta();
+
+ distance_size_type min_distance = num_vertices(g);
+ put(distance, u, min_distance);
+
+ // Examine the residual out-edges of vertex i, choosing the
+ // edge whose target vertex has the minimal distance.
+ out_edge_iterator ai, a_end, min_edge_iter;
+ for (boost::tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai)
+ {
+ ++work_since_last_update;
+ edge_descriptor a = *ai;
+ vertex_descriptor v = target(a, g);
+ if (is_residual_edge(a) && get(distance, v) < min_distance)
+ {
+ min_distance = get(distance, v);
+ min_edge_iter = ai;
+ }
+ }
+ ++min_distance;
+ if (min_distance < n)
+ {
+ put(distance, u, min_distance); // this is the main action
+ current[u].first = min_edge_iter;
+ max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(
+ min_distance, max_distance);
+ }
+ return min_distance;
+ } // relabel_distance()
+
+ //=======================================================================
+ // cleanup beyond the gap
+ void gap(distance_size_type empty_distance)
+ {
+ ++gap_count;
+
+ distance_size_type r; // distance of layer before the current layer
+ r = empty_distance - 1;
+
+ // Set the distance for the vertices beyond the gap to "infinity".
+ for (layer_iterator l = layers.begin() + empty_distance + 1;
+ l < layers.begin() + max_distance; ++l)
+ {
+ list_iterator i;
+ for (i = l->inactive_vertices.begin();
+ i != l->inactive_vertices.end(); ++i)
+ {
+ put(distance, *i, n);
+ ++gap_node_count;
+ }
+ l->inactive_vertices.clear();
+ }
+ max_distance = r;
+ max_active = r;
+ }
+
+ //=======================================================================
+ // This is the core part of the algorithm, "phase one".
+ FlowValue maximum_preflow()
+ {
+ work_since_last_update = 0;
+
+ while (max_active >= min_active)
+ { // "main" loop
+
+ Layer& layer = layers[max_active];
+ list_iterator u_iter = layer.active_vertices.begin();
+
+ if (u_iter == layer.active_vertices.end())
+ --max_active;
+ else
+ {
+ vertex_descriptor u = *u_iter;
+ remove_from_active_list(u);
+
+ discharge(u);
+
+ if (work_since_last_update * global_update_frequency() > nm)
+ {
+ global_distance_update();
+ work_since_last_update = 0;
+ }
+ }
+ } // while (max_active >= min_active)
+
+ return get(excess_flow, sink);
+ } // maximum_preflow()
+
+ //=======================================================================
+ // remove excess flow, the "second phase"
+ // This does a DFS on the reverse flow graph of nodes with excess flow.
+ // If a cycle is found, cancel it.
+ // Return the nodes with excess flow in topological order.
+ //
+ // Unlike the prefl_to_flow() implementation, we use
+ // "color" instead of "distance" for the DFS labels
+ // "parent" instead of nl_prev for the DFS tree
+ // "topo_next" instead of nl_next for the topological ordering
+ void convert_preflow_to_flow()
+ {
+ vertex_iterator u_iter, u_end;
+ out_edge_iterator ai, a_end;
+
+ vertex_descriptor r, restart, u;
+
+ std::vector< vertex_descriptor > parent(n);
+ std::vector< vertex_descriptor > topo_next(n);
+
+ vertex_descriptor tos(parent[0]),
+ bos(parent[0]); // bogus initialization, just to avoid warning
+ bool bos_null = true;
+
+ // handle self-loops
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ for (boost::tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end;
+ ++ai)
+ if (target(*ai, g) == *u_iter)
+ put(residual_capacity, *ai, get(capacity, *ai));
+
+ // initialize
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ {
+ u = *u_iter;
+ put(color, u, ColorTraits::white());
+ parent[get(index, u)] = u;
+ current[u] = out_edges(u, g);
+ }
+ // eliminate flow cycles and topologically order the vertices
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ {
+ u = *u_iter;
+ if (get(color, u) == ColorTraits::white()
+ && get(excess_flow, u) > 0 && u != src && u != sink)
+ {
+ r = u;
+ put(color, r, ColorTraits::gray());
+ while (1)
+ {
+ for (; current[u].first != current[u].second;
+ ++current[u].first)
+ {
+ edge_descriptor a = *current[u].first;
+ if (get(capacity, a) == 0 && is_residual_edge(a))
+ {
+ vertex_descriptor v = target(a, g);
+ if (get(color, v) == ColorTraits::white())
+ {
+ put(color, v, ColorTraits::gray());
+ parent[get(index, v)] = u;
+ u = v;
+ break;
+ }
+ else if (get(color, v) == ColorTraits::gray())
+ {
+ // find minimum flow on the cycle
+ FlowValue delta = get(residual_capacity, a);
+ while (1)
+ {
+ BOOST_USING_STD_MIN();
+ delta = min
+ BOOST_PREVENT_MACRO_SUBSTITUTION(
+ delta,
+ get(residual_capacity,
+ *current[v].first));
+ if (v == u)
+ break;
+ else
+ v = target(*current[v].first, g);
+ }
+ // remove delta flow units
+ v = u;
+ while (1)
+ {
+ a = *current[v].first;
+ put(residual_capacity, a,
+ get(residual_capacity, a) - delta);
+ edge_descriptor rev
+ = get(reverse_edge, a);
+ put(residual_capacity, rev,
+ get(residual_capacity, rev)
+ + delta);
+ v = target(a, g);
+ if (v == u)
+ break;
+ }
+
+ // back-out of DFS to the first saturated
+ // edge
+ restart = u;
+ for (v = target(*current[u].first, g);
+ v != u; v = target(a, g))
+ {
+ a = *current[v].first;
+ if (get(color, v)
+ == ColorTraits::white()
+ || is_saturated(a))
+ {
+ put(color,
+ target(*current[v].first, g),
+ ColorTraits::white());
+ if (get(color, v)
+ != ColorTraits::white())
+ restart = v;
+ }
+ }
+ if (restart != u)
+ {
+ u = restart;
+ ++current[u].first;
+ break;
+ }
+ } // else if (color[v] == ColorTraits::gray())
+ } // if (get(capacity, a) == 0 ...
+ } // for out_edges(u, g) (though "u" changes during
+ // loop)
+
+ if (current[u].first == current[u].second)
+ {
+ // scan of i is complete
+ put(color, u, ColorTraits::black());
+ if (u != src)
+ {
+ if (bos_null)
+ {
+ bos = u;
+ bos_null = false;
+ tos = u;
+ }
+ else
+ {
+ topo_next[get(index, u)] = tos;
+ tos = u;
+ }
+ }
+ if (u != r)
+ {
+ u = parent[get(index, u)];
+ ++current[u].first;
+ }
+ else
+ break;
+ }
+ } // while (1)
+ } // if (color[u] == white && excess_flow[u] > 0 & ...)
+ } // for all vertices in g
+
+ // return excess flows
+ // note that the sink is not on the stack
+ if (!bos_null)
+ {
+ for (u = tos; u != bos; u = topo_next[get(index, u)])
+ {
+ boost::tie(ai, a_end) = out_edges(u, g);
+ while (get(excess_flow, u) > 0 && ai != a_end)
+ {
+ if (get(capacity, *ai) == 0 && is_residual_edge(*ai))
+ push_flow(*ai);
+ ++ai;
+ }
+ }
+ // do the bottom
+ u = bos;
+ boost::tie(ai, a_end) = out_edges(u, g);
+ while (get(excess_flow, u) > 0 && ai != a_end)
+ {
+ if (get(capacity, *ai) == 0 && is_residual_edge(*ai))
+ push_flow(*ai);
+ ++ai;
+ }
+ }
+
+ } // convert_preflow_to_flow()
+
+ //=======================================================================
+ inline bool is_flow()
+ {
+ vertex_iterator u_iter, u_end;
+ out_edge_iterator ai, a_end;
+
+ // check edge flow values
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ {
+ for (boost::tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end;
+ ++ai)
+ {
+ edge_descriptor a = *ai;
+ if (get(capacity, a) > 0)
+ if ((get(residual_capacity, a)
+ + get(
+ residual_capacity, get(reverse_edge, a))
+ != get(capacity, a)
+ + get(capacity, get(reverse_edge, a)))
+ || (get(residual_capacity, a) < 0)
+ || (get(residual_capacity, get(reverse_edge, a))
+ < 0))
+ return false;
+ }
+ }
+
+ // check conservation
+ FlowValue sum;
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ {
+ vertex_descriptor u = *u_iter;
+ if (u != src && u != sink)
+ {
+ if (get(excess_flow, u) != 0)
+ return false;
+ sum = 0;
+ for (boost::tie(ai, a_end) = out_edges(u, g); ai != a_end;
+ ++ai)
+ if (get(capacity, *ai) > 0)
+ sum -= get(capacity, *ai)
+ - get(residual_capacity, *ai);
+ else
+ sum += get(residual_capacity, *ai);
+
+ if (get(excess_flow, u) != sum)
+ return false;
+ }
+ }
+
+ return true;
+ } // is_flow()
+
+ bool is_optimal()
+ {
+ // check if mincut is saturated...
+ global_distance_update();
+ return get(distance, src) >= n;
+ }
+
+ void print_statistics(std::ostream& os) const
+ {
+ os << "pushes: " << push_count << std::endl
+ << "relabels: " << relabel_count << std::endl
+ << "updates: " << update_count << std::endl
+ << "gaps: " << gap_count << std::endl
+ << "gap nodes: " << gap_node_count << std::endl
+ << std::endl;
+ }
+
+ void print_flow_values(std::ostream& os) const
+ {
+ os << "flow values" << std::endl;
+ vertex_iterator u_iter, u_end;
+ out_edge_iterator ei, e_end;
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end;
+ ++u_iter)
+ for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end;
+ ++ei)
+ if (get(capacity, *ei) > 0)
+ os << *u_iter << " " << target(*ei, g) << " "
+ << (get(capacity, *ei) - get(residual_capacity, *ei))
+ << std::endl;
+ os << std::endl;
+ }
+
+ //=======================================================================
+
+ Graph& g;
+ vertices_size_type n;
+ vertices_size_type nm;
+ EdgeCapacityMap capacity;
+ vertex_descriptor src;
+ vertex_descriptor sink;
+ VertexIndexMap index;
+
+ // will need to use random_access_property_map with these
+ std::vector< FlowValue > excess_flow_data;
+ iterator_property_map< typename std::vector< FlowValue >::iterator,
+ VertexIndexMap >
+ excess_flow;
+ std::vector< std::pair< out_edge_iterator, out_edge_iterator > >
+ current_data;
+ iterator_property_map<
+ typename std::vector<
+ std::pair< out_edge_iterator, out_edge_iterator > >::iterator,
+ VertexIndexMap >
+ current;
+ std::vector< distance_size_type > distance_data;
+ iterator_property_map<
+ typename std::vector< distance_size_type >::iterator,
+ VertexIndexMap >
+ distance;
+ std::vector< default_color_type > color_data;
+ iterator_property_map< std::vector< default_color_type >::iterator,
+ VertexIndexMap >
+ color;
+
+ // Edge Property Maps that must be interior to the graph
+ ReverseEdgeMap reverse_edge;
+ ResidualCapacityEdgeMap residual_capacity;
+
+ LayerArray layers;
+ std::vector< list_iterator > layer_list_ptr_data;
+ iterator_property_map< typename std::vector< list_iterator >::iterator,
+ VertexIndexMap >
+ layer_list_ptr;
+ distance_size_type max_distance; // maximal distance
+ distance_size_type max_active; // maximal distance with active node
+ distance_size_type min_active; // minimal distance with active node
+ boost::queue< vertex_descriptor > Q;
+
+ // Statistics counters
+ long push_count;
+ long update_count;
+ long relabel_count;
+ long gap_count;
+ long gap_node_count;
+
+ inline double global_update_frequency() { return 0.5; }
+ inline vertices_size_type alpha() { return 6; }
+ inline long beta() { return 12; }
+
+ long work_since_last_update;
+ };
+
+} // namespace detail
+
+template < class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap,
+ class ReverseEdgeMap, class VertexIndexMap >
+typename property_traits< CapacityEdgeMap >::value_type push_relabel_max_flow(
+ Graph& g, typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink, CapacityEdgeMap cap,
+ ResidualCapacityEdgeMap res, ReverseEdgeMap rev, VertexIndexMap index_map)
+{
+ typedef typename property_traits< CapacityEdgeMap >::value_type FlowValue;
+
+ detail::push_relabel< Graph, CapacityEdgeMap, ResidualCapacityEdgeMap,
+ ReverseEdgeMap, VertexIndexMap, FlowValue >
+ algo(g, cap, res, rev, src, sink, index_map);
+
+ FlowValue flow = algo.maximum_preflow();
+
+ algo.convert_preflow_to_flow();
+
+ BOOST_ASSERT(algo.is_flow());
+ BOOST_ASSERT(algo.is_optimal());
+
+ return flow;
+} // push_relabel_max_flow()
+
+template < class Graph, class P, class T, class R >
+typename detail::edge_capacity_value< Graph, P, T, R >::type
+push_relabel_max_flow(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink,
+ const bgl_named_params< P, T, R >& params)
+{
+ return push_relabel_max_flow(g, src, sink,
+ choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
+ choose_pmap(get_param(params, edge_residual_capacity), g,
+ edge_residual_capacity),
+ choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index));
+}
+
+template < class Graph >
+typename property_traits<
+ typename property_map< Graph, edge_capacity_t >::const_type >::value_type
+push_relabel_max_flow(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink)
+{
+ bgl_named_params< int, buffer_param_t > params(0); // bogus empty param
+ return push_relabel_max_flow(g, src, sink, params);
+}
+
+} // namespace boost
+
+#endif // BOOST_PUSH_RELABEL_MAX_FLOW_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/r_c_shortest_paths.hpp b/contrib/restricted/boost/graph/include/boost/graph/r_c_shortest_paths.hpp
new file mode 100644
index 0000000000..12edb43dcf
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/r_c_shortest_paths.hpp
@@ -0,0 +1,727 @@
+// r_c_shortest_paths.hpp header file
+
+// Copyright Michael Drexl 2005, 2006.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_R_C_SHORTEST_PATHS_HPP
+#define BOOST_GRAPH_R_C_SHORTEST_PATHS_HPP
+
+#include <map>
+#include <queue>
+#include <vector>
+#include <list>
+
+#include <boost/make_shared.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+
+// r_c_shortest_paths_label struct
+template < class Graph, class Resource_Container >
+struct r_c_shortest_paths_label
+: public boost::enable_shared_from_this<
+ r_c_shortest_paths_label< Graph, Resource_Container > >
+{
+ r_c_shortest_paths_label(const unsigned long n,
+ const Resource_Container& rc = Resource_Container(),
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >
+ pl
+ = boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >(),
+ const typename graph_traits< Graph >::edge_descriptor& ed
+ = graph_traits< Graph >::edge_descriptor(),
+ const typename graph_traits< Graph >::vertex_descriptor& vd
+ = graph_traits< Graph >::vertex_descriptor())
+ : num(n)
+ , cumulated_resource_consumption(rc)
+ , p_pred_label(pl)
+ , pred_edge(ed)
+ , resident_vertex(vd)
+ , b_is_dominated(false)
+ , b_is_processed(false)
+ {
+ }
+
+ r_c_shortest_paths_label& operator=(const r_c_shortest_paths_label& other)
+ {
+ if (this == &other)
+ return *this;
+ this->~r_c_shortest_paths_label();
+ new (this) r_c_shortest_paths_label(other);
+ return *this;
+ }
+ const unsigned long num;
+ Resource_Container cumulated_resource_consumption;
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >
+ p_pred_label;
+ const typename graph_traits< Graph >::edge_descriptor pred_edge;
+ const typename graph_traits< Graph >::vertex_descriptor resident_vertex;
+ bool b_is_dominated;
+ bool b_is_processed;
+}; // r_c_shortest_paths_label
+
+template < class Graph, class Resource_Container >
+inline bool operator==(
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
+{
+ return l1.cumulated_resource_consumption
+ == l2.cumulated_resource_consumption;
+}
+
+template < class Graph, class Resource_Container >
+inline bool operator!=(
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
+{
+ return !(l1 == l2);
+}
+
+template < class Graph, class Resource_Container >
+inline bool operator<(
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
+{
+ return l1.cumulated_resource_consumption
+ < l2.cumulated_resource_consumption;
+}
+
+template < class Graph, class Resource_Container >
+inline bool operator>(
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
+{
+ return l2.cumulated_resource_consumption
+ < l1.cumulated_resource_consumption;
+}
+
+template < class Graph, class Resource_Container >
+inline bool operator<=(
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
+{
+ return l1 < l2 || l1 == l2;
+}
+
+template < class Graph, class Resource_Container >
+inline bool operator>=(
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
+ const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
+{
+ return l2 < l1 || l1 == l2;
+}
+
+template < typename Graph, typename Resource_Container >
+inline bool operator<(
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >& t,
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >& u)
+{
+ return *t < *u;
+}
+
+template < typename Graph, typename Resource_Container >
+inline bool operator<=(
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >& t,
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >& u)
+{
+ return *t <= *u;
+}
+
+template < typename Graph, typename Resource_Container >
+inline bool operator>(
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >& t,
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >& u)
+{
+ return *t > *u;
+}
+
+template < typename Graph, typename Resource_Container >
+inline bool operator>=(
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >& t,
+ const boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >& u)
+{
+ return *t >= *u;
+}
+
+namespace detail
+{
+
+ // r_c_shortest_paths_dispatch function (body/implementation)
+ template < class Graph, class VertexIndexMap, class EdgeIndexMap,
+ class Resource_Container, class Resource_Extension_Function,
+ class Dominance_Function, class Label_Allocator, class Visitor >
+ void r_c_shortest_paths_dispatch(const Graph& g,
+ const VertexIndexMap& vertex_index_map,
+ const EdgeIndexMap& /*edge_index_map*/,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t,
+ // each inner vector corresponds to a pareto-optimal path
+ std::vector<
+ std::vector< typename graph_traits< Graph >::edge_descriptor > >&
+ pareto_optimal_solutions,
+ std::vector< Resource_Container >& pareto_optimal_resource_containers,
+ bool b_all_pareto_optimal_solutions,
+ // to initialize the first label/resource container
+ // and to carry the type information
+ const Resource_Container& rc, Resource_Extension_Function& ref,
+ Dominance_Function& dominance,
+ // to specify the memory management strategy for the labels
+ Label_Allocator /*la*/, Visitor vis)
+ {
+ pareto_optimal_resource_containers.clear();
+ pareto_optimal_solutions.clear();
+
+ size_t i_label_num = 0;
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+ typedef typename Label_Allocator::template rebind<
+ r_c_shortest_paths_label< Graph, Resource_Container > >::other
+ LAlloc;
+#else
+ typedef typename std::allocator_traits< Label_Allocator >::
+ template rebind_alloc<
+ r_c_shortest_paths_label< Graph, Resource_Container > >
+ LAlloc;
+ typedef std::allocator_traits< LAlloc > LTraits;
+#endif
+ LAlloc l_alloc;
+ typedef boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >
+ Splabel;
+ std::priority_queue< Splabel, std::vector< Splabel >,
+ std::greater< Splabel > >
+ unprocessed_labels;
+
+ bool b_feasible = true;
+ Splabel splabel_first_label = boost::allocate_shared<
+ r_c_shortest_paths_label< Graph, Resource_Container > >(l_alloc,
+ i_label_num++, rc,
+ boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >(),
+ typename graph_traits< Graph >::edge_descriptor(), s);
+
+ unprocessed_labels.push(splabel_first_label);
+ std::vector< std::list< Splabel > > vec_vertex_labels_data(
+ num_vertices(g));
+ iterator_property_map<
+ typename std::vector< std::list< Splabel > >::iterator,
+ VertexIndexMap >
+ vec_vertex_labels(vec_vertex_labels_data.begin(), vertex_index_map);
+ vec_vertex_labels[s].push_back(splabel_first_label);
+ typedef std::vector< typename std::list< Splabel >::iterator >
+ vec_last_valid_positions_for_dominance_data_type;
+ vec_last_valid_positions_for_dominance_data_type
+ vec_last_valid_positions_for_dominance_data(num_vertices(g));
+ iterator_property_map<
+ typename vec_last_valid_positions_for_dominance_data_type::iterator,
+ VertexIndexMap >
+ vec_last_valid_positions_for_dominance(
+ vec_last_valid_positions_for_dominance_data.begin(),
+ vertex_index_map);
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ put(vec_last_valid_positions_for_dominance, v,
+ vec_vertex_labels[v].begin());
+ }
+ std::vector< size_t > vec_last_valid_index_for_dominance_data(
+ num_vertices(g), 0);
+ iterator_property_map< std::vector< size_t >::iterator, VertexIndexMap >
+ vec_last_valid_index_for_dominance(
+ vec_last_valid_index_for_dominance_data.begin(),
+ vertex_index_map);
+ std::vector< bool > b_vec_vertex_already_checked_for_dominance_data(
+ num_vertices(g), false);
+ iterator_property_map< std::vector< bool >::iterator, VertexIndexMap >
+ b_vec_vertex_already_checked_for_dominance(
+ b_vec_vertex_already_checked_for_dominance_data.begin(),
+ vertex_index_map);
+
+ while (!unprocessed_labels.empty()
+ && vis.on_enter_loop(unprocessed_labels, g))
+ {
+ Splabel cur_label = unprocessed_labels.top();
+ unprocessed_labels.pop();
+ vis.on_label_popped(*cur_label, g);
+ // an Splabel object in unprocessed_labels and the respective
+ // Splabel object in the respective list<Splabel> of
+ // vec_vertex_labels share their embedded r_c_shortest_paths_label
+ // object to avoid memory leaks, dominated r_c_shortest_paths_label
+ // objects are marked and deleted when popped from
+ // unprocessed_labels, as they can no longer be deleted at the end
+ // of the function; only the Splabel object in unprocessed_labels
+ // still references the r_c_shortest_paths_label object this is also
+ // for efficiency, because the else branch is executed only if there
+ // is a chance that extending the label leads to new undominated
+ // labels, which in turn is possible only if the label to be
+ // extended is undominated
+ if (!cur_label->b_is_dominated)
+ {
+ typename boost::graph_traits< Graph >::vertex_descriptor
+ i_cur_resident_vertex
+ = cur_label->resident_vertex;
+ std::list< Splabel >& list_labels_cur_vertex
+ = get(vec_vertex_labels, i_cur_resident_vertex);
+ if (list_labels_cur_vertex.size() >= 2
+ && vec_last_valid_index_for_dominance[i_cur_resident_vertex]
+ < list_labels_cur_vertex.size())
+ {
+ typename std::list< Splabel >::iterator outer_iter
+ = list_labels_cur_vertex.begin();
+ bool b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
+ = false;
+ while (outer_iter != list_labels_cur_vertex.end())
+ {
+ Splabel cur_outer_splabel = *outer_iter;
+ typename std::list< Splabel >::iterator inner_iter
+ = outer_iter;
+ if (!b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
+ && outer_iter
+ == get(vec_last_valid_positions_for_dominance,
+ i_cur_resident_vertex))
+ b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
+ = true;
+ if (!get(b_vec_vertex_already_checked_for_dominance,
+ i_cur_resident_vertex)
+ || b_outer_iter_at_or_beyond_last_valid_pos_for_dominance)
+ {
+ ++inner_iter;
+ }
+ else
+ {
+ inner_iter
+ = get(vec_last_valid_positions_for_dominance,
+ i_cur_resident_vertex);
+ ++inner_iter;
+ }
+ bool b_outer_iter_erased = false;
+ while (inner_iter != list_labels_cur_vertex.end())
+ {
+ Splabel cur_inner_splabel = *inner_iter;
+ if (dominance(cur_outer_splabel
+ ->cumulated_resource_consumption,
+ cur_inner_splabel
+ ->cumulated_resource_consumption))
+ {
+ typename std::list< Splabel >::iterator buf
+ = inner_iter;
+ ++inner_iter;
+ list_labels_cur_vertex.erase(buf);
+ if (cur_inner_splabel->b_is_processed)
+ {
+ cur_inner_splabel.reset();
+ }
+ else
+ cur_inner_splabel->b_is_dominated = true;
+ continue;
+ }
+ else
+ ++inner_iter;
+ if (dominance(cur_inner_splabel
+ ->cumulated_resource_consumption,
+ cur_outer_splabel
+ ->cumulated_resource_consumption))
+ {
+ typename std::list< Splabel >::iterator buf
+ = outer_iter;
+ ++outer_iter;
+ list_labels_cur_vertex.erase(buf);
+ b_outer_iter_erased = true;
+ if (cur_outer_splabel->b_is_processed)
+ {
+ cur_outer_splabel.reset();
+ }
+ else
+ cur_outer_splabel->b_is_dominated = true;
+ break;
+ }
+ }
+ if (!b_outer_iter_erased)
+ ++outer_iter;
+ }
+ if (list_labels_cur_vertex.size() > 1)
+ put(vec_last_valid_positions_for_dominance,
+ i_cur_resident_vertex,
+ (--(list_labels_cur_vertex.end())));
+ else
+ put(vec_last_valid_positions_for_dominance,
+ i_cur_resident_vertex,
+ list_labels_cur_vertex.begin());
+ put(b_vec_vertex_already_checked_for_dominance,
+ i_cur_resident_vertex, true);
+ put(vec_last_valid_index_for_dominance,
+ i_cur_resident_vertex,
+ list_labels_cur_vertex.size() - 1);
+ }
+ }
+ if (!b_all_pareto_optimal_solutions
+ && cur_label->resident_vertex == t)
+ {
+ // the devil don't sleep
+ if (cur_label->b_is_dominated)
+ {
+ cur_label.reset();
+ }
+ while (unprocessed_labels.size())
+ {
+ Splabel l = unprocessed_labels.top();
+ unprocessed_labels.pop();
+ // delete only dominated labels, because nondominated labels
+ // are deleted at the end of the function
+ if (l->b_is_dominated)
+ {
+ l.reset();
+ }
+ }
+ break;
+ }
+ if (!cur_label->b_is_dominated)
+ {
+ cur_label->b_is_processed = true;
+ vis.on_label_not_dominated(*cur_label, g);
+ typename graph_traits< Graph >::vertex_descriptor cur_vertex
+ = cur_label->resident_vertex;
+ typename graph_traits< Graph >::out_edge_iterator oei, oei_end;
+ for (boost::tie(oei, oei_end) = out_edges(cur_vertex, g);
+ oei != oei_end; ++oei)
+ {
+ b_feasible = true;
+ Splabel new_label = boost::allocate_shared<
+ r_c_shortest_paths_label< Graph, Resource_Container > >(
+ l_alloc, i_label_num++,
+ cur_label->cumulated_resource_consumption, cur_label,
+ *oei, target(*oei, g));
+ b_feasible = ref(g,
+ new_label->cumulated_resource_consumption,
+ new_label->p_pred_label->cumulated_resource_consumption,
+ new_label->pred_edge);
+
+ if (!b_feasible)
+ {
+ vis.on_label_not_feasible(*new_label, g);
+ new_label.reset();
+ }
+ else
+ {
+ vis.on_label_feasible(*new_label, g);
+ vec_vertex_labels[new_label->resident_vertex].push_back(
+ new_label);
+ unprocessed_labels.push(new_label);
+ }
+ }
+ }
+ else
+ {
+ vis.on_label_dominated(*cur_label, g);
+ cur_label.reset();
+ }
+ }
+ std::list< Splabel > dsplabels = get(vec_vertex_labels, t);
+ if(!b_all_pareto_optimal_solutions)
+ {
+ dsplabels.sort();
+ }
+ typename std::list< Splabel >::const_iterator csi = dsplabels.begin();
+ typename std::list< Splabel >::const_iterator csi_end = dsplabels.end();
+ // if d could be reached from o
+ if (!dsplabels.empty())
+ {
+ for (; csi != csi_end; ++csi)
+ {
+ std::vector< typename graph_traits< Graph >::edge_descriptor >
+ cur_pareto_optimal_path;
+ boost::shared_ptr<
+ r_c_shortest_paths_label< Graph, Resource_Container > >
+ p_cur_label = *csi;
+ pareto_optimal_resource_containers.push_back(
+ p_cur_label->cumulated_resource_consumption);
+ while (p_cur_label->num != 0)
+ {
+ cur_pareto_optimal_path.push_back(p_cur_label->pred_edge);
+ p_cur_label = p_cur_label->p_pred_label;
+
+ // assertion b_is_valid beyond this point is not correct if
+ // the domination function requires resource levels to be
+ // strictly greater than existing values
+ //
+ // Example
+ // Customers
+ // id min_arrival max_departure
+ // 2 0 974
+ // 3 0 972
+ // 4 0 964
+ // 5 678 801
+ //
+ // Path A: 2-3-4-5 (times: 0-16-49-84-678)
+ // Path B: 3-2-4-5 (times: 0-18-51-62-678)
+ // The partial path 3-2-4 dominates the other partial path
+ // 2-3-4, though the path 3-2-4-5 does not strictly dominate
+ // the path 2-3-4-5
+ }
+ pareto_optimal_solutions.push_back(cur_pareto_optimal_path);
+ if (!b_all_pareto_optimal_solutions)
+ break;
+ }
+ }
+
+ BGL_FORALL_VERTICES_T(i, g, Graph)
+ {
+ std::list< Splabel >& list_labels_cur_vertex = vec_vertex_labels[i];
+ typename std::list< Splabel >::iterator si
+ = list_labels_cur_vertex.begin();
+ const typename std::list< Splabel >::iterator si_end
+ = list_labels_cur_vertex.end();
+ for (; si != si_end; ++si)
+ {
+ (*si).reset();
+ }
+ }
+ } // r_c_shortest_paths_dispatch
+
+} // detail
+
+// default_r_c_shortest_paths_visitor struct
+struct default_r_c_shortest_paths_visitor
+{
+ template < class Label, class Graph >
+ void on_label_popped(const Label&, const Graph&)
+ {
+ }
+ template < class Label, class Graph >
+ void on_label_feasible(const Label&, const Graph&)
+ {
+ }
+ template < class Label, class Graph >
+ void on_label_not_feasible(const Label&, const Graph&)
+ {
+ }
+ template < class Label, class Graph >
+ void on_label_dominated(const Label&, const Graph&)
+ {
+ }
+ template < class Label, class Graph >
+ void on_label_not_dominated(const Label&, const Graph&)
+ {
+ }
+ template < class Queue, class Graph >
+ bool on_enter_loop(const Queue& queue, const Graph& graph)
+ {
+ return true;
+ }
+}; // default_r_c_shortest_paths_visitor
+
+// default_r_c_shortest_paths_allocator
+typedef std::allocator< int > default_r_c_shortest_paths_allocator;
+// default_r_c_shortest_paths_allocator
+
+// r_c_shortest_paths functions (handle/interface)
+// first overload:
+// - return all pareto-optimal solutions
+// - specify Label_Allocator and Visitor arguments
+template < class Graph, class VertexIndexMap, class EdgeIndexMap,
+ class Resource_Container, class Resource_Extension_Function,
+ class Dominance_Function, class Label_Allocator, class Visitor >
+void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
+ const EdgeIndexMap& edge_index_map,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t,
+ // each inner vector corresponds to a pareto-optimal path
+ std::vector<
+ std::vector< typename graph_traits< Graph >::edge_descriptor > >&
+ pareto_optimal_solutions,
+ std::vector< Resource_Container >& pareto_optimal_resource_containers,
+ // to initialize the first label/resource container
+ // and to carry the type information
+ const Resource_Container& rc, const Resource_Extension_Function& ref,
+ const Dominance_Function& dominance,
+ // to specify the memory management strategy for the labels
+ Label_Allocator la, Visitor vis)
+{
+ r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
+ pareto_optimal_solutions, pareto_optimal_resource_containers, true, rc,
+ ref, dominance, la, vis);
+}
+
+// second overload:
+// - return only one pareto-optimal solution
+// - specify Label_Allocator and Visitor arguments
+template < class Graph, class VertexIndexMap, class EdgeIndexMap,
+ class Resource_Container, class Resource_Extension_Function,
+ class Dominance_Function, class Label_Allocator, class Visitor >
+void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
+ const EdgeIndexMap& edge_index_map,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >&
+ pareto_optimal_solution,
+ Resource_Container& pareto_optimal_resource_container,
+ // to initialize the first label/resource container
+ // and to carry the type information
+ const Resource_Container& rc, const Resource_Extension_Function& ref,
+ const Dominance_Function& dominance,
+ // to specify the memory management strategy for the labels
+ Label_Allocator la, Visitor vis)
+{
+ // each inner vector corresponds to a pareto-optimal path
+ std::vector<
+ std::vector< typename graph_traits< Graph >::edge_descriptor > >
+ pareto_optimal_solutions;
+ std::vector< Resource_Container > pareto_optimal_resource_containers;
+ r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
+ pareto_optimal_solutions, pareto_optimal_resource_containers, false, rc,
+ ref, dominance, la, vis);
+ if (!pareto_optimal_solutions.empty())
+ {
+ pareto_optimal_solution = pareto_optimal_solutions[0];
+ pareto_optimal_resource_container
+ = pareto_optimal_resource_containers[0];
+ }
+}
+
+// third overload:
+// - return all pareto-optimal solutions
+// - use default Label_Allocator and Visitor
+template < class Graph, class VertexIndexMap, class EdgeIndexMap,
+ class Resource_Container, class Resource_Extension_Function,
+ class Dominance_Function >
+void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
+ const EdgeIndexMap& edge_index_map,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t,
+ // each inner vector corresponds to a pareto-optimal path
+ std::vector<
+ std::vector< typename graph_traits< Graph >::edge_descriptor > >&
+ pareto_optimal_solutions,
+ std::vector< Resource_Container >& pareto_optimal_resource_containers,
+ // to initialize the first label/resource container
+ // and to carry the type information
+ const Resource_Container& rc, const Resource_Extension_Function& ref,
+ const Dominance_Function& dominance)
+{
+ r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
+ pareto_optimal_solutions, pareto_optimal_resource_containers, true, rc,
+ ref, dominance, default_r_c_shortest_paths_allocator(),
+ default_r_c_shortest_paths_visitor());
+}
+
+// fourth overload:
+// - return only one pareto-optimal solution
+// - use default Label_Allocator and Visitor
+template < class Graph, class VertexIndexMap, class EdgeIndexMap,
+ class Resource_Container, class Resource_Extension_Function,
+ class Dominance_Function >
+void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
+ const EdgeIndexMap& edge_index_map,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t,
+ std::vector< typename graph_traits< Graph >::edge_descriptor >&
+ pareto_optimal_solution,
+ Resource_Container& pareto_optimal_resource_container,
+ // to initialize the first label/resource container
+ // and to carry the type information
+ const Resource_Container& rc, const Resource_Extension_Function& ref,
+ const Dominance_Function& dominance)
+{
+ // each inner vector corresponds to a pareto-optimal path
+ std::vector<
+ std::vector< typename graph_traits< Graph >::edge_descriptor > >
+ pareto_optimal_solutions;
+ std::vector< Resource_Container > pareto_optimal_resource_containers;
+ r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
+ pareto_optimal_solutions, pareto_optimal_resource_containers, false, rc,
+ ref, dominance, default_r_c_shortest_paths_allocator(),
+ default_r_c_shortest_paths_visitor());
+ if (!pareto_optimal_solutions.empty())
+ {
+ pareto_optimal_solution = pareto_optimal_solutions[0];
+ pareto_optimal_resource_container
+ = pareto_optimal_resource_containers[0];
+ }
+}
+// r_c_shortest_paths
+
+// check_r_c_path function
+template < class Graph, class Resource_Container,
+ class Resource_Extension_Function >
+void check_r_c_path(const Graph& g,
+ const std::vector< typename graph_traits< Graph >::edge_descriptor >&
+ ed_vec_path,
+ const Resource_Container& initial_resource_levels,
+ // if true, computed accumulated final resource levels must
+ // be equal to desired_final_resource_levels
+ // if false, computed accumulated final resource levels must
+ // be less than or equal to desired_final_resource_levels
+ bool b_result_must_be_equal_to_desired_final_resource_levels,
+ const Resource_Container& desired_final_resource_levels,
+ Resource_Container& actual_final_resource_levels,
+ const Resource_Extension_Function& ref, bool& b_is_a_path_at_all,
+ bool& b_feasible, bool& b_correctly_extended,
+ typename graph_traits< Graph >::edge_descriptor& ed_last_extended_arc)
+{
+ size_t i_size_ed_vec_path = ed_vec_path.size();
+ std::vector< typename graph_traits< Graph >::edge_descriptor > buf_path;
+ if (i_size_ed_vec_path == 0)
+ b_feasible = true;
+ else
+ {
+ if (i_size_ed_vec_path == 1
+ || target(ed_vec_path[0], g) == source(ed_vec_path[1], g))
+ buf_path = ed_vec_path;
+ else
+ for (size_t i = i_size_ed_vec_path; i > 0; --i)
+ buf_path.push_back(ed_vec_path[i - 1]);
+ for (size_t i = 0; i < i_size_ed_vec_path - 1; ++i)
+ {
+ if (target(buf_path[i], g) != source(buf_path[i + 1], g))
+ {
+ b_is_a_path_at_all = false;
+ b_feasible = false;
+ b_correctly_extended = false;
+ return;
+ }
+ }
+ }
+ b_is_a_path_at_all = true;
+ b_feasible = true;
+ b_correctly_extended = false;
+ Resource_Container current_resource_levels = initial_resource_levels;
+ actual_final_resource_levels = current_resource_levels;
+ for (size_t i = 0; i < i_size_ed_vec_path; ++i)
+ {
+ ed_last_extended_arc = buf_path[i];
+ b_feasible = ref(g, actual_final_resource_levels,
+ current_resource_levels, buf_path[i]);
+ current_resource_levels = actual_final_resource_levels;
+ if (!b_feasible)
+ return;
+ }
+ if (b_result_must_be_equal_to_desired_final_resource_levels)
+ b_correctly_extended
+ = actual_final_resource_levels == desired_final_resource_levels
+ ? true
+ : false;
+ else
+ {
+ if (actual_final_resource_levels < desired_final_resource_levels
+ || actual_final_resource_levels == desired_final_resource_levels)
+ b_correctly_extended = true;
+ }
+} // check_path
+
+} // namespace
+
+#endif // BOOST_GRAPH_R_C_SHORTEST_PATHS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/random.hpp b/contrib/restricted/boost/graph/include/boost/graph/random.hpp
new file mode 100644
index 0000000000..4c1261b110
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/random.hpp
@@ -0,0 +1,290 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright (C) Vladimir Prus 2003
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_RANDOM_HPP
+#define BOOST_GRAPH_RANDOM_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/variate_generator.hpp>
+
+#include <boost/pending/property.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/next_prior.hpp>
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/copy.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#include <iostream>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+
+// grab a random vertex from the graph's vertex set
+template < class Graph, class RandomNumGen >
+typename graph_traits< Graph >::vertex_descriptor random_vertex(
+ Graph& g, RandomNumGen& gen)
+{
+ if (num_vertices(g) > 1)
+ {
+#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581))
+ std::size_t n = std::random(num_vertices(g));
+#else
+ uniform_int<> distrib(0, num_vertices(g) - 1);
+ variate_generator< RandomNumGen&, uniform_int<> > rand_gen(
+ gen, distrib);
+ std::size_t n = rand_gen();
+#endif
+ typename graph_traits< Graph >::vertex_iterator i = vertices(g).first;
+ return *(boost::next(i, n));
+ }
+ else
+ return *vertices(g).first;
+}
+
+template < class Graph, class RandomNumGen >
+typename graph_traits< Graph >::edge_descriptor random_edge(
+ Graph& g, RandomNumGen& gen)
+{
+ if (num_edges(g) > 1)
+ {
+#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581))
+ typename graph_traits< Graph >::edges_size_type n
+ = std::random(num_edges(g));
+#else
+ uniform_int<> distrib(0, num_edges(g) - 1);
+ variate_generator< RandomNumGen&, uniform_int<> > rand_gen(
+ gen, distrib);
+ typename graph_traits< Graph >::edges_size_type n = rand_gen();
+#endif
+ typename graph_traits< Graph >::edge_iterator i = edges(g).first;
+ return *(boost::next(i, n));
+ }
+ else
+ return *edges(g).first;
+}
+
+template < typename Graph, typename RandomNumGen >
+typename graph_traits< Graph >::edge_descriptor random_out_edge(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor src, RandomNumGen& gen)
+{
+ typedef typename graph_traits< Graph >::degree_size_type degree_size_type;
+ typedef boost::uniform_int< degree_size_type > ui_type;
+ ui_type ui(0, out_degree(src, g) - 1);
+ boost::variate_generator< RandomNumGen&, ui_type > variate(gen, ui);
+ typename graph_traits< Graph >::out_edge_iterator it
+ = out_edges(src, g).first;
+ std::advance(it, variate());
+ return *it;
+}
+
+template < typename Graph, typename WeightMap, typename RandomNumGen >
+typename graph_traits< Graph >::edge_descriptor weighted_random_out_edge(
+ Graph& g, typename graph_traits< Graph >::vertex_descriptor src,
+ WeightMap weight, RandomNumGen& gen)
+{
+ typedef typename property_traits< WeightMap >::value_type weight_type;
+ weight_type weight_sum(0);
+ BGL_FORALL_OUTEDGES_T(src, e, g, Graph) { weight_sum += get(weight, e); }
+ typedef boost::uniform_real<> ur_type;
+ ur_type ur(0, weight_sum);
+ boost::variate_generator< RandomNumGen&, ur_type > variate(gen, ur);
+ weight_type chosen_weight = variate();
+ BGL_FORALL_OUTEDGES_T(src, e, g, Graph)
+ {
+ weight_type w = get(weight, e);
+ if (chosen_weight < w)
+ {
+ return e;
+ }
+ else
+ {
+ chosen_weight -= w;
+ }
+ }
+ BOOST_ASSERT(false); // Should not get here
+ return typename graph_traits< Graph >::edge_descriptor();
+}
+
+namespace detail
+{
+ class dummy_property_copier
+ {
+ public:
+ template < class V1, class V2 >
+ void operator()(const V1&, const V2&) const
+ {
+ }
+ };
+}
+
+template < typename MutableGraph, class RandNumGen >
+void generate_random_graph1(MutableGraph& g,
+ typename graph_traits< MutableGraph >::vertices_size_type V,
+ typename graph_traits< MutableGraph >::vertices_size_type E,
+ RandNumGen& gen, bool allow_parallel = true, bool self_edges = false)
+{
+ typedef graph_traits< MutableGraph > Traits;
+ typedef typename Traits::edge_descriptor edge_t;
+ typedef typename Traits::vertices_size_type v_size_t;
+ typedef typename Traits::edges_size_type e_size_t;
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+
+ // When parallel edges are not allowed, we create a new graph which
+ // does not allow parallel edges, construct it and copy back.
+ // This is not efficient if 'g' already disallow parallel edges,
+ // but that's task for later.
+ if (!allow_parallel)
+ {
+
+ typedef
+ typename boost::graph_traits< MutableGraph >::directed_category dir;
+ typedef typename mpl::if_< is_convertible< dir, directed_tag >,
+ directedS, undirectedS >::type select;
+ adjacency_list< setS, vecS, select > g2;
+ generate_random_graph1(g2, V, E, gen, true, self_edges);
+
+ copy_graph(g2, g,
+ vertex_copy(detail::dummy_property_copier())
+ .edge_copy(detail::dummy_property_copier()));
+ }
+ else
+ {
+
+ for (v_size_t i = 0; i < V; ++i)
+ add_vertex(g);
+
+ e_size_t not_inserted_counter
+ = 0; /* Number of edge insertion failures */
+ e_size_t num_vertices_squared = num_vertices(g) * num_vertices(g);
+ for (e_size_t j = 0; j < E; /* Increment in body */)
+ {
+ vertex_descriptor a = random_vertex(g, gen), b;
+ do
+ {
+ b = random_vertex(g, gen);
+ } while (self_edges == false && a == b);
+ edge_t e;
+ bool inserted;
+ boost::tie(e, inserted) = add_edge(a, b, g);
+ if (inserted)
+ {
+ ++j;
+ }
+ else
+ {
+ ++not_inserted_counter;
+ }
+ if (not_inserted_counter >= num_vertices_squared)
+ {
+ return; /* Rather than looping forever on complete graph */
+ }
+ }
+ }
+}
+
+template < typename MutableGraph, class RandNumGen >
+void generate_random_graph(MutableGraph& g,
+ typename graph_traits< MutableGraph >::vertices_size_type V,
+ typename graph_traits< MutableGraph >::vertices_size_type E,
+ RandNumGen& gen, bool allow_parallel = true, bool self_edges = false)
+{
+ generate_random_graph1(g, V, E, gen, allow_parallel, self_edges);
+}
+
+template < typename MutableGraph, typename RandNumGen,
+ typename VertexOutputIterator, typename EdgeOutputIterator >
+void generate_random_graph(MutableGraph& g,
+ typename graph_traits< MutableGraph >::vertices_size_type V,
+ typename graph_traits< MutableGraph >::vertices_size_type E,
+ RandNumGen& gen, VertexOutputIterator vertex_out,
+ EdgeOutputIterator edge_out, bool self_edges = false)
+{
+ typedef graph_traits< MutableGraph > Traits;
+ typedef typename Traits::vertices_size_type v_size_t;
+ typedef typename Traits::edges_size_type e_size_t;
+ typedef typename Traits::vertex_descriptor vertex_t;
+ typedef typename Traits::edge_descriptor edge_t;
+
+ for (v_size_t i = 0; i < V; ++i)
+ *vertex_out++ = add_vertex(g);
+
+ e_size_t not_inserted_counter = 0; /* Number of edge insertion failures */
+ e_size_t num_vertices_squared = num_vertices(g) * num_vertices(g);
+ for (e_size_t j = 0; j < E; /* Increment in body */)
+ {
+ vertex_t a = random_vertex(g, gen), b;
+ do
+ {
+ b = random_vertex(g, gen);
+ } while (self_edges == false && a == b);
+ edge_t e;
+ bool inserted;
+ boost::tie(e, inserted) = add_edge(a, b, g);
+ if (inserted)
+ {
+ *edge_out++ = std::make_pair(source(e, g), target(e, g));
+ ++j;
+ }
+ else
+ {
+ ++not_inserted_counter;
+ }
+ if (not_inserted_counter >= num_vertices_squared)
+ {
+ return; /* Rather than looping forever on complete graph */
+ }
+ }
+}
+
+namespace detail
+{
+
+ template < class Property, class G, class RandomGenerator >
+ void randomize_property(
+ G& g, RandomGenerator& rg, Property, vertex_property_tag)
+ {
+ typename property_map< G, Property >::type pm = get(Property(), g);
+ typename graph_traits< G >::vertex_iterator vi, ve;
+ for (boost::tie(vi, ve) = vertices(g); vi != ve; ++vi)
+ {
+ pm[*vi] = rg();
+ }
+ }
+
+ template < class Property, class G, class RandomGenerator >
+ void randomize_property(
+ G& g, RandomGenerator& rg, Property, edge_property_tag)
+ {
+ typename property_map< G, Property >::type pm = get(Property(), g);
+ typename graph_traits< G >::edge_iterator ei, ee;
+ for (boost::tie(ei, ee) = edges(g); ei != ee; ++ei)
+ {
+ pm[*ei] = rg();
+ }
+ }
+}
+
+template < class Property, class G, class RandomGenerator >
+void randomize_property(G& g, RandomGenerator& rg)
+{
+ detail::randomize_property(
+ g, rg, Property(), typename property_kind< Property >::type());
+}
+
+}
+
+#include <boost/graph/iteration_macros_undef.hpp>
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/random_layout.hpp b/contrib/restricted/boost/graph/include/boost/graph/random_layout.hpp
new file mode 100644
index 0000000000..757585ced7
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/random_layout.hpp
@@ -0,0 +1,35 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_RANDOM_LAYOUT_HPP
+#define BOOST_GRAPH_RANDOM_LAYOUT_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/graph/iteration_macros.hpp>
+
+namespace boost
+{
+
+template < typename Topology, typename Graph, typename PositionMap >
+void random_graph_layout(
+ const Graph& g, PositionMap position_map, const Topology& topology)
+{
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ put(position_map, v, topology.random_point());
+ }
+}
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_RANDOM_LAYOUT_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/random_spanning_tree.hpp b/contrib/restricted/boost/graph/include/boost/graph/random_spanning_tree.hpp
new file mode 100644
index 0000000000..593261da81
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/random_spanning_tree.hpp
@@ -0,0 +1,144 @@
+// Copyright 2010 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jeremiah Willcock
+// Andrew Lumsdaine
+
+#ifndef BOOST_GRAPH_RANDOM_SPANNING_TREE_HPP
+#define BOOST_GRAPH_RANDOM_SPANNING_TREE_HPP
+
+#include <vector>
+#include <boost/assert.hpp>
+#include <boost/graph/loop_erased_random_walk.hpp>
+#include <boost/graph/random.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+ // Use Wilson's algorithm (based on loop-free random walks) to generate a
+ // random spanning tree. The distribution of edges used is controlled by
+ // the next_edge() function, so this version allows either weighted or
+ // unweighted selection of trees.
+ // Algorithm is from http://en.wikipedia.org/wiki/Uniform_spanning_tree
+ template < typename Graph, typename PredMap, typename ColorMap,
+ typename NextEdge >
+ void random_spanning_tree_internal(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s, PredMap pred,
+ ColorMap color, NextEdge next_edge)
+ {
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+
+ BOOST_ASSERT(num_vertices(g)
+ >= 1); // g must also be undirected (or symmetric) and connected
+
+ typedef color_traits< typename property_traits< ColorMap >::value_type >
+ color_gen;
+ BGL_FORALL_VERTICES_T(v, g, Graph) put(color, v, color_gen::white());
+
+ std::vector< vertex_descriptor > path;
+
+ put(color, s, color_gen::black());
+ put(pred, s, graph_traits< Graph >::null_vertex());
+
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ if (get(color, v) != color_gen::white())
+ continue;
+ loop_erased_random_walk(g, v, next_edge, color, path);
+ for (typename std::vector<
+ vertex_descriptor >::const_reverse_iterator i
+ = path.rbegin();
+ boost::next(i)
+ != (typename std::vector<
+ vertex_descriptor >::const_reverse_iterator)path.rend();
+ ++i)
+ {
+ typename std::vector<
+ vertex_descriptor >::const_reverse_iterator j
+ = i;
+ ++j;
+ BOOST_ASSERT(get(color, *j) == color_gen::gray());
+ put(color, *j, color_gen::black());
+ put(pred, *j, *i);
+ }
+ }
+ }
+}
+
+// Compute a uniformly-distributed spanning tree on a graph. Use Wilson's
+// algorithm:
+// @inproceedings{wilson96generating,
+// author = {Wilson, David Bruce},
+// title = {Generating random spanning trees more quickly than the cover
+// time}, booktitle = {STOC '96: Proceedings of the twenty-eighth annual ACM
+// symposium on Theory of computing}, year = {1996}, isbn = {0-89791-785-5},
+// pages = {296--303},
+// location = {Philadelphia, Pennsylvania, United States},
+// doi = {http://doi.acm.org/10.1145/237814.237880},
+// publisher = {ACM},
+// address = {New York, NY, USA},
+// }
+//
+template < typename Graph, typename Gen, typename PredMap, typename ColorMap >
+void random_spanning_tree(const Graph& g, Gen& gen,
+ typename graph_traits< Graph >::vertex_descriptor root, PredMap pred,
+ static_property_map< double >, ColorMap color)
+{
+ unweighted_random_out_edge_gen< Graph, Gen > random_oe(gen);
+ detail::random_spanning_tree_internal(g, root, pred, color, random_oe);
+}
+
+// Compute a weight-distributed spanning tree on a graph.
+template < typename Graph, typename Gen, typename PredMap, typename WeightMap,
+ typename ColorMap >
+void random_spanning_tree(const Graph& g, Gen& gen,
+ typename graph_traits< Graph >::vertex_descriptor root, PredMap pred,
+ WeightMap weight, ColorMap color)
+{
+ weighted_random_out_edge_gen< Graph, WeightMap, Gen > random_oe(
+ weight, gen);
+ detail::random_spanning_tree_internal(g, root, pred, color, random_oe);
+}
+
+template < typename Graph, typename Gen, typename P, typename T, typename R >
+void random_spanning_tree(
+ const Graph& g, Gen& gen, const bgl_named_params< P, T, R >& params)
+{
+ using namespace boost::graph::keywords;
+ typedef bgl_named_params< P, T, R > params_type;
+ BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params)
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+ vertex_descriptor default_vertex = *vertices(g).first;
+ vertex_descriptor start_vertex = arg_pack[_root_vertex | default_vertex];
+ typename boost::parameter::binding< arg_pack_type,
+ boost::graph::keywords::tag::predecessor_map >::type pred_map
+ = arg_pack[_predecessor_map];
+ static_property_map< double > default_weight_map(1.);
+ typename boost::parameter::value_type< arg_pack_type,
+ boost::graph::keywords::tag::weight_map,
+ static_property_map< double > >::type e_w_map
+ = arg_pack[_weight_map | default_weight_map];
+ typename boost::detail::map_maker< Graph, arg_pack_type,
+ boost::graph::keywords::tag::color_map,
+ boost::default_color_type >::map_type c_map
+ = boost::detail::make_color_map_from_arg_pack(g, arg_pack);
+ random_spanning_tree(g, gen, start_vertex, pred_map, e_w_map, c_map);
+}
+}
+
+#include <boost/graph/iteration_macros_undef.hpp>
+
+#endif // BOOST_GRAPH_RANDOM_SPANNING_TREE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/read_dimacs.hpp b/contrib/restricted/boost/graph/include/boost/graph/read_dimacs.hpp
new file mode 100644
index 0000000000..4e702793b9
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/read_dimacs.hpp
@@ -0,0 +1,370 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+/*
+ Reads maximal flow problem in extended DIMACS format.
+ This works, but could use some polishing.
+*/
+
+/* ----------------------------------------------------------------- */
+
+#ifndef BOOST_GRAPH_READ_DIMACS_HPP
+#define BOOST_GRAPH_READ_DIMACS_HPP
+
+#include <vector>
+#include <iostream>
+#include <string>
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+
+#include <boost/graph/graph_traits.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < class Graph, class CapacityMap, class ReverseEdgeMap >
+ int read_dimacs_max_flow_internal(Graph& g, CapacityMap capacity,
+ ReverseEdgeMap reverse_edge,
+ typename graph_traits< Graph >::vertex_descriptor& src,
+ typename graph_traits< Graph >::vertex_descriptor& sink,
+ std::istream& in, bool require_source_and_sink,
+ const std::string& problem_type)
+ {
+ // const int MAXLINE = 100; /* max line length in the input file
+ // */
+ const int ARC_FIELDS = 3; /* no of fields in arc line */
+ const int NODE_FIELDS = 2; /* no of fields in node line */
+ const int P_FIELDS = 3; /* no of fields in problem line */
+
+ typedef
+ typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor;
+
+ std::vector< vertex_descriptor > verts;
+
+ long m, n, /* number of edges and nodes */
+ i, head, tail, cap;
+
+ long no_lines = 0, /* no of current input line */
+ no_plines = 0, /* no of problem-lines */
+ no_nslines = 0, /* no of node-source-lines */
+ no_nklines = 0, /* no of node-source-lines */
+ no_alines = 0; /* no of arc-lines */
+
+ std::string in_line; /* for reading input line */
+ char pr_type[4]; /* for reading type of the problem */
+ char nd; /* source (s) or sink (t) */
+
+ int k, /* temporary */
+ err_no; /* no of detected error */
+
+ /* -------------- error numbers & error messages ---------------- */
+ const int EN1 = 0;
+ const int EN2 = 1;
+ const int EN3 = 2;
+ const int EN4 = 3;
+ // const int EN6 = 4;
+ // const int EN10 = 5;
+ // const int EN7 = 6;
+ const int EN8 = 7;
+ const int EN9 = 8;
+ const int EN11 = 9;
+ const int EN12 = 10;
+ // const int EN13 = 11;
+ const int EN14 = 12;
+ const int EN16 = 13;
+ const int EN15 = 14;
+ const int EN17 = 15;
+ const int EN18 = 16;
+ const int EN21 = 17;
+ const int EN19 = 18;
+ const int EN20 = 19;
+ const int EN22 = 20;
+
+ static const char* err_message[] = {
+ /* 0*/ "more than one problem line.",
+ /* 1*/ "wrong number of parameters in the problem line.",
+ /* 2*/ "it is not a Max Flow problem line.",
+ /* 3*/ "bad value of a parameter in the problem line.",
+ /* 4*/ "can't obtain enough memory to solve this problem.",
+ /* 5*/ "more than one line with the problem name.",
+ /* 6*/ "can't read problem name.",
+ /* 7*/ "problem description must be before node description.",
+ /* 8*/ "this parser doesn't support multiply sources and sinks.",
+ /* 9*/ "wrong number of parameters in the node line.",
+ /*10*/ "wrong value of parameters in the node line.",
+ /*11*/ " ",
+ /*12*/
+ "source and sink descriptions must be before arc descriptions.",
+ /*13*/ "too many arcs in the input.",
+ /*14*/ "wrong number of parameters in the arc line.",
+ /*15*/ "wrong value of parameters in the arc line.",
+ /*16*/ "unknown line type in the input.",
+ /*17*/ "reading error.",
+ /*18*/ "not enough arcs in the input.",
+ /*19*/ "source or sink doesn't have incident arcs.",
+ /*20*/ "can't read anything from the input file."
+ };
+ /* --------------------------------------------------------------- */
+
+ /* The main loop:
+ - reads the line of the input,
+ - analyses its type,
+ - checks correctness of parameters,
+ - puts data to the arrays,
+ - does service functions
+ */
+
+ while (std::getline(in, in_line))
+ {
+ ++no_lines;
+
+ switch (in_line[0])
+ {
+ case 'c': /* skip lines with comments */
+ case '\n': /* skip empty lines */
+ case '\0': /* skip empty lines at the end of file */
+ break;
+
+ case 'p': /* problem description */
+ if (no_plines > 0)
+ /* more than one problem line */
+ {
+ err_no = EN1;
+ goto error;
+ }
+
+ no_plines = 1;
+
+ if (
+ /* reading problem line: type of problem, no of nodes, no of
+ arcs */
+ std::sscanf(
+ in_line.c_str(), "%*c %3s %ld %ld", pr_type, &n, &m)
+ != P_FIELDS)
+ /*wrong number of parameters in the problem line*/
+ {
+ err_no = EN2;
+ goto error;
+ }
+
+ if (pr_type != problem_type)
+ /*wrong problem type*/
+ {
+ err_no = EN3;
+ goto error;
+ }
+
+ if (n <= 0 || m <= 0)
+ /*wrong value of no of arcs or nodes*/
+ {
+ err_no = EN4;
+ goto error;
+ }
+
+ {
+ for (long vi = 0; vi < n; ++vi)
+ verts.push_back(add_vertex(g));
+ }
+ break;
+
+ case 'n': /* source(s) description */
+ if (no_plines == 0)
+ /* there was not problem line above */
+ {
+ err_no = EN8;
+ goto error;
+ }
+
+ /* reading source or sink */
+ k = std::sscanf(in_line.c_str(), "%*c %ld %c", &i, &nd);
+ --i; // index from 0
+ if (k < NODE_FIELDS)
+ /* node line is incorrect */
+ {
+ err_no = EN11;
+ goto error;
+ }
+
+ if (i < 0 || i > n)
+ /* wrong value of node */
+ {
+ err_no = EN12;
+ goto error;
+ }
+
+ switch (nd)
+ {
+ case 's': /* source line */
+
+ if (no_nslines != 0)
+ /* more than one source line */
+ {
+ err_no = EN9;
+ goto error;
+ }
+
+ no_nslines = 1;
+ src = verts[i];
+ break;
+
+ case 't': /* sink line */
+
+ if (no_nklines != 0)
+ /* more than one sink line */
+ {
+ err_no = EN9;
+ goto error;
+ }
+
+ no_nklines = 1;
+ sink = verts[i];
+ break;
+
+ default:
+ /* wrong type of node-line */
+ err_no = EN12;
+ goto error;
+ }
+ break;
+
+ case 'a': /* arc description */
+ if (require_source_and_sink
+ && (no_nslines == 0 || no_nklines == 0))
+ /* there was not source and sink description above */
+ {
+ err_no = EN14;
+ goto error;
+ }
+
+ if (no_alines >= m)
+ /*too many arcs on input*/
+ {
+ err_no = EN16;
+ goto error;
+ }
+
+ if (
+ /* reading an arc description */
+ std::sscanf(
+ in_line.c_str(), "%*c %ld %ld %ld", &tail, &head, &cap)
+ != ARC_FIELDS)
+ /* arc description is not correct */
+ {
+ err_no = EN15;
+ goto error;
+ }
+
+ --tail; // index from 0, not 1
+ --head;
+ if (tail < 0 || tail > n || head < 0 || head > n)
+ /* wrong value of nodes */
+ {
+ err_no = EN17;
+ goto error;
+ }
+
+ {
+ edge_descriptor e1, e2;
+ bool in1, in2;
+ boost::tie(e1, in1) = add_edge(verts[tail], verts[head], g);
+ boost::tie(e2, in2) = add_edge(verts[head], verts[tail], g);
+ if (!in1 || !in2)
+ {
+ std::cerr << "unable to add edge (" << head << ","
+ << tail << ")" << std::endl;
+ return -1;
+ }
+ capacity[e1] = cap;
+ capacity[e2] = 0;
+ reverse_edge[e1] = e2;
+ reverse_edge[e2] = e1;
+ }
+ ++no_alines;
+ break;
+
+ default:
+ /* unknown type of line */
+ err_no = EN18;
+ goto error;
+
+ } /* end of switch */
+ } /* end of input loop */
+
+ /* ----- all is red or error while reading ----- */
+
+ if (in.eof() == 0) /* reading error */
+ {
+ err_no = EN21;
+ goto error;
+ }
+
+ if (no_lines == 0) /* empty input */
+ {
+ err_no = EN22;
+ goto error;
+ }
+
+ if (no_alines < m) /* not enough arcs */
+ {
+ err_no = EN19;
+ goto error;
+ }
+
+ if (require_source_and_sink
+ && (out_degree(src, g) == 0 || out_degree(sink, g) == 0))
+ /* no arc goes out of the source */
+ {
+ err_no = EN20;
+ goto error;
+ }
+
+ /* Thanks God! all is done */
+ return (0);
+
+ /* ---------------------------------- */
+ error: /* error found reading input */
+
+ std::printf(
+ "\nline %ld of input - %s\n", no_lines, err_message[err_no]);
+
+ return -1;
+ }
+ /* -------------------- end of parser -------------------*/
+
+} // namespace detail
+
+template < class Graph, class CapacityMap, class ReverseEdgeMap >
+int read_dimacs_max_flow(Graph& g, CapacityMap capacity,
+ ReverseEdgeMap reverse_edge,
+ typename graph_traits< Graph >::vertex_descriptor& src,
+ typename graph_traits< Graph >::vertex_descriptor& sink,
+ std::istream& in = std::cin)
+{
+ return detail::read_dimacs_max_flow_internal(
+ g, capacity, reverse_edge, src, sink, in, true, "max");
+}
+
+template < class Graph, class CapacityMap, class ReverseEdgeMap >
+int read_dimacs_min_cut(Graph& g, CapacityMap capacity,
+ ReverseEdgeMap reverse_edge, std::istream& in = std::cin)
+{
+ typename graph_traits< Graph >::vertex_descriptor dummy_src,
+ dummy_sink; // Not filled in
+ return detail::read_dimacs_max_flow_internal(
+ g, capacity, reverse_edge, dummy_src, dummy_sink, in, false, "cut");
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_READ_DIMACS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/rmat_graph_generator.hpp b/contrib/restricted/boost/graph/include/boost/graph/rmat_graph_generator.hpp
new file mode 100644
index 0000000000..35c71ec347
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/rmat_graph_generator.hpp
@@ -0,0 +1,663 @@
+// Copyright 2004, 2005 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Nick Edmonds
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_RMAT_GENERATOR_HPP
+#define BOOST_GRAPH_RMAT_GENERATOR_HPP
+
+#include <math.h>
+#include <iterator>
+#include <utility>
+#include <vector>
+#include <queue>
+#include <map>
+#include <boost/shared_ptr.hpp>
+#include <boost/assert.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/detail/mpi_include.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/type_traits/is_same.hpp>
+// #include <boost/test/floating_point_comparison.hpp>
+
+using boost::shared_ptr;
+using boost::uniform_01;
+
+// Returns floor(log_2(n)), and -1 when n is 0
+template < typename IntegerType > inline int int_log2(IntegerType n)
+{
+ int l = 0;
+ while (n > 0)
+ {
+ ++l;
+ n >>= 1;
+ }
+ return l - 1;
+}
+
+struct keep_all_edges
+{
+ template < typename T > bool operator()(const T&, const T&) { return true; }
+};
+
+template < typename Distribution, typename ProcessId > struct keep_local_edges
+{
+
+ keep_local_edges(const Distribution& distrib, const ProcessId& id)
+ : distrib(distrib), id(id)
+ {
+ }
+
+ template < typename T > bool operator()(const T& x, const T& y)
+ {
+ return distrib(x) == id || distrib(y) == id;
+ }
+
+private:
+ const Distribution& distrib;
+ const ProcessId& id;
+};
+
+template < typename RandomGenerator, typename T >
+void generate_permutation_vector(
+ RandomGenerator& gen, std::vector< T >& vertexPermutation, T n)
+{
+ using boost::uniform_int;
+
+ vertexPermutation.resize(n);
+
+ // Generate permutation map of vertex numbers
+ uniform_int< T > rand_vertex(0, n - 1);
+ for (T i = 0; i < n; ++i)
+ vertexPermutation[i] = i;
+
+ // Can't use std::random_shuffle unless we create another (synchronized)
+ // PRNG
+ for (T i = 0; i < n; ++i)
+ std::swap(vertexPermutation[i], vertexPermutation[rand_vertex(gen)]);
+}
+
+template < typename RandomGenerator, typename T >
+std::pair< T, T > generate_edge(
+ shared_ptr< uniform_01< RandomGenerator > > prob, T n, unsigned int SCALE,
+ double a, double b, double c, double d)
+{
+ T u = 0, v = 0;
+ T step = n / 2;
+ for (unsigned int j = 0; j < SCALE; ++j)
+ {
+ double p = (*prob)();
+
+ if (p < a)
+ ;
+ else if (p >= a && p < a + b)
+ v += step;
+ else if (p >= a + b && p < a + b + c)
+ u += step;
+ else
+ { // p > a + b + c && p < a + b + c + d
+ u += step;
+ v += step;
+ }
+
+ step /= 2;
+
+ // 0.2 and 0.9 are hardcoded in the reference SSCA implementation.
+ // The maximum change in any given value should be less than 10%
+ a *= 0.9 + 0.2 * (*prob)();
+ b *= 0.9 + 0.2 * (*prob)();
+ c *= 0.9 + 0.2 * (*prob)();
+ d *= 0.9 + 0.2 * (*prob)();
+
+ double S = a + b + c + d;
+
+ a /= S;
+ b /= S;
+ c /= S;
+ // d /= S;
+ // Ensure all values add up to 1, regardless of floating point errors
+ d = 1. - a - b - c;
+ }
+
+ return std::make_pair(u, v);
+}
+
+namespace boost
+{
+
+/*
+ Chakrabarti's R-MAT scale free generator.
+
+ For all flavors of the R-MAT iterator a+b+c+d must equal 1 and for the
+ unique_rmat_iterator 'm' << 'n^2'. If 'm' is too close to 'n^2' the
+ generator may be unable to generate sufficient unique edges
+
+ To get a true scale free distribution {a, b, c, d : a > b, a > c, a > d}
+*/
+
+template < typename RandomGenerator, typename Graph > class rmat_iterator
+{
+ typedef typename graph_traits< Graph >::directed_category directed_category;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+ typedef typename graph_traits< Graph >::edges_size_type edges_size_type;
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< vertices_size_type, vertices_size_type > value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef std::ptrdiff_t difference_type; // Not used
+
+ // No argument constructor, set to terminating condition
+ rmat_iterator() : gen(), edge(0) {}
+
+ // Initialize for edge generation
+ rmat_iterator(RandomGenerator& gen, vertices_size_type n, edges_size_type m,
+ double a, double b, double c, double d, bool permute_vertices = true)
+ : gen()
+ , n(n)
+ , a(a)
+ , b(b)
+ , c(c)
+ , d(d)
+ , edge(m)
+ , permute_vertices(permute_vertices)
+ , SCALE(int_log2(n))
+
+ {
+ this->gen.reset(new uniform_01< RandomGenerator >(gen));
+
+ // BOOST_ASSERT(boost::test_tools::check_is_close(a + b + c +
+ // d, 1., 1.e-5));
+
+ if (permute_vertices)
+ generate_permutation_vector(gen, vertexPermutation, n);
+
+ // TODO: Generate the entire adjacency matrix then "Clip and flip" if
+ // undirected graph
+
+ // Generate the first edge
+ vertices_size_type u, v;
+ boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d);
+
+ if (permute_vertices)
+ current
+ = std::make_pair(vertexPermutation[u], vertexPermutation[v]);
+ else
+ current = std::make_pair(u, v);
+
+ --edge;
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return &current; }
+
+ rmat_iterator& operator++()
+ {
+ vertices_size_type u, v;
+ boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d);
+
+ if (permute_vertices)
+ current
+ = std::make_pair(vertexPermutation[u], vertexPermutation[v]);
+ else
+ current = std::make_pair(u, v);
+
+ --edge;
+
+ return *this;
+ }
+
+ rmat_iterator operator++(int)
+ {
+ rmat_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const rmat_iterator& other) const
+ {
+ return edge == other.edge;
+ }
+
+ bool operator!=(const rmat_iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ // Parameters
+ shared_ptr< uniform_01< RandomGenerator > > gen;
+ vertices_size_type n;
+ double a, b, c, d;
+ int edge;
+ bool permute_vertices;
+ int SCALE;
+
+ // Internal data structures
+ std::vector< vertices_size_type > vertexPermutation;
+ value_type current;
+};
+
+// Sorted version for CSR
+template < typename T > struct sort_pair
+{
+ bool operator()(const std::pair< T, T >& x, const std::pair< T, T >& y)
+ {
+ if (x.first == y.first)
+ return x.second > y.second;
+ else
+ return x.first > y.first;
+ }
+};
+
+template < typename RandomGenerator, typename Graph,
+ typename EdgePredicate = keep_all_edges >
+class sorted_rmat_iterator
+{
+ typedef typename graph_traits< Graph >::directed_category directed_category;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+ typedef typename graph_traits< Graph >::edges_size_type edges_size_type;
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< vertices_size_type, vertices_size_type > value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef std::ptrdiff_t difference_type; // Not used
+
+ // No argument constructor, set to terminating condition
+ sorted_rmat_iterator()
+ : gen(), values(sort_pair< vertices_size_type >()), done(true)
+ {
+ }
+
+ // Initialize for edge generation
+ sorted_rmat_iterator(RandomGenerator& gen, vertices_size_type n,
+ edges_size_type m, double a, double b, double c, double d,
+ bool permute_vertices = true, EdgePredicate ep = keep_all_edges())
+ : gen()
+ , permute_vertices(permute_vertices)
+ , values(sort_pair< vertices_size_type >())
+ , done(false)
+
+ {
+ // BOOST_ASSERT(boost::test_tools::check_is_close(a + b + c +
+ // d, 1., 1.e-5));
+
+ this->gen.reset(new uniform_01< RandomGenerator >(gen));
+
+ std::vector< vertices_size_type > vertexPermutation;
+ if (permute_vertices)
+ generate_permutation_vector(gen, vertexPermutation, n);
+
+ // TODO: "Clip and flip" if undirected graph
+ int SCALE = int_log2(n);
+
+ for (edges_size_type i = 0; i < m; ++i)
+ {
+
+ vertices_size_type u, v;
+ boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d);
+
+ if (permute_vertices)
+ {
+ if (ep(vertexPermutation[u], vertexPermutation[v]))
+ values.push(std::make_pair(
+ vertexPermutation[u], vertexPermutation[v]));
+ }
+ else
+ {
+ if (ep(u, v))
+ values.push(std::make_pair(u, v));
+ }
+ }
+
+ current = values.top();
+ values.pop();
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return &current; }
+
+ sorted_rmat_iterator& operator++()
+ {
+ if (!values.empty())
+ {
+ current = values.top();
+ values.pop();
+ }
+ else
+ done = true;
+
+ return *this;
+ }
+
+ sorted_rmat_iterator operator++(int)
+ {
+ sorted_rmat_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const sorted_rmat_iterator& other) const
+ {
+ return values.empty() && other.values.empty() && done && other.done;
+ }
+
+ bool operator!=(const sorted_rmat_iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ // Parameters
+ shared_ptr< uniform_01< RandomGenerator > > gen;
+ bool permute_vertices;
+
+ // Internal data structures
+ std::priority_queue< value_type, std::vector< value_type >,
+ sort_pair< vertices_size_type > >
+ values;
+ value_type current;
+ bool done;
+};
+
+// This version is slow but guarantees unique edges
+template < typename RandomGenerator, typename Graph,
+ typename EdgePredicate = keep_all_edges >
+class unique_rmat_iterator
+{
+ typedef typename graph_traits< Graph >::directed_category directed_category;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+ typedef typename graph_traits< Graph >::edges_size_type edges_size_type;
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< vertices_size_type, vertices_size_type > value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef std::ptrdiff_t difference_type; // Not used
+
+ // No argument constructor, set to terminating condition
+ unique_rmat_iterator() : gen(), done(true) {}
+
+ // Initialize for edge generation
+ unique_rmat_iterator(RandomGenerator& gen, vertices_size_type n,
+ edges_size_type m, double a, double b, double c, double d,
+ bool permute_vertices = true, EdgePredicate ep = keep_all_edges())
+ : gen(), done(false)
+
+ {
+ // BOOST_ASSERT(boost::test_tools::check_is_close(a + b + c +
+ // d, 1., 1.e-5));
+
+ this->gen.reset(new uniform_01< RandomGenerator >(gen));
+
+ std::vector< vertices_size_type > vertexPermutation;
+ if (permute_vertices)
+ generate_permutation_vector(gen, vertexPermutation, n);
+
+ int SCALE = int_log2(n);
+
+ std::map< value_type, bool > edge_map;
+
+ edges_size_type edges = 0;
+ do
+ {
+ vertices_size_type u, v;
+ boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d);
+
+ // Lowest vertex number always comes first
+ // (this means we don't have to worry about i->j and j->i being in
+ // the edge list)
+ if (u > v && is_same< directed_category, undirected_tag >::value)
+ std::swap(u, v);
+
+ if (edge_map.find(std::make_pair(u, v)) == edge_map.end())
+ {
+ edge_map[std::make_pair(u, v)] = true;
+
+ if (permute_vertices)
+ {
+ if (ep(vertexPermutation[u], vertexPermutation[v]))
+ values.push_back(std::make_pair(
+ vertexPermutation[u], vertexPermutation[v]));
+ }
+ else
+ {
+ if (ep(u, v))
+ values.push_back(std::make_pair(u, v));
+ }
+
+ edges++;
+ }
+ } while (edges < m);
+ // NGE - Asking for more than n^2 edges will result in an infinite loop
+ // here
+ // Asking for a value too close to n^2 edges may as well
+
+ current = values.back();
+ values.pop_back();
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return &current; }
+
+ unique_rmat_iterator& operator++()
+ {
+ if (!values.empty())
+ {
+ current = values.back();
+ values.pop_back();
+ }
+ else
+ done = true;
+
+ return *this;
+ }
+
+ unique_rmat_iterator operator++(int)
+ {
+ unique_rmat_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const unique_rmat_iterator& other) const
+ {
+ return values.empty() && other.values.empty() && done && other.done;
+ }
+
+ bool operator!=(const unique_rmat_iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ // Parameters
+ shared_ptr< uniform_01< RandomGenerator > > gen;
+
+ // Internal data structures
+ std::vector< value_type > values;
+ value_type current;
+ bool done;
+};
+
+// This version is slow but guarantees unique edges
+template < typename RandomGenerator, typename Graph,
+ typename EdgePredicate = keep_all_edges >
+class sorted_unique_rmat_iterator
+{
+ typedef typename graph_traits< Graph >::directed_category directed_category;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+ typedef typename graph_traits< Graph >::edges_size_type edges_size_type;
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< vertices_size_type, vertices_size_type > value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef std::ptrdiff_t difference_type; // Not used
+
+ // No argument constructor, set to terminating condition
+ sorted_unique_rmat_iterator()
+ : gen(), values(sort_pair< vertices_size_type >()), done(true)
+ {
+ }
+
+ // Initialize for edge generation
+ sorted_unique_rmat_iterator(RandomGenerator& gen, vertices_size_type n,
+ edges_size_type m, double a, double b, double c, double d,
+ bool bidirectional = false, bool permute_vertices = true,
+ EdgePredicate ep = keep_all_edges())
+ : gen()
+ , bidirectional(bidirectional)
+ , values(sort_pair< vertices_size_type >())
+ , done(false)
+
+ {
+ // BOOST_ASSERT(boost::test_tools::check_is_close(a + b + c +
+ // d, 1., 1.e-5));
+
+ this->gen.reset(new uniform_01< RandomGenerator >(gen));
+
+ std::vector< vertices_size_type > vertexPermutation;
+ if (permute_vertices)
+ generate_permutation_vector(gen, vertexPermutation, n);
+
+ int SCALE = int_log2(n);
+
+ std::map< value_type, bool > edge_map;
+
+ edges_size_type edges = 0;
+ do
+ {
+
+ vertices_size_type u, v;
+ boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d);
+
+ if (bidirectional)
+ {
+ if (edge_map.find(std::make_pair(u, v)) == edge_map.end())
+ {
+ edge_map[std::make_pair(u, v)] = true;
+ edge_map[std::make_pair(v, u)] = true;
+
+ if (ep(u, v))
+ {
+ if (permute_vertices)
+ {
+ values.push(std::make_pair(
+ vertexPermutation[u], vertexPermutation[v]));
+ values.push(std::make_pair(
+ vertexPermutation[v], vertexPermutation[u]));
+ }
+ else
+ {
+ values.push(std::make_pair(u, v));
+ values.push(std::make_pair(v, u));
+ }
+ }
+
+ ++edges;
+ }
+ }
+ else
+ {
+ // Lowest vertex number always comes first
+ // (this means we don't have to worry about i->j and j->i being
+ // in the edge list)
+ if (u > v
+ && is_same< directed_category, undirected_tag >::value)
+ std::swap(u, v);
+
+ if (edge_map.find(std::make_pair(u, v)) == edge_map.end())
+ {
+ edge_map[std::make_pair(u, v)] = true;
+
+ if (permute_vertices)
+ {
+ if (ep(vertexPermutation[u], vertexPermutation[v]))
+ values.push(std::make_pair(
+ vertexPermutation[u], vertexPermutation[v]));
+ }
+ else
+ {
+ if (ep(u, v))
+ values.push(std::make_pair(u, v));
+ }
+
+ ++edges;
+ }
+ }
+
+ } while (edges < m);
+ // NGE - Asking for more than n^2 edges will result in an infinite loop
+ // here
+ // Asking for a value too close to n^2 edges may as well
+
+ current = values.top();
+ values.pop();
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return &current; }
+
+ sorted_unique_rmat_iterator& operator++()
+ {
+ if (!values.empty())
+ {
+ current = values.top();
+ values.pop();
+ }
+ else
+ done = true;
+
+ return *this;
+ }
+
+ sorted_unique_rmat_iterator operator++(int)
+ {
+ sorted_unique_rmat_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const sorted_unique_rmat_iterator& other) const
+ {
+ return values.empty() && other.values.empty() && done && other.done;
+ }
+
+ bool operator!=(const sorted_unique_rmat_iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ // Parameters
+ shared_ptr< uniform_01< RandomGenerator > > gen;
+ bool bidirectional;
+
+ // Internal data structures
+ std::priority_queue< value_type, std::vector< value_type >,
+ sort_pair< vertices_size_type > >
+ values;
+ value_type current;
+ bool done;
+};
+
+} // end namespace boost
+
+
+
+#endif // BOOST_GRAPH_RMAT_GENERATOR_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/sequential_vertex_coloring.hpp b/contrib/restricted/boost/graph/include/boost/graph/sequential_vertex_coloring.hpp
new file mode 100644
index 0000000000..fcfa24301e
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/sequential_vertex_coloring.hpp
@@ -0,0 +1,126 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004 The Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_SEQUENTIAL_VERTEX_COLORING_HPP
+#define BOOST_GRAPH_SEQUENTIAL_VERTEX_COLORING_HPP
+
+#include <vector>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/limits.hpp>
+
+#ifdef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+#include <iterator>
+#endif
+
+/* This algorithm is to find coloring of a graph
+
+ Algorithm:
+ Let G = (V,E) be a graph with vertices (somehow) ordered v_1, v_2, ...,
+ v_n. For k = 1, 2, ..., n the sequential algorithm assigns v_k to the
+ smallest possible color.
+
+ Reference:
+
+ Thomas F. Coleman and Jorge J. More, Estimation of sparse Jacobian
+ matrices and graph coloring problems. J. Numer. Anal. V20, P187-209, 1983
+
+ v_k is stored as o[k] here.
+
+ The color of the vertex v will be stored in color[v].
+ i.e., vertex v belongs to coloring color[v] */
+
+namespace boost
+{
+template < class VertexListGraph, class OrderPA, class ColorMap >
+typename property_traits< ColorMap >::value_type sequential_vertex_coloring(
+ const VertexListGraph& G, OrderPA order, ColorMap color)
+{
+ typedef graph_traits< VertexListGraph > GraphTraits;
+ typedef typename GraphTraits::vertex_descriptor Vertex;
+ typedef typename property_traits< ColorMap >::value_type size_type;
+
+ size_type max_color = 0;
+ const size_type V = num_vertices(G);
+
+ // We need to keep track of which colors are used by
+ // adjacent vertices. We do this by marking the colors
+ // that are used. The mark array contains the mark
+ // for each color. The length of mark is the
+ // number of vertices since the maximum possible number of colors
+ // is the number of vertices.
+ std::vector< size_type > mark(V,
+ std::numeric_limits< size_type >::max
+ BOOST_PREVENT_MACRO_SUBSTITUTION());
+
+ // Initialize colors
+ typename GraphTraits::vertex_iterator v, vend;
+ for (boost::tie(v, vend) = vertices(G); v != vend; ++v)
+ put(color, *v, V - 1);
+
+ // Determine the color for every vertex one by one
+ for (size_type i = 0; i < V; i++)
+ {
+ Vertex current = get(order, i);
+ typename GraphTraits::adjacency_iterator v, vend;
+
+ // Mark the colors of vertices adjacent to current.
+ // i can be the value for marking since i increases successively
+ for (boost::tie(v, vend) = adjacent_vertices(current, G); v != vend;
+ ++v)
+ mark[get(color, *v)] = i;
+
+ // Next step is to assign the smallest un-marked color
+ // to the current vertex.
+ size_type j = 0;
+
+ // Scan through all useable colors, find the smallest possible
+ // color that is not used by neighbors. Note that if mark[j]
+ // is equal to i, color j is used by one of the current vertex's
+ // neighbors.
+ while (j < max_color && mark[j] == i)
+ ++j;
+
+ if (j == max_color) // All colors are used up. Add one more color
+ ++max_color;
+
+ // At this point, j is the smallest possible color
+ put(color, current, j); // Save the color of vertex current
+ }
+
+ return max_color;
+}
+
+template < class VertexListGraph, class ColorMap >
+typename property_traits< ColorMap >::value_type sequential_vertex_coloring(
+ const VertexListGraph& G, ColorMap color)
+{
+ typedef typename graph_traits< VertexListGraph >::vertex_descriptor
+ vertex_descriptor;
+ typedef typename graph_traits< VertexListGraph >::vertex_iterator
+ vertex_iterator;
+
+ std::pair< vertex_iterator, vertex_iterator > v = vertices(G);
+#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+ std::vector< vertex_descriptor > order(v.first, v.second);
+#else
+ std::vector< vertex_descriptor > order;
+ order.reserve(std::distance(v.first, v.second));
+ while (v.first != v.second)
+ order.push_back(*v.first++);
+#endif
+ return sequential_vertex_coloring(G,
+ make_iterator_property_map(order.begin(), identity_property_map(),
+ graph_traits< VertexListGraph >::null_vertex()),
+ color);
+}
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/simple_point.hpp b/contrib/restricted/boost/graph/include/boost/graph/simple_point.hpp
new file mode 100644
index 0000000000..0e3dffca63
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/simple_point.hpp
@@ -0,0 +1,23 @@
+//=======================================================================
+// Copyright 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Douglas Gregor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_SIMPLE_POINT_HPP
+#define BOOST_GRAPH_SIMPLE_POINT_HPP
+
+namespace boost
+{
+
+template < typename T > struct simple_point
+{
+ T x;
+ T y;
+};
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_SIMPLE_POINT_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/sloan_ordering.hpp b/contrib/restricted/boost/graph/include/boost/graph/sloan_ordering.hpp
new file mode 100644
index 0000000000..88f845b81c
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/sloan_ordering.hpp
@@ -0,0 +1,448 @@
+//
+//=======================================================================
+// Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch)
+// ETH Zurich, Center of Structure Technologies
+// (https://web.archive.org/web/20050307090307/http://www.structures.ethz.ch/)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+
+#ifndef BOOST_GRAPH_SLOAN_HPP
+#define BOOST_GRAPH_SLOAN_HPP
+
+#define WEIGHT1 1 // default weight for the distance in the Sloan algorithm
+#define WEIGHT2 2 // default weight for the degree in the Sloan algorithm
+
+#include <boost/config.hpp>
+#include <vector>
+#include <queue>
+#include <algorithm>
+#include <limits>
+#include <boost/pending/queue.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/cuthill_mckee_ordering.hpp>
+
+////////////////////////////////////////////////////////////
+//
+// Sloan-Algorithm for graph reordering
+//(optimzes profile and wavefront, not primiraly bandwidth
+//
+////////////////////////////////////////////////////////////
+
+namespace boost
+{
+
+/////////////////////////////////////////////////////////////////////////
+// Function that returns the maximum depth of
+// a rooted level strucutre (RLS)
+//
+/////////////////////////////////////////////////////////////////////////
+template < class Distance > typename Distance::value_type RLS_depth(Distance& d)
+{
+ typename Distance::value_type h_s = 0;
+ typename Distance::iterator iter;
+
+ for (iter = d.begin(); iter != d.end(); ++iter)
+ {
+ if (*iter > h_s)
+ {
+ h_s = *iter;
+ }
+ }
+
+ return h_s;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// Function that returns the width of the largest level of
+// a rooted level strucutre (RLS)
+//
+/////////////////////////////////////////////////////////////////////////
+template < class Distance, class my_int >
+typename Distance::value_type RLS_max_width(Distance& d, my_int depth)
+{
+
+ typedef typename Distance::value_type Degree;
+
+ // Searching for the maximum width of a level
+ std::vector< Degree > dummy_width(depth + 1, 0);
+ typename std::vector< Degree >::iterator my_it;
+ typename Distance::iterator iter;
+ Degree w_max = 0;
+
+ for (iter = d.begin(); iter != d.end(); ++iter)
+ {
+ dummy_width[*iter]++;
+ }
+
+ for (my_it = dummy_width.begin(); my_it != dummy_width.end(); ++my_it)
+ {
+ if (*my_it > w_max)
+ w_max = *my_it;
+ }
+
+ return w_max;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// Function for finding a good starting node for Sloan algorithm
+//
+// This is to find a good starting node. "good" is in the sense
+// of the ordering generated.
+/////////////////////////////////////////////////////////////////////////
+template < class Graph, class ColorMap, class DegreeMap >
+typename graph_traits< Graph >::vertex_descriptor sloan_start_end_vertices(
+ Graph& G, typename graph_traits< Graph >::vertex_descriptor& s,
+ ColorMap color, DegreeMap degree)
+{
+ typedef typename property_traits< DegreeMap >::value_type Degree;
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename std::vector<
+ typename graph_traits< Graph >::vertices_size_type >::iterator vec_iter;
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+
+ typedef typename property_map< Graph, vertex_index_t >::const_type VertexID;
+
+ s = *(vertices(G).first);
+ Vertex e = s;
+ Vertex i;
+ Degree my_degree = get(degree, s);
+ Degree dummy, h_i, h_s, w_i, w_e;
+ bool new_start = true;
+ Degree maximum_degree = 0;
+
+ // Creating a std-vector for storing the distance from the start vertex in
+ // dist
+ std::vector< typename graph_traits< Graph >::vertices_size_type > dist(
+ num_vertices(G), 0);
+
+ // Wrap a property_map_iterator around the std::iterator
+ boost::iterator_property_map< vec_iter, VertexID, size_type, size_type& >
+ dist_pmap(dist.begin(), get(vertex_index, G));
+
+ // Creating a property_map for the indices of a vertex
+ typename property_map< Graph, vertex_index_t >::type index_map
+ = get(vertex_index, G);
+
+ // Creating a priority queue
+ typedef indirect_cmp< DegreeMap, std::greater< Degree > > Compare;
+ Compare comp(degree);
+ std::priority_queue< Vertex, std::vector< Vertex >, Compare > degree_queue(
+ comp);
+
+ // step 1
+ // Scan for the vertex with the smallest degree and the maximum degree
+ typename graph_traits< Graph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
+ {
+ dummy = get(degree, *ui);
+
+ if (dummy < my_degree)
+ {
+ my_degree = dummy;
+ s = *ui;
+ }
+
+ if (dummy > maximum_degree)
+ {
+ maximum_degree = dummy;
+ }
+ }
+ // end 1
+
+ do
+ {
+ new_start = false; // Setting the loop repetition status to false
+
+ // step 2
+ // initialize the the disance std-vector with 0
+ for (typename std::vector< typename graph_traits<
+ Graph >::vertices_size_type >::iterator iter
+ = dist.begin();
+ iter != dist.end(); ++iter)
+ *iter = 0;
+
+ // generating the RLS (rooted level structure)
+ breadth_first_search(G, s,
+ visitor(
+ make_bfs_visitor(record_distances(dist_pmap, on_tree_edge()))));
+
+ // end 2
+
+ // step 3
+ // calculating the depth of the RLS
+ h_s = RLS_depth(dist);
+
+ // step 4
+ // pushing one node of each degree in an ascending manner into
+ // degree_queue
+ std::vector< bool > shrink_trace(maximum_degree, false);
+ for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
+ {
+ dummy = get(degree, *ui);
+
+ if ((dist[index_map[*ui]] == h_s) && (!shrink_trace[dummy]))
+ {
+ degree_queue.push(*ui);
+ shrink_trace[dummy] = true;
+ }
+ }
+
+ // end 3 & 4
+
+ // step 5
+ // Initializing w
+ w_e = (std::numeric_limits< Degree >::max)();
+ // end 5
+
+ // step 6
+ // Testing for termination
+ while (!degree_queue.empty())
+ {
+ i = degree_queue.top(); // getting the node with the lowest degree
+ // from the degree queue
+ degree_queue.pop(); // ereasing the node with the lowest degree from
+ // the degree queue
+
+ // generating a RLS
+ for (typename std::vector< typename graph_traits<
+ Graph >::vertices_size_type >::iterator iter
+ = dist.begin();
+ iter != dist.end(); ++iter)
+ *iter = 0;
+
+ breadth_first_search(G, i,
+ boost::visitor(make_bfs_visitor(
+ record_distances(dist_pmap, on_tree_edge()))));
+
+ // Calculating depth and width of the rooted level
+ h_i = RLS_depth(dist);
+ w_i = RLS_max_width(dist, h_i);
+
+ // Testing for termination
+ if ((h_i > h_s) && (w_i < w_e))
+ {
+ h_s = h_i;
+ s = i;
+ while (!degree_queue.empty())
+ degree_queue.pop();
+ new_start = true;
+ }
+ else if (w_i < w_e)
+ {
+ w_e = w_i;
+ e = i;
+ }
+ }
+ // end 6
+
+ } while (new_start);
+
+ return e;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Sloan algorithm with a given starting Vertex.
+//
+// This algorithm requires user to provide a starting vertex to
+// compute Sloan ordering.
+//////////////////////////////////////////////////////////////////////////
+template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
+ class PriorityMap, class Weight >
+OutputIterator sloan_ordering(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor e,
+ OutputIterator permutation, ColorMap color, DegreeMap degree,
+ PriorityMap priority, Weight W1, Weight W2)
+{
+ // typedef typename property_traits<DegreeMap>::value_type Degree;
+ typedef typename property_traits< PriorityMap >::value_type Degree;
+ typedef typename property_traits< ColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename std::vector<
+ typename graph_traits< Graph >::vertices_size_type >::iterator vec_iter;
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+
+ typedef typename property_map< Graph, vertex_index_t >::const_type VertexID;
+
+ // Creating a std-vector for storing the distance from the end vertex in it
+ typename std::vector< typename graph_traits< Graph >::vertices_size_type >
+ dist(num_vertices(g), 0);
+
+ // Wrap a property_map_iterator around the std::iterator
+ boost::iterator_property_map< vec_iter, VertexID, size_type, size_type& >
+ dist_pmap(dist.begin(), get(vertex_index, g));
+
+ breadth_first_search(g, e,
+ visitor(make_bfs_visitor(record_distances(dist_pmap, on_tree_edge()))));
+
+ // Creating a property_map for the indices of a vertex
+ typename property_map< Graph, vertex_index_t >::type index_map
+ = get(vertex_index, g);
+
+ // Sets the color and priority to their initial status
+ Degree cdeg;
+ typename graph_traits< Graph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ put(color, *ui, Color::white());
+ cdeg = get(degree, *ui) + 1;
+ put(priority, *ui, W1 * dist[index_map[*ui]] - W2 * cdeg);
+ }
+
+ // Priority list
+ typedef indirect_cmp< PriorityMap, std::greater< Degree > > Compare;
+ Compare comp(priority);
+ std::list< Vertex > priority_list;
+
+ // Some more declarations
+ typename graph_traits< Graph >::out_edge_iterator ei, ei_end, ei2, ei2_end;
+ Vertex u, v, w;
+
+ put(color, s,
+ Color::green()); // Sets the color of the starting vertex to gray
+ priority_list.push_front(s); // Puts s into the priority_list
+
+ while (!priority_list.empty())
+ {
+ priority_list.sort(comp); // Orders the elements in the priority list in
+ // an ascending manner
+
+ u = priority_list
+ .front(); // Accesses the last element in the priority list
+ priority_list
+ .pop_front(); // Removes the last element in the priority list
+
+ if (get(color, u) == Color::green())
+ {
+ // for-loop over all out-edges of vertex u
+ for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
+ {
+ v = target(*ei, g);
+
+ put(priority, v, get(priority, v) + W2); // updates the priority
+
+ if (get(color, v)
+ == Color::white()) // test if the vertex is inactive
+ {
+ put(color, v,
+ Color::green()); // giving the vertex a preactive status
+ priority_list.push_front(
+ v); // writing the vertex in the priority_queue
+ }
+ }
+ }
+
+ // Here starts step 8
+ *permutation++
+ = u; // Puts u to the first position in the permutation-vector
+ put(color, u, Color::black()); // Gives u an inactive status
+
+ // for loop over all the adjacent vertices of u
+ for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
+ {
+
+ v = target(*ei, g);
+
+ if (get(color, v) == Color::green())
+ { // tests if the vertex is inactive
+
+ put(color, v,
+ Color::red()); // giving the vertex an active status
+ put(priority, v, get(priority, v) + W2); // updates the priority
+
+ // for loop over alll adjacent vertices of v
+ for (boost::tie(ei2, ei2_end) = out_edges(v, g); ei2 != ei2_end;
+ ++ei2)
+ {
+ w = target(*ei2, g);
+
+ if (get(color, w) != Color::black())
+ { // tests if vertex is postactive
+
+ put(priority, w,
+ get(priority, w) + W2); // updates the priority
+
+ if (get(color, w) == Color::white())
+ {
+
+ put(color, w, Color::green()); // gives the vertex a
+ // preactive status
+ priority_list.push_front(
+ w); // puts the vertex into the priority queue
+
+ } // end if
+
+ } // end if
+
+ } // end for
+
+ } // end if
+
+ } // end for
+
+ } // end while
+
+ return permutation;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Same algorithm as before, but without the weights given (taking default
+// weights
+template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
+ class PriorityMap >
+OutputIterator sloan_ordering(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor e,
+ OutputIterator permutation, ColorMap color, DegreeMap degree,
+ PriorityMap priority)
+{
+ return sloan_ordering(
+ g, s, e, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Sloan algorithm without a given starting Vertex.
+//
+// This algorithm finds a good starting vertex itself to
+// compute Sloan-ordering.
+//////////////////////////////////////////////////////////////////////////
+
+template < class Graph, class OutputIterator, class Color, class Degree,
+ class Priority, class Weight >
+inline OutputIterator sloan_ordering(Graph& G, OutputIterator permutation,
+ Color color, Degree degree, Priority priority, Weight W1, Weight W2)
+{
+ typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex;
+
+ Vertex s, e;
+ e = sloan_start_end_vertices(G, s, color, degree);
+
+ return sloan_ordering(
+ G, s, e, permutation, color, degree, priority, W1, W2);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Same as before, but without given weights (default weights are taken instead)
+template < class Graph, class OutputIterator, class Color, class Degree,
+ class Priority >
+inline OutputIterator sloan_ordering(Graph& G, OutputIterator permutation,
+ Color color, Degree degree, Priority priority)
+{
+ return sloan_ordering(
+ G, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_SLOAN_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/small_world_generator.hpp b/contrib/restricted/boost/graph/include/boost/graph/small_world_generator.hpp
new file mode 100644
index 0000000000..f2d0d084ac
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/small_world_generator.hpp
@@ -0,0 +1,132 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP
+#define BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP
+
+#include <iterator>
+#include <utility>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/uniform_int.hpp>
+
+namespace boost
+{
+
+// Assumes undirected
+template < typename RandomGenerator, typename Graph > class small_world_iterator
+{
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< vertices_size_type, vertices_size_type > value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef void difference_type;
+
+ small_world_iterator() : gen(0) {}
+ small_world_iterator(RandomGenerator& gen, vertices_size_type n,
+ vertices_size_type k, double prob = 0.0, bool allow_self_loops = false)
+ : gen(&gen)
+ , n(n)
+ , k(k)
+ , prob(prob)
+ , source(0)
+ , target(allow_self_loops ? 0 : 1)
+ , allow_self_loops(allow_self_loops)
+ , current(0, allow_self_loops ? 0 : 1)
+ {
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return &current; }
+
+ small_world_iterator& operator++()
+ {
+ target = (target + 1) % n;
+ if (target == (source + k / 2 + 1) % n)
+ {
+ ++source;
+ if (allow_self_loops)
+ target = source;
+ else
+ target = (source + 1) % n;
+ }
+ current.first = source;
+
+ uniform_01< RandomGenerator, double > rand01(*gen);
+ uniform_int< vertices_size_type > rand_vertex_gen(0, n - 1);
+ double x = rand01();
+ *gen = rand01.base(); // GRRRR
+ if (x < prob)
+ {
+ vertices_size_type lower = (source + n - k / 2) % n;
+ vertices_size_type upper = (source + k / 2) % n;
+ do
+ {
+ current.second = rand_vertex_gen(*gen);
+ } while ((current.second >= lower && current.second <= upper)
+ || (upper < lower
+ && (current.second >= lower || current.second <= upper)));
+ }
+ else
+ {
+ current.second = target;
+ }
+ return *this;
+ }
+
+ small_world_iterator operator++(int)
+ {
+ small_world_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const small_world_iterator& other) const
+ {
+ if (!gen && other.gen)
+ return other == *this;
+ else if (gen && !other.gen)
+ return source == n;
+ else if (!gen && !other.gen)
+ return true;
+ return source == other.source && target == other.target;
+ }
+
+ bool operator!=(const small_world_iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ void next()
+ {
+ uniform_int< vertices_size_type > rand_vertex(0, n - 1);
+ current.first = rand_vertex(*gen);
+ do
+ {
+ current.second = rand_vertex(*gen);
+ } while (current.first == current.second && !allow_self_loops);
+ }
+
+ RandomGenerator* gen;
+ vertices_size_type n;
+ vertices_size_type k;
+ double prob;
+ vertices_size_type source;
+ vertices_size_type target;
+ bool allow_self_loops;
+ value_type current;
+};
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/smallest_last_ordering.hpp b/contrib/restricted/boost/graph/include/boost/graph/smallest_last_ordering.hpp
new file mode 100644
index 0000000000..88af0ea931
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/smallest_last_ordering.hpp
@@ -0,0 +1,152 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+// Revision History:
+// 17 March 2006: Fixed a bug: when updating the degree a vertex
+// could be moved to a wrong bucket. (Roman Dementiev)
+//
+
+#ifndef BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP
+#define BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP
+/*
+ The smallest-last ordering is defined for the loopless graph G with
+ vertices a(j), j = 1,2,...,n where a(j) is the j-th column of A and
+ with edge (a(i),a(j)) if and only if columns i and j have a
+ non-zero in the same row position. The smallest-last ordering is
+ determined recursively by letting list(k), k = n,...,1 be a column
+ with least degree in the subgraph spanned by the un-ordered
+ columns.
+ */
+#include <vector>
+#include <algorithm>
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/bucket_sorter.hpp>
+
+namespace boost
+{
+
+template < class VertexListGraph, class Order, class Degree, class Marker >
+void smallest_last_vertex_ordering(
+ const VertexListGraph& G, Order order, Degree degree, Marker marker)
+{
+ typedef typename boost::graph_traits< VertexListGraph > GraphTraits;
+ typedef typename GraphTraits::vertex_descriptor Vertex;
+ // typedef typename GraphTraits::size_type size_type;
+ typedef std::size_t size_type;
+
+ const size_type num = num_vertices(G);
+
+ typedef
+ typename boost::property_map< VertexListGraph, vertex_index_t >::type
+ ID;
+ typedef bucket_sorter< size_type, Vertex, Degree, ID > BucketSorter;
+
+ BucketSorter degree_bucket_sorter(num, num, degree, get(vertex_index, G));
+
+ smallest_last_vertex_ordering(
+ G, order, degree, marker, degree_bucket_sorter);
+}
+
+template < class VertexListGraph, class Order, class Degree, class Marker,
+ class BucketSorter >
+void smallest_last_vertex_ordering(const VertexListGraph& G, Order order,
+ Degree degree, Marker marker, BucketSorter& degree_buckets)
+{
+ typedef typename boost::graph_traits< VertexListGraph > GraphTraits;
+ typedef typename GraphTraits::vertex_descriptor Vertex;
+ // typedef typename GraphTraits::size_type size_type;
+ typedef std::size_t size_type;
+
+ const size_type num = num_vertices(G);
+
+ typename GraphTraits::vertex_iterator v, vend;
+ for (boost::tie(v, vend) = vertices(G); v != vend; ++v)
+ {
+ put(marker, *v, num);
+ put(degree, *v, out_degree(*v, G));
+ degree_buckets.push(*v);
+ }
+
+ size_type minimum_degree = 0;
+ size_type current_order = num - 1;
+
+ while (1)
+ {
+ typedef typename BucketSorter::stack MDStack;
+ MDStack minimum_degree_stack = degree_buckets[minimum_degree];
+ while (minimum_degree_stack.empty())
+ minimum_degree_stack = degree_buckets[++minimum_degree];
+
+ Vertex node = minimum_degree_stack.top();
+ put(order, current_order, node);
+
+ if (current_order == 0) // find all vertices
+ break;
+
+ minimum_degree_stack.pop();
+ put(marker, node, 0); // node has been ordered.
+
+ typename GraphTraits::adjacency_iterator v, vend;
+ for (boost::tie(v, vend) = adjacent_vertices(node, G); v != vend; ++v)
+
+ if (get(marker, *v) > current_order)
+ { //*v is unordered vertex
+ put(marker, *v,
+ current_order); // mark the columns adjacent to node
+
+ // delete *v from the bucket sorter
+ degree_buckets.remove(*v);
+
+ // It is possible minimum degree goes down
+ // Here we keep tracking it.
+ put(degree, *v, get(degree, *v) - 1);
+ BOOST_USING_STD_MIN();
+ minimum_degree = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ minimum_degree, get(degree, *v));
+
+ // reinsert *v in the bucket sorter with the new degree
+ degree_buckets.push(*v);
+ }
+
+ current_order--;
+ }
+
+ // at this point, order[i] = v_i;
+}
+
+template < class VertexListGraph, class Order >
+void smallest_last_vertex_ordering(const VertexListGraph& G, Order order)
+{
+ typedef typename graph_traits< VertexListGraph >::vertex_descriptor
+ vertex_descriptor;
+ typedef typename graph_traits< VertexListGraph >::degree_size_type
+ degree_size_type;
+ smallest_last_vertex_ordering(G, order,
+ make_shared_array_property_map(
+ num_vertices(G), degree_size_type(0), get(vertex_index, G)),
+ make_shared_array_property_map(
+ num_vertices(G), (std::size_t)(0), get(vertex_index, G)));
+}
+
+template < class VertexListGraph >
+std::vector< typename graph_traits< VertexListGraph >::vertex_descriptor >
+smallest_last_vertex_ordering(const VertexListGraph& G)
+{
+ std::vector< typename graph_traits< VertexListGraph >::vertex_descriptor >
+ o(num_vertices(G));
+ smallest_last_vertex_ordering(G,
+ make_iterator_property_map(
+ o.begin(), typed_identity_property_map< std::size_t >()));
+ return o;
+}
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/ssca_graph_generator.hpp b/contrib/restricted/boost/graph/include/boost/graph/ssca_graph_generator.hpp
new file mode 100644
index 0000000000..a2281236ca
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/ssca_graph_generator.hpp
@@ -0,0 +1,197 @@
+// Copyright 2004, 2005 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Nick Edmonds
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_SSCA_GENERATOR_HPP
+#define BOOST_GRAPH_SSCA_GENERATOR_HPP
+
+#include <iterator>
+#include <utility>
+#include <vector>
+#include <queue>
+#include <boost/config.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+enum Direction
+{
+ FORWARD = 1,
+ BACKWARD = 2,
+ BOTH = FORWARD | BACKWARD
+};
+
+namespace boost
+{
+
+// This generator generates graphs according to the method specified
+// in SSCA 1.1. Current versions of SSCA use R-MAT graphs
+
+template < typename RandomGenerator, typename Graph > class ssca_iterator
+{
+ typedef typename graph_traits< Graph >::directed_category directed_category;
+ typedef
+ typename graph_traits< Graph >::vertices_size_type vertices_size_type;
+
+public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< vertices_size_type, vertices_size_type > value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef void difference_type;
+
+ // No argument constructor, set to terminating condition
+ ssca_iterator() : gen(), verticesRemaining(0) {}
+
+ // Initialize for edge generation
+ ssca_iterator(RandomGenerator& gen, vertices_size_type totVertices,
+ vertices_size_type maxCliqueSize, double probUnidirectional,
+ int maxParallelEdges, double probIntercliqueEdges)
+ : gen(&gen)
+ , totVertices(totVertices)
+ , maxCliqueSize(maxCliqueSize)
+ , probUnidirectional(probUnidirectional)
+ , maxParallelEdges(maxParallelEdges)
+ , probIntercliqueEdges(probIntercliqueEdges)
+ , currentClique(0)
+ , verticesRemaining(totVertices)
+ {
+ cliqueNum = std::vector< int >(totVertices, -1);
+ current = std::make_pair(0, 0);
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return &current; }
+
+ ssca_iterator& operator++()
+ {
+ BOOST_USING_STD_MIN();
+ while (values.empty() && verticesRemaining > 0)
+ { // If there are no values left, generate a new clique
+ uniform_int< vertices_size_type > clique_size(1, maxCliqueSize);
+ uniform_int< vertices_size_type > rand_vertex(0, totVertices - 1);
+ uniform_int< int > num_parallel_edges(1, maxParallelEdges);
+ uniform_int< short > direction(0, 1);
+ uniform_01< RandomGenerator > prob(*gen);
+ std::vector< vertices_size_type > cliqueVertices;
+
+ cliqueVertices.clear();
+ vertices_size_type size = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ clique_size(*gen), verticesRemaining);
+ while (cliqueVertices.size() < size)
+ {
+ vertices_size_type v = rand_vertex(*gen);
+ if (cliqueNum[v] == -1)
+ {
+ cliqueNum[v] = currentClique;
+ cliqueVertices.push_back(v);
+ verticesRemaining--;
+ }
+ } // Nick: This is inefficient when only a few vertices remain...
+ // I should probably just select the remaining vertices
+ // in order when only a certain fraction remain.
+
+ typename std::vector< vertices_size_type >::iterator first, second;
+ for (first = cliqueVertices.begin(); first != cliqueVertices.end();
+ ++first)
+ for (second = first + 1; second != cliqueVertices.end();
+ ++second)
+ {
+ Direction d;
+ int edges;
+
+ d = prob() < probUnidirectional
+ ? (direction(*gen) == 0 ? FORWARD : BACKWARD)
+ : BOTH;
+
+ if (d & FORWARD)
+ {
+ edges = num_parallel_edges(*gen);
+ for (int i = 0; i < edges; ++i)
+ values.push(std::make_pair(*first, *second));
+ }
+
+ if (d & BACKWARD)
+ {
+ edges = num_parallel_edges(*gen);
+ for (int i = 0; i < edges; ++i)
+ values.push(std::make_pair(*second, *first));
+ }
+ }
+
+ if (verticesRemaining == 0)
+ {
+ // Generate interclique edges
+ for (vertices_size_type i = 0; i < totVertices; ++i)
+ {
+ double p = probIntercliqueEdges;
+ for (vertices_size_type d = 2; d < totVertices / 2;
+ d *= 2, p /= 2)
+ {
+ vertices_size_type j = (i + d) % totVertices;
+ if (cliqueNum[j] != cliqueNum[i] && prob() < p)
+ {
+ int edges = num_parallel_edges(*gen);
+ for (int i = 0; i < edges; ++i)
+ values.push(std::make_pair(i, j));
+ }
+ }
+ }
+ }
+
+ currentClique++;
+ }
+
+ if (!values.empty())
+ { // If we're not done return a value
+ current = values.front();
+ values.pop();
+ }
+
+ return *this;
+ }
+
+ ssca_iterator operator++(int)
+ {
+ ssca_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const ssca_iterator& other) const
+ {
+ return verticesRemaining == other.verticesRemaining && values.empty()
+ && other.values.empty();
+ }
+
+ bool operator!=(const ssca_iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+private:
+ // Parameters
+ RandomGenerator* gen;
+ vertices_size_type totVertices;
+ vertices_size_type maxCliqueSize;
+ double probUnidirectional;
+ int maxParallelEdges;
+ double probIntercliqueEdges;
+
+ // Internal data structures
+ std::vector< int > cliqueNum;
+ std::queue< value_type > values;
+ int currentClique;
+ vertices_size_type verticesRemaining;
+ value_type current;
+};
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_SSCA_GENERATOR_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/st_connected.hpp b/contrib/restricted/boost/graph/include/boost/graph/st_connected.hpp
new file mode 100644
index 0000000000..2e8f444319
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/st_connected.hpp
@@ -0,0 +1,89 @@
+// Copyright (C) 2006 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_DISTRIBUTED_ST_CONNECTED_HPP
+#define BOOST_GRAPH_DISTRIBUTED_ST_CONNECTED_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/two_bit_color_map.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/pending/queue.hpp>
+
+namespace boost
+{
+namespace graph
+{
+
+ template < typename Graph, typename ColorMap >
+ bool st_connected(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t, ColorMap color)
+ {
+ typedef typename property_traits< ColorMap >::value_type Color;
+ typedef color_traits< Color > ColorTraits;
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+
+ // Set all vertices to white (unvisited)
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ put(color, v, ColorTraits::white());
+
+ // Vertices found from the source are grey
+ put(color, s, ColorTraits::gray());
+
+ // Vertices found from the target are greeen
+ put(color, t, ColorTraits::green());
+ queue< Vertex > Q;
+ Q.push(s);
+ Q.push(t);
+
+ while (!Q.empty())
+ {
+ Vertex u = Q.top();
+ Q.pop();
+ Color u_color = get(color, u);
+
+ BGL_FORALL_OUTEDGES_T(u, e, g, Graph)
+ {
+ Vertex v = target(e, g);
+ Color v_color = get(color, v);
+ if (v_color == ColorTraits::white())
+ {
+ // We have not seen "v" before; mark it with the same color
+ // as u
+ Color u_color = get(color, u);
+ put(color, v, u_color);
+
+ // Push it on the queue
+ Q.push(v);
+ }
+ else if (v_color != ColorTraits::black() && u_color != v_color)
+ {
+ // Colors have collided. We're done!
+ return true;
+ }
+ }
+ // u is done, so mark it black
+ put(color, u, ColorTraits::black());
+ }
+
+ return false;
+ }
+
+ template < typename Graph >
+ inline bool st_connected(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t)
+ {
+ return st_connected(g, s, t,
+ make_two_bit_color_map(num_vertices(g), get(vertex_index, g)));
+ }
+
+}
+} // end namespace boost::graph
+
+#endif // BOOST_GRAPH_DISTRIBUTED_ST_CONNECTED_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/stanford_graph.hpp b/contrib/restricted/boost/graph/include/boost/graph/stanford_graph.hpp
new file mode 100644
index 0000000000..a3b949e610
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/stanford_graph.hpp
@@ -0,0 +1,586 @@
+//=======================================================================
+// Copyright 1997-2001 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#ifndef BOOST_GRAPH_SGB_GRAPH_HPP
+#define BOOST_GRAPH_SGB_GRAPH_HPP
+
+#include <boost/config.hpp>
+#include <boost/operators.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+
+// Thanks to Andreas Scherer for numerous suggestions and fixes!
+
+// This file adapts a Stanford GraphBase (SGB) Graph pointer into a
+// VertexListGraph. Note that a graph adaptor class is not needed,
+// SGB's Graph* is used as is. The VertexListGraph concept is fulfilled by
+// defining the appropriate non-member functions for Graph*.
+//
+// The PROTOTYPES change file extensions to SGB must be applied so
+// that the SGB functions have real prototypes which are necessary for
+// the C++ compiler. To apply the PROTOTYPES extensions, before you do
+// "make tests install" for SGB do "ln -s PROTOTYPES/* ." to the SGB
+// root directory (or just copy all the files from the PROTOTYPES
+// directory to the SGB root directory).
+//
+extern "C"
+{
+ // We include all global definitions for the general stuff
+ // of The Stanford GraphBase and its various graph generator
+ // functions by reading all SGB headerfiles as in section 2 of
+ // the "test_sample" program.
+#include <gb_graph.h> /* SGB data structures */
+#include <gb_io.h> /* SGB input/output routines */
+#include <gb_flip.h> /* random number generator */
+#include <gb_dijk.h> /* routines for shortest paths */
+#include <gb_basic.h> /* the basic graph operations */
+#undef empty /* avoid name clash with C++ standard library */
+ inline Graph* empty(long n) /* and provide workaround */
+ {
+ return board(n, 0L, 0L, 0L, 2L, 0L, 0L);
+ }
+#include <gb_books.h> /* graphs based on literature */
+#include <gb_econ.h> /* graphs based on economic data */
+#include <gb_games.h> /* graphs based on football scores */
+#undef ap /* avoid name clash with BGL parameter */
+ // ap ==> Vertex::u.I
+#include <gb_gates.h> /* graphs based on logic circuits */
+#undef val /* avoid name clash with g++ headerfile stl_tempbuf.h */
+ // val ==> Vertex::x.I
+#include <gb_lisa.h> /* graphs based on Mona Lisa */
+#include <gb_miles.h> /* graphs based on mileage data */
+#include <gb_plane.h> /* planar graphs */
+#include <gb_raman.h> /* Ramanujan graphs */
+#include <gb_rand.h> /* random graphs */
+#include <gb_roget.h> /* graphs based on Roget's Thesaurus */
+#include <gb_save.h> /* we save results in ASCII format */
+#include <gb_words.h> /* five-letter-word graphs */
+#undef weight /* avoid name clash with BGL parameter */
+ // weight ==> Vertex::u.I
+}
+
+namespace boost
+{
+class sgb_edge;
+}
+
+class sgb_out_edge_iterator;
+class sgb_adj_iterator;
+class sgb_vertex_iterator;
+
+namespace boost
+{
+typedef Graph* sgb_graph_ptr;
+typedef const Graph* sgb_const_graph_ptr;
+
+struct sgb_traversal_tag : public virtual vertex_list_graph_tag,
+ public virtual incidence_graph_tag,
+ public virtual adjacency_graph_tag
+{
+};
+
+template <> struct graph_traits< sgb_graph_ptr >
+{
+ typedef Vertex* vertex_descriptor;
+ typedef boost::sgb_edge edge_descriptor;
+ typedef sgb_out_edge_iterator out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef sgb_adj_iterator adjacency_iterator;
+ typedef sgb_vertex_iterator vertex_iterator;
+ typedef void edge_iterator;
+ typedef long vertices_size_type;
+ typedef long edge_size_type;
+ typedef long degree_size_type;
+ typedef directed_tag directed_category;
+ typedef sgb_traversal_tag traversal_category;
+ typedef allow_parallel_edge_tag edge_parallel_category;
+ /** Return a null descriptor */
+ static vertex_descriptor null_vertex() { return NULL; }
+};
+template <> struct graph_traits< sgb_const_graph_ptr >
+{
+ typedef Vertex* vertex_descriptor;
+ typedef boost::sgb_edge edge_descriptor;
+ typedef sgb_out_edge_iterator out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef sgb_adj_iterator adjacency_iterator;
+ typedef sgb_vertex_iterator vertex_iterator;
+ typedef void edge_iterator;
+ typedef long vertices_size_type;
+ typedef long edge_size_type;
+ typedef long degree_size_type;
+ typedef directed_tag directed_category;
+ typedef sgb_traversal_tag traversal_category;
+ typedef allow_parallel_edge_tag edge_parallel_category;
+ /** Return a null descriptor */
+ static vertex_descriptor null_vertex() { return NULL; }
+};
+}
+
+namespace boost
+{
+
+struct edge_length_t
+{
+ typedef edge_property_tag kind;
+};
+
+// We could just use Arc* as the edge descriptor type, but
+// we want to add the source(e,g) function which requires
+// that we carry along a pointer to the source vertex.
+class sgb_edge
+{
+ typedef sgb_edge self;
+
+public:
+ sgb_edge() : _arc(0), _src(0) {}
+ sgb_edge(Arc* a, Vertex* s) : _arc(a), _src(s) {}
+ friend Vertex* source(self e, sgb_const_graph_ptr) { return e._src; }
+ friend Vertex* target(self e, sgb_const_graph_ptr) { return e._arc->tip; }
+ friend bool operator==(const self& a, const self& b)
+ {
+ return a._arc == b._arc;
+ }
+ friend bool operator!=(const self& a, const self& b)
+ {
+ return a._arc != b._arc;
+ }
+#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+ template < class Ref > friend class sgb_edge_length_map;
+ template < class Tag, class Ref > friend class sgb_edge_util_map;
+ friend long get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key);
+ friend long get(
+ edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key);
+ friend void put(
+ edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value);
+
+protected:
+#endif
+ Arc* _arc;
+ Vertex* _src;
+};
+} // namespace boost
+
+class sgb_out_edge_iterator
+: public boost::forward_iterator_helper< sgb_out_edge_iterator, boost::sgb_edge,
+ std::ptrdiff_t, boost::sgb_edge*, boost::sgb_edge >
+{
+ typedef sgb_out_edge_iterator self;
+
+public:
+ sgb_out_edge_iterator() : _src(0), _arc(0) {}
+ sgb_out_edge_iterator(Vertex* s, Arc* d) : _src(s), _arc(d) {}
+ boost::sgb_edge operator*() { return boost::sgb_edge(_arc, _src); }
+ self& operator++()
+ {
+ _arc = _arc->next;
+ return *this;
+ }
+ friend bool operator==(const self& x, const self& y)
+ {
+ return x._arc == y._arc;
+ }
+
+protected:
+ Vertex* _src;
+ Arc* _arc;
+};
+
+class sgb_adj_iterator
+: public boost::forward_iterator_helper< sgb_adj_iterator, Vertex*,
+ std::ptrdiff_t, Vertex**, Vertex* >
+{
+ typedef sgb_adj_iterator self;
+
+public:
+ sgb_adj_iterator() : _arc(0) {}
+ sgb_adj_iterator(Arc* d) : _arc(d) {}
+ Vertex* operator*() { return _arc->tip; }
+ self& operator++()
+ {
+ _arc = _arc->next;
+ return *this;
+ }
+ friend bool operator==(const self& x, const self& y)
+ {
+ return x._arc == y._arc;
+ }
+
+protected:
+ Arc* _arc;
+};
+
+// The reason we have this instead of just using Vertex* is that we
+// want to use Vertex* as the vertex_descriptor instead of just
+// Vertex, which avoids problems with boost passing vertex descriptors
+// by value and how that interacts with the sgb_vertex_id_map.
+class sgb_vertex_iterator
+: public boost::forward_iterator_helper< sgb_vertex_iterator, Vertex*,
+ std::ptrdiff_t, Vertex**, Vertex* >
+{
+ typedef sgb_vertex_iterator self;
+
+public:
+ sgb_vertex_iterator() : _v(0) {}
+ sgb_vertex_iterator(Vertex* v) : _v(v) {}
+ Vertex* operator*() { return _v; }
+ self& operator++()
+ {
+ ++_v;
+ return *this;
+ }
+ friend bool operator==(const self& x, const self& y)
+ {
+ return x._v == y._v;
+ }
+
+protected:
+ Vertex* _v;
+};
+
+namespace boost
+{
+
+inline std::pair< sgb_vertex_iterator, sgb_vertex_iterator > vertices(
+ sgb_const_graph_ptr g)
+{
+ return std::make_pair(sgb_vertex_iterator(g->vertices),
+ sgb_vertex_iterator(g->vertices + g->n));
+}
+
+inline std::pair< sgb_out_edge_iterator, sgb_out_edge_iterator > out_edges(
+ Vertex* u, sgb_const_graph_ptr)
+{
+ return std::make_pair(
+ sgb_out_edge_iterator(u, u->arcs), sgb_out_edge_iterator(u, 0));
+}
+
+inline boost::graph_traits< sgb_graph_ptr >::degree_size_type out_degree(
+ Vertex* u, sgb_const_graph_ptr g)
+{
+ boost::graph_traits< sgb_graph_ptr >::out_edge_iterator i, i_end;
+ boost::tie(i, i_end) = out_edges(u, g);
+ return std::distance(i, i_end);
+}
+
+// in_edges?
+
+inline std::pair< sgb_adj_iterator, sgb_adj_iterator > adjacent_vertices(
+ Vertex* u, sgb_const_graph_ptr)
+{
+ return std::make_pair(sgb_adj_iterator(u->arcs), sgb_adj_iterator(0));
+}
+
+inline long num_vertices(sgb_const_graph_ptr g) { return g->n; }
+inline long num_edges(sgb_const_graph_ptr g) { return g->m; }
+
+inline Vertex* vertex(long v, sgb_const_graph_ptr g) { return g->vertices + v; }
+
+// Various Property Maps
+
+// Vertex ID
+class sgb_vertex_id_map
+: public boost::put_get_helper< long, sgb_vertex_id_map >
+{
+public:
+ typedef boost::readable_property_map_tag category;
+ typedef long value_type;
+ typedef long reference;
+ typedef Vertex* key_type;
+ sgb_vertex_id_map() : _g(0) {}
+ sgb_vertex_id_map(sgb_graph_ptr g) : _g(g) {}
+ long operator[](Vertex* v) const { return v - _g->vertices; }
+
+protected:
+ sgb_graph_ptr _g;
+};
+inline sgb_vertex_id_map get(vertex_index_t, sgb_graph_ptr g)
+{
+ return sgb_vertex_id_map(g);
+}
+
+// Vertex Name
+class sgb_vertex_name_map
+: public boost::put_get_helper< char*, sgb_vertex_name_map >
+{
+public:
+ typedef boost::readable_property_map_tag category;
+ typedef char* value_type;
+ typedef char* reference;
+ typedef Vertex* key_type;
+ char* operator[](Vertex* v) const { return v->name; }
+};
+inline sgb_vertex_name_map get(vertex_name_t, sgb_graph_ptr)
+{
+ return sgb_vertex_name_map();
+}
+
+// Vertex Property Tags
+#define SGB_PROPERTY_TAG(KIND, TAG) \
+ template < class T > struct TAG##_property \
+ { \
+ typedef KIND##_property_tag kind; \
+ typedef T type; \
+ };
+SGB_PROPERTY_TAG(vertex, u)
+SGB_PROPERTY_TAG(vertex, v)
+SGB_PROPERTY_TAG(vertex, w)
+SGB_PROPERTY_TAG(vertex, x)
+SGB_PROPERTY_TAG(vertex, y)
+SGB_PROPERTY_TAG(vertex, z)
+
+// Edge Property Tags
+SGB_PROPERTY_TAG(edge, a)
+SGB_PROPERTY_TAG(edge, b)
+
+// Various Utility Maps
+
+// helpers
+inline Vertex*& get_util(util& u, Vertex*) { return u.V; }
+inline Arc*& get_util(util& u, Arc*) { return u.A; }
+inline sgb_graph_ptr& get_util(util& u, sgb_graph_ptr) { return u.G; }
+inline char*& get_util(util& u, char*) { return u.S; }
+inline long& get_util(util& u, long) { return u.I; }
+
+#define SGB_GET_UTIL_FIELD(KIND, X) \
+ template < class T > inline T& get_util_field(KIND* k, X##_property< T >) \
+ { \
+ return get_util(k->X, T()); \
+ }
+
+SGB_GET_UTIL_FIELD(Vertex, u)
+SGB_GET_UTIL_FIELD(Vertex, v)
+SGB_GET_UTIL_FIELD(Vertex, w)
+SGB_GET_UTIL_FIELD(Vertex, x)
+SGB_GET_UTIL_FIELD(Vertex, y)
+SGB_GET_UTIL_FIELD(Vertex, z)
+
+SGB_GET_UTIL_FIELD(Arc, a)
+SGB_GET_UTIL_FIELD(Arc, b)
+
+// Vertex Utility Map
+template < class Tag, class Ref >
+class sgb_vertex_util_map
+: public boost::put_get_helper< Ref, sgb_vertex_util_map< Tag, Ref > >
+{
+ Tag tag;
+
+public:
+ explicit sgb_vertex_util_map(Tag tag = Tag()) : tag(tag) {}
+ typedef boost::lvalue_property_map_tag category;
+ typedef typename Tag::type value_type;
+ typedef Vertex* key_type;
+ typedef Ref reference;
+ reference operator[](Vertex* v) const { return get_util_field(v, tag); }
+};
+
+// Edge Utility Map
+template < class Tag, class Ref >
+class sgb_edge_util_map
+: public boost::put_get_helper< Ref, sgb_edge_util_map< Tag, Ref > >
+{
+ Tag tag;
+
+public:
+ explicit sgb_edge_util_map(Tag tag = Tag()) : tag(tag) {}
+ typedef boost::lvalue_property_map_tag category;
+ typedef typename Tag::type value_type;
+ typedef Vertex* key_type;
+ typedef Ref reference;
+ reference operator[](const sgb_edge& e) const
+ {
+ return get_util_field(e._arc, tag);
+ }
+};
+
+template < class Tag >
+inline sgb_vertex_util_map< Tag, const typename Tag::type& > get_property_map(
+ Tag, const sgb_graph_ptr& g, vertex_property_tag)
+{
+ return sgb_vertex_util_map< Tag, const typename Tag::type& >();
+}
+template < class Tag >
+inline sgb_vertex_util_map< Tag, typename Tag::type& > get_property_map(
+ Tag, sgb_graph_ptr& g, vertex_property_tag)
+{
+ return sgb_vertex_util_map< Tag, typename Tag::type& >();
+}
+
+template < class Tag >
+inline sgb_edge_util_map< Tag, const typename Tag::type& > get_property_map(
+ Tag, const sgb_graph_ptr& g, edge_property_tag)
+{
+ return sgb_edge_util_map< Tag, const typename Tag::type& >();
+}
+template < class Tag >
+inline sgb_edge_util_map< Tag, typename Tag::type& > get_property_map(
+ Tag, sgb_graph_ptr& g, edge_property_tag)
+{
+ return sgb_edge_util_map< Tag, typename Tag::type& >();
+}
+
+// Edge Length Access
+template < class Ref >
+class sgb_edge_length_map
+: public boost::put_get_helper< Ref, sgb_edge_length_map< Ref > >
+{
+public:
+ typedef boost::lvalue_property_map_tag category;
+ typedef long value_type;
+ typedef sgb_edge key_type;
+ typedef Ref reference;
+ reference operator[](const sgb_edge& e) const { return e._arc->len; }
+};
+
+inline sgb_edge_length_map< const long& > get(
+ edge_length_t, const sgb_graph_ptr&)
+{
+ return sgb_edge_length_map< const long& >();
+}
+inline sgb_edge_length_map< const long& > get(
+ edge_length_t, const sgb_const_graph_ptr&)
+{
+ return sgb_edge_length_map< const long& >();
+}
+inline sgb_edge_length_map< long& > get(edge_length_t, sgb_graph_ptr&)
+{
+ return sgb_edge_length_map< long& >();
+}
+inline long get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key)
+{
+ return key._arc->len;
+}
+inline long get(edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key)
+{
+ return key._arc->len;
+}
+inline void put(edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value)
+{
+ key._arc->len = value;
+}
+
+// Property Map Traits Classes
+template <> struct property_map< sgb_graph_ptr, edge_length_t >
+{
+ typedef sgb_edge_length_map< long& > type;
+ typedef sgb_edge_length_map< const long& > const_type;
+};
+template <> struct property_map< sgb_graph_ptr, vertex_index_t >
+{
+ typedef sgb_vertex_id_map type;
+ typedef sgb_vertex_id_map const_type;
+};
+template <> struct property_map< sgb_graph_ptr, vertex_name_t >
+{
+ typedef sgb_vertex_name_map type;
+ typedef sgb_vertex_name_map const_type;
+};
+
+template <> struct property_map< sgb_const_graph_ptr, edge_length_t >
+{
+ typedef sgb_edge_length_map< const long& > const_type;
+};
+template <> struct property_map< sgb_const_graph_ptr, vertex_index_t >
+{
+ typedef sgb_vertex_id_map const_type;
+};
+template <> struct property_map< sgb_const_graph_ptr, vertex_name_t >
+{
+ typedef sgb_vertex_name_map const_type;
+};
+
+namespace detail
+{
+ template < class Kind, class PropertyTag > struct sgb_choose_property_map
+ {
+ };
+ template < class PropertyTag >
+ struct sgb_choose_property_map< vertex_property_tag, PropertyTag >
+ {
+ typedef typename PropertyTag::type value_type;
+ typedef sgb_vertex_util_map< PropertyTag, value_type& > type;
+ typedef sgb_vertex_util_map< PropertyTag, const value_type& >
+ const_type;
+ };
+ template < class PropertyTag >
+ struct sgb_choose_property_map< edge_property_tag, PropertyTag >
+ {
+ typedef typename PropertyTag::type value_type;
+ typedef sgb_edge_util_map< PropertyTag, value_type& > type;
+ typedef sgb_edge_util_map< PropertyTag, const value_type& > const_type;
+ };
+} // namespace detail
+template < class PropertyTag > struct property_map< sgb_graph_ptr, PropertyTag >
+{
+ typedef typename property_kind< PropertyTag >::type Kind;
+ typedef detail::sgb_choose_property_map< Kind, PropertyTag > Choice;
+ typedef typename Choice::type type;
+ typedef typename Choice::const_type const_type;
+};
+template < class PropertyTag >
+struct property_map< sgb_const_graph_ptr, PropertyTag >
+{
+ typedef typename property_kind< PropertyTag >::type Kind;
+ typedef detail::sgb_choose_property_map< Kind, PropertyTag > Choice;
+ typedef typename Choice::const_type const_type;
+};
+
+#define SGB_UTIL_ACCESSOR(KIND, X) \
+ template < class T > \
+ inline sgb_##KIND##_util_map< X##_property< T >, T& > get( \
+ X##_property< T >, sgb_graph_ptr&) \
+ { \
+ return sgb_##KIND##_util_map< X##_property< T >, T& >(); \
+ } \
+ template < class T > \
+ inline sgb_##KIND##_util_map< X##_property< T >, const T& > get( \
+ X##_property< T >, const sgb_graph_ptr&) \
+ { \
+ return sgb_##KIND##_util_map< X##_property< T >, const T& >(); \
+ } \
+ template < class T > \
+ inline sgb_##KIND##_util_map< X##_property< T >, const T& > get( \
+ X##_property< T >, const sgb_const_graph_ptr&) \
+ { \
+ return sgb_##KIND##_util_map< X##_property< T >, const T& >(); \
+ } \
+ template < class T, class Key > \
+ inline typename sgb_##KIND##_util_map< X##_property< T >, \
+ const T& >::value_type \
+ get(X##_property< T >, const sgb_graph_ptr&, const Key& key) \
+ { \
+ return sgb_##KIND##_util_map< X##_property< T >, const T& >()[key]; \
+ } \
+ template < class T, class Key > \
+ inline typename sgb_##KIND##_util_map< X##_property< T >, \
+ const T& >::value_type \
+ get(X##_property< T >, const sgb_const_graph_ptr&, const Key& key) \
+ { \
+ return sgb_##KIND##_util_map< X##_property< T >, const T& >()[key]; \
+ } \
+ template < class T, class Key, class Value > \
+ inline void put( \
+ X##_property< T >, sgb_graph_ptr&, const Key& key, const Value& value) \
+ { \
+ sgb_##KIND##_util_map< X##_property< T >, T& >()[key] = value; \
+ }
+
+SGB_UTIL_ACCESSOR(vertex, u)
+SGB_UTIL_ACCESSOR(vertex, v)
+SGB_UTIL_ACCESSOR(vertex, w)
+SGB_UTIL_ACCESSOR(vertex, x)
+SGB_UTIL_ACCESSOR(vertex, y)
+SGB_UTIL_ACCESSOR(vertex, z)
+
+SGB_UTIL_ACCESSOR(edge, a)
+SGB_UTIL_ACCESSOR(edge, b)
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_SGB_GRAPH_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/stoer_wagner_min_cut.hpp b/contrib/restricted/boost/graph/include/boost/graph/stoer_wagner_min_cut.hpp
new file mode 100644
index 0000000000..33ef6e9693
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/stoer_wagner_min_cut.hpp
@@ -0,0 +1,383 @@
+// Copyright Daniel Trebbien 2010.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or the copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_STOER_WAGNER_MIN_CUT_HPP
+#define BOOST_GRAPH_STOER_WAGNER_MIN_CUT_HPP 1
+
+#include <boost/assert.hpp>
+#include <set>
+#include <vector>
+#include <boost/concept_check.hpp>
+#include <boost/concept/assert.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/buffer_concepts.hpp>
+#include <boost/graph/exception.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/maximum_adjacency_search.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/one_bit_color_map.hpp>
+#include <boost/graph/detail/d_ary_heap.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/graph/iteration_macros.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+ /**
+ * \brief Performs a phase of the Stoer-Wagner min-cut algorithm
+ *
+ * Performs a phase of the Stoer-Wagner min-cut algorithm.
+ *
+ * As described by Stoer & Wagner (1997), a phase is simply a maximum
+ * adjacency search (also called a maximum cardinality search), which
+ * results in the selection of two vertices \em s and \em t, and, as a side
+ * product, a minimum <em>s</em>-<em>t</em> cut of the input graph. Here,
+ * the input graph is basically \p g, but some vertices are virtually
+ * assigned to others as a way of viewing \p g as a graph with some sets of
+ * vertices merged together.
+ *
+ * This implementation is a translation of pseudocode by Professor Uri
+ * Zwick, School of Computer Science, Tel Aviv University.
+ *
+ * \pre \p g is a connected, undirected graph
+ * \param[in] g the input graph
+ * \param[in] assignments a read/write property map from each vertex to the
+ * vertex that it is assigned to
+ * \param[in] assignedVertices a list of vertices that are assigned to
+ * others
+ * \param[in] weights a readable property map from each edge to its
+ * weight (a non-negative value)
+ * \param[out] pq a keyed, updatable max-priority queue
+ * \returns a tuple (\em s, \em t, \em w) of the "<em>s</em>" and
+ * "<em>t</em>" of the minimum <em>s</em>-<em>t</em> cut and the
+ * cut weight \em w of the minimum <em>s</em>-<em>t</em> cut.
+ * \see http://www.cs.tau.ac.il/~zwick/grad-algo-08/gmc.pdf
+ *
+ * \author Daniel Trebbien
+ * \date 2010-09-11
+ */
+ template < class UndirectedGraph, class VertexAssignmentMap,
+ class WeightMap, class KeyedUpdatablePriorityQueue >
+ boost::tuple<
+ typename boost::graph_traits< UndirectedGraph >::vertex_descriptor,
+ typename boost::graph_traits< UndirectedGraph >::vertex_descriptor,
+ typename boost::property_traits< WeightMap >::value_type >
+ stoer_wagner_phase(const UndirectedGraph& g,
+ VertexAssignmentMap assignments,
+ const std::set< typename boost::graph_traits<
+ UndirectedGraph >::vertex_descriptor >& assignedVertices,
+ WeightMap weights, KeyedUpdatablePriorityQueue& pq)
+ {
+ typedef
+ typename boost::graph_traits< UndirectedGraph >::vertex_descriptor
+ vertex_descriptor;
+ typedef typename boost::property_traits< WeightMap >::value_type
+ weight_type;
+
+ BOOST_ASSERT(pq.empty());
+ typename KeyedUpdatablePriorityQueue::key_map keys = pq.keys();
+
+ BGL_FORALL_VERTICES_T(v, g, UndirectedGraph)
+ {
+ if (v == get(assignments, v))
+ { // foreach u \in V do
+ put(keys, v, weight_type(0));
+
+ pq.push(v);
+ }
+ }
+
+ BOOST_ASSERT(pq.size() >= 2);
+
+ vertex_descriptor s
+ = boost::graph_traits< UndirectedGraph >::null_vertex();
+ vertex_descriptor t
+ = boost::graph_traits< UndirectedGraph >::null_vertex();
+ weight_type w;
+ while (!pq.empty())
+ { // while PQ \neq {} do
+ const vertex_descriptor u = pq.top(); // u = extractmax(PQ)
+ w = get(keys, u);
+ pq.pop();
+
+ s = t;
+ t = u;
+
+ BGL_FORALL_OUTEDGES_T(u, e, g, UndirectedGraph)
+ { // foreach (u, v) \in E do
+ const vertex_descriptor v = get(assignments, target(e, g));
+
+ if (pq.contains(v))
+ { // if v \in PQ then
+ put(keys, v,
+ get(keys, v)
+ + get(weights,
+ e)); // increasekey(PQ, v, wA(v) + w(u, v))
+ pq.update(v);
+ }
+ }
+
+ typename std::set< vertex_descriptor >::const_iterator
+ assignedVertexIt,
+ assignedVertexEnd = assignedVertices.end();
+ for (assignedVertexIt = assignedVertices.begin();
+ assignedVertexIt != assignedVertexEnd; ++assignedVertexIt)
+ {
+ const vertex_descriptor uPrime = *assignedVertexIt;
+
+ if (get(assignments, uPrime) == u)
+ {
+ BGL_FORALL_OUTEDGES_T(uPrime, e, g, UndirectedGraph)
+ { // foreach (u, v) \in E do
+ const vertex_descriptor v
+ = get(assignments, target(e, g));
+
+ if (pq.contains(v))
+ { // if v \in PQ then
+ put(keys, v,
+ get(keys, v)
+ + get(weights, e)); // increasekey(PQ, v,
+ // wA(v) + w(u, v))
+ pq.update(v);
+ }
+ }
+ }
+ }
+ }
+
+ return boost::make_tuple(s, t, w);
+ }
+
+ /**
+ * \brief Computes a min-cut of the input graph
+ *
+ * Computes a min-cut of the input graph using the Stoer-Wagner algorithm.
+ *
+ * \pre \p g is a connected, undirected graph
+ * \pre <code>pq.empty()</code>
+ * \param[in] g the input graph
+ * \param[in] weights a readable property map from each edge to its weight
+ * (a non-negative value) \param[out] parities a writable property map from
+ * each vertex to a bool type object for distinguishing the two vertex sets
+ * of the min-cut \param[out] assignments a read/write property map from
+ * each vertex to a \c vertex_descriptor object. This map serves as work
+ * space, and no particular meaning should be derived from property values
+ * after completion of the algorithm.
+ * \param[out] pq a keyed, updatable max-priority queue
+ * \returns the cut weight of the min-cut
+ * \see
+ * http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.114.6687&rep=rep1&type=pdf
+ * \see
+ * http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.31.614&rep=rep1&type=pdf
+ *
+ * \author Daniel Trebbien
+ * \date 2010-09-11
+ */
+ template < class UndirectedGraph, class WeightMap, class ParityMap,
+ class VertexAssignmentMap, class KeyedUpdatablePriorityQueue,
+ class IndexMap >
+ typename boost::property_traits< WeightMap >::value_type
+ stoer_wagner_min_cut(const UndirectedGraph& g, WeightMap weights,
+ ParityMap parities, VertexAssignmentMap assignments,
+ KeyedUpdatablePriorityQueue& pq, IndexMap index_map)
+ {
+ typedef
+ typename boost::graph_traits< UndirectedGraph >::vertex_descriptor
+ vertex_descriptor;
+ typedef typename boost::property_traits< WeightMap >::value_type
+ weight_type;
+ typedef
+ typename boost::graph_traits< UndirectedGraph >::vertices_size_type
+ vertices_size_type;
+ typedef typename boost::property_traits< ParityMap >::value_type
+ parity_type;
+
+ vertices_size_type n = num_vertices(g);
+
+ std::set< vertex_descriptor > assignedVertices;
+
+ // initialize `assignments` (all vertices are initially assigned to
+ // themselves)
+ BGL_FORALL_VERTICES_T(v, g, UndirectedGraph) { put(assignments, v, v); }
+
+ vertex_descriptor s, t;
+ weight_type bestW;
+
+ boost::tie(s, t, bestW) = boost::detail::stoer_wagner_phase(
+ g, assignments, assignedVertices, weights, pq);
+ BOOST_ASSERT(s != t);
+ BGL_FORALL_VERTICES_T(v, g, UndirectedGraph)
+ {
+ put(parities, v, parity_type(v == t ? 1 : 0));
+ }
+ put(assignments, t, s);
+ assignedVertices.insert(t);
+ --n;
+
+ for (; n >= 2; --n)
+ {
+ weight_type w;
+ boost::tie(s, t, w) = boost::detail::stoer_wagner_phase(
+ g, assignments, assignedVertices, weights, pq);
+ BOOST_ASSERT(s != t);
+
+ if (w < bestW)
+ {
+ BGL_FORALL_VERTICES_T(v, g, UndirectedGraph)
+ {
+ put(parities, v,
+ parity_type(get(assignments, v) == t ? 1 : 0));
+
+ if (get(assignments, v)
+ == t) // all vertices that were assigned to t are now
+ // assigned to s
+ put(assignments, v, s);
+ }
+
+ bestW = w;
+ }
+ else
+ {
+ BGL_FORALL_VERTICES_T(v, g, UndirectedGraph)
+ {
+ if (get(assignments, v)
+ == t) // all vertices that were assigned to t are now
+ // assigned to s
+ put(assignments, v, s);
+ }
+ }
+ put(assignments, t, s);
+ assignedVertices.insert(t);
+ }
+
+ BOOST_ASSERT(pq.empty());
+
+ return bestW;
+ }
+} // end `namespace detail` within `namespace boost`
+
+template < class UndirectedGraph, class WeightMap, class ParityMap,
+ class VertexAssignmentMap, class KeyedUpdatablePriorityQueue,
+ class IndexMap >
+typename boost::property_traits< WeightMap >::value_type stoer_wagner_min_cut(
+ const UndirectedGraph& g, WeightMap weights, ParityMap parities,
+ VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue& pq,
+ IndexMap index_map)
+{
+ BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept< UndirectedGraph >));
+ BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept< UndirectedGraph >));
+ typedef typename boost::graph_traits< UndirectedGraph >::vertex_descriptor
+ vertex_descriptor;
+ typedef typename boost::graph_traits< UndirectedGraph >::vertices_size_type
+ vertices_size_type;
+ typedef typename boost::graph_traits< UndirectedGraph >::edge_descriptor
+ edge_descriptor;
+ BOOST_CONCEPT_ASSERT((boost::Convertible<
+ typename boost::graph_traits< UndirectedGraph >::directed_category,
+ boost::undirected_tag >));
+ BOOST_CONCEPT_ASSERT(
+ (boost::ReadablePropertyMapConcept< WeightMap, edge_descriptor >));
+ // typedef typename boost::property_traits<WeightMap>::value_type
+ // weight_type;
+ BOOST_CONCEPT_ASSERT(
+ (boost::WritablePropertyMapConcept< ParityMap, vertex_descriptor >));
+ // typedef typename boost::property_traits<ParityMap>::value_type
+ // parity_type;
+ BOOST_CONCEPT_ASSERT(
+ (boost::ReadWritePropertyMapConcept< VertexAssignmentMap,
+ vertex_descriptor >));
+ BOOST_CONCEPT_ASSERT((boost::Convertible< vertex_descriptor,
+ typename boost::property_traits< VertexAssignmentMap >::value_type >));
+ BOOST_CONCEPT_ASSERT(
+ (boost::KeyedUpdatableQueueConcept< KeyedUpdatablePriorityQueue >));
+
+ vertices_size_type n = num_vertices(g);
+ if (n < 2)
+ throw boost::bad_graph(
+ "the input graph must have at least two vertices.");
+ else if (!pq.empty())
+ throw std::invalid_argument(
+ "the max-priority queue must be empty initially.");
+
+ return detail::stoer_wagner_min_cut(
+ g, weights, parities, assignments, pq, index_map);
+}
+
+namespace graph
+{
+ namespace detail
+ {
+ template < class UndirectedGraph, class WeightMap >
+ struct stoer_wagner_min_cut_impl
+ {
+ typedef typename boost::property_traits< WeightMap >::value_type
+ result_type;
+ template < typename ArgPack >
+ result_type operator()(const UndirectedGraph& g, WeightMap weights,
+ const ArgPack& arg_pack) const
+ {
+ using namespace boost::graph::keywords;
+ typedef typename boost::graph_traits<
+ UndirectedGraph >::vertex_descriptor vertex_descriptor;
+ typedef typename boost::property_traits< WeightMap >::value_type
+ weight_type;
+
+ typedef boost::detail::make_priority_queue_from_arg_pack_gen<
+ boost::graph::keywords::tag::max_priority_queue,
+ weight_type, vertex_descriptor,
+ std::greater< weight_type > >
+ gen_type;
+
+ gen_type gen(
+ choose_param(get_param(arg_pack, boost::distance_zero_t()),
+ weight_type(0)));
+
+ typename boost::result_of< gen_type(
+ const UndirectedGraph&, const ArgPack&) >::type pq
+ = gen(g, arg_pack);
+
+ boost::dummy_property_map dummy_prop;
+ return boost::stoer_wagner_min_cut(g, weights,
+ arg_pack[_parity_map | dummy_prop],
+ boost::detail::make_property_map_from_arg_pack_gen<
+ tag::vertex_assignment_map, vertex_descriptor >(
+ vertex_descriptor())(g, arg_pack),
+ pq,
+ boost::detail::override_const_property(
+ arg_pack, _vertex_index_map, g, vertex_index));
+ }
+ };
+ }
+ BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(stoer_wagner_min_cut, 2, 4)
+}
+
+// Named parameter interface
+BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(stoer_wagner_min_cut, 2)
+namespace graph
+{
+ // version without IndexMap kept for backwards compatibility
+ // (but requires vertex_index_t to be defined in the graph)
+ // Place after the macro to avoid compilation errors
+ template < class UndirectedGraph, class WeightMap, class ParityMap,
+ class VertexAssignmentMap, class KeyedUpdatablePriorityQueue >
+ typename boost::property_traits< WeightMap >::value_type
+ stoer_wagner_min_cut(const UndirectedGraph& g, WeightMap weights,
+ ParityMap parities, VertexAssignmentMap assignments,
+ KeyedUpdatablePriorityQueue& pq)
+ {
+
+ return stoer_wagner_min_cut(
+ g, weights, parities, assignments, pq, get(vertex_index, g));
+ }
+} // end `namespace graph`
+} // end `namespace boost`
+
+#include <boost/graph/iteration_macros_undef.hpp>
+
+#endif // !BOOST_GRAPH_STOER_WAGNER_MIN_CUT_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp b/contrib/restricted/boost/graph/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp
new file mode 100644
index 0000000000..8e1f5ad94a
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp
@@ -0,0 +1,255 @@
+//=======================================================================
+// Copyright 2013 University of Warsaw.
+// Authors: Piotr Wygocki
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+// This algorithm is described in "Network Flows: Theory, Algorithms, and
+// Applications"
+// by Ahuja, Magnanti, Orlin.
+
+#ifndef BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP
+#define BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP
+
+#include <numeric>
+
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/detail/augment.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < class Graph, class Weight, class Distance, class Reversed >
+ class MapReducedWeight
+ : public put_get_helper< typename property_traits< Weight >::value_type,
+ MapReducedWeight< Graph, Weight, Distance, Reversed > >
+ {
+ typedef graph_traits< Graph > gtraits;
+
+ public:
+ typedef boost::readable_property_map_tag category;
+ typedef typename property_traits< Weight >::value_type value_type;
+ typedef value_type reference;
+ typedef typename gtraits::edge_descriptor key_type;
+ MapReducedWeight(const Graph& g, Weight w, Distance d, Reversed r)
+ : g_(g), weight_(w), distance_(d), rev_(r)
+ {
+ }
+
+ reference operator[](key_type v) const
+ {
+ return get(distance_, source(v, g_)) - get(distance_, target(v, g_))
+ + get(weight_, v);
+ }
+
+ private:
+ const Graph& g_;
+ Weight weight_;
+ Distance distance_;
+ Reversed rev_;
+ };
+
+ template < class Graph, class Weight, class Distance, class Reversed >
+ MapReducedWeight< Graph, Weight, Distance, Reversed > make_mapReducedWeight(
+ const Graph& g, Weight w, Distance d, Reversed r)
+ {
+ return MapReducedWeight< Graph, Weight, Distance, Reversed >(
+ g, w, d, r);
+ }
+
+} // detail
+
+template < class Graph, class Capacity, class ResidualCapacity, class Reversed,
+ class Pred, class Weight, class Distance, class Distance2,
+ class VertexIndex >
+void successive_shortest_path_nonnegative_weights(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity,
+ ResidualCapacity residual_capacity, Weight weight, Reversed rev,
+ VertexIndex index, Pred pred, Distance distance, Distance2 distance_prev)
+{
+ filtered_graph< const Graph, is_residual_edge< ResidualCapacity > > gres
+ = detail::residual_graph(g, residual_capacity);
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor;
+
+ BGL_FORALL_EDGES_T(e, g, Graph)
+ {
+ put(residual_capacity, e, get(capacity, e));
+ }
+
+ BGL_FORALL_VERTICES_T(v, g, Graph) { put(distance_prev, v, 0); }
+
+ while (true)
+ {
+ BGL_FORALL_VERTICES_T(v, g, Graph) { put(pred, v, edge_descriptor()); }
+ dijkstra_shortest_paths(gres, s,
+ weight_map(
+ detail::make_mapReducedWeight(gres, weight, distance_prev, rev))
+ .distance_map(distance)
+ .vertex_index_map(index)
+ .visitor(make_dijkstra_visitor(
+ record_edge_predecessors(pred, on_edge_relaxed()))));
+
+ if (get(pred, t) == edge_descriptor())
+ {
+ break;
+ }
+
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ {
+ put(distance_prev, v, get(distance_prev, v) + get(distance, v));
+ }
+
+ detail::augment(g, s, t, pred, residual_capacity, rev);
+ }
+}
+
+// in this namespace argument dispatching tak place
+namespace detail
+{
+
+ template < class Graph, class Capacity, class ResidualCapacity,
+ class Weight, class Reversed, class Pred, class Distance,
+ class Distance2, class VertexIndex >
+ void successive_shortest_path_nonnegative_weights_dispatch3(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity,
+ ResidualCapacity residual_capacity, Weight weight, Reversed rev,
+ VertexIndex index, Pred pred, Distance dist, Distance2 dist_pred)
+ {
+ successive_shortest_path_nonnegative_weights(g, s, t, capacity,
+ residual_capacity, weight, rev, index, pred, dist, dist_pred);
+ }
+
+ // setting default distance map
+ template < class Graph, class Capacity, class ResidualCapacity,
+ class Weight, class Reversed, class Pred, class Distance,
+ class VertexIndex >
+ void successive_shortest_path_nonnegative_weights_dispatch3(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity,
+ ResidualCapacity residual_capacity, Weight weight, Reversed rev,
+ VertexIndex index, Pred pred, Distance dist, param_not_found)
+ {
+ typedef typename property_traits< Weight >::value_type D;
+
+ std::vector< D > d_map(num_vertices(g));
+
+ successive_shortest_path_nonnegative_weights(g, s, t, capacity,
+ residual_capacity, weight, rev, index, pred, dist,
+ make_iterator_property_map(d_map.begin(), index));
+ }
+
+ template < class Graph, class P, class T, class R, class Capacity,
+ class ResidualCapacity, class Weight, class Reversed, class Pred,
+ class Distance, class VertexIndex >
+ void successive_shortest_path_nonnegative_weights_dispatch2(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity,
+ ResidualCapacity residual_capacity, Weight weight, Reversed rev,
+ VertexIndex index, Pred pred, Distance dist,
+ const bgl_named_params< P, T, R >& params)
+ {
+ successive_shortest_path_nonnegative_weights_dispatch3(g, s, t,
+ capacity, residual_capacity, weight, rev, index, pred, dist,
+ get_param(params, vertex_distance2));
+ }
+
+ // setting default distance map
+ template < class Graph, class P, class T, class R, class Capacity,
+ class ResidualCapacity, class Weight, class Reversed, class Pred,
+ class VertexIndex >
+ void successive_shortest_path_nonnegative_weights_dispatch2(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity,
+ ResidualCapacity residual_capacity, Weight weight, Reversed rev,
+ VertexIndex index, Pred pred, param_not_found,
+ const bgl_named_params< P, T, R >& params)
+ {
+ typedef typename property_traits< Weight >::value_type D;
+
+ std::vector< D > d_map(num_vertices(g));
+
+ successive_shortest_path_nonnegative_weights_dispatch3(g, s, t,
+ capacity, residual_capacity, weight, rev, index, pred,
+ make_iterator_property_map(d_map.begin(), index),
+ get_param(params, vertex_distance2));
+ }
+
+ template < class Graph, class P, class T, class R, class Capacity,
+ class ResidualCapacity, class Weight, class Reversed, class Pred,
+ class VertexIndex >
+ void successive_shortest_path_nonnegative_weights_dispatch1(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity,
+ ResidualCapacity residual_capacity, Weight weight, Reversed rev,
+ VertexIndex index, Pred pred, const bgl_named_params< P, T, R >& params)
+ {
+ successive_shortest_path_nonnegative_weights_dispatch2(g, s, t,
+ capacity, residual_capacity, weight, rev, index, pred,
+ get_param(params, vertex_distance), params);
+ }
+
+ // setting default predecessors map
+ template < class Graph, class P, class T, class R, class Capacity,
+ class ResidualCapacity, class Weight, class Reversed,
+ class VertexIndex >
+ void successive_shortest_path_nonnegative_weights_dispatch1(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t, Capacity capacity,
+ ResidualCapacity residual_capacity, Weight weight, Reversed rev,
+ VertexIndex index, param_not_found,
+ const bgl_named_params< P, T, R >& params)
+ {
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor;
+ std::vector< edge_descriptor > pred_vec(num_vertices(g));
+
+ successive_shortest_path_nonnegative_weights_dispatch2(g, s, t,
+ capacity, residual_capacity, weight, rev, index,
+ make_iterator_property_map(pred_vec.begin(), index),
+ get_param(params, vertex_distance), params);
+ }
+
+} // detail
+
+template < class Graph, class P, class T, class R >
+void successive_shortest_path_nonnegative_weights(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t,
+ const bgl_named_params< P, T, R >& params)
+{
+
+ return detail::successive_shortest_path_nonnegative_weights_dispatch1(g, s,
+ t,
+ choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
+ choose_pmap(get_param(params, edge_residual_capacity), g,
+ edge_residual_capacity),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ get_param(params, vertex_predecessor), params);
+}
+
+template < class Graph >
+void successive_shortest_path_nonnegative_weights(Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t)
+{
+ bgl_named_params< int, buffer_param_t > params(0);
+ successive_shortest_path_nonnegative_weights(g, s, t, params);
+}
+
+} // boost
+#endif /* BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP */
diff --git a/contrib/restricted/boost/graph/include/boost/graph/tiernan_all_cycles.hpp b/contrib/restricted/boost/graph/include/boost/graph/tiernan_all_cycles.hpp
new file mode 100644
index 0000000000..c24c87553f
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/tiernan_all_cycles.hpp
@@ -0,0 +1,372 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_CYCLE_HPP
+#define BOOST_GRAPH_CYCLE_HPP
+
+#include <vector>
+
+#include <boost/config.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/concept/assert.hpp>
+
+#include <boost/concept/detail/concept_def.hpp>
+namespace boost
+{
+namespace concepts
+{
+ BOOST_concept(CycleVisitor, (Visitor)(Path)(Graph))
+ {
+ BOOST_CONCEPT_USAGE(CycleVisitor) { vis.cycle(p, g); }
+
+ private:
+ Visitor vis;
+ Graph g;
+ Path p;
+ };
+} /* namespace concepts */
+using concepts::CycleVisitorConcept;
+} /* namespace boost */
+#include <boost/concept/detail/concept_undef.hpp>
+
+namespace boost
+{
+
+// The implementation of this algorithm is a reproduction of the Teirnan
+// approach for directed graphs: bibtex follows
+//
+// @article{362819,
+// author = {James C. Tiernan},
+// title = {An efficient search algorithm to find the elementary
+// circuits of a graph}, journal = {Commun. ACM}, volume = {13}, number
+// = {12}, year = {1970}, issn = {0001-0782}, pages = {722--726}, doi =
+// {http://doi.acm.org/10.1145/362814.362819},
+// publisher = {ACM Press},
+// address = {New York, NY, USA},
+// }
+//
+// It should be pointed out that the author does not provide a complete analysis
+// for either time or space. This is in part, due to the fact that it's a fairly
+// input sensitive problem related to the density and construction of the graph,
+// not just its size.
+//
+// I've also taken some liberties with the interpretation of the algorithm -
+// I've basically modernized it to use real data structures (no more arrays and
+// matrices). Oh... and there's explicit control structures - not just gotos.
+//
+// The problem is definitely NP-complete, an unbounded implementation of this
+// will probably run for quite a while on a large graph. The conclusions
+// of this paper also reference a Paton algorithm for undirected graphs as being
+// much more efficient (apparently based on spanning trees). Although not
+// implemented, it can be found here:
+//
+// @article{363232,
+// author = {Keith Paton},
+// title = {An algorithm for finding a fundamental set of cycles of a
+// graph}, journal = {Commun. ACM}, volume = {12}, number = {9}, year =
+// {1969}, issn = {0001-0782}, pages = {514--518}, doi =
+// {http://doi.acm.org/10.1145/363219.363232},
+// publisher = {ACM Press},
+// address = {New York, NY, USA},
+// }
+
+/**
+ * The default cycle visitor provides an empty visit function for cycle
+ * visitors.
+ */
+struct cycle_visitor
+{
+ template < typename Path, typename Graph >
+ inline void cycle(const Path& p, const Graph& g)
+ {
+ }
+};
+
+/**
+ * The min_max_cycle_visitor simultaneously records the minimum and maximum
+ * cycles in a graph.
+ */
+struct min_max_cycle_visitor
+{
+ min_max_cycle_visitor(std::size_t& min_, std::size_t& max_)
+ : minimum(min_), maximum(max_)
+ {
+ }
+
+ template < typename Path, typename Graph >
+ inline void cycle(const Path& p, const Graph& g)
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ std::size_t len = p.size();
+ minimum = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum, len);
+ maximum = max BOOST_PREVENT_MACRO_SUBSTITUTION(maximum, len);
+ }
+ std::size_t& minimum;
+ std::size_t& maximum;
+};
+
+inline min_max_cycle_visitor find_min_max_cycle(
+ std::size_t& min_, std::size_t& max_)
+{
+ return min_max_cycle_visitor(min_, max_);
+}
+
+namespace detail
+{
+ template < typename Graph, typename Path >
+ inline bool is_vertex_in_path(const Graph&,
+ typename graph_traits< Graph >::vertex_descriptor v, const Path& p)
+ {
+ return (std::find(p.begin(), p.end(), v) != p.end());
+ }
+
+ template < typename Graph, typename ClosedMatrix >
+ inline bool is_path_closed(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor u,
+ typename graph_traits< Graph >::vertex_descriptor v,
+ const ClosedMatrix& closed)
+ {
+ // the path from u to v is closed if v can be found in the list
+ // of closed vertices associated with u.
+ typedef typename ClosedMatrix::const_reference Row;
+ Row r = closed[get(vertex_index, g, u)];
+ if (find(r.begin(), r.end(), v) != r.end())
+ {
+ return true;
+ }
+ return false;
+ }
+
+ template < typename Graph, typename Path, typename ClosedMatrix >
+ inline bool can_extend_path(const Graph& g,
+ typename graph_traits< Graph >::edge_descriptor e, const Path& p,
+ const ClosedMatrix& m)
+ {
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((VertexIndexGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+
+ // get the vertices in question
+ Vertex u = source(e, g), v = target(e, g);
+
+ // conditions for allowing a traversal along this edge are:
+ // 1. the index of v must be greater than that at which the
+ // path is rooted (p.front()).
+ // 2. the vertex v cannot already be in the path
+ // 3. the vertex v cannot be closed to the vertex u
+
+ bool indices
+ = get(vertex_index, g, p.front()) < get(vertex_index, g, v);
+ bool path = !is_vertex_in_path(g, v, p);
+ bool closed = !is_path_closed(g, u, v, m);
+ return indices && path && closed;
+ }
+
+ template < typename Graph, typename Path >
+ inline bool can_wrap_path(const Graph& g, const Path& p)
+ {
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::out_edge_iterator OutIterator;
+
+ // iterate over the out-edges of the back, looking for the
+ // front of the path. also, we can't travel along the same
+ // edge that we did on the way here, but we don't quite have the
+ // stringent requirements that we do in can_extend_path().
+ Vertex u = p.back(), v = p.front();
+ OutIterator i, end;
+ for (boost::tie(i, end) = out_edges(u, g); i != end; ++i)
+ {
+ if ((target(*i, g) == v))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template < typename Graph, typename Path, typename ClosedMatrix >
+ inline typename graph_traits< Graph >::vertex_descriptor extend_path(
+ const Graph& g, Path& p, ClosedMatrix& closed)
+ {
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::out_edge_iterator OutIterator;
+
+ // get the current vertex
+ Vertex u = p.back();
+ Vertex ret = graph_traits< Graph >::null_vertex();
+
+ // AdjacencyIterator i, end;
+ OutIterator i, end;
+ for (boost::tie(i, end) = out_edges(u, g); i != end; ++i)
+ {
+ Vertex v = target(*i, g);
+
+ // if we can actually extend along this edge,
+ // then that's what we want to do
+ if (can_extend_path(g, *i, p, closed))
+ {
+ p.push_back(v); // add the vertex to the path
+ ret = v;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ template < typename Graph, typename Path, typename ClosedMatrix >
+ inline bool exhaust_paths(const Graph& g, Path& p, ClosedMatrix& closed)
+ {
+ BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+
+ // if there's more than one vertex in the path, this closes
+ // of some possible routes and returns true. otherwise, if there's
+ // only one vertex left, the vertex has been used up
+ if (p.size() > 1)
+ {
+ // get the last and second to last vertices, popping the last
+ // vertex off the path
+ Vertex last, prev;
+ last = p.back();
+ p.pop_back();
+ prev = p.back();
+
+ // reset the closure for the last vertex of the path and
+ // indicate that the last vertex in p is now closed to
+ // the next-to-last vertex in p
+ closed[get(vertex_index, g, last)].clear();
+ closed[get(vertex_index, g, prev)].push_back(last);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ template < typename Graph, typename Visitor >
+ inline void all_cycles_from_vertex(const Graph& g,
+ typename graph_traits< Graph >::vertex_descriptor v, Visitor vis,
+ std::size_t minlen, std::size_t maxlen)
+ {
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef std::vector< Vertex > Path;
+ BOOST_CONCEPT_ASSERT((CycleVisitorConcept< Visitor, Path, Graph >));
+ typedef std::vector< Vertex > VertexList;
+ typedef std::vector< VertexList > ClosedMatrix;
+
+ Path p;
+ ClosedMatrix closed(num_vertices(g), VertexList());
+ Vertex null = graph_traits< Graph >::null_vertex();
+
+ // each path investigation starts at the ith vertex
+ p.push_back(v);
+
+ while (1)
+ {
+ // extend the path until we've reached the end or the
+ // maxlen-sized cycle
+ Vertex j = null;
+ while (((j = detail::extend_path(g, p, closed)) != null)
+ && (p.size() < maxlen))
+ ; // empty loop
+
+ // if we're done extending the path and there's an edge
+ // connecting the back to the front, then we should have
+ // a cycle.
+ if (detail::can_wrap_path(g, p) && p.size() >= minlen)
+ {
+ vis.cycle(p, g);
+ }
+
+ if (!detail::exhaust_paths(g, p, closed))
+ {
+ break;
+ }
+ }
+ }
+
+ // Select the minimum allowable length of a cycle based on the directedness
+ // of the graph - 2 for directed, 3 for undirected.
+ template < typename D > struct min_cycles
+ {
+ enum
+ {
+ value = 2
+ };
+ };
+ template <> struct min_cycles< undirected_tag >
+ {
+ enum
+ {
+ value = 3
+ };
+ };
+} /* namespace detail */
+
+template < typename Graph, typename Visitor >
+inline void tiernan_all_cycles(
+ const Graph& g, Visitor vis, std::size_t minlen, std::size_t maxlen)
+{
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+
+ VertexIterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ {
+ detail::all_cycles_from_vertex(g, *i, vis, minlen, maxlen);
+ }
+}
+
+template < typename Graph, typename Visitor >
+inline void tiernan_all_cycles(const Graph& g, Visitor vis, std::size_t maxlen)
+{
+ typedef typename graph_traits< Graph >::directed_category Dir;
+ tiernan_all_cycles(g, vis, detail::min_cycles< Dir >::value, maxlen);
+}
+
+template < typename Graph, typename Visitor >
+inline void tiernan_all_cycles(const Graph& g, Visitor vis)
+{
+ typedef typename graph_traits< Graph >::directed_category Dir;
+ tiernan_all_cycles(g, vis, detail::min_cycles< Dir >::value,
+ (std::numeric_limits< std::size_t >::max)());
+}
+
+template < typename Graph >
+inline std::pair< std::size_t, std::size_t > tiernan_girth_and_circumference(
+ const Graph& g)
+{
+ std::size_t min_ = (std::numeric_limits< std::size_t >::max)(), max_ = 0;
+ tiernan_all_cycles(g, find_min_max_cycle(min_, max_));
+
+ // if this is the case, the graph is acyclic...
+ if (max_ == 0)
+ max_ = min_;
+
+ return std::make_pair(min_, max_);
+}
+
+template < typename Graph > inline std::size_t tiernan_girth(const Graph& g)
+{
+ return tiernan_girth_and_circumference(g).first;
+}
+
+template < typename Graph >
+inline std::size_t tiernan_circumference(const Graph& g)
+{
+ return tiernan_girth_and_circumference(g).second;
+}
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/topology.hpp b/contrib/restricted/boost/graph/include/boost/graph/topology.hpp
new file mode 100644
index 0000000000..73dc3d944e
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/topology.hpp
@@ -0,0 +1,702 @@
+// Copyright 2009 The Trustees of Indiana University.
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jeremiah Willcock
+// Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_TOPOLOGY_HPP
+#define BOOST_GRAPH_TOPOLOGY_HPP
+
+#include <boost/algorithm/minmax.hpp>
+#include <boost/config.hpp> // For BOOST_STATIC_CONSTANT
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/math/constants/constants.hpp> // For root_two
+#include <boost/math/special_functions/hypot.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <cmath>
+
+// Classes and concepts to represent points in a space, with distance and move
+// operations (used for Gurson-Atun layout), plus other things like bounding
+// boxes used for other layout algorithms.
+
+namespace boost
+{
+
+/***********************************************************
+ * Topologies *
+ ***********************************************************/
+template < std::size_t Dims > class convex_topology
+{
+public: // For VisualAge C++
+ struct point
+ {
+ BOOST_STATIC_CONSTANT(std::size_t, dimensions = Dims);
+ point() {}
+ double& operator[](std::size_t i) { return values[i]; }
+ const double& operator[](std::size_t i) const { return values[i]; }
+
+ private:
+ double values[Dims];
+ };
+
+public: // For VisualAge C++
+ struct point_difference
+ {
+ BOOST_STATIC_CONSTANT(std::size_t, dimensions = Dims);
+ point_difference()
+ {
+ for (std::size_t i = 0; i < Dims; ++i)
+ values[i] = 0.;
+ }
+ double& operator[](std::size_t i) { return values[i]; }
+ const double& operator[](std::size_t i) const { return values[i]; }
+
+ friend point_difference operator+(
+ const point_difference& a, const point_difference& b)
+ {
+ point_difference result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = a[i] + b[i];
+ return result;
+ }
+
+ friend point_difference& operator+=(
+ point_difference& a, const point_difference& b)
+ {
+ for (std::size_t i = 0; i < Dims; ++i)
+ a[i] += b[i];
+ return a;
+ }
+
+ friend point_difference operator-(const point_difference& a)
+ {
+ point_difference result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = -a[i];
+ return result;
+ }
+
+ friend point_difference operator-(
+ const point_difference& a, const point_difference& b)
+ {
+ point_difference result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = a[i] - b[i];
+ return result;
+ }
+
+ friend point_difference& operator-=(
+ point_difference& a, const point_difference& b)
+ {
+ for (std::size_t i = 0; i < Dims; ++i)
+ a[i] -= b[i];
+ return a;
+ }
+
+ friend point_difference operator*(
+ const point_difference& a, const point_difference& b)
+ {
+ point_difference result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = a[i] * b[i];
+ return result;
+ }
+
+ friend point_difference operator*(const point_difference& a, double b)
+ {
+ point_difference result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = a[i] * b;
+ return result;
+ }
+
+ friend point_difference operator*(double a, const point_difference& b)
+ {
+ point_difference result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = a * b[i];
+ return result;
+ }
+
+ friend point_difference operator/(
+ const point_difference& a, const point_difference& b)
+ {
+ point_difference result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = (b[i] == 0.) ? 0. : a[i] / b[i];
+ return result;
+ }
+
+ friend double dot(const point_difference& a, const point_difference& b)
+ {
+ double result = 0;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result += a[i] * b[i];
+ return result;
+ }
+
+ private:
+ double values[Dims];
+ };
+
+public:
+ typedef point point_type;
+ typedef point_difference point_difference_type;
+
+ double distance(point a, point b) const
+ {
+ double dist = 0.;
+ for (std::size_t i = 0; i < Dims; ++i)
+ {
+ double diff = b[i] - a[i];
+ dist = boost::math::hypot(dist, diff);
+ }
+ // Exact properties of the distance are not important, as long as
+ // < on what this returns matches real distances; l_2 is used because
+ // Fruchterman-Reingold also uses this code and it relies on l_2.
+ return dist;
+ }
+
+ point move_position_toward(point a, double fraction, point b) const
+ {
+ point result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = a[i] + (b[i] - a[i]) * fraction;
+ return result;
+ }
+
+ point_difference difference(point a, point b) const
+ {
+ point_difference result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = a[i] - b[i];
+ return result;
+ }
+
+ point adjust(point a, point_difference delta) const
+ {
+ point result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = a[i] + delta[i];
+ return result;
+ }
+
+ point pointwise_min(point a, point b) const
+ {
+ BOOST_USING_STD_MIN();
+ point result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = min BOOST_PREVENT_MACRO_SUBSTITUTION(a[i], b[i]);
+ return result;
+ }
+
+ point pointwise_max(point a, point b) const
+ {
+ BOOST_USING_STD_MAX();
+ point result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = max BOOST_PREVENT_MACRO_SUBSTITUTION(a[i], b[i]);
+ return result;
+ }
+
+ double norm(point_difference delta) const
+ {
+ double n = 0.;
+ for (std::size_t i = 0; i < Dims; ++i)
+ n = boost::math::hypot(n, delta[i]);
+ return n;
+ }
+
+ double volume(point_difference delta) const
+ {
+ double n = 1.;
+ for (std::size_t i = 0; i < Dims; ++i)
+ n *= delta[i];
+ return n;
+ }
+};
+
+template < std::size_t Dims, typename RandomNumberGenerator = minstd_rand >
+class hypercube_topology : public convex_topology< Dims >
+{
+ typedef uniform_01< RandomNumberGenerator, double > rand_t;
+
+public:
+ typedef typename convex_topology< Dims >::point_type point_type;
+ typedef typename convex_topology< Dims >::point_difference_type
+ point_difference_type;
+
+ explicit hypercube_topology(double scaling = 1.0)
+ : gen_ptr(new RandomNumberGenerator)
+ , rand(new rand_t(*gen_ptr))
+ , scaling(scaling)
+ {
+ }
+
+ hypercube_topology(RandomNumberGenerator& gen, double scaling = 1.0)
+ : gen_ptr(), rand(new rand_t(gen)), scaling(scaling)
+ {
+ }
+
+ point_type random_point() const
+ {
+ point_type p;
+ for (std::size_t i = 0; i < Dims; ++i)
+ p[i] = (*rand)() * scaling;
+ return p;
+ }
+
+ point_type bound(point_type a) const
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ point_type p;
+ for (std::size_t i = 0; i < Dims; ++i)
+ p[i] = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ scaling, max BOOST_PREVENT_MACRO_SUBSTITUTION(-scaling, a[i]));
+ return p;
+ }
+
+ double distance_from_boundary(point_type a) const
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::abs;
+#endif
+ BOOST_STATIC_ASSERT(Dims >= 1);
+ double dist = abs(scaling - a[0]);
+ for (std::size_t i = 1; i < Dims; ++i)
+ dist = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ dist, abs(scaling - a[i]));
+ return dist;
+ }
+
+ point_type center() const
+ {
+ point_type result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = scaling * .5;
+ return result;
+ }
+
+ point_type origin() const
+ {
+ point_type result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = 0;
+ return result;
+ }
+
+ point_difference_type extent() const
+ {
+ point_difference_type result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = scaling;
+ return result;
+ }
+
+private:
+ shared_ptr< RandomNumberGenerator > gen_ptr;
+ shared_ptr< rand_t > rand;
+ double scaling;
+};
+
+template < typename RandomNumberGenerator = minstd_rand >
+class square_topology : public hypercube_topology< 2, RandomNumberGenerator >
+{
+ typedef hypercube_topology< 2, RandomNumberGenerator > inherited;
+
+public:
+ explicit square_topology(double scaling = 1.0) : inherited(scaling) {}
+
+ square_topology(RandomNumberGenerator& gen, double scaling = 1.0)
+ : inherited(gen, scaling)
+ {
+ }
+};
+
+template < typename RandomNumberGenerator = minstd_rand >
+class rectangle_topology : public convex_topology< 2 >
+{
+ typedef uniform_01< RandomNumberGenerator, double > rand_t;
+
+public:
+ rectangle_topology(double left, double top, double right, double bottom)
+ : gen_ptr(new RandomNumberGenerator)
+ , rand(new rand_t(*gen_ptr))
+ , left(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(left, right))
+ , top(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(top, bottom))
+ , right(std::max BOOST_PREVENT_MACRO_SUBSTITUTION(left, right))
+ , bottom(std::max BOOST_PREVENT_MACRO_SUBSTITUTION(top, bottom))
+ {
+ }
+
+ rectangle_topology(RandomNumberGenerator& gen, double left, double top,
+ double right, double bottom)
+ : gen_ptr()
+ , rand(new rand_t(gen))
+ , left(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(left, right))
+ , top(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(top, bottom))
+ , right(std::max BOOST_PREVENT_MACRO_SUBSTITUTION(left, right))
+ , bottom(std::max BOOST_PREVENT_MACRO_SUBSTITUTION(top, bottom))
+ {
+ }
+
+ typedef typename convex_topology< 2 >::point_type point_type;
+ typedef typename convex_topology< 2 >::point_difference_type
+ point_difference_type;
+
+ point_type random_point() const
+ {
+ point_type p;
+ p[0] = (*rand)() * (right - left) + left;
+ p[1] = (*rand)() * (bottom - top) + top;
+ return p;
+ }
+
+ point_type bound(point_type a) const
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ point_type p;
+ p[0] = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ right, max BOOST_PREVENT_MACRO_SUBSTITUTION(left, a[0]));
+ p[1] = min BOOST_PREVENT_MACRO_SUBSTITUTION(
+ bottom, max BOOST_PREVENT_MACRO_SUBSTITUTION(top, a[1]));
+ return p;
+ }
+
+ double distance_from_boundary(point_type a) const
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::abs;
+#endif
+ double dist = abs(left - a[0]);
+ dist = min BOOST_PREVENT_MACRO_SUBSTITUTION(dist, abs(right - a[0]));
+ dist = min BOOST_PREVENT_MACRO_SUBSTITUTION(dist, abs(top - a[1]));
+ dist = min BOOST_PREVENT_MACRO_SUBSTITUTION(dist, abs(bottom - a[1]));
+ return dist;
+ }
+
+ point_type center() const
+ {
+ point_type result;
+ result[0] = (left + right) / 2.;
+ result[1] = (top + bottom) / 2.;
+ return result;
+ }
+
+ point_type origin() const
+ {
+ point_type result;
+ result[0] = left;
+ result[1] = top;
+ return result;
+ }
+
+ point_difference_type extent() const
+ {
+ point_difference_type result;
+ result[0] = right - left;
+ result[1] = bottom - top;
+ return result;
+ }
+
+private:
+ shared_ptr< RandomNumberGenerator > gen_ptr;
+ shared_ptr< rand_t > rand;
+ double left, top, right, bottom;
+};
+
+template < typename RandomNumberGenerator = minstd_rand >
+class cube_topology : public hypercube_topology< 3, RandomNumberGenerator >
+{
+ typedef hypercube_topology< 3, RandomNumberGenerator > inherited;
+
+public:
+ explicit cube_topology(double scaling = 1.0) : inherited(scaling) {}
+
+ cube_topology(RandomNumberGenerator& gen, double scaling = 1.0)
+ : inherited(gen, scaling)
+ {
+ }
+};
+
+template < std::size_t Dims, typename RandomNumberGenerator = minstd_rand >
+class ball_topology : public convex_topology< Dims >
+{
+ typedef uniform_01< RandomNumberGenerator, double > rand_t;
+
+public:
+ typedef typename convex_topology< Dims >::point_type point_type;
+ typedef typename convex_topology< Dims >::point_difference_type
+ point_difference_type;
+
+ explicit ball_topology(double radius = 1.0)
+ : gen_ptr(new RandomNumberGenerator)
+ , rand(new rand_t(*gen_ptr))
+ , radius(radius)
+ {
+ }
+
+ ball_topology(RandomNumberGenerator& gen, double radius = 1.0)
+ : gen_ptr(), rand(new rand_t(gen)), radius(radius)
+ {
+ }
+
+ point_type random_point() const
+ {
+ point_type p;
+ double dist_sum;
+ do
+ {
+ dist_sum = 0.0;
+ for (std::size_t i = 0; i < Dims; ++i)
+ {
+ double x = (*rand)() * 2 * radius - radius;
+ p[i] = x;
+ dist_sum += x * x;
+ }
+ } while (dist_sum > radius * radius);
+ return p;
+ }
+
+ point_type bound(point_type a) const
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ double r = 0.;
+ for (std::size_t i = 0; i < Dims; ++i)
+ r = boost::math::hypot(r, a[i]);
+ if (r <= radius)
+ return a;
+ double scaling_factor = radius / r;
+ point_type p;
+ for (std::size_t i = 0; i < Dims; ++i)
+ p[i] = a[i] * scaling_factor;
+ return p;
+ }
+
+ double distance_from_boundary(point_type a) const
+ {
+ double r = 0.;
+ for (std::size_t i = 0; i < Dims; ++i)
+ r = boost::math::hypot(r, a[i]);
+ return radius - r;
+ }
+
+ point_type center() const
+ {
+ point_type result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = 0;
+ return result;
+ }
+
+ point_type origin() const
+ {
+ point_type result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = -radius;
+ return result;
+ }
+
+ point_difference_type extent() const
+ {
+ point_difference_type result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = 2. * radius;
+ return result;
+ }
+
+private:
+ shared_ptr< RandomNumberGenerator > gen_ptr;
+ shared_ptr< rand_t > rand;
+ double radius;
+};
+
+template < typename RandomNumberGenerator = minstd_rand >
+class circle_topology : public ball_topology< 2, RandomNumberGenerator >
+{
+ typedef ball_topology< 2, RandomNumberGenerator > inherited;
+
+public:
+ explicit circle_topology(double radius = 1.0) : inherited(radius) {}
+
+ circle_topology(RandomNumberGenerator& gen, double radius = 1.0)
+ : inherited(gen, radius)
+ {
+ }
+};
+
+template < typename RandomNumberGenerator = minstd_rand >
+class sphere_topology : public ball_topology< 3, RandomNumberGenerator >
+{
+ typedef ball_topology< 3, RandomNumberGenerator > inherited;
+
+public:
+ explicit sphere_topology(double radius = 1.0) : inherited(radius) {}
+
+ sphere_topology(RandomNumberGenerator& gen, double radius = 1.0)
+ : inherited(gen, radius)
+ {
+ }
+};
+
+template < typename RandomNumberGenerator = minstd_rand > class heart_topology
+{
+ // Heart is defined as the union of three shapes:
+ // Square w/ corners (+-1000, -1000), (0, 0), (0, -2000)
+ // Circle centered at (-500, -500) radius 500*sqrt(2)
+ // Circle centered at (500, -500) radius 500*sqrt(2)
+ // Bounding box (-1000, -2000) - (1000, 500*(sqrt(2) - 1))
+
+ struct point
+ {
+ point()
+ {
+ values[0] = 0.0;
+ values[1] = 0.0;
+ }
+ point(double x, double y)
+ {
+ values[0] = x;
+ values[1] = y;
+ }
+
+ double& operator[](std::size_t i) { return values[i]; }
+ double operator[](std::size_t i) const { return values[i]; }
+
+ private:
+ double values[2];
+ };
+
+ bool in_heart(point p) const
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::abs;
+#endif
+
+ if (p[1] < abs(p[0]) - 2000)
+ return false; // Bottom
+ if (p[1] <= -1000)
+ return true; // Diagonal of square
+ if (boost::math::hypot(p[0] - -500, p[1] - -500)
+ <= 500. * boost::math::constants::root_two< double >())
+ return true; // Left circle
+ if (boost::math::hypot(p[0] - 500, p[1] - -500)
+ <= 500. * boost::math::constants::root_two< double >())
+ return true; // Right circle
+ return false;
+ }
+
+ bool segment_within_heart(point p1, point p2) const
+ {
+ // Assumes that p1 and p2 are within the heart
+ if ((p1[0] < 0) == (p2[0] < 0))
+ return true; // Same side of symmetry line
+ if (p1[0] == p2[0])
+ return true; // Vertical
+ double slope = (p2[1] - p1[1]) / (p2[0] - p1[0]);
+ double intercept = p1[1] - p1[0] * slope;
+ if (intercept > 0)
+ return false; // Crosses between circles
+ return true;
+ }
+
+ typedef uniform_01< RandomNumberGenerator, double > rand_t;
+
+public:
+ typedef point point_type;
+
+ heart_topology()
+ : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr))
+ {
+ }
+
+ heart_topology(RandomNumberGenerator& gen)
+ : gen_ptr(), rand(new rand_t(gen))
+ {
+ }
+
+ point random_point() const
+ {
+ point result;
+ do
+ {
+ result[0] = (*rand)()
+ * (1000
+ + 1000 * boost::math::constants::root_two< double >())
+ - (500 + 500 * boost::math::constants::root_two< double >());
+ result[1] = (*rand)()
+ * (2000
+ + 500
+ * (boost::math::constants::root_two< double >()
+ - 1))
+ - 2000;
+ } while (!in_heart(result));
+ return result;
+ }
+
+ // Not going to provide clipping to bounding region or distance from
+ // boundary
+
+ double distance(point a, point b) const
+ {
+ if (segment_within_heart(a, b))
+ {
+ // Straight line
+ return boost::math::hypot(b[0] - a[0], b[1] - a[1]);
+ }
+ else
+ {
+ // Straight line bending around (0, 0)
+ return boost::math::hypot(a[0], a[1])
+ + boost::math::hypot(b[0], b[1]);
+ }
+ }
+
+ point move_position_toward(point a, double fraction, point b) const
+ {
+ if (segment_within_heart(a, b))
+ {
+ // Straight line
+ return point(a[0] + (b[0] - a[0]) * fraction,
+ a[1] + (b[1] - a[1]) * fraction);
+ }
+ else
+ {
+ double distance_to_point_a = boost::math::hypot(a[0], a[1]);
+ double distance_to_point_b = boost::math::hypot(b[0], b[1]);
+ double location_of_point = distance_to_point_a
+ / (distance_to_point_a + distance_to_point_b);
+ if (fraction < location_of_point)
+ return point(a[0] * (1 - fraction / location_of_point),
+ a[1] * (1 - fraction / location_of_point));
+ else
+ return point(b[0]
+ * ((fraction - location_of_point)
+ / (1 - location_of_point)),
+ b[1]
+ * ((fraction - location_of_point)
+ / (1 - location_of_point)));
+ }
+ }
+
+private:
+ shared_ptr< RandomNumberGenerator > gen_ptr;
+ shared_ptr< rand_t > rand;
+};
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_TOPOLOGY_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/transitive_closure.hpp b/contrib/restricted/boost/graph/include/boost/graph/transitive_closure.hpp
new file mode 100644
index 0000000000..fa8a7cd9e7
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/transitive_closure.hpp
@@ -0,0 +1,392 @@
+// Copyright (C) 2001 Vladimir Prus <ghost@cs.msu.su>
+// Copyright (C) 2001 Jeremy Siek <jsiek@cs.indiana.edu>
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// NOTE: this final is generated by libs/graph/doc/transitive_closure.w
+
+#ifndef BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP
+#define BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP
+
+#include <vector>
+#include <algorithm> // for std::min and std::max
+#include <functional>
+#include <boost/config.hpp>
+#include <boost/bind/bind.hpp>
+#include <boost/graph/strong_components.hpp>
+#include <boost/graph/topological_sort.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+ inline void union_successor_sets(const std::vector< std::size_t >& s1,
+ const std::vector< std::size_t >& s2, std::vector< std::size_t >& s3)
+ {
+ BOOST_USING_STD_MIN();
+ for (std::size_t k = 0; k < s1.size(); ++k)
+ s3[k] = min BOOST_PREVENT_MACRO_SUBSTITUTION(s1[k], s2[k]);
+ }
+} // namespace detail
+
+namespace detail
+{
+ template < typename TheContainer, typename ST = std::size_t,
+ typename VT = typename TheContainer::value_type >
+ struct subscript_t
+ {
+ typedef ST argument_type;
+ typedef VT& result_type;
+
+ subscript_t(TheContainer& c) : container(&c) {}
+ VT& operator()(const ST& i) const { return (*container)[i]; }
+
+ protected:
+ TheContainer* container;
+ };
+ template < typename TheContainer >
+ subscript_t< TheContainer > subscript(TheContainer& c)
+ {
+ return subscript_t< TheContainer >(c);
+ }
+} // namespace detail
+
+template < typename Graph, typename GraphTC, typename G_to_TC_VertexMap,
+ typename VertexIndexMap >
+void transitive_closure(const Graph& g, GraphTC& tc,
+ G_to_TC_VertexMap g_to_tc_map, VertexIndexMap index_map)
+{
+ if (num_vertices(g) == 0)
+ return;
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator;
+ typedef typename property_traits< VertexIndexMap >::value_type size_type;
+ typedef
+ typename graph_traits< Graph >::adjacency_iterator adjacency_iterator;
+
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((AdjacencyGraphConcept< Graph >));
+ BOOST_CONCEPT_ASSERT((VertexMutableGraphConcept< GraphTC >));
+ BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept< GraphTC >));
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< VertexIndexMap, vertex >));
+
+ typedef size_type cg_vertex;
+ std::vector< cg_vertex > component_number_vec(num_vertices(g));
+ iterator_property_map< cg_vertex*, VertexIndexMap, cg_vertex, cg_vertex& >
+ component_number(&component_number_vec[0], index_map);
+
+ const cg_vertex num_scc
+ = strong_components(g, component_number, vertex_index_map(index_map));
+
+ std::vector< std::vector< vertex > > components;
+ build_component_lists(g, num_scc, component_number, components);
+
+ typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS >
+ CG_t;
+ CG_t CG(num_scc);
+ for (cg_vertex s = 0; s < components.size(); ++s)
+ {
+ std::vector< cg_vertex > adj;
+ for (size_type i = 0; i < components[s].size(); ++i)
+ {
+ vertex u = components[s][i];
+ adjacency_iterator v, v_end;
+ for (boost::tie(v, v_end) = adjacent_vertices(u, g); v != v_end;
+ ++v)
+ {
+ cg_vertex t = component_number[*v];
+ if (s != t) // Avoid loops in the condensation graph
+ adj.push_back(t);
+ }
+ }
+ std::sort(adj.begin(), adj.end());
+ const typename std::vector< cg_vertex >::iterator di
+ = std::unique(adj.begin(), adj.end());
+
+ for (typename std::vector< cg_vertex >::const_iterator i = adj.begin();
+ i != di; ++i)
+ {
+ add_edge(s, *i, CG);
+ }
+ }
+
+ std::vector< cg_vertex > topo_order;
+ std::vector< cg_vertex > topo_number(num_vertices(CG));
+ topological_sort(CG, std::back_inserter(topo_order),
+ vertex_index_map(identity_property_map()));
+ std::reverse(topo_order.begin(), topo_order.end());
+ size_type n = 0;
+ for (typename std::vector< cg_vertex >::iterator iter = topo_order.begin();
+ iter != topo_order.end(); ++iter)
+ topo_number[*iter] = n++;
+
+ std::vector< std::vector< cg_vertex > > CG_vec(num_vertices(CG));
+ for (size_type i = 0; i < num_vertices(CG); ++i)
+ {
+ using namespace boost::placeholders;
+
+ typedef typename boost::graph_traits< CG_t >::adjacency_iterator
+ cg_adj_iter;
+ std::pair< cg_adj_iter, cg_adj_iter > pr = adjacent_vertices(i, CG);
+ CG_vec[i].assign(pr.first, pr.second);
+ std::sort(CG_vec[i].begin(), CG_vec[i].end(),
+ boost::bind(std::less< cg_vertex >(),
+ boost::bind(detail::subscript(topo_number), _1),
+ boost::bind(detail::subscript(topo_number), _2)));
+ }
+
+ std::vector< std::vector< cg_vertex > > chains;
+ {
+ std::vector< cg_vertex > in_a_chain(CG_vec.size());
+ for (typename std::vector< cg_vertex >::iterator i = topo_order.begin();
+ i != topo_order.end(); ++i)
+ {
+ cg_vertex v = *i;
+ if (!in_a_chain[v])
+ {
+ chains.resize(chains.size() + 1);
+ std::vector< cg_vertex >& chain = chains.back();
+ for (;;)
+ {
+ chain.push_back(v);
+ in_a_chain[v] = true;
+
+ typename std::vector< cg_vertex >::const_iterator next
+ #ifdef __cpp_lib_not_fn
+ = std::find_if(CG_vec[v].begin(), CG_vec[v].end(),
+ std::not_fn(detail::subscript(in_a_chain)));
+ #else
+ = std::find_if(CG_vec[v].begin(), CG_vec[v].end(),
+ std::not1(detail::subscript(in_a_chain)));
+ #endif
+
+ if (next != CG_vec[v].end())
+ v = *next;
+ else
+ break; // end of chain, dead-end
+ }
+ }
+ }
+ }
+ std::vector< size_type > chain_number(CG_vec.size());
+ std::vector< size_type > pos_in_chain(CG_vec.size());
+ for (size_type i = 0; i < chains.size(); ++i)
+ for (size_type j = 0; j < chains[i].size(); ++j)
+ {
+ cg_vertex v = chains[i][j];
+ chain_number[v] = i;
+ pos_in_chain[v] = j;
+ }
+
+ cg_vertex inf = (std::numeric_limits< cg_vertex >::max)();
+ std::vector< std::vector< cg_vertex > > successors(
+ CG_vec.size(), std::vector< cg_vertex >(chains.size(), inf));
+ for (typename std::vector< cg_vertex >::reverse_iterator i
+ = topo_order.rbegin();
+ i != topo_order.rend(); ++i)
+ {
+ cg_vertex u = *i;
+ typename std::vector< cg_vertex >::const_iterator adj, adj_last;
+ for (adj = CG_vec[u].begin(), adj_last = CG_vec[u].end();
+ adj != adj_last; ++adj)
+ {
+ cg_vertex v = *adj;
+ if (topo_number[v] < successors[u][chain_number[v]])
+ {
+ // Succ(u) = Succ(u) U Succ(v)
+ detail::union_successor_sets(
+ successors[u], successors[v], successors[u]);
+ // Succ(u) = Succ(u) U {v}
+ successors[u][chain_number[v]] = topo_number[v];
+ }
+ }
+ }
+
+ for (size_type i = 0; i < CG_vec.size(); ++i)
+ CG_vec[i].clear();
+ for (size_type i = 0; i < CG_vec.size(); ++i)
+ for (size_type j = 0; j < chains.size(); ++j)
+ {
+ size_type topo_num = successors[i][j];
+ if (topo_num < inf)
+ {
+ cg_vertex v = topo_order[topo_num];
+ for (size_type k = pos_in_chain[v]; k < chains[j].size(); ++k)
+ CG_vec[i].push_back(chains[j][k]);
+ }
+ }
+
+ // Add vertices to the transitive closure graph
+ {
+ vertex_iterator i, i_end;
+ for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i)
+ g_to_tc_map[*i] = add_vertex(tc);
+ }
+ // Add edges between all the vertices in two adjacent SCCs
+ typename std::vector< std::vector< cg_vertex > >::const_iterator si, si_end;
+ for (si = CG_vec.begin(), si_end = CG_vec.end(); si != si_end; ++si)
+ {
+ cg_vertex s = si - CG_vec.begin();
+ typename std::vector< cg_vertex >::const_iterator i, i_end;
+ for (i = CG_vec[s].begin(), i_end = CG_vec[s].end(); i != i_end; ++i)
+ {
+ cg_vertex t = *i;
+ for (size_type k = 0; k < components[s].size(); ++k)
+ for (size_type l = 0; l < components[t].size(); ++l)
+ add_edge(g_to_tc_map[components[s][k]],
+ g_to_tc_map[components[t][l]], tc);
+ }
+ }
+ // Add edges connecting all vertices in a SCC
+ for (size_type i = 0; i < components.size(); ++i)
+ if (components[i].size() > 1)
+ for (size_type k = 0; k < components[i].size(); ++k)
+ for (size_type l = 0; l < components[i].size(); ++l)
+ {
+ vertex u = components[i][k], v = components[i][l];
+ add_edge(g_to_tc_map[u], g_to_tc_map[v], tc);
+ }
+
+ // Find loopbacks in the original graph.
+ // Need to add it to transitive closure.
+ {
+ vertex_iterator i, i_end;
+ for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i)
+ {
+ adjacency_iterator ab, ae;
+ for (boost::tie(ab, ae) = adjacent_vertices(*i, g); ab != ae; ++ab)
+ {
+ if (*ab == *i)
+ if (components[component_number[*i]].size() == 1)
+ add_edge(g_to_tc_map[*i], g_to_tc_map[*i], tc);
+ }
+ }
+ }
+}
+
+template < typename Graph, typename GraphTC >
+void transitive_closure(const Graph& g, GraphTC& tc)
+{
+ if (num_vertices(g) == 0)
+ return;
+ typedef typename property_map< Graph, vertex_index_t >::const_type
+ VertexIndexMap;
+ VertexIndexMap index_map = get(vertex_index, g);
+
+ typedef typename graph_traits< GraphTC >::vertex_descriptor tc_vertex;
+ std::vector< tc_vertex > to_tc_vec(num_vertices(g));
+ iterator_property_map< tc_vertex*, VertexIndexMap, tc_vertex, tc_vertex& >
+ g_to_tc_map(&to_tc_vec[0], index_map);
+
+ transitive_closure(g, tc, g_to_tc_map, index_map);
+}
+
+namespace detail
+{
+ template < typename Graph, typename GraphTC, typename G_to_TC_VertexMap,
+ typename VertexIndexMap >
+ void transitive_closure_dispatch(const Graph& g, GraphTC& tc,
+ G_to_TC_VertexMap g_to_tc_map, VertexIndexMap index_map)
+ {
+ typedef typename graph_traits< GraphTC >::vertex_descriptor tc_vertex;
+ typename std::vector< tc_vertex >::size_type n
+ = is_default_param(g_to_tc_map) ? num_vertices(g) : 1;
+ std::vector< tc_vertex > to_tc_vec(n);
+
+ transitive_closure(g, tc,
+ choose_param(g_to_tc_map,
+ make_iterator_property_map(
+ to_tc_vec.begin(), index_map, to_tc_vec[0])),
+ index_map);
+ }
+} // namespace detail
+
+template < typename Graph, typename GraphTC, typename P, typename T,
+ typename R >
+void transitive_closure(
+ const Graph& g, GraphTC& tc, const bgl_named_params< P, T, R >& params)
+{
+ if (num_vertices(g) == 0)
+ return;
+ detail::transitive_closure_dispatch(g, tc,
+ get_param(params, orig_to_copy_t()),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index));
+}
+
+template < typename G > void warshall_transitive_closure(G& g)
+{
+ typedef typename graph_traits< G >::vertex_iterator vertex_iterator;
+
+ BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< G >));
+ BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept< G >));
+
+ // Matrix form:
+ // for k
+ // for i
+ // if A[i,k]
+ // for j
+ // A[i,j] = A[i,j] | A[k,j]
+ vertex_iterator ki, ke, ii, ie, ji, je;
+ for (boost::tie(ki, ke) = vertices(g); ki != ke; ++ki)
+ for (boost::tie(ii, ie) = vertices(g); ii != ie; ++ii)
+ if (edge(*ii, *ki, g).second)
+ for (boost::tie(ji, je) = vertices(g); ji != je; ++ji)
+ if (!edge(*ii, *ji, g).second && edge(*ki, *ji, g).second)
+ {
+ add_edge(*ii, *ji, g);
+ }
+}
+
+template < typename G > void warren_transitive_closure(G& g)
+{
+ using namespace boost;
+ typedef typename graph_traits< G >::vertex_iterator vertex_iterator;
+
+ BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< G >));
+ BOOST_CONCEPT_ASSERT((EdgeMutableGraphConcept< G >));
+
+ // Make sure second loop will work
+ if (num_vertices(g) == 0)
+ return;
+
+ // for i = 2 to n
+ // for k = 1 to i - 1
+ // if A[i,k]
+ // for j = 1 to n
+ // A[i,j] = A[i,j] | A[k,j]
+
+ vertex_iterator ic, ie, jc, je, kc, ke;
+ for (boost::tie(ic, ie) = vertices(g), ++ic; ic != ie; ++ic)
+ for (boost::tie(kc, ke) = vertices(g); *kc != *ic; ++kc)
+ if (edge(*ic, *kc, g).second)
+ for (boost::tie(jc, je) = vertices(g); jc != je; ++jc)
+ if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second)
+ {
+ add_edge(*ic, *jc, g);
+ }
+ // for i = 1 to n - 1
+ // for k = i + 1 to n
+ // if A[i,k]
+ // for j = 1 to n
+ // A[i,j] = A[i,j] | A[k,j]
+
+ for (boost::tie(ic, ie) = vertices(g), --ie; ic != ie; ++ic)
+ for (kc = ic, ke = ie, ++kc; kc != ke; ++kc)
+ if (edge(*ic, *kc, g).second)
+ for (boost::tie(jc, je) = vertices(g); jc != je; ++jc)
+ if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second)
+ {
+ add_edge(*ic, *jc, g);
+ }
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/transitive_reduction.hpp b/contrib/restricted/boost/graph/include/boost/graph/transitive_reduction.hpp
new file mode 100644
index 0000000000..32cb384aaa
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/transitive_reduction.hpp
@@ -0,0 +1,137 @@
+// (C) Copyright 2009 Eric Bose-Wolf
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_TRANSITIVE_REDUCTION_HPP
+#define BOOST_GRAPH_TRANSITIVE_REDUCTION_HPP
+
+#include <vector>
+#include <algorithm> //std::find
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/topological_sort.hpp>
+
+// also I didn't got all of the concepts thin. Am I suppose to check
+// for all concepts, which are needed for functions I call? (As if I
+// wouldn't do that, the users would see the functions called by
+// complaining about missings concepts, which would be clearly an error
+// message revealing internal implementation and should therefore be avoided?)
+
+// the pseudocode which I followed implementing this algorithmn was taken
+// from the german book Algorithmische Graphentheorie by Volker Turau
+// it is proposed to be of O(n + nm_red ) where n is the number
+// of vertices and m_red is the number of edges in the transitive
+// reduction, but I think my implementation spoiled this up at some point
+// indicated below.
+
+namespace boost
+{
+
+template < typename Graph, typename GraphTR, typename G_to_TR_VertexMap,
+ typename VertexIndexMap >
+BOOST_CONCEPT_REQUIRES(
+ ((VertexListGraphConcept< Graph >))((IncidenceGraphConcept< Graph >))(
+ (MutableGraphConcept< GraphTR >))(
+ (ReadablePropertyMapConcept< VertexIndexMap,
+ typename graph_traits< Graph >::vertex_descriptor >))(
+ (Integer< typename property_traits< VertexIndexMap >::value_type >))(
+ (LvaluePropertyMapConcept< G_to_TR_VertexMap,
+ typename graph_traits< Graph >::vertex_descriptor >)),
+ (void))
+transitive_reduction(const Graph& g, GraphTR& tr, G_to_TR_VertexMap g_to_tr_map,
+ VertexIndexMap g_index_map)
+{
+ typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
+ typedef typename std::vector< Vertex >::size_type size_type;
+
+ std::vector< Vertex > topo_order;
+ topological_sort(g, std::back_inserter(topo_order));
+
+ std::vector< size_type > topo_number_storage(num_vertices(g));
+
+ iterator_property_map< size_type*, VertexIndexMap, size_type, size_type& >
+ topo_number(&topo_number_storage[0], g_index_map);
+
+ {
+ typename std::vector< Vertex >::reverse_iterator it
+ = topo_order.rbegin();
+ size_type n = 0;
+ for (; it != topo_order.rend(); ++it, ++n)
+ {
+ topo_number[*it] = n;
+ }
+ }
+
+ std::vector< std::vector< bool > > edge_in_closure(
+ num_vertices(g), std::vector< bool >(num_vertices(g), false));
+ {
+ typename std::vector< Vertex >::reverse_iterator it
+ = topo_order.rbegin();
+ for (; it != topo_order.rend(); ++it)
+ {
+ g_to_tr_map[*it] = add_vertex(tr);
+ }
+ }
+
+ typename std::vector< Vertex >::iterator it = topo_order.begin(),
+ end = topo_order.end();
+ for (; it != end; ++it)
+ {
+ size_type i = topo_number[*it];
+ edge_in_closure[i][i] = true;
+ std::vector< Vertex > neighbors;
+
+ // I have to collect the successors of *it and traverse them in
+ // ascending topological order. I didn't know a better way, how to
+ // do that. So what I'm doint is, collection the successors of *it here
+ {
+ typename Graph::out_edge_iterator oi, oi_end;
+ for (boost::tie(oi, oi_end) = out_edges(*it, g); oi != oi_end; ++oi)
+ {
+ neighbors.push_back(target(*oi, g));
+ }
+ }
+
+ {
+ // and run through all vertices in topological order
+ typename std::vector< Vertex >::reverse_iterator rit
+ = topo_order.rbegin(),
+ rend = topo_order.rend();
+ for (; rit != rend; ++rit)
+ {
+ // looking if they are successors of *it
+ if (std::find(neighbors.begin(), neighbors.end(), *rit)
+ != neighbors.end())
+ {
+ size_type j = topo_number[*rit];
+ if (not edge_in_closure[i][j])
+ {
+ for (size_type k = j; k < num_vertices(g); ++k)
+ {
+ if (not edge_in_closure[i][k])
+ {
+ // here we need edge_in_closure to be in
+ // topological order,
+ edge_in_closure[i][k] = edge_in_closure[j][k];
+ }
+ }
+ // therefore we only access edge_in_closure only through
+ // topo_number property_map
+ add_edge(g_to_tr_map[*it], g_to_tr_map[*rit], tr);
+ } // if ( not edge_in_
+ } // if (find (
+ } // for( typename vector<Vertex>::reverse_iterator
+ } // {
+
+ } // for( typename vector<Vertex>::iterator
+
+} // void transitive_reduction
+
+} // namespace boost
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/tree_traits.hpp b/contrib/restricted/boost/graph/include/boost/graph/tree_traits.hpp
new file mode 100644
index 0000000000..e27396ebfd
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/tree_traits.hpp
@@ -0,0 +1,48 @@
+// (C) Copyright Jeremy Siek 1999.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_TREE_STRUCTURE_HPP
+#define BOOST_TREE_STRUCTURE_HPP
+
+#include <boost/tuple/tuple.hpp> //For boost::tie()
+
+namespace boost
+{
+
+template < class T > struct tree_traits
+{
+ typedef typename T::node_descriptor node_descriptor;
+ typedef typename T::children_iterator children_iterator;
+};
+
+template < class Tree, class TreeVisitor >
+void traverse_tree(typename tree_traits< Tree >::node_descriptor v, Tree& t,
+ TreeVisitor visitor)
+{
+ visitor.preorder(v, t);
+ typename tree_traits< Tree >::children_iterator i, end;
+ boost::tie(i, end) = children(v, t);
+ if (i != end)
+ {
+ traverse_tree(*i++, t, visitor);
+ visitor.inorder(v, t);
+ while (i != end)
+ traverse_tree(*i++, t, visitor);
+ }
+ else
+ visitor.inorder(v, t);
+ visitor.postorder(v, t);
+}
+
+struct null_tree_visitor
+{
+ template < typename Node, typename Tree > void preorder(Node, Tree&) {}
+ template < typename Node, typename Tree > void inorder(Node, Tree&) {}
+ template < typename Node, typename Tree > void postorder(Node, Tree&) {}
+};
+
+} /* namespace boost */
+
+#endif /* BOOST_TREE_STRUCTURE_HPP */
diff --git a/contrib/restricted/boost/graph/include/boost/graph/two_graphs_common_spanning_trees.hpp b/contrib/restricted/boost/graph/include/boost/graph/two_graphs_common_spanning_trees.hpp
new file mode 100644
index 0000000000..a41dc84b21
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/two_graphs_common_spanning_trees.hpp
@@ -0,0 +1,852 @@
+// Copyright (C) 2012, Michele Caini.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Two Graphs Common Spanning Trees Algorithm
+// Based on academic article of Mint, Read and Tarjan
+// Efficient Algorithm for Common Spanning Tree Problem
+// Electron. Lett., 28 April 1983, Volume 19, Issue 9, p.346-347
+
+#ifndef BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP
+#define BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP
+
+#include <boost/config.hpp>
+
+#include <boost/bimap.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/concept/requires.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/undirected_dfs.hpp>
+#include <boost/graph/connected_components.hpp>
+#include <boost/graph/filtered_graph.hpp>
+#include <vector>
+#include <stack>
+#include <map>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < typename TreeMap, typename PredMap, typename DistMap,
+ typename LowMap, typename Buffer >
+ struct bridges_visitor : public default_dfs_visitor
+ {
+ bridges_visitor(TreeMap tree, PredMap pred, DistMap dist, LowMap low,
+ Buffer& buffer)
+ : mTree(tree), mPred(pred), mDist(dist), mLow(low), mBuffer(buffer)
+ {
+ mNum = -1;
+ }
+
+ template < typename Vertex, typename Graph >
+ void initialize_vertex(const Vertex& u, const Graph& g)
+ {
+ put(mPred, u, u);
+ put(mDist, u, -1);
+ }
+
+ template < typename Vertex, typename Graph >
+ void discover_vertex(const Vertex& u, const Graph& g)
+ {
+ put(mDist, u, ++mNum);
+ put(mLow, u, get(mDist, u));
+ }
+
+ template < typename Edge, typename Graph >
+ void tree_edge(const Edge& e, const Graph& g)
+ {
+ put(mPred, target(e, g), source(e, g));
+ put(mTree, target(e, g), e);
+ }
+
+ template < typename Edge, typename Graph >
+ void back_edge(const Edge& e, const Graph& g)
+ {
+ put(mLow, source(e, g),
+ (std::min)(get(mLow, source(e, g)), get(mDist, target(e, g))));
+ }
+
+ template < typename Vertex, typename Graph >
+ void finish_vertex(const Vertex& u, const Graph& g)
+ {
+ Vertex parent = get(mPred, u);
+ if (get(mLow, u) > get(mDist, parent))
+ mBuffer.push(get(mTree, u));
+ put(mLow, parent, (std::min)(get(mLow, parent), get(mLow, u)));
+ }
+
+ TreeMap mTree;
+ PredMap mPred;
+ DistMap mDist;
+ LowMap mLow;
+ Buffer& mBuffer;
+ int mNum;
+ };
+
+ template < typename Buffer >
+ struct cycle_finder : public base_visitor< cycle_finder< Buffer > >
+ {
+ typedef on_back_edge event_filter;
+ cycle_finder() : mBuffer(0) {}
+ cycle_finder(Buffer* buffer) : mBuffer(buffer) {}
+ template < typename Edge, typename Graph >
+ void operator()(const Edge& e, const Graph& g)
+ {
+ if (mBuffer)
+ mBuffer->push(e);
+ }
+ Buffer* mBuffer;
+ };
+
+ template < typename DeletedMap > struct deleted_edge_status
+ {
+ deleted_edge_status() {}
+ deleted_edge_status(DeletedMap map) : mMap(map) {}
+ template < typename Edge > bool operator()(const Edge& e) const
+ {
+ return (!get(mMap, e));
+ }
+ DeletedMap mMap;
+ };
+
+ template < typename InLMap > struct inL_edge_status
+ {
+ inL_edge_status() {}
+ inL_edge_status(InLMap map) : mMap(map) {}
+ template < typename Edge > bool operator()(const Edge& e) const
+ {
+ return get(mMap, e);
+ }
+ InLMap mMap;
+ };
+
+ template < typename Graph, typename Func, typename Seq, typename Map >
+ void rec_two_graphs_common_spanning_trees(const Graph& iG,
+ bimap< bimaps::set_of< int >,
+ bimaps::set_of< typename graph_traits< Graph >::edge_descriptor > >
+ iG_bimap,
+ Map aiG_inL, Map diG, const Graph& vG,
+ bimap< bimaps::set_of< int >,
+ bimaps::set_of< typename graph_traits< Graph >::edge_descriptor > >
+ vG_bimap,
+ Map avG_inL, Map dvG, Func func, Seq inL)
+ {
+ typedef graph_traits< Graph > GraphTraits;
+
+ typedef typename GraphTraits::vertex_descriptor vertex_descriptor;
+ typedef typename GraphTraits::edge_descriptor edge_descriptor;
+
+ typedef typename Seq::size_type seq_size_type;
+
+ int edges = num_vertices(iG) - 1;
+ //
+ // [ Michele Caini ]
+ //
+ // Using the condition (edges != 0) leads to the accidental submission
+ // of
+ // sub-graphs ((V-1+1)-fake-tree, named here fat-tree).
+ // Remove this condition is a workaround for the problem of fat-trees.
+ // Please do not add that condition, even if it improves performance.
+ //
+ // Here is proposed the previous guard (that was wrong):
+ // for(seq_size_type i = 0; (i < inL.size()) && (edges != 0); ++i)
+ //
+ {
+ for (seq_size_type i = 0; i < inL.size(); ++i)
+ if (inL[i])
+ --edges;
+
+ if (edges < 0)
+ return;
+ }
+
+ bool is_tree = (edges == 0);
+ if (is_tree)
+ {
+ func(inL);
+ }
+ else
+ {
+ std::map< vertex_descriptor, default_color_type > vertex_color;
+ std::map< edge_descriptor, default_color_type > edge_color;
+
+ std::stack< edge_descriptor > iG_buf, vG_buf;
+ bool found = false;
+
+ seq_size_type m;
+ for (seq_size_type j = 0; j < inL.size() && !found; ++j)
+ {
+ if (!inL[j] && !get(diG, iG_bimap.left.at(j))
+ && !get(dvG, vG_bimap.left.at(j)))
+ {
+ put(aiG_inL, iG_bimap.left.at(j), true);
+ put(avG_inL, vG_bimap.left.at(j), true);
+
+ undirected_dfs(
+ make_filtered_graph(iG,
+ detail::inL_edge_status< associative_property_map<
+ std::map< edge_descriptor, bool > > >(aiG_inL)),
+ make_dfs_visitor(detail::cycle_finder<
+ std::stack< edge_descriptor > >(&iG_buf)),
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(
+ edge_color));
+ undirected_dfs(
+ make_filtered_graph(vG,
+ detail::inL_edge_status< associative_property_map<
+ std::map< edge_descriptor, bool > > >(avG_inL)),
+ make_dfs_visitor(detail::cycle_finder<
+ std::stack< edge_descriptor > >(&vG_buf)),
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(
+ edge_color));
+
+ if (iG_buf.empty() && vG_buf.empty())
+ {
+ inL[j] = true;
+ found = true;
+ m = j;
+ }
+ else
+ {
+ while (!iG_buf.empty())
+ iG_buf.pop();
+ while (!vG_buf.empty())
+ vG_buf.pop();
+ put(aiG_inL, iG_bimap.left.at(j), false);
+ put(avG_inL, vG_bimap.left.at(j), false);
+ }
+ }
+ }
+
+ if (found)
+ {
+
+ std::stack< edge_descriptor > iG_buf_copy, vG_buf_copy;
+ for (seq_size_type j = 0; j < inL.size(); ++j)
+ {
+ if (!inL[j] && !get(diG, iG_bimap.left.at(j))
+ && !get(dvG, vG_bimap.left.at(j)))
+ {
+
+ put(aiG_inL, iG_bimap.left.at(j), true);
+ put(avG_inL, vG_bimap.left.at(j), true);
+
+ undirected_dfs(
+ make_filtered_graph(iG,
+ detail::inL_edge_status<
+ associative_property_map<
+ std::map< edge_descriptor, bool > > >(
+ aiG_inL)),
+ make_dfs_visitor(detail::cycle_finder<
+ std::stack< edge_descriptor > >(&iG_buf)),
+ associative_property_map< std::map<
+ vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map< std::map< edge_descriptor,
+ default_color_type > >(edge_color));
+ undirected_dfs(
+ make_filtered_graph(vG,
+ detail::inL_edge_status<
+ associative_property_map<
+ std::map< edge_descriptor, bool > > >(
+ avG_inL)),
+ make_dfs_visitor(detail::cycle_finder<
+ std::stack< edge_descriptor > >(&vG_buf)),
+ associative_property_map< std::map<
+ vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map< std::map< edge_descriptor,
+ default_color_type > >(edge_color));
+
+ if (!iG_buf.empty() || !vG_buf.empty())
+ {
+ while (!iG_buf.empty())
+ iG_buf.pop();
+ while (!vG_buf.empty())
+ vG_buf.pop();
+ put(diG, iG_bimap.left.at(j), true);
+ put(dvG, vG_bimap.left.at(j), true);
+ iG_buf_copy.push(iG_bimap.left.at(j));
+ vG_buf_copy.push(vG_bimap.left.at(j));
+ }
+
+ put(aiG_inL, iG_bimap.left.at(j), false);
+ put(avG_inL, vG_bimap.left.at(j), false);
+ }
+ }
+
+ // REC
+ detail::rec_two_graphs_common_spanning_trees< Graph, Func, Seq,
+ Map >(iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL,
+ dvG, func, inL);
+
+ while (!iG_buf_copy.empty())
+ {
+ put(diG, iG_buf_copy.top(), false);
+ put(dvG,
+ vG_bimap.left.at(iG_bimap.right.at(iG_buf_copy.top())),
+ false);
+ iG_buf_copy.pop();
+ }
+ while (!vG_buf_copy.empty())
+ {
+ put(dvG, vG_buf_copy.top(), false);
+ put(diG,
+ iG_bimap.left.at(vG_bimap.right.at(vG_buf_copy.top())),
+ false);
+ vG_buf_copy.pop();
+ }
+
+ inL[m] = false;
+ put(aiG_inL, iG_bimap.left.at(m), false);
+ put(avG_inL, vG_bimap.left.at(m), false);
+
+ put(diG, iG_bimap.left.at(m), true);
+ put(dvG, vG_bimap.left.at(m), true);
+
+ std::map< vertex_descriptor, edge_descriptor > tree_map;
+ std::map< vertex_descriptor, vertex_descriptor > pred_map;
+ std::map< vertex_descriptor, int > dist_map, low_map;
+
+ detail::bridges_visitor<
+ associative_property_map<
+ std::map< vertex_descriptor, edge_descriptor > >,
+ associative_property_map<
+ std::map< vertex_descriptor, vertex_descriptor > >,
+ associative_property_map<
+ std::map< vertex_descriptor, int > >,
+ associative_property_map<
+ std::map< vertex_descriptor, int > >,
+ std::stack< edge_descriptor > >
+ iG_vis(associative_property_map<
+ std::map< vertex_descriptor, edge_descriptor > >(
+ tree_map),
+ associative_property_map<
+ std::map< vertex_descriptor, vertex_descriptor > >(
+ pred_map),
+ associative_property_map<
+ std::map< vertex_descriptor, int > >(dist_map),
+ associative_property_map<
+ std::map< vertex_descriptor, int > >(low_map),
+ iG_buf),
+ vG_vis(associative_property_map<
+ std::map< vertex_descriptor, edge_descriptor > >(
+ tree_map),
+ associative_property_map<
+ std::map< vertex_descriptor, vertex_descriptor > >(
+ pred_map),
+ associative_property_map<
+ std::map< vertex_descriptor, int > >(dist_map),
+ associative_property_map<
+ std::map< vertex_descriptor, int > >(low_map),
+ vG_buf);
+
+ undirected_dfs(
+ make_filtered_graph(iG,
+ detail::deleted_edge_status< associative_property_map<
+ std::map< edge_descriptor, bool > > >(diG)),
+ iG_vis,
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(
+ edge_color));
+ undirected_dfs(
+ make_filtered_graph(vG,
+ detail::deleted_edge_status< associative_property_map<
+ std::map< edge_descriptor, bool > > >(dvG)),
+ vG_vis,
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(
+ edge_color));
+
+ found = false;
+ std::stack< edge_descriptor > iG_buf_tmp, vG_buf_tmp;
+ while (!iG_buf.empty() && !found)
+ {
+ if (!inL[iG_bimap.right.at(iG_buf.top())])
+ {
+ put(aiG_inL, iG_buf.top(), true);
+ put(avG_inL,
+ vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())),
+ true);
+
+ undirected_dfs(
+ make_filtered_graph(iG,
+ detail::inL_edge_status<
+ associative_property_map<
+ std::map< edge_descriptor, bool > > >(
+ aiG_inL)),
+ make_dfs_visitor(detail::cycle_finder<
+ std::stack< edge_descriptor > >(&iG_buf_tmp)),
+ associative_property_map< std::map<
+ vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map< std::map< edge_descriptor,
+ default_color_type > >(edge_color));
+ undirected_dfs(
+ make_filtered_graph(vG,
+ detail::inL_edge_status<
+ associative_property_map<
+ std::map< edge_descriptor, bool > > >(
+ avG_inL)),
+ make_dfs_visitor(detail::cycle_finder<
+ std::stack< edge_descriptor > >(&vG_buf_tmp)),
+ associative_property_map< std::map<
+ vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map< std::map< edge_descriptor,
+ default_color_type > >(edge_color));
+
+ if (!iG_buf_tmp.empty() || !vG_buf_tmp.empty())
+ {
+ found = true;
+ }
+ else
+ {
+ while (!iG_buf_tmp.empty())
+ iG_buf_tmp.pop();
+ while (!vG_buf_tmp.empty())
+ vG_buf_tmp.pop();
+ iG_buf_copy.push(iG_buf.top());
+ }
+
+ put(aiG_inL, iG_buf.top(), false);
+ put(avG_inL,
+ vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())),
+ false);
+ }
+ iG_buf.pop();
+ }
+ while (!vG_buf.empty() && !found)
+ {
+ if (!inL[vG_bimap.right.at(vG_buf.top())])
+ {
+ put(avG_inL, vG_buf.top(), true);
+ put(aiG_inL,
+ iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())),
+ true);
+
+ undirected_dfs(
+ make_filtered_graph(iG,
+ detail::inL_edge_status<
+ associative_property_map<
+ std::map< edge_descriptor, bool > > >(
+ aiG_inL)),
+ make_dfs_visitor(detail::cycle_finder<
+ std::stack< edge_descriptor > >(&iG_buf_tmp)),
+ associative_property_map< std::map<
+ vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map< std::map< edge_descriptor,
+ default_color_type > >(edge_color));
+ undirected_dfs(
+ make_filtered_graph(vG,
+ detail::inL_edge_status<
+ associative_property_map<
+ std::map< edge_descriptor, bool > > >(
+ avG_inL)),
+ make_dfs_visitor(detail::cycle_finder<
+ std::stack< edge_descriptor > >(&vG_buf_tmp)),
+ associative_property_map< std::map<
+ vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map< std::map< edge_descriptor,
+ default_color_type > >(edge_color));
+
+ if (!iG_buf_tmp.empty() || !vG_buf_tmp.empty())
+ {
+ found = true;
+ }
+ else
+ {
+ while (!iG_buf_tmp.empty())
+ iG_buf_tmp.pop();
+ while (!vG_buf_tmp.empty())
+ vG_buf_tmp.pop();
+ vG_buf_copy.push(vG_buf.top());
+ }
+
+ put(avG_inL, vG_buf.top(), false);
+ put(aiG_inL,
+ iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())),
+ false);
+ }
+ vG_buf.pop();
+ }
+
+ if (!found)
+ {
+
+ while (!iG_buf_copy.empty())
+ {
+ inL[iG_bimap.right.at(iG_buf_copy.top())] = true;
+ put(aiG_inL, iG_buf_copy.top(), true);
+ put(avG_inL,
+ vG_bimap.left.at(
+ iG_bimap.right.at(iG_buf_copy.top())),
+ true);
+ iG_buf.push(iG_buf_copy.top());
+ iG_buf_copy.pop();
+ }
+ while (!vG_buf_copy.empty())
+ {
+ inL[vG_bimap.right.at(vG_buf_copy.top())] = true;
+ put(avG_inL, vG_buf_copy.top(), true);
+ put(aiG_inL,
+ iG_bimap.left.at(
+ vG_bimap.right.at(vG_buf_copy.top())),
+ true);
+ vG_buf.push(vG_buf_copy.top());
+ vG_buf_copy.pop();
+ }
+
+ // REC
+ detail::rec_two_graphs_common_spanning_trees< Graph, Func,
+ Seq, Map >(iG, iG_bimap, aiG_inL, diG, vG, vG_bimap,
+ aiG_inL, dvG, func, inL);
+
+ while (!iG_buf.empty())
+ {
+ inL[iG_bimap.right.at(iG_buf.top())] = false;
+ put(aiG_inL, iG_buf.top(), false);
+ put(avG_inL,
+ vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())),
+ false);
+ iG_buf.pop();
+ }
+ while (!vG_buf.empty())
+ {
+ inL[vG_bimap.right.at(vG_buf.top())] = false;
+ put(avG_inL, vG_buf.top(), false);
+ put(aiG_inL,
+ iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())),
+ false);
+ vG_buf.pop();
+ }
+ }
+
+ put(diG, iG_bimap.left.at(m), false);
+ put(dvG, vG_bimap.left.at(m), false);
+ }
+ }
+ }
+
+} // namespace detail
+
+template < typename Coll, typename Seq > struct tree_collector
+{
+
+public:
+ BOOST_CONCEPT_ASSERT((BackInsertionSequence< Coll >));
+ BOOST_CONCEPT_ASSERT((RandomAccessContainer< Seq >));
+ BOOST_CONCEPT_ASSERT((CopyConstructible< Seq >));
+
+ typedef typename Coll::value_type coll_value_type;
+ typedef typename Seq::value_type seq_value_type;
+
+ BOOST_STATIC_ASSERT((is_same< coll_value_type, Seq >::value));
+ BOOST_STATIC_ASSERT((is_same< seq_value_type, bool >::value));
+
+ tree_collector(Coll& seqs) : mSeqs(seqs) {}
+
+ inline void operator()(Seq seq) { mSeqs.push_back(seq); }
+
+private:
+ Coll& mSeqs;
+};
+
+template < typename Graph, typename Order, typename Func, typename Seq >
+BOOST_CONCEPT_REQUIRES(
+ ((RandomAccessContainer< Order >))((IncidenceGraphConcept< Graph >))(
+ (UnaryFunction< Func, void, Seq >))(
+ (Mutable_RandomAccessContainer< Seq >))(
+ (VertexAndEdgeListGraphConcept< Graph >)),
+ (void))
+two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG,
+ Order vG_map, Func func, Seq inL)
+{
+ typedef graph_traits< Graph > GraphTraits;
+
+ typedef typename GraphTraits::directed_category directed_category;
+ typedef typename GraphTraits::vertex_descriptor vertex_descriptor;
+ typedef typename GraphTraits::edge_descriptor edge_descriptor;
+
+ typedef typename GraphTraits::edges_size_type edges_size_type;
+ typedef typename GraphTraits::edge_iterator edge_iterator;
+
+ typedef typename Seq::value_type seq_value_type;
+ typedef typename Seq::size_type seq_size_type;
+
+ typedef typename Order::value_type order_value_type;
+ typedef typename Order::size_type order_size_type;
+
+ BOOST_STATIC_ASSERT((is_same< order_value_type, edge_descriptor >::value));
+ BOOST_CONCEPT_ASSERT((Convertible< order_size_type, edges_size_type >));
+
+ BOOST_CONCEPT_ASSERT((Convertible< seq_size_type, edges_size_type >));
+ BOOST_STATIC_ASSERT((is_same< seq_value_type, bool >::value));
+
+ BOOST_STATIC_ASSERT((is_same< directed_category, undirected_tag >::value));
+
+ if (num_vertices(iG) != num_vertices(vG))
+ return;
+
+ if (inL.size() != num_edges(iG) || inL.size() != num_edges(vG))
+ return;
+
+ if (iG_map.size() != num_edges(iG) || vG_map.size() != num_edges(vG))
+ return;
+
+ typedef bimaps::bimap< bimaps::set_of< int >,
+ bimaps::set_of< order_value_type > >
+ bimap_type;
+ typedef typename bimap_type::value_type bimap_value;
+
+ bimap_type iG_bimap, vG_bimap;
+ for (order_size_type i = 0; i < iG_map.size(); ++i)
+ iG_bimap.insert(bimap_value(i, iG_map[i]));
+ for (order_size_type i = 0; i < vG_map.size(); ++i)
+ vG_bimap.insert(bimap_value(i, vG_map[i]));
+
+ edge_iterator current, last;
+ boost::tuples::tie(current, last) = edges(iG);
+ for (; current != last; ++current)
+ if (iG_bimap.right.find(*current) == iG_bimap.right.end())
+ return;
+ boost::tuples::tie(current, last) = edges(vG);
+ for (; current != last; ++current)
+ if (vG_bimap.right.find(*current) == vG_bimap.right.end())
+ return;
+
+ std::stack< edge_descriptor > iG_buf, vG_buf;
+
+ std::map< vertex_descriptor, edge_descriptor > tree_map;
+ std::map< vertex_descriptor, vertex_descriptor > pred_map;
+ std::map< vertex_descriptor, int > dist_map, low_map;
+
+ detail::bridges_visitor< associative_property_map< std::map<
+ vertex_descriptor, edge_descriptor > >,
+ associative_property_map<
+ std::map< vertex_descriptor, vertex_descriptor > >,
+ associative_property_map< std::map< vertex_descriptor, int > >,
+ associative_property_map< std::map< vertex_descriptor, int > >,
+ std::stack< edge_descriptor > >
+ iG_vis(associative_property_map<
+ std::map< vertex_descriptor, edge_descriptor > >(tree_map),
+ associative_property_map<
+ std::map< vertex_descriptor, vertex_descriptor > >(pred_map),
+ associative_property_map< std::map< vertex_descriptor, int > >(
+ dist_map),
+ associative_property_map< std::map< vertex_descriptor, int > >(low_map),
+ iG_buf),
+ vG_vis(associative_property_map<
+ std::map< vertex_descriptor, edge_descriptor > >(tree_map),
+ associative_property_map<
+ std::map< vertex_descriptor, vertex_descriptor > >(pred_map),
+ associative_property_map< std::map< vertex_descriptor, int > >(
+ dist_map),
+ associative_property_map< std::map< vertex_descriptor, int > >(
+ low_map),
+ vG_buf);
+
+ std::map< vertex_descriptor, default_color_type > vertex_color;
+ std::map< edge_descriptor, default_color_type > edge_color;
+
+ undirected_dfs(iG, iG_vis,
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(edge_color));
+ undirected_dfs(vG, vG_vis,
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(edge_color));
+
+ while (!iG_buf.empty())
+ {
+ inL[iG_bimap.right.at(iG_buf.top())] = true;
+ iG_buf.pop();
+ }
+ while (!vG_buf.empty())
+ {
+ inL[vG_bimap.right.at(vG_buf.top())] = true;
+ vG_buf.pop();
+ }
+
+ std::map< edge_descriptor, bool > iG_inL, vG_inL;
+ associative_property_map< std::map< edge_descriptor, bool > > aiG_inL(
+ iG_inL),
+ avG_inL(vG_inL);
+
+ for (seq_size_type i = 0; i < inL.size(); ++i)
+ {
+ if (inL[i])
+ {
+ put(aiG_inL, iG_bimap.left.at(i), true);
+ put(avG_inL, vG_bimap.left.at(i), true);
+ }
+ else
+ {
+ put(aiG_inL, iG_bimap.left.at(i), false);
+ put(avG_inL, vG_bimap.left.at(i), false);
+ }
+ }
+
+ undirected_dfs(
+ make_filtered_graph(iG,
+ detail::inL_edge_status<
+ associative_property_map< std::map< edge_descriptor, bool > > >(
+ aiG_inL)),
+ make_dfs_visitor(
+ detail::cycle_finder< std::stack< edge_descriptor > >(&iG_buf)),
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(edge_color));
+ undirected_dfs(
+ make_filtered_graph(vG,
+ detail::inL_edge_status<
+ associative_property_map< std::map< edge_descriptor, bool > > >(
+ avG_inL)),
+ make_dfs_visitor(
+ detail::cycle_finder< std::stack< edge_descriptor > >(&vG_buf)),
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(edge_color));
+
+ if (iG_buf.empty() && vG_buf.empty())
+ {
+
+ std::map< edge_descriptor, bool > iG_deleted, vG_deleted;
+ associative_property_map< std::map< edge_descriptor, bool > > diG(
+ iG_deleted);
+ associative_property_map< std::map< edge_descriptor, bool > > dvG(
+ vG_deleted);
+
+ boost::tuples::tie(current, last) = edges(iG);
+ for (; current != last; ++current)
+ put(diG, *current, false);
+ boost::tuples::tie(current, last) = edges(vG);
+ for (; current != last; ++current)
+ put(dvG, *current, false);
+
+ for (seq_size_type j = 0; j < inL.size(); ++j)
+ {
+ if (!inL[j])
+ {
+ put(aiG_inL, iG_bimap.left.at(j), true);
+ put(avG_inL, vG_bimap.left.at(j), true);
+
+ undirected_dfs(
+ make_filtered_graph(iG,
+ detail::inL_edge_status< associative_property_map<
+ std::map< edge_descriptor, bool > > >(aiG_inL)),
+ make_dfs_visitor(
+ detail::cycle_finder< std::stack< edge_descriptor > >(
+ &iG_buf)),
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(
+ edge_color));
+ undirected_dfs(
+ make_filtered_graph(vG,
+ detail::inL_edge_status< associative_property_map<
+ std::map< edge_descriptor, bool > > >(avG_inL)),
+ make_dfs_visitor(
+ detail::cycle_finder< std::stack< edge_descriptor > >(
+ &vG_buf)),
+ associative_property_map<
+ std::map< vertex_descriptor, default_color_type > >(
+ vertex_color),
+ associative_property_map<
+ std::map< edge_descriptor, default_color_type > >(
+ edge_color));
+
+ if (!iG_buf.empty() || !vG_buf.empty())
+ {
+ while (!iG_buf.empty())
+ iG_buf.pop();
+ while (!vG_buf.empty())
+ vG_buf.pop();
+ put(diG, iG_bimap.left.at(j), true);
+ put(dvG, vG_bimap.left.at(j), true);
+ }
+
+ put(aiG_inL, iG_bimap.left.at(j), false);
+ put(avG_inL, vG_bimap.left.at(j), false);
+ }
+ }
+
+ int cc = 0;
+
+ std::map< vertex_descriptor, int > com_map;
+ cc += connected_components(
+ make_filtered_graph(iG,
+ detail::deleted_edge_status< associative_property_map<
+ std::map< edge_descriptor, bool > > >(diG)),
+ associative_property_map< std::map< vertex_descriptor, int > >(
+ com_map));
+ cc += connected_components(
+ make_filtered_graph(vG,
+ detail::deleted_edge_status< associative_property_map<
+ std::map< edge_descriptor, bool > > >(dvG)),
+ associative_property_map< std::map< vertex_descriptor, int > >(
+ com_map));
+
+ if (cc != 2)
+ return;
+
+ // REC
+ detail::rec_two_graphs_common_spanning_trees< Graph, Func, Seq,
+ associative_property_map< std::map< edge_descriptor, bool > > >(
+ iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, dvG, func, inL);
+ }
+}
+
+template < typename Graph, typename Func, typename Seq >
+BOOST_CONCEPT_REQUIRES(
+ ((IncidenceGraphConcept< Graph >))((EdgeListGraphConcept< Graph >)), (void))
+two_graphs_common_spanning_trees(
+ const Graph& iG, const Graph& vG, Func func, Seq inL)
+{
+ typedef graph_traits< Graph > GraphTraits;
+
+ typedef typename GraphTraits::edge_descriptor edge_descriptor;
+ typedef typename GraphTraits::edge_iterator edge_iterator;
+
+ std::vector< edge_descriptor > iGO, vGO;
+ edge_iterator curr, last;
+
+ boost::tuples::tie(curr, last) = edges(iG);
+ for (; curr != last; ++curr)
+ iGO.push_back(*curr);
+
+ boost::tuples::tie(curr, last) = edges(vG);
+ for (; curr != last; ++curr)
+ vGO.push_back(*curr);
+
+ two_graphs_common_spanning_trees(iG, iGO, vG, vGO, func, inL);
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/undirected_dfs.hpp b/contrib/restricted/boost/graph/include/boost/graph/undirected_dfs.hpp
new file mode 100644
index 0000000000..62088c87fb
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/undirected_dfs.hpp
@@ -0,0 +1,269 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_UNDIRECTED_DFS_HPP
+#define BOOST_GRAPH_UNDIRECTED_DFS_HPP
+
+#include <boost/graph/depth_first_search.hpp>
+#include <vector>
+#include <boost/concept/assert.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+// Define BOOST_RECURSIVE_DFS to use older, recursive version.
+// It is retained for a while in order to perform performance
+// comparison.
+#ifndef BOOST_RECURSIVE_DFS
+
+ template < typename IncidenceGraph, typename DFSVisitor,
+ typename VertexColorMap, typename EdgeColorMap >
+ void undir_dfv_impl(const IncidenceGraph& g,
+ typename graph_traits< IncidenceGraph >::vertex_descriptor u,
+ DFSVisitor& vis, VertexColorMap vertex_color, EdgeColorMap edge_color)
+ {
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< IncidenceGraph >));
+ BOOST_CONCEPT_ASSERT((DFSVisitorConcept< DFSVisitor, IncidenceGraph >));
+ typedef
+ typename graph_traits< IncidenceGraph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< IncidenceGraph >::edge_descriptor Edge;
+ BOOST_CONCEPT_ASSERT(
+ (ReadWritePropertyMapConcept< VertexColorMap, Vertex >));
+ BOOST_CONCEPT_ASSERT(
+ (ReadWritePropertyMapConcept< EdgeColorMap, Edge >));
+ typedef
+ typename property_traits< VertexColorMap >::value_type ColorValue;
+ typedef
+ typename property_traits< EdgeColorMap >::value_type EColorValue;
+ BOOST_CONCEPT_ASSERT((ColorValueConcept< ColorValue >));
+ BOOST_CONCEPT_ASSERT((ColorValueConcept< EColorValue >));
+ typedef color_traits< ColorValue > Color;
+ typedef color_traits< EColorValue > EColor;
+ typedef typename graph_traits< IncidenceGraph >::out_edge_iterator Iter;
+ typedef std::pair< Vertex,
+ std::pair< boost::optional< Edge >, std::pair< Iter, Iter > > >
+ VertexInfo;
+
+ std::vector< VertexInfo > stack;
+
+ put(vertex_color, u, Color::gray());
+ vis.discover_vertex(u, g);
+ stack.push_back(std::make_pair(
+ u, std::make_pair(boost::optional< Edge >(), out_edges(u, g))));
+ while (!stack.empty())
+ {
+ VertexInfo& back = stack.back();
+ u = back.first;
+ boost::optional< Edge > src_e = back.second.first;
+ Iter ei = back.second.second.first,
+ ei_end = back.second.second.second;
+ stack.pop_back();
+ while (ei != ei_end)
+ {
+ Vertex v = target(*ei, g);
+ vis.examine_edge(*ei, g);
+ ColorValue v_color = get(vertex_color, v);
+ EColorValue uv_color = get(edge_color, *ei);
+ put(edge_color, *ei, EColor::black());
+ if (v_color == Color::white())
+ {
+ vis.tree_edge(*ei, g);
+ src_e = *ei;
+ stack.push_back(std::make_pair(u,
+ std::make_pair(src_e, std::make_pair(++ei, ei_end))));
+ u = v;
+ put(vertex_color, u, Color::gray());
+ vis.discover_vertex(u, g);
+ boost::tie(ei, ei_end) = out_edges(u, g);
+ }
+ else if (v_color == Color::gray())
+ {
+ if (uv_color == EColor::white())
+ vis.back_edge(*ei, g);
+ call_finish_edge(vis, *ei, g);
+ ++ei;
+ }
+ else
+ { // if (v_color == Color::black())
+ call_finish_edge(vis, *ei, g);
+ ++ei;
+ }
+ }
+ put(vertex_color, u, Color::black());
+ vis.finish_vertex(u, g);
+ if (src_e)
+ call_finish_edge(vis, src_e.get(), g);
+ }
+ }
+
+#else // BOOST_RECURSIVE_DFS
+
+ template < typename IncidenceGraph, typename DFSVisitor,
+ typename VertexColorMap, typename EdgeColorMap >
+ void undir_dfv_impl(const IncidenceGraph& g,
+ typename graph_traits< IncidenceGraph >::vertex_descriptor u,
+ DFSVisitor& vis, // pass-by-reference here, important!
+ VertexColorMap vertex_color, EdgeColorMap edge_color)
+ {
+ BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< IncidenceGraph >));
+ BOOST_CONCEPT_ASSERT((DFSVisitorConcept< DFSVisitor, IncidenceGraph >));
+ typedef
+ typename graph_traits< IncidenceGraph >::vertex_descriptor Vertex;
+ typedef typename graph_traits< IncidenceGraph >::edge_descriptor Edge;
+ BOOST_CONCEPT_ASSERT(
+ (ReadWritePropertyMapConcept< VertexColorMap, Vertex >));
+ BOOST_CONCEPT_ASSERT(
+ (ReadWritePropertyMapConcept< EdgeColorMap, Edge >));
+ typedef
+ typename property_traits< VertexColorMap >::value_type ColorValue;
+ typedef
+ typename property_traits< EdgeColorMap >::value_type EColorValue;
+ BOOST_CONCEPT_ASSERT((ColorValueConcept< ColorValue >));
+ BOOST_CONCEPT_ASSERT((ColorValueConcept< EColorValue >));
+ typedef color_traits< ColorValue > Color;
+ typedef color_traits< EColorValue > EColor;
+ typename graph_traits< IncidenceGraph >::out_edge_iterator ei, ei_end;
+
+ put(vertex_color, u, Color::gray());
+ vis.discover_vertex(u, g);
+ for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
+ {
+ Vertex v = target(*ei, g);
+ vis.examine_edge(*ei, g);
+ ColorValue v_color = get(vertex_color, v);
+ EColorValue uv_color = get(edge_color, *ei);
+ put(edge_color, *ei, EColor::black());
+ if (v_color == Color::white())
+ {
+ vis.tree_edge(*ei, g);
+ undir_dfv_impl(g, v, vis, vertex_color, edge_color);
+ }
+ else if (v_color == Color::gray() && uv_color == EColor::white())
+ vis.back_edge(*ei, g);
+ call_finish_edge(vis, *ei, g);
+ }
+ put(vertex_color, u, Color::black());
+ vis.finish_vertex(u, g);
+ }
+
+#endif // ! BOOST_RECURSIVE_DFS
+
+} // namespace detail
+
+template < typename Graph, typename DFSVisitor, typename VertexColorMap,
+ typename EdgeColorMap, typename Vertex >
+void undirected_dfs(const Graph& g, DFSVisitor vis, VertexColorMap vertex_color,
+ EdgeColorMap edge_color, Vertex start_vertex)
+{
+ BOOST_CONCEPT_ASSERT((DFSVisitorConcept< DFSVisitor, Graph >));
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >));
+
+ typedef typename property_traits< VertexColorMap >::value_type ColorValue;
+ typedef color_traits< ColorValue > Color;
+
+ typename graph_traits< Graph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ put(vertex_color, *ui, Color::white());
+ vis.initialize_vertex(*ui, g);
+ }
+ typename graph_traits< Graph >::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ put(edge_color, *ei, Color::white());
+
+ if (start_vertex != *vertices(g).first)
+ {
+ vis.start_vertex(start_vertex, g);
+ detail::undir_dfv_impl(g, start_vertex, vis, vertex_color, edge_color);
+ }
+
+ for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ ColorValue u_color = get(vertex_color, *ui);
+ if (u_color == Color::white())
+ {
+ vis.start_vertex(*ui, g);
+ detail::undir_dfv_impl(g, *ui, vis, vertex_color, edge_color);
+ }
+ }
+}
+
+template < typename Graph, typename DFSVisitor, typename VertexColorMap,
+ typename EdgeColorMap >
+void undirected_dfs(const Graph& g, DFSVisitor vis, VertexColorMap vertex_color,
+ EdgeColorMap edge_color)
+{
+ undirected_dfs(g, vis, vertex_color, edge_color, *vertices(g).first);
+}
+
+namespace detail
+{
+ template < typename VertexColorMap > struct udfs_dispatch
+ {
+
+ template < typename Graph, typename Vertex, typename DFSVisitor,
+ typename EdgeColorMap, typename P, typename T, typename R >
+ static void apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
+ const bgl_named_params< P, T, R >&, EdgeColorMap edge_color,
+ VertexColorMap vertex_color)
+ {
+ undirected_dfs(g, vis, vertex_color, edge_color, start_vertex);
+ }
+ };
+
+ template <> struct udfs_dispatch< param_not_found >
+ {
+ template < typename Graph, typename Vertex, typename DFSVisitor,
+ typename EdgeColorMap, typename P, typename T, typename R >
+ static void apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
+ const bgl_named_params< P, T, R >& params, EdgeColorMap edge_color,
+ param_not_found)
+ {
+ std::vector< default_color_type > color_vec(num_vertices(g));
+ default_color_type c = white_color; // avoid warning about un-init
+ undirected_dfs(g, vis,
+ make_iterator_property_map(color_vec.begin(),
+ choose_const_pmap(
+ get_param(params, vertex_index), g, vertex_index),
+ c),
+ edge_color, start_vertex);
+ }
+ };
+
+} // namespace detail
+
+// Named Parameter Variant
+template < typename Graph, typename P, typename T, typename R >
+void undirected_dfs(const Graph& g, const bgl_named_params< P, T, R >& params)
+{
+ typedef typename get_param_type< vertex_color_t,
+ bgl_named_params< P, T, R > >::type C;
+ detail::udfs_dispatch< C >::apply(g,
+ choose_param(
+ get_param(params, graph_visitor), make_dfs_visitor(null_visitor())),
+ choose_param(get_param(params, root_vertex_t()), *vertices(g).first),
+ params, get_param(params, edge_color), get_param(params, vertex_color));
+}
+
+template < typename IncidenceGraph, typename DFSVisitor,
+ typename VertexColorMap, typename EdgeColorMap >
+void undirected_depth_first_visit(const IncidenceGraph& g,
+ typename graph_traits< IncidenceGraph >::vertex_descriptor u,
+ DFSVisitor vis, VertexColorMap vertex_color, EdgeColorMap edge_color)
+{
+ detail::undir_dfv_impl(g, u, vis, vertex_color, edge_color);
+}
+
+} // namespace boost
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/undirected_graph.hpp b/contrib/restricted/boost/graph/include/boost/graph/undirected_graph.hpp
new file mode 100644
index 0000000000..ec1bbbba61
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/undirected_graph.hpp
@@ -0,0 +1,822 @@
+// (C) Copyright 2007-2009 Andrew Sutton
+//
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0 (See accompanying file
+// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GRAPH_UNDIRECTED_GRAPH_HPP
+#define BOOST_GRAPH_UNDIRECTED_GRAPH_HPP
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/property.hpp>
+#include <boost/property_map/transform_value_property_map.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/mpl/if.hpp>
+
+namespace boost
+{
+struct undirected_graph_tag
+{
+};
+
+/**
+ * The undirected_graph class template is a simplified version of the BGL
+ * adjacency list. This class is provided for ease of use, but may not
+ * perform as well as custom-defined adjacency list classes. Instances of
+ * this template model the VertexIndexGraph, and EdgeIndexGraph concepts. The
+ * graph is also fully mutable, supporting both insertions and removals of
+ * vertices and edges.
+ *
+ * @note Special care must be taken when removing vertices or edges since
+ * those operations can invalidate the numbering of vertices.
+ */
+template < typename VertexProp = no_property, typename EdgeProp = no_property,
+ typename GraphProp = no_property >
+class undirected_graph
+{
+public:
+ typedef GraphProp graph_property_type;
+ typedef VertexProp vertex_property_type;
+ typedef EdgeProp edge_property_type;
+ typedef typename lookup_one_property< GraphProp, graph_bundle_t >::type
+ graph_bundled;
+ typedef typename lookup_one_property< VertexProp, vertex_bundle_t >::type
+ vertex_bundled;
+ typedef typename lookup_one_property< EdgeProp, edge_bundle_t >::type
+ edge_bundled;
+
+public:
+ // Embed indices into the vertex type.
+ typedef property< vertex_index_t, unsigned, vertex_property_type >
+ internal_vertex_property;
+ typedef property< edge_index_t, unsigned, edge_property_type >
+ internal_edge_property;
+
+public:
+ typedef adjacency_list< listS, listS, undirectedS, internal_vertex_property,
+ internal_edge_property, GraphProp, listS >
+ graph_type;
+
+private:
+ // storage selectors
+ typedef typename graph_type::vertex_list_selector vertex_list_selector;
+ typedef typename graph_type::edge_list_selector edge_list_selector;
+ typedef typename graph_type::out_edge_list_selector out_edge_list_selector;
+ typedef typename graph_type::directed_selector directed_selector;
+
+public:
+ // more commonly used graph types
+ typedef typename graph_type::stored_vertex stored_vertex;
+ typedef typename graph_type::vertices_size_type vertices_size_type;
+ typedef typename graph_type::edges_size_type edges_size_type;
+ typedef typename graph_type::degree_size_type degree_size_type;
+ typedef typename graph_type::vertex_descriptor vertex_descriptor;
+ typedef typename graph_type::edge_descriptor edge_descriptor;
+
+ // iterator types
+ typedef typename graph_type::vertex_iterator vertex_iterator;
+ typedef typename graph_type::edge_iterator edge_iterator;
+ typedef typename graph_type::out_edge_iterator out_edge_iterator;
+ typedef typename graph_type::in_edge_iterator in_edge_iterator;
+ typedef typename graph_type::adjacency_iterator adjacency_iterator;
+
+ // miscellaneous types
+ typedef undirected_graph_tag graph_tag;
+ typedef typename graph_type::directed_category directed_category;
+ typedef typename graph_type::edge_parallel_category edge_parallel_category;
+ typedef typename graph_type::traversal_category traversal_category;
+
+ typedef std::size_t vertex_index_type;
+ typedef std::size_t edge_index_type;
+
+ inline undirected_graph(GraphProp const& p = GraphProp())
+ : m_graph(p)
+ , m_num_vertices(0)
+ , m_num_edges(0)
+ , m_max_vertex_index(0)
+ , m_max_edge_index(0)
+ {
+ }
+
+ inline undirected_graph(undirected_graph const& x)
+ : m_graph(x.m_graph)
+ , m_num_vertices(x.m_num_vertices)
+ , m_num_edges(x.m_num_edges)
+ , m_max_vertex_index(x.m_max_vertex_index)
+ , m_max_edge_index(x.m_max_edge_index)
+ {
+ }
+
+ inline undirected_graph(
+ vertices_size_type n, GraphProp const& p = GraphProp())
+ : m_graph(n, p)
+ , m_num_vertices(n)
+ , m_num_edges(0)
+ , m_max_vertex_index(n)
+ , m_max_edge_index(0)
+ {
+ renumber_vertex_indices();
+ }
+
+ template < typename EdgeIterator >
+ inline undirected_graph(EdgeIterator f, EdgeIterator l,
+ vertices_size_type n, edges_size_type m = 0,
+ GraphProp const& p = GraphProp())
+ : m_graph(f, l, n, m, p)
+ , m_num_vertices(n)
+ , m_num_edges(0)
+ , m_max_vertex_index(n)
+ , m_max_edge_index(0)
+ {
+ // Unfortunately, we have to renumber to ensure correct indexing.
+ renumber_indices();
+
+ // Can't always guarantee that the number of edges is actually
+ // m if distance(f, l) != m (or is undefined).
+ m_num_edges = m_max_edge_index = boost::num_edges(m_graph);
+ }
+
+ undirected_graph& operator=(undirected_graph const& g)
+ {
+ if (&g != this)
+ {
+ m_graph = g.m_graph;
+ m_num_vertices = g.m_num_vertices;
+ m_num_edges = g.m_num_edges;
+ m_max_vertex_index = g.m_max_vertex_index;
+ }
+ return *this;
+ }
+
+ // The impl_() methods are not part of the public interface.
+ graph_type& impl() { return m_graph; }
+
+ graph_type const& impl() const { return m_graph; }
+
+ // The following methods are not part of the public interface
+ vertices_size_type num_vertices() const { return m_num_vertices; }
+
+private:
+ // This helper function manages the attribution of vertex indices.
+ vertex_descriptor make_index(vertex_descriptor v)
+ {
+ boost::put(vertex_index, m_graph, v, m_max_vertex_index);
+ m_num_vertices++;
+ m_max_vertex_index++;
+ return v;
+ }
+
+public:
+ vertex_descriptor add_vertex()
+ {
+ return make_index(boost::add_vertex(m_graph));
+ }
+
+ vertex_descriptor add_vertex(vertex_property_type const& p)
+ {
+ return make_index(
+ boost::add_vertex(internal_vertex_property(0u, p), m_graph));
+ }
+
+ void clear_vertex(vertex_descriptor v)
+ {
+ std::pair< out_edge_iterator, out_edge_iterator > p
+ = boost::out_edges(v, m_graph);
+ m_num_edges -= std::distance(p.first, p.second);
+ boost::clear_vertex(v, m_graph);
+ }
+
+ void remove_vertex(vertex_descriptor v)
+ {
+ boost::remove_vertex(v, m_graph);
+ --m_num_vertices;
+ }
+
+ edges_size_type num_edges() const { return m_num_edges; }
+
+private:
+ // A helper fucntion for managing edge index attributes.
+ std::pair< edge_descriptor, bool > const& make_index(
+ std::pair< edge_descriptor, bool > const& x)
+ {
+ if (x.second)
+ {
+ boost::put(edge_index, m_graph, x.first, m_max_edge_index);
+ ++m_num_edges;
+ ++m_max_edge_index;
+ }
+ return x;
+ }
+
+public:
+ std::pair< edge_descriptor, bool > add_edge(
+ vertex_descriptor u, vertex_descriptor v)
+ {
+ return make_index(boost::add_edge(u, v, m_graph));
+ }
+
+ std::pair< edge_descriptor, bool > add_edge(
+ vertex_descriptor u, vertex_descriptor v, edge_property_type const& p)
+ {
+ return make_index(
+ boost::add_edge(u, v, internal_edge_property(0u, p), m_graph));
+ }
+
+ void remove_edge(vertex_descriptor u, vertex_descriptor v)
+ {
+ // find all edges, (u, v)
+ std::vector< edge_descriptor > edges;
+ out_edge_iterator i, i_end;
+ for (boost::tie(i, i_end) = boost::out_edges(u, m_graph); i != i_end;
+ ++i)
+ {
+ if (boost::target(*i, m_graph) == v)
+ {
+ edges.push_back(*i);
+ }
+ }
+ // remove all edges, (u, v)
+ typename std::vector< edge_descriptor >::iterator j = edges.begin(),
+ j_end = edges.end();
+ for (; j != j_end; ++j)
+ {
+ remove_edge(*j);
+ }
+ }
+
+ void remove_edge(edge_iterator i) { remove_edge(*i); }
+
+ void remove_edge(edge_descriptor e)
+ {
+ boost::remove_edge(e, m_graph);
+ --m_num_edges;
+ }
+
+ vertex_index_type max_vertex_index() const { return m_max_vertex_index; }
+
+ void renumber_vertex_indices()
+ {
+ vertex_iterator i, i_end;
+ boost::tie(i, i_end) = vertices(m_graph);
+ m_max_vertex_index = renumber_vertex_indices(i, i_end, 0);
+ }
+
+ void remove_vertex_and_renumber_indices(vertex_iterator i)
+ {
+ vertex_iterator j = next(i), end = vertices(m_graph).second;
+ vertex_index_type n = get(vertex_index, m_graph, *i);
+
+ // remove the offending vertex and renumber everything after
+ remove_vertex(*i);
+ m_max_vertex_index = renumber_vertex_indices(j, end, n);
+ }
+
+ edge_index_type max_edge_index() const { return m_max_edge_index; }
+
+ void renumber_edge_indices()
+ {
+ edge_iterator i, end;
+ boost::tie(i, end) = edges(m_graph);
+ m_max_edge_index = renumber_edge_indices(i, end, 0);
+ }
+
+ void remove_edge_and_renumber_indices(edge_iterator i)
+ {
+ edge_iterator j = next(i), end = edges(m_graph.second);
+ edge_index_type n = get(edge_index, m_graph, *i);
+
+ // remove the edge and renumber everything after it
+ remove_edge(*i);
+ m_max_edge_index = renumber_edge_indices(j, end, n);
+ }
+
+ void renumber_indices()
+ {
+ renumber_vertex_indices();
+ renumber_edge_indices();
+ }
+
+ // bundled property support
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ vertex_bundled& operator[](vertex_descriptor v) { return m_graph[v]; }
+
+ vertex_bundled const& operator[](vertex_descriptor v) const
+ {
+ return m_graph[v];
+ }
+
+ edge_bundled& operator[](edge_descriptor e) { return m_graph[e]; }
+
+ edge_bundled const& operator[](edge_descriptor e) const
+ {
+ return m_graph[e];
+ }
+
+ graph_bundled& operator[](graph_bundle_t) { return get_property(*this); }
+
+ graph_bundled const& operator[](graph_bundle_t) const
+ {
+ return get_property(*this);
+ }
+#endif
+
+ // Graph concepts
+ static vertex_descriptor null_vertex() { return graph_type::null_vertex(); }
+
+ void clear()
+ {
+ m_graph.clear();
+ m_num_vertices = m_max_vertex_index = 0;
+ m_num_edges = m_max_edge_index = 0;
+ }
+
+ void swap(undirected_graph& g)
+ {
+ m_graph.swap(g.m_graph);
+ std::swap(m_num_vertices, g.m_num_vertices);
+ std::swap(m_max_vertex_index, g.m_max_vertex_index);
+ std::swap(m_num_edges, g.m_num_edges);
+ std::swap(m_max_edge_index, g.m_max_edge_index);
+ }
+
+private:
+ vertices_size_type renumber_vertex_indices(
+ vertex_iterator i, vertex_iterator end, vertices_size_type n)
+ {
+ typedef
+ typename property_map< graph_type, vertex_index_t >::type IndexMap;
+ IndexMap indices = get(vertex_index, m_graph);
+ for (; i != end; ++i)
+ {
+ indices[*i] = n++;
+ }
+ return n;
+ }
+
+ edges_size_type renumber_edge_indices(
+ edge_iterator i, edge_iterator end, edges_size_type n)
+ {
+ typedef
+ typename property_map< graph_type, edge_index_t >::type IndexMap;
+ IndexMap indices = get(edge_index, m_graph);
+ for (; i != end; ++i)
+ {
+ indices[*i] = n++;
+ }
+ return n;
+ }
+
+ graph_type m_graph;
+ vertices_size_type m_num_vertices;
+ edges_size_type m_num_edges;
+ vertex_index_type m_max_vertex_index;
+ edge_index_type m_max_edge_index;
+};
+
+#define UNDIRECTED_GRAPH_PARAMS typename VP, typename EP, typename GP
+#define UNDIRECTED_GRAPH undirected_graph< VP, EP, GP >
+
+// IncidenceGraph concepts
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::vertex_descriptor source(
+ typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH const& g)
+{
+ return source(e, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::vertex_descriptor target(
+ typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH const& g)
+{
+ return target(e, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::degree_size_type out_degree(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return out_degree(v, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline std::pair< typename UNDIRECTED_GRAPH::out_edge_iterator,
+ typename UNDIRECTED_GRAPH::out_edge_iterator >
+out_edges(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return out_edges(v, g.impl());
+}
+
+// BidirectionalGraph concepts
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::degree_size_type in_degree(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return in_degree(v, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline std::pair< typename UNDIRECTED_GRAPH::in_edge_iterator,
+ typename UNDIRECTED_GRAPH::in_edge_iterator >
+in_edges(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return in_edges(v, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline std::pair< typename UNDIRECTED_GRAPH::out_edge_iterator,
+ typename UNDIRECTED_GRAPH::out_edge_iterator >
+incident_edges(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return out_edges(v, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::degree_size_type degree(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return degree(v, g.impl());
+}
+
+// AdjacencyGraph concepts
+template < UNDIRECTED_GRAPH_PARAMS >
+inline std::pair< typename UNDIRECTED_GRAPH::adjacency_iterator,
+ typename UNDIRECTED_GRAPH::adjacency_iterator >
+adjacent_vertices(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return adjacent_vertices(v, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+typename UNDIRECTED_GRAPH::vertex_descriptor vertex(
+ typename UNDIRECTED_GRAPH::vertices_size_type n, UNDIRECTED_GRAPH const& g)
+{
+ return vertex(n, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > edge(
+ typename UNDIRECTED_GRAPH::vertex_descriptor u,
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return edge(u, v, g.impl());
+}
+
+// VertexListGraph concepts
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::vertices_size_type num_vertices(
+ UNDIRECTED_GRAPH const& g)
+{
+ return g.num_vertices();
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline std::pair< typename UNDIRECTED_GRAPH::vertex_iterator,
+ typename UNDIRECTED_GRAPH::vertex_iterator >
+vertices(UNDIRECTED_GRAPH const& g)
+{
+ return vertices(g.impl());
+}
+
+// EdgeListGraph concepts
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::edges_size_type num_edges(
+ UNDIRECTED_GRAPH const& g)
+{
+ return g.num_edges();
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline std::pair< typename UNDIRECTED_GRAPH::edge_iterator,
+ typename UNDIRECTED_GRAPH::edge_iterator >
+edges(UNDIRECTED_GRAPH const& g)
+{
+ return edges(g.impl());
+}
+
+// MutableGraph concepts
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::vertex_descriptor add_vertex(
+ UNDIRECTED_GRAPH& g)
+{
+ return g.add_vertex();
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::vertex_descriptor add_vertex(
+ typename UNDIRECTED_GRAPH::vertex_property_type const& p,
+ UNDIRECTED_GRAPH& g)
+{
+ return g.add_vertex(p);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void clear_vertex(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
+{
+ return g.clear_vertex(v);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void remove_vertex(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
+{
+ return g.remove_vertex(v);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > add_edge(
+ typename UNDIRECTED_GRAPH::vertex_descriptor u,
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
+{
+ return g.add_edge(u, v);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > add_edge(
+ typename UNDIRECTED_GRAPH::vertex_descriptor u,
+ typename UNDIRECTED_GRAPH::vertex_descriptor v,
+ typename UNDIRECTED_GRAPH::edge_property_type const& p, UNDIRECTED_GRAPH& g)
+{
+ return g.add_edge(u, v, p);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void remove_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
+{
+ return g.remove_edge(u, v);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void remove_edge(
+ typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH& g)
+{
+ return g.remove_edge(e);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void remove_edge(
+ typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g)
+{
+ return g.remove_edge(i);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
+inline void remove_edge_if(Predicate pred, UNDIRECTED_GRAPH& g)
+{
+ return remove_edge_if(pred, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
+inline void remove_incident_edge_if(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, Predicate pred,
+ UNDIRECTED_GRAPH& g)
+{
+ return remove_out_edge_if(v, pred, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
+inline void remove_out_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,
+ Predicate pred, UNDIRECTED_GRAPH& g)
+{
+ return remove_out_edge_if(v, pred, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
+inline void remove_in_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,
+ Predicate pred, UNDIRECTED_GRAPH& g)
+{
+ return remove_in_edge_if(v, pred, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, typename Property >
+struct property_map< UNDIRECTED_GRAPH, Property >
+: property_map< typename UNDIRECTED_GRAPH::graph_type, Property >
+{
+};
+
+template < UNDIRECTED_GRAPH_PARAMS >
+struct property_map< UNDIRECTED_GRAPH, vertex_all_t >
+{
+ typedef transform_value_property_map< detail::remove_first_property,
+ typename property_map< typename UNDIRECTED_GRAPH::graph_type,
+ vertex_all_t >::const_type >
+ const_type;
+ typedef transform_value_property_map< detail::remove_first_property,
+ typename property_map< typename UNDIRECTED_GRAPH::graph_type,
+ vertex_all_t >::type >
+ type;
+};
+
+template < UNDIRECTED_GRAPH_PARAMS >
+struct property_map< UNDIRECTED_GRAPH, edge_all_t >
+{
+ typedef transform_value_property_map< detail::remove_first_property,
+ typename property_map< typename UNDIRECTED_GRAPH::graph_type,
+ edge_all_t >::const_type >
+ const_type;
+ typedef transform_value_property_map< detail::remove_first_property,
+ typename property_map< typename UNDIRECTED_GRAPH::graph_type,
+ edge_all_t >::type >
+ type;
+};
+
+// PropertyGraph concepts
+template < UNDIRECTED_GRAPH_PARAMS, typename Property >
+inline typename property_map< UNDIRECTED_GRAPH, Property >::type get(
+ Property p, UNDIRECTED_GRAPH& g)
+{
+ return get(p, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, typename Property >
+inline typename property_map< UNDIRECTED_GRAPH, Property >::const_type get(
+ Property p, UNDIRECTED_GRAPH const& g)
+{
+ return get(p, g.impl());
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::type get(
+ vertex_all_t, UNDIRECTED_GRAPH& g)
+{
+ return typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::type(
+ detail::remove_first_property(), get(vertex_all, g.impl()));
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::const_type get(
+ vertex_all_t, UNDIRECTED_GRAPH const& g)
+{
+ return typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::const_type(
+ detail::remove_first_property(), get(vertex_all, g.impl()));
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename property_map< UNDIRECTED_GRAPH, edge_all_t >::type get(
+ edge_all_t, UNDIRECTED_GRAPH& g)
+{
+ return typename property_map< UNDIRECTED_GRAPH, edge_all_t >::type(
+ detail::remove_first_property(), get(edge_all, g.impl()));
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename property_map< UNDIRECTED_GRAPH, edge_all_t >::const_type get(
+ edge_all_t, UNDIRECTED_GRAPH const& g)
+{
+ return typename property_map< UNDIRECTED_GRAPH, edge_all_t >::const_type(
+ detail::remove_first_property(), get(edge_all, g.impl()));
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key >
+inline typename property_traits< typename property_map<
+ typename UNDIRECTED_GRAPH::graph_type, Property >::const_type >::value_type
+get(Property p, UNDIRECTED_GRAPH const& g, Key const& k)
+{
+ return get(p, g.impl(), k);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, typename Key >
+inline typename property_traits<
+ typename property_map< typename UNDIRECTED_GRAPH::graph_type,
+ vertex_all_t >::const_type >::value_type
+get(vertex_all_t, UNDIRECTED_GRAPH const& g, Key const& k)
+{
+ return get(vertex_all, g.impl(), k).m_base;
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, typename Key >
+inline typename property_traits<
+ typename property_map< typename UNDIRECTED_GRAPH::graph_type,
+ edge_all_t >::const_type >::value_type
+get(edge_all_t, UNDIRECTED_GRAPH const& g, Key const& k)
+{
+ return get(edge_all, g.impl(), k).m_base;
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key,
+ typename Value >
+inline void put(Property p, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
+{
+ put(p, g.impl(), k, v);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, typename Key, typename Value >
+inline void put(vertex_all_t, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
+{
+ put(vertex_all, g.impl(), k,
+ typename UNDIRECTED_GRAPH::internal_vertex_property(
+ get(vertex_index, g.impl(), k), v));
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, typename Key, typename Value >
+inline void put(edge_all_t, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
+{
+ put(edge_all, g.impl(), k,
+ typename UNDIRECTED_GRAPH::internal_vertex_property(
+ get(edge_index, g.impl(), k), v));
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, class Property >
+inline typename graph_property< UNDIRECTED_GRAPH, Property >::type&
+get_property(UNDIRECTED_GRAPH& g, Property p)
+{
+ return get_property(g.impl(), p);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, class Property >
+inline typename graph_property< UNDIRECTED_GRAPH, Property >::type const&
+get_property(UNDIRECTED_GRAPH const& g, Property p)
+{
+ return get_property(g.impl(), p);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS, class Property, class Value >
+inline void set_property(UNDIRECTED_GRAPH& g, Property p, Value v)
+{
+ return set_property(g.impl(), p, v);
+}
+
+// Indexed Vertex graph
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::vertex_index_type get_vertex_index(
+ typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return get(vertex_index, g, v);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+typename UNDIRECTED_GRAPH::vertex_index_type max_vertex_index(
+ UNDIRECTED_GRAPH const& g)
+{
+ return g.max_vertex_index();
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void renumber_vertex_indices(UNDIRECTED_GRAPH& g)
+{
+ g.renumber_vertex_indices();
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void remove_vertex_and_renumber_indices(
+ typename UNDIRECTED_GRAPH::vertex_iterator i, UNDIRECTED_GRAPH& g)
+{
+ g.remove_vertex_and_renumber_indices(i);
+}
+
+// Edge index management
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline typename UNDIRECTED_GRAPH::edge_index_type get_edge_index(
+ typename UNDIRECTED_GRAPH::edge_descriptor v, UNDIRECTED_GRAPH const& g)
+{
+ return get(edge_index, g, v);
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+typename UNDIRECTED_GRAPH::edge_index_type max_edge_index(
+ UNDIRECTED_GRAPH const& g)
+{
+ return g.max_edge_index();
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void renumber_edge_indices(UNDIRECTED_GRAPH& g)
+{
+ g.renumber_edge_indices();
+}
+
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void remove_edge_and_renumber_indices(
+ typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g)
+{
+ g.remove_edge_and_renumber_indices(i);
+}
+
+// Index management
+template < UNDIRECTED_GRAPH_PARAMS >
+inline void renumber_indices(UNDIRECTED_GRAPH& g)
+{
+ g.renumber_indices();
+}
+
+// Mutability Traits
+template < UNDIRECTED_GRAPH_PARAMS >
+struct graph_mutability_traits< UNDIRECTED_GRAPH >
+{
+ typedef mutable_property_graph_tag category;
+};
+
+#undef UNDIRECTED_GRAPH_PARAMS
+#undef UNDIRECTED_GRAPH
+
+} /* namespace boost */
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/graph/vector_as_graph.hpp b/contrib/restricted/boost/graph/include/boost/graph/vector_as_graph.hpp
new file mode 100644
index 0000000000..444df87674
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/vector_as_graph.hpp
@@ -0,0 +1,334 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2006 The Trustees of Indiana University.
+// Copyright (C) 2001 Vladimir Prus <ghost@cs.msu.su>
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Douglas Gregor
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+// The mutating functions (add_edge, etc.) were added by Vladimir Prus.
+
+#ifndef BOOST_VECTOR_AS_GRAPH_HPP
+#define BOOST_VECTOR_AS_GRAPH_HPP
+
+#include <cassert>
+#include <utility>
+#include <vector>
+#include <cstddef>
+#include <iterator>
+#include <boost/iterator/counting_iterator.hpp>
+#include <boost/range/irange.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/graph/properties.hpp>
+#include <algorithm>
+
+/*
+ This module implements the VertexListGraph concept using a
+ std::vector as the "back-bone" of the graph (the vector *is* the
+ graph object). The edge-lists type of the graph is templated, so the
+ user can choose any STL container, so long as the value_type of the
+ container is convertible to the size_type of the vector. For now any
+ graph properties must be stored seperately.
+
+ This module requires the C++ compiler to support partial
+ specialization for the graph_traits class, so this is not portable
+ to VC++.
+
+*/
+
+namespace boost
+{
+namespace detail
+{
+ template < class EdgeList > struct val_out_edge_ret;
+ template < class EdgeList > struct val_out_edge_iter;
+ template < class EdgeList > struct val_edge;
+}
+}
+
+namespace boost
+{
+
+struct vector_as_graph_traversal_tag : public vertex_list_graph_tag,
+ public adjacency_graph_tag,
+ public incidence_graph_tag
+{
+};
+
+template < class EdgeList > struct graph_traits< std::vector< EdgeList > >
+{
+ typedef typename EdgeList::value_type V;
+ typedef V vertex_descriptor;
+ typedef typename detail::val_edge< EdgeList >::type edge_descriptor;
+ typedef typename EdgeList::const_iterator adjacency_iterator;
+ typedef
+ typename detail::val_out_edge_iter< EdgeList >::type out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef void edge_iterator;
+ typedef counting_iterator< V > vertex_iterator;
+ typedef directed_tag directed_category;
+ typedef allow_parallel_edge_tag edge_parallel_category;
+ typedef vector_as_graph_traversal_tag traversal_category;
+ typedef typename std::vector< EdgeList >::size_type vertices_size_type;
+ typedef void edges_size_type;
+ typedef typename EdgeList::size_type degree_size_type;
+ static V null_vertex() { return V(-1); }
+};
+template < class EdgeList > struct edge_property_type< std::vector< EdgeList > >
+{
+ typedef void type;
+};
+template < class EdgeList >
+struct vertex_property_type< std::vector< EdgeList > >
+{
+ typedef void type;
+};
+template < class EdgeList >
+struct graph_property_type< std::vector< EdgeList > >
+{
+ typedef void type;
+};
+}
+
+namespace boost
+{
+
+namespace detail
+{
+
+ // "val" is short for Vector Adjacency List
+
+ template < class EdgeList > struct val_edge
+ {
+ typedef typename EdgeList::value_type V;
+ typedef std::pair< V, V > type;
+ };
+
+ // need rewrite this using boost::iterator_adaptor
+ template < class V, class Iter > class val_out_edge_iterator
+ {
+ typedef val_out_edge_iterator self;
+ typedef std::pair< V, V > Edge;
+
+ public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair< V, V > value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::pair< V, V >* pointer;
+ typedef const std::pair< V, V > reference;
+ val_out_edge_iterator() {}
+ val_out_edge_iterator(V s, Iter i) : _source(s), _iter(i) {}
+ Edge operator*() const { return Edge(_source, *_iter); }
+ self& operator++()
+ {
+ ++_iter;
+ return *this;
+ }
+ self operator++(int)
+ {
+ self t = *this;
+ ++_iter;
+ return t;
+ }
+ bool operator==(const self& x) const { return _iter == x._iter; }
+ bool operator!=(const self& x) const { return _iter != x._iter; }
+
+ protected:
+ V _source;
+ Iter _iter;
+ };
+
+ template < class EdgeList > struct val_out_edge_iter
+ {
+ typedef typename EdgeList::value_type V;
+ typedef typename EdgeList::const_iterator Iter;
+ typedef val_out_edge_iterator< V, Iter > type;
+ };
+
+ template < class EdgeList > struct val_out_edge_ret
+ {
+ typedef typename val_out_edge_iter< EdgeList >::type IncIter;
+ typedef std::pair< IncIter, IncIter > type;
+ };
+
+} // namesapce detail
+
+template < class EdgeList, class Alloc >
+typename detail::val_out_edge_ret< EdgeList >::type out_edges(
+ typename EdgeList::value_type v, const std::vector< EdgeList, Alloc >& g)
+{
+ typedef typename detail::val_out_edge_iter< EdgeList >::type Iter;
+ typedef typename detail::val_out_edge_ret< EdgeList >::type return_type;
+ return return_type(Iter(v, g[v].begin()), Iter(v, g[v].end()));
+}
+
+template < class EdgeList, class Alloc >
+typename EdgeList::size_type out_degree(
+ typename EdgeList::value_type v, const std::vector< EdgeList, Alloc >& g)
+{
+ return g[v].size();
+}
+
+template < class EdgeList, class Alloc >
+std::pair< typename EdgeList::const_iterator,
+ typename EdgeList::const_iterator >
+adjacent_vertices(
+ typename EdgeList::value_type v, const std::vector< EdgeList, Alloc >& g)
+{
+ return std::make_pair(g[v].begin(), g[v].end());
+}
+
+// source() and target() already provided for pairs in graph_traits.hpp
+
+template < class EdgeList, class Alloc >
+std::pair< boost::counting_iterator< typename EdgeList::value_type >,
+ boost::counting_iterator< typename EdgeList::value_type > >
+vertices(const std::vector< EdgeList, Alloc >& v)
+{
+ typedef boost::counting_iterator< typename EdgeList::value_type > Iter;
+ return std::make_pair(Iter(0), Iter(v.size()));
+}
+
+template < class EdgeList, class Alloc >
+typename std::vector< EdgeList, Alloc >::size_type num_vertices(
+ const std::vector< EdgeList, Alloc >& v)
+{
+ return v.size();
+}
+
+template < class EdgeList, class Allocator >
+typename std::pair< typename detail::val_edge< EdgeList >::type, bool >
+add_edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
+ std::vector< EdgeList, Allocator >& g)
+{
+ typedef typename detail::val_edge< EdgeList >::type edge_type;
+ g[u].insert(g[u].end(), v);
+ return std::make_pair(edge_type(u, v), true);
+}
+
+template < class EdgeList, class Allocator >
+typename std::pair< typename detail::val_edge< EdgeList >::type, bool > edge(
+ typename EdgeList::value_type u, typename EdgeList::value_type v,
+ std::vector< EdgeList, Allocator >& g)
+{
+ typedef typename detail::val_edge< EdgeList >::type edge_type;
+ typename EdgeList::iterator i = g[u].begin(), end = g[u].end();
+ for (; i != end; ++i)
+ if (*i == v)
+ return std::make_pair(edge_type(u, v), true);
+ return std::make_pair(edge_type(), false);
+}
+
+template < class EdgeList, class Allocator >
+void remove_edge(typename EdgeList::value_type u,
+ typename EdgeList::value_type v, std::vector< EdgeList, Allocator >& g)
+{
+ typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v);
+ if (i != g[u].end())
+ g[u].erase(i, g[u].end());
+}
+
+template < class EdgeList, class Allocator >
+void remove_edge(typename detail::val_edge< EdgeList >::type e,
+ std::vector< EdgeList, Allocator >& g)
+{
+ typename EdgeList::value_type u, v;
+ u = e.first;
+ v = e.second;
+ // FIXME: edge type does not fully specify the edge to be deleted
+ typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v);
+ if (i != g[u].end())
+ g[u].erase(i, g[u].end());
+}
+
+template < class EdgeList, class Allocator, class Predicate >
+void remove_edge_if(Predicate p, std::vector< EdgeList, Allocator >& g)
+{
+ for (std::size_t u = 0; u < g.size(); ++u)
+ {
+ // Oops! gcc gets internal compiler error on compose_.......
+
+ typedef typename EdgeList::iterator iterator;
+ iterator b = g[u].begin(), e = g[u].end();
+
+ if (!g[u].empty())
+ {
+
+ for (; b != e;)
+ {
+ if (p(std::make_pair(u, *b)))
+ {
+ --e;
+ if (b == e)
+ break;
+ else
+ iter_swap(b, e);
+ }
+ else
+ {
+ ++b;
+ }
+ }
+ }
+
+ if (e != g[u].end())
+ g[u].erase(e, g[u].end());
+ }
+}
+
+template < class EdgeList, class Allocator >
+typename EdgeList::value_type add_vertex(std::vector< EdgeList, Allocator >& g)
+{
+ g.resize(g.size() + 1);
+ return g.size() - 1;
+}
+
+template < class EdgeList, class Allocator >
+void clear_vertex(
+ typename EdgeList::value_type u, std::vector< EdgeList, Allocator >& g)
+{
+ g[u].clear();
+ for (std::size_t i = 0; i < g.size(); ++i)
+ remove_edge(i, u, g);
+}
+
+template < class EdgeList, class Allocator >
+void remove_vertex(
+ typename EdgeList::value_type u, std::vector< EdgeList, Allocator >& g)
+{
+ typedef typename EdgeList::iterator iterator;
+ clear_vertex(u, g);
+ g.erase(g.begin() + u);
+ for (std::size_t i = 0; i < g.size(); ++i)
+ for (iterator it = g[i].begin(); it != g[i].end(); ++it)
+ // after clear_vertex *it is never equal to u
+ if (*it > u)
+ --*it;
+}
+
+template < typename EdgeList, typename Allocator >
+struct property_map< std::vector< EdgeList, Allocator >, vertex_index_t >
+{
+ typedef identity_property_map type;
+ typedef type const_type;
+};
+
+template < typename EdgeList, typename Allocator >
+identity_property_map get(
+ vertex_index_t, const std::vector< EdgeList, Allocator >&)
+{
+ return identity_property_map();
+}
+
+template < typename EdgeList, typename Allocator >
+identity_property_map get(vertex_index_t, std::vector< EdgeList, Allocator >&)
+{
+ return identity_property_map();
+}
+} // namespace boost
+
+#endif // BOOST_VECTOR_AS_GRAPH_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/vertex_and_edge_range.hpp b/contrib/restricted/boost/graph/include/boost/graph/vertex_and_edge_range.hpp
new file mode 100644
index 0000000000..c9e217bd72
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/vertex_and_edge_range.hpp
@@ -0,0 +1,158 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+
+#ifndef BOOST_GRAPH_VERTEX_AND_EDGE_RANGE_HPP
+#define BOOST_GRAPH_VERTEX_AND_EDGE_RANGE_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <iterator>
+
+namespace boost
+{
+
+namespace graph
+{
+ template < typename Graph, typename VertexIterator, typename EdgeIterator >
+ class vertex_and_edge_range
+ {
+ typedef graph_traits< Graph > traits_type;
+
+ public:
+ typedef typename traits_type::directed_category directed_category;
+ typedef
+ typename traits_type::edge_parallel_category edge_parallel_category;
+ struct traversal_category : public virtual vertex_list_graph_tag,
+ public virtual edge_list_graph_tag
+ {
+ };
+
+ typedef std::size_t vertices_size_type;
+ typedef VertexIterator vertex_iterator;
+ typedef typename std::iterator_traits< VertexIterator >::value_type
+ vertex_descriptor;
+
+ typedef EdgeIterator edge_iterator;
+ typedef typename std::iterator_traits< EdgeIterator >::value_type
+ edge_descriptor;
+
+ typedef std::size_t edges_size_type;
+
+ typedef void adjacency_iterator;
+ typedef void out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef void degree_size_type;
+
+ static vertex_descriptor null_vertex()
+ {
+ return traits_type::null_vertex();
+ }
+
+ vertex_and_edge_range(const Graph& g, VertexIterator first_v,
+ VertexIterator last_v, vertices_size_type n, EdgeIterator first_e,
+ EdgeIterator last_e, edges_size_type m)
+ : g(&g)
+ , first_vertex(first_v)
+ , last_vertex(last_v)
+ , m_num_vertices(n)
+ , first_edge(first_e)
+ , last_edge(last_e)
+ , m_num_edges(m)
+ {
+ }
+
+ vertex_and_edge_range(const Graph& g, VertexIterator first_v,
+ VertexIterator last_v, EdgeIterator first_e, EdgeIterator last_e)
+ : g(&g)
+ , first_vertex(first_v)
+ , last_vertex(last_v)
+ , first_edge(first_e)
+ , last_edge(last_e)
+ {
+ m_num_vertices = std::distance(first_v, last_v);
+ m_num_edges = std::distance(first_e, last_e);
+ }
+
+ const Graph* g;
+ vertex_iterator first_vertex;
+ vertex_iterator last_vertex;
+ vertices_size_type m_num_vertices;
+ edge_iterator first_edge;
+ edge_iterator last_edge;
+ edges_size_type m_num_edges;
+ };
+
+ template < typename Graph, typename VertexIterator, typename EdgeIterator >
+ inline std::pair< VertexIterator, VertexIterator > vertices(
+ const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g)
+ {
+ return std::make_pair(g.first_vertex, g.last_vertex);
+ }
+
+ template < typename Graph, typename VertexIterator, typename EdgeIterator >
+ inline typename vertex_and_edge_range< Graph, VertexIterator,
+ EdgeIterator >::vertices_size_type
+ num_vertices(
+ const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g)
+ {
+ return g.m_num_vertices;
+ }
+
+ template < typename Graph, typename VertexIterator, typename EdgeIterator >
+ inline std::pair< EdgeIterator, EdgeIterator > edges(
+ const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g)
+ {
+ return std::make_pair(g.first_edge, g.last_edge);
+ }
+
+ template < typename Graph, typename VertexIterator, typename EdgeIterator >
+ inline typename vertex_and_edge_range< Graph, VertexIterator,
+ EdgeIterator >::edges_size_type
+ num_edges(
+ const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g)
+ {
+ return g.m_num_edges;
+ }
+
+ template < typename Graph, typename VertexIterator, typename EdgeIterator >
+ inline typename vertex_and_edge_range< Graph, VertexIterator,
+ EdgeIterator >::vertex_descriptor
+ source(typename vertex_and_edge_range< Graph, VertexIterator,
+ EdgeIterator >::edge_descriptor e,
+ const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g)
+ {
+ return source(e, *g.g);
+ }
+
+ template < typename Graph, typename VertexIterator, typename EdgeIterator >
+ inline typename vertex_and_edge_range< Graph, VertexIterator,
+ EdgeIterator >::vertex_descriptor
+ target(typename vertex_and_edge_range< Graph, VertexIterator,
+ EdgeIterator >::edge_descriptor e,
+ const vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >& g)
+ {
+ return target(e, *g.g);
+ }
+
+ template < typename Graph, typename VertexIterator, typename EdgeIterator >
+ inline vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >
+ make_vertex_and_edge_range(const Graph& g, VertexIterator first_v,
+ VertexIterator last_v, EdgeIterator first_e, EdgeIterator last_e)
+ {
+ typedef vertex_and_edge_range< Graph, VertexIterator, EdgeIterator >
+ result_type;
+ return result_type(g, first_v, last_v, first_e, last_e);
+ }
+
+} // end namespace graph
+
+using graph::make_vertex_and_edge_range;
+using graph::vertex_and_edge_range;
+
+} // end namespace boost
+#endif // BOOST_GRAPH_VERTEX_AND_EDGE_RANGE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/vf2_sub_graph_iso.hpp b/contrib/restricted/boost/graph/include/boost/graph/vf2_sub_graph_iso.hpp
new file mode 100644
index 0000000000..77f7496bd1
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/vf2_sub_graph_iso.hpp
@@ -0,0 +1,1301 @@
+//=======================================================================
+// Copyright (C) 2012 Flavio De Lorenzi (fdlorenzi@gmail.com)
+// Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark
+// (jlandersen@imada.sdu.dk)
+//
+// The algorithm implemented here is derived from original ideas by
+// Pasquale Foggia and colaborators. For further information see
+// e.g. Cordella et al. 2001, 2004.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+// Revision History:
+// 8 April 2013: Fixed a typo in vf2_print_callback. (Flavio De Lorenzi)
+
+#ifndef BOOST_VF2_SUB_GRAPH_ISO_HPP
+#define BOOST_VF2_SUB_GRAPH_ISO_HPP
+
+#include <iostream>
+#include <iomanip>
+#include <iterator>
+#include <vector>
+#include <utility>
+
+#include <boost/assert.hpp>
+#include <boost/concept/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/graph/graph_utility.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/mcgregor_common_subgraphs.hpp> // for always_equivalent
+#include <boost/graph/named_function_params.hpp>
+#include <boost/type_traits/has_less.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/range/algorithm/sort.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#ifndef BOOST_GRAPH_ITERATION_MACROS_HPP
+#define BOOST_ISO_INCLUDED_ITER_MACROS // local macro, see bottom of file
+#include <boost/graph/iteration_macros.hpp>
+#endif
+
+namespace boost
+{
+
+// Default print_callback
+template < typename Graph1, typename Graph2 > struct vf2_print_callback
+{
+
+ vf2_print_callback(const Graph1& graph1, const Graph2& graph2)
+ : graph1_(graph1), graph2_(graph2)
+ {
+ }
+
+ template < typename CorrespondenceMap1To2, typename CorrespondenceMap2To1 >
+ bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1) const
+ {
+
+ // Print (sub)graph isomorphism map
+ BGL_FORALL_VERTICES_T(v, graph1_, Graph1)
+ std::cout << '(' << get(vertex_index_t(), graph1_, v) << ", "
+ << get(vertex_index_t(), graph2_, get(f, v)) << ") ";
+
+ std::cout << std::endl;
+
+ return true;
+ }
+
+private:
+ const Graph1& graph1_;
+ const Graph2& graph2_;
+};
+
+namespace detail
+{
+
+ // State associated with a single graph (graph_this)
+ template < typename GraphThis, typename GraphOther, typename IndexMapThis,
+ typename IndexMapOther >
+ class base_state
+ {
+
+ typedef typename graph_traits< GraphThis >::vertex_descriptor
+ vertex_this_type;
+ typedef typename graph_traits< GraphOther >::vertex_descriptor
+ vertex_other_type;
+
+ typedef
+ typename graph_traits< GraphThis >::vertices_size_type size_type;
+
+ const GraphThis& graph_this_;
+ const GraphOther& graph_other_;
+
+ IndexMapThis index_map_this_;
+ IndexMapOther index_map_other_;
+
+ std::vector< vertex_other_type > core_vec_;
+ typedef iterator_property_map<
+ typename std::vector< vertex_other_type >::iterator, IndexMapThis,
+ vertex_other_type, vertex_other_type& >
+ core_map_type;
+ core_map_type core_;
+
+ std::vector< size_type > in_vec_, out_vec_;
+ typedef iterator_property_map<
+ typename std::vector< size_type >::iterator, IndexMapThis,
+ size_type, size_type& >
+ in_out_map_type;
+ in_out_map_type in_, out_;
+
+ size_type term_in_count_, term_out_count_, term_both_count_,
+ core_count_;
+
+ // Forbidden
+ base_state(const base_state&);
+ base_state& operator=(const base_state&);
+
+ public:
+ base_state(const GraphThis& graph_this, const GraphOther& graph_other,
+ IndexMapThis index_map_this, IndexMapOther index_map_other)
+ : graph_this_(graph_this)
+ , graph_other_(graph_other)
+ , index_map_this_(index_map_this)
+ , index_map_other_(index_map_other)
+ , core_vec_(num_vertices(graph_this_),
+ graph_traits< GraphOther >::null_vertex())
+ , core_(core_vec_.begin(), index_map_this_)
+ , in_vec_(num_vertices(graph_this_), 0)
+ , out_vec_(num_vertices(graph_this_), 0)
+ , in_(in_vec_.begin(), index_map_this_)
+ , out_(out_vec_.begin(), index_map_this_)
+ , term_in_count_(0)
+ , term_out_count_(0)
+ , term_both_count_(0)
+ , core_count_(0)
+ {
+ }
+
+ // Adds a vertex pair to the state of graph graph_this
+ void push(
+ const vertex_this_type& v_this, const vertex_other_type& v_other)
+ {
+
+ ++core_count_;
+
+ put(core_, v_this, v_other);
+
+ if (!get(in_, v_this))
+ {
+ put(in_, v_this, core_count_);
+ ++term_in_count_;
+ if (get(out_, v_this))
+ ++term_both_count_;
+ }
+
+ if (!get(out_, v_this))
+ {
+ put(out_, v_this, core_count_);
+ ++term_out_count_;
+ if (get(in_, v_this))
+ ++term_both_count_;
+ }
+
+ BGL_FORALL_INEDGES_T(v_this, e, graph_this_, GraphThis)
+ {
+ vertex_this_type w = source(e, graph_this_);
+ if (!get(in_, w))
+ {
+ put(in_, w, core_count_);
+ ++term_in_count_;
+ if (get(out_, w))
+ ++term_both_count_;
+ }
+ }
+
+ BGL_FORALL_OUTEDGES_T(v_this, e, graph_this_, GraphThis)
+ {
+ vertex_this_type w = target(e, graph_this_);
+ if (!get(out_, w))
+ {
+ put(out_, w, core_count_);
+ ++term_out_count_;
+ if (get(in_, w))
+ ++term_both_count_;
+ }
+ }
+ }
+
+ // Removes vertex pair from state of graph_this
+ void pop(const vertex_this_type& v_this, const vertex_other_type&)
+ {
+
+ if (!core_count_)
+ return;
+
+ if (get(in_, v_this) == core_count_)
+ {
+ put(in_, v_this, 0);
+ --term_in_count_;
+ if (get(out_, v_this))
+ --term_both_count_;
+ }
+
+ BGL_FORALL_INEDGES_T(v_this, e, graph_this_, GraphThis)
+ {
+ vertex_this_type w = source(e, graph_this_);
+ if (get(in_, w) == core_count_)
+ {
+ put(in_, w, 0);
+ --term_in_count_;
+ if (get(out_, w))
+ --term_both_count_;
+ }
+ }
+
+ if (get(out_, v_this) == core_count_)
+ {
+ put(out_, v_this, 0);
+ --term_out_count_;
+ if (get(in_, v_this))
+ --term_both_count_;
+ }
+
+ BGL_FORALL_OUTEDGES_T(v_this, e, graph_this_, GraphThis)
+ {
+ vertex_this_type w = target(e, graph_this_);
+ if (get(out_, w) == core_count_)
+ {
+ put(out_, w, 0);
+ --term_out_count_;
+ if (get(in_, w))
+ --term_both_count_;
+ }
+ }
+ put(core_, v_this, graph_traits< GraphOther >::null_vertex());
+
+ --core_count_;
+ }
+
+ // Returns true if the in-terminal set is not empty
+ bool term_in() const { return core_count_ < term_in_count_; }
+
+ // Returns true if vertex belongs to the in-terminal set
+ bool term_in(const vertex_this_type& v) const
+ {
+ return (get(in_, v) > 0)
+ && (get(core_, v) == graph_traits< GraphOther >::null_vertex());
+ }
+
+ // Returns true if the out-terminal set is not empty
+ bool term_out() const { return core_count_ < term_out_count_; }
+
+ // Returns true if vertex belongs to the out-terminal set
+ bool term_out(const vertex_this_type& v) const
+ {
+ return (get(out_, v) > 0)
+ && (get(core_, v) == graph_traits< GraphOther >::null_vertex());
+ }
+
+ // Returns true of both (in- and out-terminal) sets are not empty
+ bool term_both() const { return core_count_ < term_both_count_; }
+
+ // Returns true if vertex belongs to both (in- and out-terminal) sets
+ bool term_both(const vertex_this_type& v) const
+ {
+ return (get(in_, v) > 0) && (get(out_, v) > 0)
+ && (get(core_, v) == graph_traits< GraphOther >::null_vertex());
+ }
+
+ // Returns true if vertex belongs to the core map, i.e. it is in the
+ // present mapping
+ bool in_core(const vertex_this_type& v) const
+ {
+ return get(core_, v) != graph_traits< GraphOther >::null_vertex();
+ }
+
+ // Returns the number of vertices in the mapping
+ size_type count() const { return core_count_; }
+
+ // Returns the image (in graph_other) of vertex v (in graph_this)
+ vertex_other_type core(const vertex_this_type& v) const
+ {
+ return get(core_, v);
+ }
+
+ // Returns the mapping
+ core_map_type get_map() const { return core_; }
+
+ // Returns the "time" (or depth) when vertex was added to the
+ // in-terminal set
+ size_type in_depth(const vertex_this_type& v) const
+ {
+ return get(in_, v);
+ }
+
+ // Returns the "time" (or depth) when vertex was added to the
+ // out-terminal set
+ size_type out_depth(const vertex_this_type& v) const
+ {
+ return get(out_, v);
+ }
+
+ // Returns the terminal set counts
+ boost::tuple< size_type, size_type, size_type > term_set() const
+ {
+ return boost::make_tuple(
+ term_in_count_, term_out_count_, term_both_count_);
+ }
+ };
+
+ // Function object that checks whether a valid edge
+ // exists. For multi-graphs matched edges are excluded
+ template < typename Graph, typename Enable = void >
+ struct equivalent_edge_exists
+ {
+ typedef
+ typename boost::graph_traits< Graph >::edge_descriptor edge_type;
+
+ BOOST_CONCEPT_ASSERT((LessThanComparable< edge_type >));
+
+ template < typename EdgePredicate >
+ bool operator()(typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t,
+ EdgePredicate is_valid_edge, const Graph& g)
+ {
+
+ BGL_FORALL_OUTEDGES_T(s, e, g, Graph)
+ {
+ if ((target(e, g) == t) && is_valid_edge(e)
+ && (matched_edges_.find(e) == matched_edges_.end()))
+ {
+ matched_edges_.insert(e);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private:
+ std::set< edge_type > matched_edges_;
+ };
+
+ template < typename Graph >
+ struct equivalent_edge_exists< Graph,
+ typename boost::disable_if< is_multigraph< Graph > >::type >
+ {
+ template < typename EdgePredicate >
+ bool operator()(typename graph_traits< Graph >::vertex_descriptor s,
+ typename graph_traits< Graph >::vertex_descriptor t,
+ EdgePredicate is_valid_edge, const Graph& g)
+ {
+
+ typename graph_traits< Graph >::edge_descriptor e;
+ bool found;
+ boost::tie(e, found) = edge(s, t, g);
+ if (!found)
+ return false;
+ else if (is_valid_edge(e))
+ return true;
+
+ return false;
+ }
+ };
+
+ // Generates a predicate for edge e1 given a binary predicate and a
+ // fixed edge e2
+ template < typename Graph1, typename Graph2,
+ typename EdgeEquivalencePredicate >
+ struct edge1_predicate
+ {
+
+ edge1_predicate(EdgeEquivalencePredicate edge_comp,
+ typename graph_traits< Graph2 >::edge_descriptor e2)
+ : edge_comp_(edge_comp), e2_(e2)
+ {
+ }
+
+ bool operator()(typename graph_traits< Graph1 >::edge_descriptor e1)
+ {
+ return edge_comp_(e1, e2_);
+ }
+
+ EdgeEquivalencePredicate edge_comp_;
+ typename graph_traits< Graph2 >::edge_descriptor e2_;
+ };
+
+ // Generates a predicate for edge e2 given given a binary predicate and a
+ // fixed edge e1
+ template < typename Graph1, typename Graph2,
+ typename EdgeEquivalencePredicate >
+ struct edge2_predicate
+ {
+
+ edge2_predicate(EdgeEquivalencePredicate edge_comp,
+ typename graph_traits< Graph1 >::edge_descriptor e1)
+ : edge_comp_(edge_comp), e1_(e1)
+ {
+ }
+
+ bool operator()(typename graph_traits< Graph2 >::edge_descriptor e2)
+ {
+ return edge_comp_(e1_, e2);
+ }
+
+ EdgeEquivalencePredicate edge_comp_;
+ typename graph_traits< Graph1 >::edge_descriptor e1_;
+ };
+
+ enum problem_selector
+ {
+ subgraph_mono,
+ subgraph_iso,
+ isomorphism
+ };
+
+ // The actual state associated with both graphs
+ template < typename Graph1, typename Graph2, typename IndexMap1,
+ typename IndexMap2, typename EdgeEquivalencePredicate,
+ typename VertexEquivalencePredicate, typename SubGraphIsoMapCallback,
+ problem_selector problem_selection >
+ class state
+ {
+
+ typedef typename graph_traits< Graph1 >::vertex_descriptor vertex1_type;
+ typedef typename graph_traits< Graph2 >::vertex_descriptor vertex2_type;
+
+ typedef typename graph_traits< Graph1 >::edge_descriptor edge1_type;
+ typedef typename graph_traits< Graph2 >::edge_descriptor edge2_type;
+
+ typedef typename graph_traits< Graph1 >::vertices_size_type
+ graph1_size_type;
+ typedef typename graph_traits< Graph2 >::vertices_size_type
+ graph2_size_type;
+
+ const Graph1& graph1_;
+ const Graph2& graph2_;
+
+ IndexMap1 index_map1_;
+
+ EdgeEquivalencePredicate edge_comp_;
+ VertexEquivalencePredicate vertex_comp_;
+
+ base_state< Graph1, Graph2, IndexMap1, IndexMap2 > state1_;
+ base_state< Graph2, Graph1, IndexMap2, IndexMap1 > state2_;
+
+ // Three helper functions used in Feasibility and Valid functions to
+ // test terminal set counts when testing for:
+ // - graph sub-graph monomorphism, or
+ inline bool comp_term_sets(graph1_size_type a, graph2_size_type b,
+ boost::mpl::int_< subgraph_mono >) const
+ {
+ return a <= b;
+ }
+
+ // - graph sub-graph isomorphism, or
+ inline bool comp_term_sets(graph1_size_type a, graph2_size_type b,
+ boost::mpl::int_< subgraph_iso >) const
+ {
+ return a <= b;
+ }
+
+ // - graph isomorphism
+ inline bool comp_term_sets(graph1_size_type a, graph2_size_type b,
+ boost::mpl::int_< isomorphism >) const
+ {
+ return a == b;
+ }
+
+ // Forbidden
+ state(const state&);
+ state& operator=(const state&);
+
+ public:
+ state(const Graph1& graph1, const Graph2& graph2, IndexMap1 index_map1,
+ IndexMap2 index_map2, EdgeEquivalencePredicate edge_comp,
+ VertexEquivalencePredicate vertex_comp)
+ : graph1_(graph1)
+ , graph2_(graph2)
+ , index_map1_(index_map1)
+ , edge_comp_(edge_comp)
+ , vertex_comp_(vertex_comp)
+ , state1_(graph1, graph2, index_map1, index_map2)
+ , state2_(graph2, graph1, index_map2, index_map1)
+ {
+ }
+
+ // Add vertex pair to the state
+ void push(const vertex1_type& v, const vertex2_type& w)
+ {
+ state1_.push(v, w);
+ state2_.push(w, v);
+ }
+
+ // Remove vertex pair from state
+ void pop(const vertex1_type& v, const vertex2_type&)
+ {
+ vertex2_type w = state1_.core(v);
+ state1_.pop(v, w);
+ state2_.pop(w, v);
+ }
+
+ // Checks the feasibility of a new vertex pair
+ bool feasible(const vertex1_type& v_new, const vertex2_type& w_new)
+ {
+
+ if (!vertex_comp_(v_new, w_new))
+ return false;
+
+ // graph1
+ graph1_size_type term_in1_count = 0, term_out1_count = 0,
+ rest1_count = 0;
+
+ {
+ equivalent_edge_exists< Graph2 > edge2_exists;
+
+ BGL_FORALL_INEDGES_T(v_new, e1, graph1_, Graph1)
+ {
+ vertex1_type v = source(e1, graph1_);
+
+ if (state1_.in_core(v) || (v == v_new))
+ {
+ vertex2_type w = w_new;
+ if (v != v_new)
+ w = state1_.core(v);
+ if (!edge2_exists(w, w_new,
+ edge2_predicate< Graph1, Graph2,
+ EdgeEquivalencePredicate >(edge_comp_, e1),
+ graph2_))
+ return false;
+ }
+ else
+ {
+ if (0 < state1_.in_depth(v))
+ ++term_in1_count;
+ if (0 < state1_.out_depth(v))
+ ++term_out1_count;
+ if ((state1_.in_depth(v) == 0)
+ && (state1_.out_depth(v) == 0))
+ ++rest1_count;
+ }
+ }
+ }
+
+ {
+ equivalent_edge_exists< Graph2 > edge2_exists;
+
+ BGL_FORALL_OUTEDGES_T(v_new, e1, graph1_, Graph1)
+ {
+ vertex1_type v = target(e1, graph1_);
+ if (state1_.in_core(v) || (v == v_new))
+ {
+ vertex2_type w = w_new;
+ if (v != v_new)
+ w = state1_.core(v);
+
+ if (!edge2_exists(w_new, w,
+ edge2_predicate< Graph1, Graph2,
+ EdgeEquivalencePredicate >(edge_comp_, e1),
+ graph2_))
+ return false;
+ }
+ else
+ {
+ if (0 < state1_.in_depth(v))
+ ++term_in1_count;
+ if (0 < state1_.out_depth(v))
+ ++term_out1_count;
+ if ((state1_.in_depth(v) == 0)
+ && (state1_.out_depth(v) == 0))
+ ++rest1_count;
+ }
+ }
+ }
+
+ // graph2
+ graph2_size_type term_out2_count = 0, term_in2_count = 0,
+ rest2_count = 0;
+
+ {
+ equivalent_edge_exists< Graph1 > edge1_exists;
+
+ BGL_FORALL_INEDGES_T(w_new, e2, graph2_, Graph2)
+ {
+ vertex2_type w = source(e2, graph2_);
+ if (state2_.in_core(w) || (w == w_new))
+ {
+ if (problem_selection != subgraph_mono)
+ {
+ vertex1_type v = v_new;
+ if (w != w_new)
+ v = state2_.core(w);
+
+ if (!edge1_exists(v, v_new,
+ edge1_predicate< Graph1, Graph2,
+ EdgeEquivalencePredicate >(
+ edge_comp_, e2),
+ graph1_))
+ return false;
+ }
+ }
+ else
+ {
+ if (0 < state2_.in_depth(w))
+ ++term_in2_count;
+ if (0 < state2_.out_depth(w))
+ ++term_out2_count;
+ if ((state2_.in_depth(w) == 0)
+ && (state2_.out_depth(w) == 0))
+ ++rest2_count;
+ }
+ }
+ }
+
+ {
+ equivalent_edge_exists< Graph1 > edge1_exists;
+
+ BGL_FORALL_OUTEDGES_T(w_new, e2, graph2_, Graph2)
+ {
+ vertex2_type w = target(e2, graph2_);
+ if (state2_.in_core(w) || (w == w_new))
+ {
+ if (problem_selection != subgraph_mono)
+ {
+ vertex1_type v = v_new;
+ if (w != w_new)
+ v = state2_.core(w);
+
+ if (!edge1_exists(v_new, v,
+ edge1_predicate< Graph1, Graph2,
+ EdgeEquivalencePredicate >(
+ edge_comp_, e2),
+ graph1_))
+ return false;
+ }
+ }
+ else
+ {
+ if (0 < state2_.in_depth(w))
+ ++term_in2_count;
+ if (0 < state2_.out_depth(w))
+ ++term_out2_count;
+ if ((state2_.in_depth(w) == 0)
+ && (state2_.out_depth(w) == 0))
+ ++rest2_count;
+ }
+ }
+ }
+
+ if (problem_selection != subgraph_mono)
+ { // subgraph_iso and isomorphism
+ return comp_term_sets(term_in1_count, term_in2_count,
+ boost::mpl::int_< problem_selection >())
+ && comp_term_sets(term_out1_count, term_out2_count,
+ boost::mpl::int_< problem_selection >())
+ && comp_term_sets(rest1_count, rest2_count,
+ boost::mpl::int_< problem_selection >());
+ }
+ else
+ { // subgraph_mono
+ return comp_term_sets(term_in1_count, term_in2_count,
+ boost::mpl::int_< problem_selection >())
+ && comp_term_sets(term_out1_count, term_out2_count,
+ boost::mpl::int_< problem_selection >())
+ && comp_term_sets(
+ term_in1_count + term_out1_count + rest1_count,
+ term_in2_count + term_out2_count + rest2_count,
+ boost::mpl::int_< problem_selection >());
+ }
+ }
+
+ // Returns true if vertex v in graph1 is a possible candidate to
+ // be added to the current state
+ bool possible_candidate1(const vertex1_type& v) const
+ {
+ if (state1_.term_both() && state2_.term_both())
+ return state1_.term_both(v);
+ else if (state1_.term_out() && state2_.term_out())
+ return state1_.term_out(v);
+ else if (state1_.term_in() && state2_.term_in())
+ return state1_.term_in(v);
+ else
+ return !state1_.in_core(v);
+ }
+
+ // Returns true if vertex w in graph2 is a possible candidate to
+ // be added to the current state
+ bool possible_candidate2(const vertex2_type& w) const
+ {
+ if (state1_.term_both() && state2_.term_both())
+ return state2_.term_both(w);
+ else if (state1_.term_out() && state2_.term_out())
+ return state2_.term_out(w);
+ else if (state1_.term_in() && state2_.term_in())
+ return state2_.term_in(w);
+ else
+ return !state2_.in_core(w);
+ }
+
+ // Returns true if a mapping was found
+ bool success() const
+ {
+ return state1_.count() == num_vertices(graph1_);
+ }
+
+ // Returns true if a state is valid
+ bool valid() const
+ {
+ boost::tuple< graph1_size_type, graph1_size_type, graph1_size_type >
+ term1;
+ boost::tuple< graph2_size_type, graph2_size_type, graph2_size_type >
+ term2;
+
+ term1 = state1_.term_set();
+ term2 = state2_.term_set();
+
+ return comp_term_sets(boost::get< 0 >(term1),
+ boost::get< 0 >(term2),
+ boost::mpl::int_< problem_selection >())
+ && comp_term_sets(boost::get< 1 >(term1),
+ boost::get< 1 >(term2),
+ boost::mpl::int_< problem_selection >())
+ && comp_term_sets(boost::get< 2 >(term1),
+ boost::get< 2 >(term2),
+ boost::mpl::int_< problem_selection >());
+ }
+
+ // Calls the user_callback with a graph (sub)graph mapping
+ bool call_back(SubGraphIsoMapCallback user_callback) const
+ {
+ return user_callback(state1_.get_map(), state2_.get_map());
+ }
+ };
+
+ // Data structure to keep info used for back tracking during
+ // matching process
+ template < typename Graph1, typename Graph2, typename VertexOrder1 >
+ struct vf2_match_continuation
+ {
+ typename VertexOrder1::const_iterator graph1_verts_iter;
+ typename graph_traits< Graph2 >::vertex_iterator graph2_verts_iter;
+ };
+
+ // Non-recursive method that explores state space using a depth-first
+ // search strategy. At each depth possible pairs candidate are compute
+ // and tested for feasibility to extend the mapping. If a complete
+ // mapping is found, the mapping is output to user_callback in the form
+ // of a correspondence map (graph1 to graph2). Returning false from the
+ // user_callback will terminate the search. Function match will return
+ // true if the entire search space was explored.
+ template < typename Graph1, typename Graph2, typename IndexMap1,
+ typename IndexMap2, typename VertexOrder1,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename SubGraphIsoMapCallback, problem_selector problem_selection >
+ bool match(const Graph1& graph1, const Graph2& graph2,
+ SubGraphIsoMapCallback user_callback, const VertexOrder1& vertex_order1,
+ state< Graph1, Graph2, IndexMap1, IndexMap2, EdgeEquivalencePredicate,
+ VertexEquivalencePredicate, SubGraphIsoMapCallback,
+ problem_selection >& s)
+ {
+
+ typename VertexOrder1::const_iterator graph1_verts_iter;
+
+ typedef typename graph_traits< Graph2 >::vertex_iterator
+ vertex2_iterator_type;
+ vertex2_iterator_type graph2_verts_iter, graph2_verts_iter_end;
+
+ typedef vf2_match_continuation< Graph1, Graph2, VertexOrder1 >
+ match_continuation_type;
+ std::vector< match_continuation_type > k;
+ bool found_match = false;
+
+ recur:
+ if (s.success())
+ {
+ if (!s.call_back(user_callback))
+ return true;
+ found_match = true;
+
+ goto back_track;
+ }
+
+ if (!s.valid())
+ goto back_track;
+
+ graph1_verts_iter = vertex_order1.begin();
+ while (graph1_verts_iter != vertex_order1.end()
+ && !s.possible_candidate1(*graph1_verts_iter))
+ {
+ ++graph1_verts_iter;
+ }
+
+ boost::tie(graph2_verts_iter, graph2_verts_iter_end) = vertices(graph2);
+ while (graph2_verts_iter != graph2_verts_iter_end)
+ {
+ if (s.possible_candidate2(*graph2_verts_iter))
+ {
+ if (s.feasible(*graph1_verts_iter, *graph2_verts_iter))
+ {
+ match_continuation_type kk;
+ kk.graph1_verts_iter = graph1_verts_iter;
+ kk.graph2_verts_iter = graph2_verts_iter;
+ k.push_back(kk);
+
+ s.push(*graph1_verts_iter, *graph2_verts_iter);
+ goto recur;
+ }
+ }
+ graph2_loop:
+ ++graph2_verts_iter;
+ }
+
+ back_track:
+ if (k.empty())
+ return found_match;
+
+ const match_continuation_type kk = k.back();
+ graph1_verts_iter = kk.graph1_verts_iter;
+ graph2_verts_iter = kk.graph2_verts_iter;
+ k.pop_back();
+
+ s.pop(*graph1_verts_iter, *graph2_verts_iter);
+
+ goto graph2_loop;
+ }
+
+ // Used to sort nodes by in/out degrees
+ template < typename Graph > struct vertex_in_out_degree_cmp
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_type;
+
+ vertex_in_out_degree_cmp(const Graph& graph) : graph_(graph) {}
+
+ bool operator()(const vertex_type& v, const vertex_type& w) const
+ {
+ // lexicographical comparison
+ return std::make_pair(in_degree(v, graph_), out_degree(v, graph_))
+ < std::make_pair(in_degree(w, graph_), out_degree(w, graph_));
+ }
+
+ const Graph& graph_;
+ };
+
+ // Used to sort nodes by multiplicity of in/out degrees
+ template < typename Graph, typename FrequencyMap >
+ struct vertex_frequency_degree_cmp
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_type;
+
+ vertex_frequency_degree_cmp(const Graph& graph, FrequencyMap freq)
+ : graph_(graph), freq_(freq)
+ {
+ }
+
+ bool operator()(const vertex_type& v, const vertex_type& w) const
+ {
+ // lexicographical comparison
+ return std::make_pair(
+ freq_[v], in_degree(v, graph_) + out_degree(v, graph_))
+ < std::make_pair(
+ freq_[w], in_degree(w, graph_) + out_degree(w, graph_));
+ }
+
+ const Graph& graph_;
+ FrequencyMap freq_;
+ };
+
+ // Sorts vertices of a graph by multiplicity of in/out degrees
+ template < typename Graph, typename IndexMap, typename VertexOrder >
+ void sort_vertices(
+ const Graph& graph, IndexMap index_map, VertexOrder& order)
+ {
+ typedef typename graph_traits< Graph >::vertices_size_type size_type;
+
+ boost::range::sort(order, vertex_in_out_degree_cmp< Graph >(graph));
+
+ std::vector< size_type > freq_vec(num_vertices(graph), 0);
+ typedef iterator_property_map<
+ typename std::vector< size_type >::iterator, IndexMap, size_type,
+ size_type& >
+ frequency_map_type;
+
+ frequency_map_type freq
+ = make_iterator_property_map(freq_vec.begin(), index_map);
+
+ typedef typename VertexOrder::iterator order_iterator;
+
+ for (order_iterator order_iter = order.begin();
+ order_iter != order.end();)
+ {
+ size_type count = 0;
+ for (order_iterator count_iter = order_iter;
+ (count_iter != order.end())
+ && (in_degree(*order_iter, graph)
+ == in_degree(*count_iter, graph))
+ && (out_degree(*order_iter, graph)
+ == out_degree(*count_iter, graph));
+ ++count_iter)
+ ++count;
+
+ for (size_type i = 0; i < count; ++i)
+ {
+ freq[*order_iter] = count;
+ ++order_iter;
+ }
+ }
+
+ boost::range::sort(order,
+ vertex_frequency_degree_cmp< Graph, frequency_map_type >(
+ graph, freq));
+ }
+
+ // Enumerates all graph sub-graph mono-/iso-morphism mappings between graphs
+ // graph_small and graph_large. Continues until user_callback returns true
+ // or the search space has been fully explored.
+ template < problem_selector problem_selection, typename GraphSmall,
+ typename GraphLarge, typename IndexMapSmall, typename IndexMapLarge,
+ typename VertexOrderSmall, typename EdgeEquivalencePredicate,
+ typename VertexEquivalencePredicate, typename SubGraphIsoMapCallback >
+ bool vf2_subgraph_morphism(const GraphSmall& graph_small,
+ const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback,
+ IndexMapSmall index_map_small, IndexMapLarge index_map_large,
+ const VertexOrderSmall& vertex_order_small,
+ EdgeEquivalencePredicate edge_comp,
+ VertexEquivalencePredicate vertex_comp)
+ {
+
+ // Graph requirements
+ BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< GraphSmall >));
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< GraphSmall >));
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< GraphSmall >));
+ BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< GraphSmall >));
+
+ BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< GraphLarge >));
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< GraphLarge >));
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< GraphLarge >));
+ BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< GraphLarge >));
+
+ typedef typename graph_traits< GraphSmall >::vertex_descriptor
+ vertex_small_type;
+ typedef typename graph_traits< GraphLarge >::vertex_descriptor
+ vertex_large_type;
+
+ typedef typename graph_traits< GraphSmall >::vertices_size_type
+ size_type_small;
+ typedef typename graph_traits< GraphLarge >::vertices_size_type
+ size_type_large;
+
+ // Property map requirements
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< IndexMapSmall, vertex_small_type >));
+ typedef typename property_traits< IndexMapSmall >::value_type
+ IndexMapSmallValue;
+ BOOST_STATIC_ASSERT(
+ (is_convertible< IndexMapSmallValue, size_type_small >::value));
+
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< IndexMapLarge, vertex_large_type >));
+ typedef typename property_traits< IndexMapLarge >::value_type
+ IndexMapLargeValue;
+ BOOST_STATIC_ASSERT(
+ (is_convertible< IndexMapLargeValue, size_type_large >::value));
+
+ // Edge & vertex requirements
+ typedef typename graph_traits< GraphSmall >::edge_descriptor
+ edge_small_type;
+ typedef typename graph_traits< GraphLarge >::edge_descriptor
+ edge_large_type;
+
+ BOOST_CONCEPT_ASSERT((BinaryPredicateConcept< EdgeEquivalencePredicate,
+ edge_small_type, edge_large_type >));
+
+ BOOST_CONCEPT_ASSERT(
+ (BinaryPredicateConcept< VertexEquivalencePredicate,
+ vertex_small_type, vertex_large_type >));
+
+ // Vertex order requirements
+ BOOST_CONCEPT_ASSERT((ContainerConcept< VertexOrderSmall >));
+ typedef typename VertexOrderSmall::value_type order_value_type;
+ BOOST_STATIC_ASSERT(
+ (is_same< vertex_small_type, order_value_type >::value));
+ BOOST_ASSERT(num_vertices(graph_small) == vertex_order_small.size());
+
+ if (num_vertices(graph_small) > num_vertices(graph_large))
+ return false;
+
+ typename graph_traits< GraphSmall >::edges_size_type num_edges_small
+ = num_edges(graph_small);
+ typename graph_traits< GraphLarge >::edges_size_type num_edges_large
+ = num_edges(graph_large);
+
+ // Double the number of edges for undirected graphs: each edge counts as
+ // in-edge and out-edge
+ if (is_undirected(graph_small))
+ num_edges_small *= 2;
+ if (is_undirected(graph_large))
+ num_edges_large *= 2;
+ if (num_edges_small > num_edges_large)
+ return false;
+
+ detail::state< GraphSmall, GraphLarge, IndexMapSmall, IndexMapLarge,
+ EdgeEquivalencePredicate, VertexEquivalencePredicate,
+ SubGraphIsoMapCallback, problem_selection >
+ s(graph_small, graph_large, index_map_small, index_map_large,
+ edge_comp, vertex_comp);
+
+ return detail::match(
+ graph_small, graph_large, user_callback, vertex_order_small, s);
+ }
+
+} // namespace detail
+
+// Returns vertex order (vertices sorted by multiplicity of in/out degrees)
+template < typename Graph >
+std::vector< typename graph_traits< Graph >::vertex_descriptor >
+vertex_order_by_mult(const Graph& graph)
+{
+
+ std::vector< typename graph_traits< Graph >::vertex_descriptor >
+ vertex_order;
+ std::copy(vertices(graph).first, vertices(graph).second,
+ std::back_inserter(vertex_order));
+
+ detail::sort_vertices(graph, get(vertex_index, graph), vertex_order);
+ return vertex_order;
+}
+
+// Enumerates all graph sub-graph monomorphism mappings between graphs
+// graph_small and graph_large. Continues until user_callback returns true or
+// the search space has been fully explored.
+template < typename GraphSmall, typename GraphLarge, typename IndexMapSmall,
+ typename IndexMapLarge, typename VertexOrderSmall,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename SubGraphIsoMapCallback >
+bool vf2_subgraph_mono(const GraphSmall& graph_small,
+ const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback,
+ IndexMapSmall index_map_small, IndexMapLarge index_map_large,
+ const VertexOrderSmall& vertex_order_small,
+ EdgeEquivalencePredicate edge_comp, VertexEquivalencePredicate vertex_comp)
+{
+ return detail::vf2_subgraph_morphism< detail::subgraph_mono >(graph_small,
+ graph_large, user_callback, index_map_small, index_map_large,
+ vertex_order_small, edge_comp, vertex_comp);
+}
+
+// All default interface for vf2_subgraph_iso
+template < typename GraphSmall, typename GraphLarge,
+ typename SubGraphIsoMapCallback >
+bool vf2_subgraph_mono(const GraphSmall& graph_small,
+ const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback)
+{
+ return vf2_subgraph_mono(graph_small, graph_large, user_callback,
+ get(vertex_index, graph_small), get(vertex_index, graph_large),
+ vertex_order_by_mult(graph_small), always_equivalent(),
+ always_equivalent());
+}
+
+// Named parameter interface of vf2_subgraph_iso
+template < typename GraphSmall, typename GraphLarge, typename VertexOrderSmall,
+ typename SubGraphIsoMapCallback, typename Param, typename Tag,
+ typename Rest >
+bool vf2_subgraph_mono(const GraphSmall& graph_small,
+ const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback,
+ const VertexOrderSmall& vertex_order_small,
+ const bgl_named_params< Param, Tag, Rest >& params)
+{
+ return vf2_subgraph_mono(graph_small, graph_large, user_callback,
+ choose_const_pmap(
+ get_param(params, vertex_index1), graph_small, vertex_index),
+ choose_const_pmap(
+ get_param(params, vertex_index2), graph_large, vertex_index),
+ vertex_order_small,
+ choose_param(
+ get_param(params, edges_equivalent_t()), always_equivalent()),
+ choose_param(
+ get_param(params, vertices_equivalent_t()), always_equivalent()));
+}
+
+// Enumerates all graph sub-graph isomorphism mappings between graphs
+// graph_small and graph_large. Continues until user_callback returns true or
+// the search space has been fully explored.
+template < typename GraphSmall, typename GraphLarge, typename IndexMapSmall,
+ typename IndexMapLarge, typename VertexOrderSmall,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename SubGraphIsoMapCallback >
+bool vf2_subgraph_iso(const GraphSmall& graph_small,
+ const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback,
+ IndexMapSmall index_map_small, IndexMapLarge index_map_large,
+ const VertexOrderSmall& vertex_order_small,
+ EdgeEquivalencePredicate edge_comp, VertexEquivalencePredicate vertex_comp)
+{
+ return detail::vf2_subgraph_morphism< detail::subgraph_iso >(graph_small,
+ graph_large, user_callback, index_map_small, index_map_large,
+ vertex_order_small, edge_comp, vertex_comp);
+}
+
+// All default interface for vf2_subgraph_iso
+template < typename GraphSmall, typename GraphLarge,
+ typename SubGraphIsoMapCallback >
+bool vf2_subgraph_iso(const GraphSmall& graph_small,
+ const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback)
+{
+
+ return vf2_subgraph_iso(graph_small, graph_large, user_callback,
+ get(vertex_index, graph_small), get(vertex_index, graph_large),
+ vertex_order_by_mult(graph_small), always_equivalent(),
+ always_equivalent());
+}
+
+// Named parameter interface of vf2_subgraph_iso
+template < typename GraphSmall, typename GraphLarge, typename VertexOrderSmall,
+ typename SubGraphIsoMapCallback, typename Param, typename Tag,
+ typename Rest >
+bool vf2_subgraph_iso(const GraphSmall& graph_small,
+ const GraphLarge& graph_large, SubGraphIsoMapCallback user_callback,
+ const VertexOrderSmall& vertex_order_small,
+ const bgl_named_params< Param, Tag, Rest >& params)
+{
+
+ return vf2_subgraph_iso(graph_small, graph_large, user_callback,
+ choose_const_pmap(
+ get_param(params, vertex_index1), graph_small, vertex_index),
+ choose_const_pmap(
+ get_param(params, vertex_index2), graph_large, vertex_index),
+ vertex_order_small,
+ choose_param(
+ get_param(params, edges_equivalent_t()), always_equivalent()),
+ choose_param(
+ get_param(params, vertices_equivalent_t()), always_equivalent()));
+}
+
+// Enumerates all isomorphism mappings between graphs graph1_ and graph2_.
+// Continues until user_callback returns true or the search space has been
+// fully explored.
+template < typename Graph1, typename Graph2, typename IndexMap1,
+ typename IndexMap2, typename VertexOrder1,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate,
+ typename GraphIsoMapCallback >
+bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2,
+ GraphIsoMapCallback user_callback, IndexMap1 index_map1,
+ IndexMap2 index_map2, const VertexOrder1& vertex_order1,
+ EdgeEquivalencePredicate edge_comp, VertexEquivalencePredicate vertex_comp)
+{
+
+ // Graph requirements
+ BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph1 >));
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph1 >));
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph1 >));
+ BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph1 >));
+
+ BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph2 >));
+ BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph2 >));
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph2 >));
+ BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph2 >));
+
+ typedef typename graph_traits< Graph1 >::vertex_descriptor vertex1_type;
+ typedef typename graph_traits< Graph2 >::vertex_descriptor vertex2_type;
+
+ typedef typename graph_traits< Graph1 >::vertices_size_type size_type1;
+ typedef typename graph_traits< Graph2 >::vertices_size_type size_type2;
+
+ // Property map requirements
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< IndexMap1, vertex1_type >));
+ typedef typename property_traits< IndexMap1 >::value_type IndexMap1Value;
+ BOOST_STATIC_ASSERT((is_convertible< IndexMap1Value, size_type1 >::value));
+
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< IndexMap2, vertex2_type >));
+ typedef typename property_traits< IndexMap2 >::value_type IndexMap2Value;
+ BOOST_STATIC_ASSERT((is_convertible< IndexMap2Value, size_type2 >::value));
+
+ // Edge & vertex requirements
+ typedef typename graph_traits< Graph1 >::edge_descriptor edge1_type;
+ typedef typename graph_traits< Graph2 >::edge_descriptor edge2_type;
+
+ BOOST_CONCEPT_ASSERT((BinaryPredicateConcept< EdgeEquivalencePredicate,
+ edge1_type, edge2_type >));
+
+ BOOST_CONCEPT_ASSERT((BinaryPredicateConcept< VertexEquivalencePredicate,
+ vertex1_type, vertex2_type >));
+
+ // Vertex order requirements
+ BOOST_CONCEPT_ASSERT((ContainerConcept< VertexOrder1 >));
+ typedef typename VertexOrder1::value_type order_value_type;
+ BOOST_STATIC_ASSERT((is_same< vertex1_type, order_value_type >::value));
+ BOOST_ASSERT(num_vertices(graph1) == vertex_order1.size());
+
+ if (num_vertices(graph1) != num_vertices(graph2))
+ return false;
+
+ typename graph_traits< Graph1 >::edges_size_type num_edges1
+ = num_edges(graph1);
+ typename graph_traits< Graph2 >::edges_size_type num_edges2
+ = num_edges(graph2);
+
+ // Double the number of edges for undirected graphs: each edge counts as
+ // in-edge and out-edge
+ if (is_undirected(graph1))
+ num_edges1 *= 2;
+ if (is_undirected(graph2))
+ num_edges2 *= 2;
+ if (num_edges1 != num_edges2)
+ return false;
+
+ detail::state< Graph1, Graph2, IndexMap1, IndexMap2,
+ EdgeEquivalencePredicate, VertexEquivalencePredicate,
+ GraphIsoMapCallback, detail::isomorphism >
+ s(graph1, graph2, index_map1, index_map2, edge_comp, vertex_comp);
+
+ return detail::match(graph1, graph2, user_callback, vertex_order1, s);
+}
+
+// All default interface for vf2_graph_iso
+template < typename Graph1, typename Graph2, typename GraphIsoMapCallback >
+bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2,
+ GraphIsoMapCallback user_callback)
+{
+
+ return vf2_graph_iso(graph1, graph2, user_callback,
+ get(vertex_index, graph1), get(vertex_index, graph2),
+ vertex_order_by_mult(graph1), always_equivalent(), always_equivalent());
+}
+
+// Named parameter interface of vf2_graph_iso
+template < typename Graph1, typename Graph2, typename VertexOrder1,
+ typename GraphIsoMapCallback, typename Param, typename Tag, typename Rest >
+bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2,
+ GraphIsoMapCallback user_callback, const VertexOrder1& vertex_order1,
+ const bgl_named_params< Param, Tag, Rest >& params)
+{
+
+ return vf2_graph_iso(graph1, graph2, user_callback,
+ choose_const_pmap(
+ get_param(params, vertex_index1), graph1, vertex_index),
+ choose_const_pmap(
+ get_param(params, vertex_index2), graph2, vertex_index),
+ vertex_order1,
+ choose_param(
+ get_param(params, edges_equivalent_t()), always_equivalent()),
+ choose_param(
+ get_param(params, vertices_equivalent_t()), always_equivalent()));
+}
+
+// Verifies a graph (sub)graph isomorphism map
+template < typename Graph1, typename Graph2, typename CorresponenceMap1To2,
+ typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate >
+inline bool verify_vf2_subgraph_iso(const Graph1& graph1, const Graph2& graph2,
+ const CorresponenceMap1To2 f, EdgeEquivalencePredicate edge_comp,
+ VertexEquivalencePredicate vertex_comp)
+{
+
+ BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph1 >));
+ BOOST_CONCEPT_ASSERT((AdjacencyMatrixConcept< Graph2 >));
+
+ detail::equivalent_edge_exists< Graph2 > edge2_exists;
+
+ BGL_FORALL_EDGES_T(e1, graph1, Graph1)
+ {
+ typename graph_traits< Graph1 >::vertex_descriptor s1, t1;
+ typename graph_traits< Graph2 >::vertex_descriptor s2, t2;
+
+ s1 = source(e1, graph1);
+ t1 = target(e1, graph1);
+ s2 = get(f, s1);
+ t2 = get(f, t1);
+
+ if (!vertex_comp(s1, s2) || !vertex_comp(t1, t2))
+ return false;
+
+ typename graph_traits< Graph2 >::edge_descriptor e2;
+
+ if (!edge2_exists(s2, t2,
+ detail::edge2_predicate< Graph1, Graph2,
+ EdgeEquivalencePredicate >(edge_comp, e1),
+ graph2))
+ return false;
+ }
+
+ return true;
+}
+
+// Variant of verify_subgraph_iso with all default parameters
+template < typename Graph1, typename Graph2, typename CorresponenceMap1To2 >
+inline bool verify_vf2_subgraph_iso(
+ const Graph1& graph1, const Graph2& graph2, const CorresponenceMap1To2 f)
+{
+ return verify_vf2_subgraph_iso(
+ graph1, graph2, f, always_equivalent(), always_equivalent());
+}
+
+} // namespace boost
+
+#ifdef BOOST_ISO_INCLUDED_ITER_MACROS
+#undef BOOST_ISO_INCLUDED_ITER_MACROS
+#include <boost/graph/iteration_macros_undef.hpp>
+#endif
+
+#endif // BOOST_VF2_SUB_GRAPH_ISO_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/wavefront.hpp b/contrib/restricted/boost/graph/include/boost/graph/wavefront.hpp
new file mode 100644
index 0000000000..aec2853671
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/wavefront.hpp
@@ -0,0 +1,125 @@
+//
+//=======================================================================
+// Copyright 2002 Marc Wintermantel (wintermantel@even-ag.ch)
+// ETH Zurich, Center of Structure Technologies
+// (https://web.archive.org/web/20050307090307/http://www.structures.ethz.ch/)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+
+#ifndef BOOST_GRAPH_WAVEFRONT_HPP
+#define BOOST_GRAPH_WAVEFRONT_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/detail/numeric_traits.hpp>
+#include <boost/graph/bandwidth.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <vector>
+#include <algorithm> // for std::min and std::max
+
+namespace boost
+{
+
+template < typename Graph, typename VertexIndexMap >
+typename graph_traits< Graph >::vertices_size_type ith_wavefront(
+ typename graph_traits< Graph >::vertex_descriptor i, const Graph& g,
+ VertexIndexMap index)
+{
+ typename graph_traits< Graph >::vertex_descriptor v, w;
+ typename graph_traits< Graph >::vertices_size_type b = 1;
+ typename graph_traits< Graph >::out_edge_iterator edge_it2, edge_it2_end;
+ typename graph_traits< Graph >::vertices_size_type index_i = index[i];
+ std::vector< bool > rows_active(num_vertices(g), false);
+
+ rows_active[index_i] = true;
+
+ typename graph_traits< Graph >::vertex_iterator ui, ui_end;
+ for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ v = *ui;
+ if (index[v] <= index_i)
+ {
+ for (boost::tie(edge_it2, edge_it2_end) = out_edges(v, g);
+ edge_it2 != edge_it2_end; ++edge_it2)
+ {
+ w = target(*edge_it2, g);
+ if ((index[w] >= index_i) && (!rows_active[index[w]]))
+ {
+ b++;
+ rows_active[index[w]] = true;
+ }
+ }
+ }
+ }
+
+ return b;
+}
+
+template < typename Graph >
+typename graph_traits< Graph >::vertices_size_type ith_wavefront(
+ typename graph_traits< Graph >::vertex_descriptor i, const Graph& g)
+{
+ return ith_wavefront(i, g, get(vertex_index, g));
+}
+
+template < typename Graph, typename VertexIndexMap >
+typename graph_traits< Graph >::vertices_size_type max_wavefront(
+ const Graph& g, VertexIndexMap index)
+{
+ BOOST_USING_STD_MAX();
+ typename graph_traits< Graph >::vertices_size_type b = 0;
+ typename graph_traits< Graph >::vertex_iterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ b = max BOOST_PREVENT_MACRO_SUBSTITUTION(
+ b, ith_wavefront(*i, g, index));
+ return b;
+}
+
+template < typename Graph >
+typename graph_traits< Graph >::vertices_size_type max_wavefront(const Graph& g)
+{
+ return max_wavefront(g, get(vertex_index, g));
+}
+
+template < typename Graph, typename VertexIndexMap >
+double aver_wavefront(const Graph& g, VertexIndexMap index)
+{
+ double b = 0;
+ typename graph_traits< Graph >::vertex_iterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ b += ith_wavefront(*i, g, index);
+
+ b /= num_vertices(g);
+ return b;
+}
+
+template < typename Graph > double aver_wavefront(const Graph& g)
+{
+ return aver_wavefront(g, get(vertex_index, g));
+}
+
+template < typename Graph, typename VertexIndexMap >
+double rms_wavefront(const Graph& g, VertexIndexMap index)
+{
+ double b = 0;
+ typename graph_traits< Graph >::vertex_iterator i, end;
+ for (boost::tie(i, end) = vertices(g); i != end; ++i)
+ b += std::pow(double(ith_wavefront(*i, g, index)), 2.0);
+
+ b /= num_vertices(g);
+
+ return std::sqrt(b);
+}
+
+template < typename Graph > double rms_wavefront(const Graph& g)
+{
+ return rms_wavefront(g, get(vertex_index, g));
+}
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_WAVEFRONT_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/graph/write_dimacs.hpp b/contrib/restricted/boost/graph/include/boost/graph/write_dimacs.hpp
new file mode 100644
index 0000000000..36ab7f81e4
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/graph/write_dimacs.hpp
@@ -0,0 +1,75 @@
+// Copyright (c) 2006, Stephan Diederich
+//
+// This code may be used under either of the following two licences:
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE.
+//
+// Or:
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Writes maximal flow problem in extended DIMACS format to an OutputIterator
+ Vertex indices are read from an IndexMap and shiftet by 1.
+ so their new range is [1..num_vertices(g)]
+*/
+
+/* ----------------------------------------------------------------- */
+
+#include <vector>
+#include <string>
+#include <ostream>
+
+#include <boost/graph/graph_traits.hpp>
+
+namespace boost
+{
+
+template < class Graph, class CapacityMap, class IndexMap >
+void write_dimacs_max_flow(const Graph& g, CapacityMap capacity, IndexMap idx,
+ typename graph_traits< Graph >::vertex_descriptor src,
+ typename graph_traits< Graph >::vertex_descriptor sink, std::ostream& out)
+{
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator;
+
+ out << "c DIMACS max-flow file generated from boost::write_dimacs_max_flow"
+ << std::endl;
+ out << "p max " << num_vertices(g) << " " << num_edges(g)
+ << std::endl; // print problem description "max" and number of verts and
+ // edges
+ out << "n " << get(idx, src) + 1 << " s" << std::endl;
+ ; // say which one is source
+ out << "n " << get(idx, sink) + 1 << " t"
+ << std::endl; // say which one is sink
+
+ // output the edges
+ edge_iterator ei, e_end;
+ for (boost::tie(ei, e_end) = edges(g); ei != e_end; ++ei)
+ {
+ out << "a " << idx[source(*ei, g)] + 1 << " " << idx[target(*ei, g)] + 1
+ << " " << get(capacity, *ei) << std::endl;
+ }
+}
+
+} // namespace boost
diff --git a/contrib/restricted/boost/graph/include/boost/pending/bucket_sorter.hpp b/contrib/restricted/boost/graph/include/boost/pending/bucket_sorter.hpp
new file mode 100644
index 0000000000..e39133d435
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/pending/bucket_sorter.hpp
@@ -0,0 +1,158 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+//
+// Revision History:
+// 13 June 2001: Changed some names for clarity. (Jeremy Siek)
+// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
+//
+#ifndef BOOST_GRAPH_DETAIL_BUCKET_SORTER_HPP
+#define BOOST_GRAPH_DETAIL_BUCKET_SORTER_HPP
+
+#include <vector>
+#include <cassert>
+#include <boost/limits.hpp>
+#include <boost/concept/assert.hpp>
+#include <boost/property_map/property_map.hpp>
+
+namespace boost
+{
+
+template < class BucketType, class ValueType, class Bucket,
+ class ValueIndexMap >
+class bucket_sorter
+{
+ BOOST_CONCEPT_ASSERT(
+ (ReadablePropertyMapConcept< ValueIndexMap, ValueType >));
+
+public:
+ typedef BucketType bucket_type;
+ typedef ValueType value_type;
+ typedef typename std::vector< value_type >::size_type size_type;
+
+ bucket_sorter(size_type _length, bucket_type _max_bucket,
+ const Bucket& _bucket = Bucket(),
+ const ValueIndexMap& _id = ValueIndexMap())
+ : head(_max_bucket, invalid_value())
+ , next(_length, invalid_value())
+ , prev(_length, invalid_value())
+ , id_to_value(_length)
+ , bucket(_bucket)
+ , id(_id)
+ {
+ }
+
+ void remove(const value_type& x)
+ {
+ const size_type i = get(id, x);
+ const size_type& next_node = next[i];
+ const size_type& prev_node = prev[i];
+
+ // check if i is the end of the bucket list
+ if (next_node != invalid_value())
+ prev[next_node] = prev_node;
+ // check if i is the begin of the bucket list
+ if (prev_node != invalid_value())
+ next[prev_node] = next_node;
+ else // need update head of current bucket list
+ head[bucket[x]] = next_node;
+ }
+
+ void push(const value_type& x)
+ {
+ id_to_value[get(id, x)] = x;
+ (*this)[bucket[x]].push(x);
+ }
+
+ void update(const value_type& x)
+ {
+ remove(x);
+ (*this)[bucket[x]].push(x);
+ }
+ // private:
+ // with KCC, the nested stack class is having access problems
+ // despite the friend decl.
+ static size_type invalid_value()
+ {
+ return (std::numeric_limits< size_type >::max)();
+ }
+
+ typedef typename std::vector< size_type >::iterator Iter;
+ typedef typename std::vector< value_type >::iterator IndexValueMap;
+
+public:
+ friend class stack;
+
+ class stack
+ {
+ public:
+ stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v,
+ const ValueIndexMap& _id)
+ : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v), id(_id)
+ {
+ }
+
+ // Avoid using default arg for ValueIndexMap so that the default
+ // constructor of the ValueIndexMap is not required if not used.
+ stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v)
+ : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v)
+ {
+ }
+
+ void push(const value_type& x)
+ {
+ const size_type new_head = get(id, x);
+ const size_type current = head[bucket_id];
+ if (current != invalid_value())
+ prev[current] = new_head;
+ prev[new_head] = invalid_value();
+ next[new_head] = current;
+ head[bucket_id] = new_head;
+ }
+ void pop()
+ {
+ size_type current = head[bucket_id];
+ size_type next_node = next[current];
+ head[bucket_id] = next_node;
+ if (next_node != invalid_value())
+ prev[next_node] = invalid_value();
+ }
+ value_type& top() { return value[head[bucket_id]]; }
+ const value_type& top() const { return value[head[bucket_id]]; }
+ bool empty() const { return head[bucket_id] == invalid_value(); }
+
+ private:
+ bucket_type bucket_id;
+ Iter head;
+ Iter next;
+ Iter prev;
+ IndexValueMap value;
+ ValueIndexMap id;
+ };
+
+ stack operator[](const bucket_type& i)
+ {
+ assert(i < head.size());
+ return stack(i, head.begin(), next.begin(), prev.begin(),
+ id_to_value.begin(), id);
+ }
+
+protected:
+ std::vector< size_type > head;
+ std::vector< size_type > next;
+ std::vector< size_type > prev;
+ std::vector< value_type > id_to_value;
+ Bucket bucket;
+ ValueIndexMap id;
+};
+
+}
+
+#endif
diff --git a/contrib/restricted/boost/graph/include/boost/pending/detail/disjoint_sets.hpp b/contrib/restricted/boost/graph/include/boost/pending/detail/disjoint_sets.hpp
new file mode 100644
index 0000000000..9a91b294b4
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/pending/detail/disjoint_sets.hpp
@@ -0,0 +1,93 @@
+// (C) Copyright Jeremy Siek 2004
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DETAIL_DISJOINT_SETS_HPP
+#define BOOST_DETAIL_DISJOINT_SETS_HPP
+
+#include <cassert>
+
+namespace boost
+{
+
+namespace detail
+{
+
+ template < class ParentPA, class Vertex >
+ Vertex find_representative_with_path_halving(ParentPA p, Vertex v)
+ {
+ Vertex parent = get(p, v);
+ Vertex grandparent = get(p, parent);
+ while (parent != grandparent)
+ {
+ put(p, v, grandparent);
+ v = grandparent;
+ parent = get(p, v);
+ grandparent = get(p, parent);
+ }
+ return parent;
+ }
+
+ template < class ParentPA, class Vertex >
+ Vertex find_representative_with_full_compression(ParentPA parent, Vertex v)
+ {
+ Vertex old = v;
+ Vertex ancestor = get(parent, v);
+ while (ancestor != v)
+ {
+ v = ancestor;
+ ancestor = get(parent, v);
+ }
+ v = get(parent, old);
+ while (ancestor != v)
+ {
+ put(parent, old, ancestor);
+ old = v;
+ v = get(parent, old);
+ }
+ return ancestor;
+ }
+
+ /* the postcondition of link sets is:
+ component_representative(i) == component_representative(j)
+ */
+ template < class ParentPA, class RankPA, class Vertex>
+ inline void link_sets(ParentPA p, RankPA rank, Vertex i, Vertex j)
+ {
+ assert(i == get(p, i));
+ assert(j == get(p, j));
+ if (i == j)
+ return;
+ if (get(rank, i) > get(rank, j))
+ put(p, j, i);
+ else
+ {
+ put(p, i, j);
+ if (get(rank, i) == get(rank, j))
+ put(rank, j, get(rank, j) + 1);
+ }
+ }
+
+ // normalize components has the following postcondidition:
+ // i >= p[i]
+ // that is, the representative is the node with the smallest index in its
+ // class as its precondition it it assumes that the node container is
+ // compressed
+
+ template < class ParentPA, class Vertex >
+ inline void normalize_node(ParentPA p, Vertex i)
+ {
+ if (i > get(p, i) || get(p, get(p, i)) != get(p, i))
+ put(p, i, get(p, get(p, i)));
+ else
+ {
+ put(p, get(p, i), i);
+ put(p, i, i);
+ }
+ }
+
+} // namespace detail
+} // namespace boost
+
+#endif // BOOST_DETAIL_DISJOINT_SETS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/pending/disjoint_sets.hpp b/contrib/restricted/boost/graph/include/boost/pending/disjoint_sets.hpp
new file mode 100644
index 0000000000..28bf3c3c3b
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/pending/disjoint_sets.hpp
@@ -0,0 +1,211 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+#ifndef BOOST_DISJOINT_SETS_HPP
+#define BOOST_DISJOINT_SETS_HPP
+
+#include <vector>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/detail/disjoint_sets.hpp>
+
+namespace boost
+{
+
+struct find_with_path_halving
+{
+ template < class ParentPA, class Vertex >
+ Vertex operator()(ParentPA p, Vertex v)
+ {
+ return detail::find_representative_with_path_halving(p, v);
+ }
+};
+
+struct find_with_full_path_compression
+{
+ template < class ParentPA, class Vertex >
+ Vertex operator()(ParentPA p, Vertex v)
+ {
+ return detail::find_representative_with_full_compression(p, v);
+ }
+};
+
+// This is a generalized functor to provide disjoint sets operations
+// with "union by rank" and "path compression". A disjoint-set data
+// structure maintains a collection S={S1, S2, ..., Sk} of disjoint
+// sets. Each set is identified by a representative, which is some
+// member of of the set. Sets are represented by rooted trees. Two
+// heuristics: "union by rank" and "path compression" are used to
+// speed up the operations.
+
+// Disjoint Set requires two vertex properties for internal use. A
+// RankPA and a ParentPA. The RankPA must map Vertex to some Integral type
+// (preferably the size_type associated with Vertex). The ParentPA
+// must map Vertex to Vertex.
+template < class RankPA, class ParentPA,
+ class FindCompress = find_with_full_path_compression >
+class disjoint_sets
+{
+ typedef disjoint_sets self;
+
+ inline disjoint_sets() {}
+
+public:
+ inline disjoint_sets(RankPA r, ParentPA p) : rank(r), parent(p) {}
+
+ inline disjoint_sets(const self& c) : rank(c.rank), parent(c.parent) {}
+
+ // Make Set -- Create a singleton set containing vertex x
+ template < class Element > inline void make_set(Element x)
+ {
+ put(parent, x, x);
+ typedef typename property_traits< RankPA >::value_type R;
+ put(rank, x, R());
+ }
+
+ // Link - union the two sets represented by vertex x and y
+ template < class Element > inline void link(Element x, Element y)
+ {
+ detail::link_sets(parent, rank, x, y);
+ }
+
+ // Union-Set - union the two sets containing vertex x and y
+ template < class Element > inline void union_set(Element x, Element y)
+ {
+ link(find_set(x), find_set(y));
+ }
+
+ // Find-Set - returns the Element representative of the set
+ // containing Element x and applies path compression.
+ template < class Element > inline Element find_set(Element x)
+ {
+ return rep(parent, x);
+ }
+
+ template < class ElementIterator >
+ inline std::size_t count_sets(ElementIterator first, ElementIterator last)
+ {
+ std::size_t count = 0;
+ for (; first != last; ++first)
+ if (get(parent, *first) == *first)
+ ++count;
+ return count;
+ }
+
+ template < class ElementIterator >
+ inline void normalize_sets(ElementIterator first, ElementIterator last)
+ {
+ for (; first != last; ++first)
+ detail::normalize_node(parent, *first);
+ }
+
+ template < class ElementIterator >
+ inline void compress_sets(ElementIterator first, ElementIterator last)
+ {
+ for (; first != last; ++first)
+ detail::find_representative_with_full_compression(parent, *first);
+ }
+
+protected:
+ RankPA rank;
+ ParentPA parent;
+ FindCompress rep;
+};
+
+template < class ID = identity_property_map,
+ class InverseID = identity_property_map,
+ class FindCompress = find_with_full_path_compression >
+class disjoint_sets_with_storage
+{
+ typedef typename property_traits< ID >::value_type Index;
+ typedef std::vector< Index > ParentContainer;
+ typedef std::vector< unsigned char > RankContainer;
+
+public:
+ typedef typename ParentContainer::size_type size_type;
+
+ disjoint_sets_with_storage(
+ size_type n = 0, ID id_ = ID(), InverseID inv = InverseID())
+ : id(id_), id_to_vertex(inv), rank(n, 0), parent(n)
+ {
+ for (Index i = 0; i < n; ++i)
+ parent[i] = i;
+ }
+ // note this is not normally needed
+ template < class Element > inline void make_set(Element x)
+ {
+ parent[x] = x;
+ rank[x] = 0;
+ }
+ template < class Element > inline void link(Element x, Element y)
+ {
+ extend_sets(x, y);
+ detail::link_sets(&parent[0], &rank[0], get(id, x), get(id, y));
+ }
+ template < class Element > inline void union_set(Element x, Element y)
+ {
+ Element rx = find_set(x);
+ Element ry = find_set(y);
+ link(rx, ry);
+ }
+ template < class Element > inline Element find_set(Element x)
+ {
+ return id_to_vertex[rep(&parent[0], get(id, x))];
+ }
+
+ template < class ElementIterator >
+ inline std::size_t count_sets(ElementIterator first, ElementIterator last)
+ {
+ std::size_t count = 0;
+ for (; first != last; ++first)
+ if (parent[*first] == *first)
+ ++count;
+ return count;
+ }
+
+ template < class ElementIterator >
+ inline void normalize_sets(ElementIterator first, ElementIterator last)
+ {
+ for (; first != last; ++first)
+ detail::normalize_node(&parent[0], *first);
+ }
+
+ template < class ElementIterator >
+ inline void compress_sets(ElementIterator first, ElementIterator last)
+ {
+ for (; first != last; ++first)
+ detail::find_representative_with_full_compression(
+ &parent[0], *first);
+ }
+
+ const ParentContainer& parents() { return parent; }
+
+protected:
+ template < class Element > inline void extend_sets(Element x, Element y)
+ {
+ Index needed
+ = get(id, x) > get(id, y) ? get(id, x) + 1 : get(id, y) + 1;
+ if (needed > parent.size())
+ {
+ rank.insert(rank.end(), needed - rank.size(), 0);
+ for (Index k = parent.size(); k < needed; ++k)
+ parent.push_back(k);
+ }
+ }
+
+ ID id;
+ InverseID id_to_vertex;
+ RankContainer rank;
+ ParentContainer parent;
+ FindCompress rep;
+};
+
+} // namespace boost
+
+#endif // BOOST_DISJOINT_SETS_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/pending/fenced_priority_queue.hpp b/contrib/restricted/boost/graph/include/boost/pending/fenced_priority_queue.hpp
new file mode 100644
index 0000000000..64d18692b9
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/pending/fenced_priority_queue.hpp
@@ -0,0 +1,160 @@
+// (C) Copyright Jeremiah Willcock 2004
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FENCED_PRIORITY_QUEUE_HPP
+#define BOOST_FENCED_PRIORITY_QUEUE_HPP
+
+#include <vector>
+#include <queue>
+#include <functional>
+#include <boost/pending/queue.hpp>
+
+// Fenced priority queue
+// Jeremiah Willcock
+
+// This class implements a fenced priority queue. This is similar to
+// a normal priority queue (sorts its members, and only returns the
+// first), except that members cannot be sorted around a "fence" that
+// can be placed into the buffer. This fence is inserted using the
+// fence() member function or (possibly) implicitly by the top() and
+// pop() methods, and is removed automatically when the elements
+// around it are popped.
+
+// The implementation is as follows: Q is an unsorted queue that
+// contains the already-sorted list data, and PQ is a priority queue
+// that contains new elements (since the last fence) that have yet to
+// be sorted. New elements are inserted into PQ, and a fence moves
+// all elements in PQ into the back of Q in sorted order. Elements
+// are then popped from the front of Q, and if that is empty the front
+// of PQ.
+
+namespace boost
+{
+
+template < class T, class Compare = std::less< T >, bool implicit_fence = true,
+ class Buffer = boost::queue< T > >
+class fenced_priority_queue
+{
+public:
+ typedef T value_type;
+ typedef typename Buffer::size_type size_type;
+
+ fenced_priority_queue(const Compare _comp = Compare()) : PQ(_comp) {}
+
+ void push(const T& data);
+ void pop(void);
+ T& top(void);
+ const T& top(void) const;
+ size_type size(void) const;
+ bool empty(void) const;
+ void fence(void);
+
+private:
+ void fence(void) const;
+
+ // let them mutable to allow const version of top and the same
+ // semantics with non-constant version. Rich Lee
+ mutable std::priority_queue< T, std::vector< T >, Compare > PQ;
+ mutable Buffer Q;
+};
+
+template < class T, class Compare, bool implicit_fence, class Buffer >
+inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::push(
+ const T& t)
+{
+ // Push a new element after the last fence. This puts it into the
+ // priority queue to be sorted with all other elements in its
+ // partition.
+ PQ.push(t);
+}
+
+template < class T, class Compare, bool implicit_fence, class Buffer >
+inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::pop(
+ void)
+{
+ // Pop one element from the front of the queue. Removes from the
+ // already-sorted part of the queue if it is non-empty, otherwise
+ // removes from the new-element priority queue. Runs an implicit
+ // "fence" operation if the implicit_fence template argument is
+ // true.
+ if (implicit_fence)
+ fence();
+ if (!Q.empty())
+ Q.pop();
+ else
+ PQ.pop();
+}
+
+template < class T, class Compare, bool implicit_fence, class Buffer >
+inline T& fenced_priority_queue< T, Compare, implicit_fence, Buffer >::top(void)
+{
+ // Get the top element from the queue. This element comes from Q if
+ // possible, otherwise from PQ. Causes an implicit "fence"
+ // operation if the implicit_fence template argument is true.
+ if (implicit_fence)
+ fence();
+ if (!Q.empty())
+ return Q.top();
+ else
+ // std::priority_queue only have const version of top. Rich Lee
+ return const_cast< T& >(PQ.top());
+}
+
+template < class T, class Compare, bool implicit_fence, class Buffer >
+inline const T&
+fenced_priority_queue< T, Compare, implicit_fence, Buffer >::top(void) const
+{
+ if (implicit_fence)
+ fence();
+ if (!Q.empty())
+ return Q.top();
+ else
+ return PQ.top();
+}
+
+template < class T, class Compare, bool implicit_fence, class Buffer >
+inline typename fenced_priority_queue< T, Compare, implicit_fence,
+ Buffer >::size_type
+fenced_priority_queue< T, Compare, implicit_fence, Buffer >::size(void) const
+{
+ // Returns the size of the queue (both parts together).
+ return Q.size() + PQ.size();
+}
+
+template < class T, class Compare, bool implicit_fence, class Buffer >
+inline bool fenced_priority_queue< T, Compare, implicit_fence, Buffer >::empty(
+ void) const
+{
+ // Returns if the queue is empty, i.e. both parts are empty.
+ return Q.empty() && PQ.empty();
+}
+
+template < class T, class Compare, bool implicit_fence, class Buffer >
+inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::fence(
+ void)
+{
+ // Perform a fence operation. Remove elements from PQ in sorted
+ // order and insert them in the back of Q.
+ while (!PQ.empty())
+ {
+ Q.push(PQ.top());
+ PQ.pop();
+ }
+}
+template < class T, class Compare, bool implicit_fence, class Buffer >
+inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::fence(
+ void) const
+{
+ // Perform a fence operation. Remove elements from PQ in sorted
+ // order and insert them in the back of Q.
+ while (!PQ.empty())
+ {
+ Q.push(PQ.top());
+ PQ.pop();
+ }
+}
+
+}
+#endif /* BOOST_FENCED_PRIORITY_QUEUE_HPP */
diff --git a/contrib/restricted/boost/graph/include/boost/pending/fibonacci_heap.hpp b/contrib/restricted/boost/graph/include/boost/pending/fibonacci_heap.hpp
new file mode 100644
index 0000000000..3be462369e
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/pending/fibonacci_heap.hpp
@@ -0,0 +1,320 @@
+// (C) Copyright Jeremy Siek 2004.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_FIBONACCI_HEAP_HPP
+#define BOOST_FIBONACCI_HEAP_HPP
+
+#if defined(__sgi) && !defined(__GNUC__)
+#include <math.h>
+#else
+#include <boost/config/no_tr1/cmath.hpp>
+#endif
+#include <iosfwd>
+#include <vector>
+#include <functional>
+#include <boost/config.hpp>
+#include <boost/property_map/property_map.hpp>
+
+//
+// An adaptation of Knuth's Fibonacci heap implementation
+// in "The Stanford Graph Base", pages 475-482.
+//
+
+namespace boost
+{
+
+template < class T, class Compare = std::less< T >,
+ class ID = identity_property_map >
+class fibonacci_heap
+{
+ typedef typename boost::property_traits< ID >::value_type size_type;
+ typedef T value_type;
+
+protected:
+ typedef fibonacci_heap self;
+ typedef std::vector< size_type > LinkVec;
+ typedef typename LinkVec::iterator LinkIter;
+
+public:
+ fibonacci_heap(
+ size_type n, const Compare& cmp, const ID& id = identity_property_map())
+ : _key(n)
+ , _left(n)
+ , _right(n)
+ , _p(n)
+ , _mark(n)
+ , _degree(n)
+ , _n(0)
+ , _root(n)
+ , _id(id)
+ , _compare(cmp)
+ , _child(n)
+ ,
+#if defined(BOOST_MSVC) || defined(__ICL) // need a new macro?
+ new_roots(size_type(log(float(n))) + 5)
+ {
+ }
+#else
+ new_roots(size_type(std::log(float(n))) + 5)
+ {
+ }
+#endif
+
+ // 33
+ void push(const T& d)
+ {
+ ++_n;
+ size_type v = get(_id, d);
+ _key[v] = d;
+ _p[v] = nil();
+ _degree[v] = 0;
+ _mark[v] = false;
+ _child[v] = nil();
+ if (_root == nil())
+ {
+ _root = _left[v] = _right[v] = v;
+ // std::cout << "root added" << std::endl;
+ }
+ else
+ {
+ size_type u = _left[_root];
+ _left[v] = u;
+ _right[v] = _root;
+ _left[_root] = _right[u] = v;
+ if (_compare(d, _key[_root]))
+ _root = v;
+ // std::cout << "non-root node added" << std::endl;
+ }
+ }
+ T& top() { return _key[_root]; }
+ const T& top() const { return _key[_root]; }
+
+ // 38
+ void pop()
+ {
+ --_n;
+ int h = -1;
+ size_type v, w;
+ if (_root != nil())
+ {
+ if (_degree[_root] == 0)
+ {
+ v = _right[_root];
+ }
+ else
+ {
+ w = _child[_root];
+ v = _right[w];
+ _right[w] = _right[_root];
+ for (w = v; w != _right[_root]; w = _right[w])
+ _p[w] = nil();
+ }
+ while (v != _root)
+ {
+ w = _right[v];
+ add_tree_to_new_roots(v, new_roots.begin(), h);
+ v = w;
+ }
+ rebuild_root_list(new_roots.begin(), h);
+ }
+ }
+ // 39
+ inline void add_tree_to_new_roots(size_type v, LinkIter new_roots, int& h)
+ {
+ int r;
+ size_type u;
+ r = _degree[v];
+ while (1)
+ {
+ if (h < r)
+ {
+ do
+ {
+ ++h;
+ new_roots[h] = (h == r ? v : nil());
+ } while (h < r);
+ break;
+ }
+ if (new_roots[r] == nil())
+ {
+ new_roots[r] = v;
+ break;
+ }
+ u = new_roots[r];
+ new_roots[r] = nil();
+ if (_compare(_key[u], _key[v]))
+ {
+ _degree[v] = r;
+ _mark[v] = false;
+ std::swap(u, v);
+ }
+ make_child(u, v, r);
+ ++r;
+ }
+ _degree[v] = r;
+ _mark[v] = false;
+ }
+ // 40
+ void make_child(size_type u, size_type v, size_type r)
+ {
+ if (r == 0)
+ {
+ _child[v] = u;
+ _left[u] = u;
+ _right[u] = u;
+ }
+ else
+ {
+ size_type t = _child[v];
+ _right[u] = _right[t];
+ _left[u] = t;
+ _right[t] = u;
+ _left[_right[u]] = u;
+ }
+ _p[u] = v;
+ }
+ // 41
+ inline void rebuild_root_list(LinkIter new_roots, int& h)
+ {
+ size_type u, v, w;
+ if (h < 0)
+ _root = nil();
+ else
+ {
+ T d;
+ u = v = new_roots[h];
+ d = _key[u];
+ _root = u;
+ for (h--; h >= 0; --h)
+ if (new_roots[h] != nil())
+ {
+ w = new_roots[h];
+ _left[w] = v;
+ _right[v] = w;
+ if (_compare(_key[w], d))
+ {
+ _root = w;
+ d = _key[w];
+ }
+ v = w;
+ }
+ _right[v] = u;
+ _left[u] = v;
+ }
+ }
+
+ // 34
+ void update(const T& d)
+ {
+ size_type v = get(_id, d);
+ assert(!_compare(_key[v], d));
+ _key[v] = d;
+ size_type p = _p[v];
+ if (p == nil())
+ {
+ if (_compare(d, _key[_root]))
+ _root = v;
+ }
+ else if (_compare(d, _key[p]))
+ while (1)
+ {
+ size_type r = _degree[p];
+ if (r >= 2)
+ remove_from_family(v, p);
+ insert_into_forest(v, d);
+ size_type pp = _p[p];
+ if (pp == nil())
+ {
+ --_degree[p];
+ break;
+ }
+ if (_mark[p] == false)
+ {
+ _mark[p] = true;
+ --_degree[p];
+ break;
+ }
+ else
+ --_degree[p];
+ v = p;
+ p = pp;
+ }
+ }
+
+ inline size_type size() const { return _n; }
+ inline bool empty() const { return _n == 0; }
+
+ void print(std::ostream& os)
+ {
+ if (_root != nil())
+ {
+ size_type i = _root;
+ do
+ {
+ print_recur(i, os);
+ os << std::endl;
+ i = _right[i];
+ } while (i != _root);
+ }
+ }
+
+protected:
+ // 35
+ inline void remove_from_family(size_type v, size_type p)
+ {
+ size_type u = _left[v];
+ size_type w = _right[v];
+ _right[u] = w;
+ _left[w] = u;
+ if (_child[p] == v)
+ _child[p] = w;
+ }
+ // 36
+ inline void insert_into_forest(size_type v, const T& d)
+ {
+ _p[v] = nil();
+ size_type u = _left[_root];
+ _left[v] = u;
+ _right[v] = _root;
+ _left[_root] = _right[u] = v;
+ if (_compare(d, _key[_root]))
+ _root = v;
+ }
+
+ void print_recur(size_type x, std::ostream& os)
+ {
+ if (x != nil())
+ {
+ os << x;
+ if (_degree[x] > 0)
+ {
+ os << "(";
+ size_type i = _child[x];
+ do
+ {
+ print_recur(i, os);
+ os << " ";
+ i = _right[i];
+ } while (i != _child[x]);
+ os << ")";
+ }
+ }
+ }
+
+ size_type nil() const { return _left.size(); }
+
+ std::vector< T > _key;
+ LinkVec _left, _right, _p;
+ std::vector< bool > _mark;
+ LinkVec _degree;
+ size_type _n, _root;
+ ID _id;
+ Compare _compare;
+ LinkVec _child;
+ LinkVec new_roots;
+};
+
+} // namespace boost
+
+#endif // BOOST_FIBONACCI_HEAP_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/pending/property_serialize.hpp b/contrib/restricted/boost/graph/include/boost/pending/property_serialize.hpp
new file mode 100644
index 0000000000..cbdc163a4f
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/pending/property_serialize.hpp
@@ -0,0 +1,99 @@
+// (C) Copyright Jeremy Siek 2006
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROPERTY_SERIALIZE_HPP
+#define BOOST_PROPERTY_SERIALIZE_HPP
+
+#include <boost/pending/property.hpp>
+#include <boost/serialization/is_bitwise_serializable.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/nvp.hpp>
+
+namespace boost
+{
+template < class Archive >
+inline void serialize(Archive&, no_property&, const unsigned int)
+{
+}
+
+template < class Archive, class Tag, class T, class Base >
+void serialize(
+ Archive& ar, property< Tag, T, Base >& prop, const unsigned int /*version*/)
+{
+ ar& serialization::make_nvp("property_value", prop.m_value);
+ ar& serialization::make_nvp("property_base", prop.m_base);
+}
+
+#ifdef BOOST_GRAPH_USE_MPI
+
+// Setting the serialization properties of boost::property<> and
+// boost::no_property to is_bitwise_serializable, object_serializable,
+// track_never only when BOOST_GRAPH_USE_MPI is defined is dubious.
+//
+// This changes the serialization format of these classes, and hence
+// of boost::adjacency_list, depending on whether BOOST_GRAPH_USE_MPI
+// is defined.
+//
+// These serialization properties should probably be set in either case.
+//
+// Unfortunately, doing that now will change the serialization format
+// of boost::adjacency_list in the non-MPI case, and could potentially
+// break software that reads files serialized with an older release.
+
+namespace mpi
+{
+
+ // forward declaration, to avoid including mpi
+ template < typename T > struct is_mpi_datatype;
+
+ template < typename Tag, typename T, typename Base >
+ struct is_mpi_datatype< property< Tag, T, Base > >
+ : mpl::and_< is_mpi_datatype< T >, is_mpi_datatype< Base > >
+ {
+ };
+}
+
+namespace serialization
+{
+ template < typename Tag, typename T, typename Base >
+ struct is_bitwise_serializable< property< Tag, T, Base > >
+ : mpl::and_< is_bitwise_serializable< T >, is_bitwise_serializable< Base > >
+ {
+ };
+
+ template < typename Tag, typename T, typename Base >
+ struct implementation_level< property< Tag, T, Base > >
+ : mpl::int_< object_serializable >
+ {
+ };
+
+ template < typename Tag, typename T, typename Base >
+ struct tracking_level< property< Tag, T, Base > > : mpl::int_< track_never >
+ {
+ };
+
+}
+#endif // BOOST_GRAPH_USE_MPI
+
+} // end namespace boost
+
+#ifdef BOOST_GRAPH_USE_MPI
+namespace boost
+{
+namespace mpi
+{
+ template <> struct is_mpi_datatype< boost::no_property > : mpl::true_
+ {
+ };
+
+}
+} // end namespace boost::mpi
+
+BOOST_IS_BITWISE_SERIALIZABLE(boost::no_property)
+BOOST_CLASS_IMPLEMENTATION(boost::no_property, object_serializable)
+BOOST_CLASS_TRACKING(boost::no_property, track_never)
+#endif // BOOST_GRAPH_USE_MPI
+
+#endif // BOOST_PROPERTY_SERIALIZE_HPP
diff --git a/contrib/restricted/boost/graph/include/boost/pending/relaxed_heap.hpp b/contrib/restricted/boost/graph/include/boost/pending/relaxed_heap.hpp
new file mode 100644
index 0000000000..d7747d4d75
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/pending/relaxed_heap.hpp
@@ -0,0 +1,743 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+
+#ifndef BOOST_RELAXED_HEAP_HEADER
+#define BOOST_RELAXED_HEAP_HEADER
+
+#include <boost/config/header_deprecated.hpp>
+BOOST_HEADER_DEPRECATED("the standard heap functions")
+
+#include <functional>
+#include <boost/property_map/property_map.hpp>
+#include <boost/optional.hpp>
+#include <vector>
+#include <climits> // for CHAR_BIT
+#include <boost/none.hpp>
+
+#ifdef BOOST_RELAXED_HEAP_DEBUG
+#include <iostream>
+#endif // BOOST_RELAXED_HEAP_DEBUG
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+#pragma warning(disable : 4355) // complaint about using 'this' to
+#endif // initialize a member
+
+namespace boost
+{
+
+template < typename IndexedType, typename Compare = std::less< IndexedType >,
+ typename ID = identity_property_map >
+class relaxed_heap
+{
+ struct group;
+
+ typedef relaxed_heap self_type;
+ typedef std::size_t rank_type;
+
+public:
+ typedef IndexedType value_type;
+ typedef rank_type size_type;
+
+private:
+ /**
+ * The kind of key that a group has. The actual values are discussed
+ * in-depth in the documentation of the @c kind field of the @c group
+ * structure. Note that the order of the enumerators *IS* important
+ * and must not be changed.
+ */
+ enum group_key_kind
+ {
+ smallest_key,
+ stored_key,
+ largest_key
+ };
+
+ struct group
+ {
+ explicit group(group_key_kind kind = largest_key)
+ : kind(kind), parent(this), rank(0)
+ {
+ }
+
+ /** The value associated with this group. This value is only valid
+ * when @c kind!=largest_key (which indicates a deleted
+ * element). Note that the use of boost::optional increases the
+ * memory requirements slightly but does not result in extraneous
+ * memory allocations or deallocations. The optional could be
+ * eliminated when @c value_type is a model of
+ * DefaultConstructible.
+ */
+ ::boost::optional< value_type > value;
+
+ /**
+ * The kind of key stored at this group. This may be @c
+ * smallest_key, which indicates that the key is infinitely small;
+ * @c largest_key, which indicates that the key is infinitely
+ * large; or @c stored_key, which means that the key is unknown,
+ * but its relationship to other keys can be determined via the
+ * comparison function object.
+ */
+ group_key_kind kind;
+
+ /// The parent of this group. Will only be NULL for the dummy root group
+ group* parent;
+
+ /// The rank of this group. Equivalent to the number of children in
+ /// the group.
+ rank_type rank;
+
+ /** The children of this group. For the dummy root group, these are
+ * the roots. This is an array of length log n containing pointers
+ * to the child groups.
+ */
+ group** children;
+ };
+
+ size_type log_base_2(size_type n) // log2 is a macro on some platforms
+ {
+ size_type leading_zeroes = 0;
+ do
+ {
+ size_type next = n << 1;
+ if (n == (next >> 1))
+ {
+ ++leading_zeroes;
+ n = next;
+ }
+ else
+ {
+ break;
+ }
+ } while (true);
+ return sizeof(size_type) * CHAR_BIT - leading_zeroes - 1;
+ }
+
+public:
+ relaxed_heap(
+ size_type n, const Compare& compare = Compare(), const ID& id = ID())
+ : compare(compare), id(id), root(smallest_key), groups(n), smallest_value(0)
+ {
+ if (n == 0)
+ {
+ root.children = new group*[1];
+ return;
+ }
+
+ log_n = log_base_2(n);
+ if (log_n == 0)
+ log_n = 1;
+ size_type g = n / log_n;
+ if (n % log_n > 0)
+ ++g;
+ size_type log_g = log_base_2(g);
+ size_type r = log_g;
+
+ // Reserve an appropriate amount of space for data structures, so
+ // that we do not need to expand them.
+ index_to_group.resize(g);
+ A.resize(r + 1, 0);
+ root.rank = r + 1;
+ root.children = new group*[(log_g + 1) * (g + 1)];
+ for (rank_type i = 0; i < r + 1; ++i)
+ root.children[i] = 0;
+
+ // Build initial heap
+ size_type idx = 0;
+ while (idx < g)
+ {
+ root.children[r] = &index_to_group[idx];
+ idx = build_tree(root, idx, r, log_g + 1);
+ if (idx != g)
+ r = static_cast< size_type >(log_base_2(g - idx));
+ }
+ }
+
+ ~relaxed_heap() { delete[] root.children; }
+
+ void push(const value_type& x)
+ {
+ groups[get(id, x)] = x;
+ update(x);
+ }
+
+ void update(const value_type& x)
+ {
+ group* a = &index_to_group[get(id, x) / log_n];
+ if (!a->value || *a->value == x || compare(x, *a->value))
+ {
+ if (a != smallest_value)
+ smallest_value = 0;
+ a->kind = stored_key;
+ a->value = x;
+ promote(a);
+ }
+ }
+
+ void remove(const value_type& x)
+ {
+ group* a = &index_to_group[get(id, x) / log_n];
+ assert(groups[get(id, x)]);
+ a->value = x;
+ a->kind = smallest_key;
+ promote(a);
+ smallest_value = a;
+ pop();
+ }
+
+ value_type& top()
+ {
+ find_smallest();
+ assert(smallest_value->value != none);
+ return *smallest_value->value;
+ }
+
+ const value_type& top() const
+ {
+ find_smallest();
+ assert(smallest_value->value != none);
+ return *smallest_value->value;
+ }
+
+ bool empty() const
+ {
+ find_smallest();
+ return !smallest_value || (smallest_value->kind == largest_key);
+ }
+
+ bool contains(const value_type& x) const
+ {
+ return static_cast< bool >(groups[get(id, x)]);
+ }
+
+ void pop()
+ {
+ // Fill in smallest_value. This is the group x.
+ find_smallest();
+ group* x = smallest_value;
+ smallest_value = 0;
+
+ // Make x a leaf, giving it the smallest value within its group
+ rank_type r = x->rank;
+ group* p = x->parent;
+ {
+ assert(x->value != none);
+
+ // Find x's group
+ size_type start = get(id, *x->value) - get(id, *x->value) % log_n;
+ size_type end = start + log_n;
+ if (end > groups.size())
+ end = groups.size();
+
+ // Remove the smallest value from the group, and find the new
+ // smallest value.
+ groups[get(id, *x->value)].reset();
+ x->value.reset();
+ x->kind = largest_key;
+ for (size_type i = start; i < end; ++i)
+ {
+ if (groups[i] && (!x->value || compare(*groups[i], *x->value)))
+ {
+ x->kind = stored_key;
+ x->value = groups[i];
+ }
+ }
+ }
+ x->rank = 0;
+
+ // Combine prior children of x with x
+ group* y = x;
+ for (size_type c = 0; c < r; ++c)
+ {
+ group* child = x->children[c];
+ if (A[c] == child)
+ A[c] = 0;
+ y = combine(y, child);
+ }
+
+ // If we got back something other than x, let y take x's place
+ if (y != x)
+ {
+ y->parent = p;
+ p->children[r] = y;
+
+ assert(r == y->rank);
+ if (A[y->rank] == x)
+ A[y->rank] = do_compare(y, p) ? y : 0;
+ }
+ }
+
+#ifdef BOOST_RELAXED_HEAP_DEBUG
+ /*************************************************************************
+ * Debugging support *
+ *************************************************************************/
+ void dump_tree() { dump_tree(std::cout); }
+ void dump_tree(std::ostream& out) { dump_tree(out, &root); }
+
+ void dump_tree(std::ostream& out, group* p, bool in_progress = false)
+ {
+ if (!in_progress)
+ {
+ out << "digraph heap {\n"
+ << " edge[dir=\"back\"];\n";
+ }
+
+ size_type p_index = 0;
+ if (p != &root)
+ while (&index_to_group[p_index] != p)
+ ++p_index;
+
+ for (size_type i = 0; i < p->rank; ++i)
+ {
+ group* c = p->children[i];
+ if (c)
+ {
+ size_type c_index = 0;
+ if (c != &root)
+ while (&index_to_group[c_index] != c)
+ ++c_index;
+
+ out << " ";
+ if (p == &root)
+ out << 'p';
+ else
+ out << p_index;
+ out << " -> ";
+ if (c == &root)
+ out << 'p';
+ else
+ out << c_index;
+ if (A[c->rank] == c)
+ out << " [style=\"dotted\"]";
+ out << ";\n";
+ dump_tree(out, c, true);
+
+ // Emit node information
+ out << " ";
+ if (c == &root)
+ out << 'p';
+ else
+ out << c_index;
+ out << " [label=\"";
+ if (c == &root)
+ out << 'p';
+ else
+ out << c_index;
+ out << ":";
+ size_type start = c_index * log_n;
+ size_type end = start + log_n;
+ if (end > groups.size())
+ end = groups.size();
+ while (start != end)
+ {
+ if (groups[start])
+ {
+ out << " " << get(id, *groups[start]);
+ if (*groups[start] == *c->value)
+ out << "(*)";
+ }
+ ++start;
+ }
+ out << '"';
+
+ if (do_compare(c, p))
+ {
+ out << " ";
+ if (c == &root)
+ out << 'p';
+ else
+ out << c_index;
+ out << ", style=\"filled\", fillcolor=\"gray\"";
+ }
+ out << "];\n";
+ }
+ else
+ {
+ assert(p->parent == p);
+ }
+ }
+ if (!in_progress)
+ out << "}\n";
+ }
+
+ bool valid()
+ {
+ // Check that the ranks in the A array match the ranks of the
+ // groups stored there. Also, the active groups must be the last
+ // child of their parent.
+ for (size_type r = 0; r < A.size(); ++r)
+ {
+ if (A[r] && A[r]->rank != r)
+ return false;
+
+ if (A[r] && A[r]->parent->children[A[r]->parent->rank - 1] != A[r])
+ return false;
+ }
+
+ // The root must have no value and a key of -Infinity
+ if (root.kind != smallest_key)
+ return false;
+
+ return valid(&root);
+ }
+
+ bool valid(group* p)
+ {
+ for (size_type i = 0; i < p->rank; ++i)
+ {
+ group* c = p->children[i];
+ if (c)
+ {
+ // Check link structure
+ if (c->parent != p)
+ return false;
+ if (c->rank != i)
+ return false;
+
+ // A bad group must be active
+ if (do_compare(c, p) && A[i] != c)
+ return false;
+
+ // Check recursively
+ if (!valid(c))
+ return false;
+ }
+ else
+ {
+ // Only the root may
+ if (p != &root)
+ return false;
+ }
+ }
+ return true;
+ }
+
+#endif // BOOST_RELAXED_HEAP_DEBUG
+
+private:
+ size_type build_tree(
+ group& parent, size_type idx, size_type r, size_type max_rank)
+ {
+ group& this_group = index_to_group[idx];
+ this_group.parent = &parent;
+ ++idx;
+
+ this_group.children = root.children + (idx * max_rank);
+ this_group.rank = r;
+ for (size_type i = 0; i < r; ++i)
+ {
+ this_group.children[i] = &index_to_group[idx];
+ idx = build_tree(this_group, idx, i, max_rank);
+ }
+ return idx;
+ }
+
+ void find_smallest() const
+ {
+ group** roots = root.children;
+
+ if (!smallest_value)
+ {
+ std::size_t i;
+ for (i = 0; i < root.rank; ++i)
+ {
+ if (roots[i]
+ && (!smallest_value
+ || do_compare(roots[i], smallest_value)))
+ {
+ smallest_value = roots[i];
+ }
+ }
+ for (i = 0; i < A.size(); ++i)
+ {
+ if (A[i]
+ && (!smallest_value || do_compare(A[i], smallest_value)))
+ smallest_value = A[i];
+ }
+ }
+ }
+
+ bool do_compare(group* x, group* y) const
+ {
+ return (x->kind < y->kind
+ || (x->kind == y->kind && x->kind == stored_key
+ && compare(*x->value, *y->value)));
+ }
+
+ void promote(group* a)
+ {
+ assert(a != 0);
+ rank_type r = a->rank;
+ group* p = a->parent;
+ assert(p != 0);
+ if (do_compare(a, p))
+ {
+ // s is the rank + 1 sibling
+ group* s = p->rank > r + 1 ? p->children[r + 1] : 0;
+
+ // If a is the last child of p
+ if (r == p->rank - 1)
+ {
+ if (!A[r])
+ A[r] = a;
+ else if (A[r] != a)
+ pair_transform(a);
+ }
+ else
+ {
+ assert(s != 0);
+ if (A[r + 1] == s)
+ active_sibling_transform(a, s);
+ else
+ good_sibling_transform(a, s);
+ }
+ }
+ }
+
+ group* combine(group* a1, group* a2)
+ {
+ assert(a1->rank == a2->rank);
+ if (do_compare(a2, a1))
+ do_swap(a1, a2);
+ a1->children[a1->rank++] = a2;
+ a2->parent = a1;
+ clean(a1);
+ return a1;
+ }
+
+ void clean(group* q)
+ {
+ if (2 > q->rank)
+ return;
+ group* qp = q->children[q->rank - 1];
+ rank_type s = q->rank - 2;
+ group* x = q->children[s];
+ group* xp = qp->children[s];
+ assert(s == x->rank);
+
+ // If x is active, swap x and xp
+ if (A[s] == x)
+ {
+ q->children[s] = xp;
+ xp->parent = q;
+ qp->children[s] = x;
+ x->parent = qp;
+ }
+ }
+
+ void pair_transform(group* a)
+ {
+#if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
+ std::cerr << "- pair transform\n";
+#endif
+ rank_type r = a->rank;
+
+ // p is a's parent
+ group* p = a->parent;
+ assert(p != 0);
+
+ // g is p's parent (a's grandparent)
+ group* g = p->parent;
+ assert(g != 0);
+
+ // a' <- A(r)
+ assert(A[r] != 0);
+ group* ap = A[r];
+ assert(ap != 0);
+
+ // A(r) <- nil
+ A[r] = 0;
+
+ // let a' have parent p'
+ group* pp = ap->parent;
+ assert(pp != 0);
+
+ // let a' have grandparent g'
+ group* gp = pp->parent;
+ assert(gp != 0);
+
+ // Remove a and a' from their parents
+ assert(ap
+ == pp->children[pp->rank - 1]); // Guaranteed because ap is active
+ --pp->rank;
+
+ // Guaranteed by caller
+ assert(a == p->children[p->rank - 1]);
+ --p->rank;
+
+ // Note: a, ap, p, pp all have rank r
+ if (do_compare(pp, p))
+ {
+ do_swap(a, ap);
+ do_swap(p, pp);
+ do_swap(g, gp);
+ }
+
+ // Assuming k(p) <= k(p')
+ // make p' the rank r child of p
+ assert(r == p->rank);
+ p->children[p->rank++] = pp;
+ pp->parent = p;
+
+ // Combine a, ap into a rank r+1 group c
+ group* c = combine(a, ap);
+
+ // make c the rank r+1 child of g'
+ assert(gp->rank > r + 1);
+ gp->children[r + 1] = c;
+ c->parent = gp;
+
+#if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
+ std::cerr << "After pair transform...\n";
+ dump_tree();
+#endif
+
+ if (A[r + 1] == pp)
+ A[r + 1] = c;
+ else
+ promote(c);
+ }
+
+ void active_sibling_transform(group* a, group* s)
+ {
+#if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
+ std::cerr << "- active sibling transform\n";
+#endif
+ group* p = a->parent;
+ group* g = p->parent;
+
+ // remove a, s from their parents
+ assert(s->parent == p);
+ assert(p->children[p->rank - 1] == s);
+ --p->rank;
+ assert(p->children[p->rank - 1] == a);
+ --p->rank;
+
+ rank_type r = a->rank;
+ A[r + 1] = 0;
+ a = combine(p, a);
+ group* c = combine(a, s);
+
+ // make c the rank r+2 child of g
+ assert(g->children[r + 2] == p);
+ g->children[r + 2] = c;
+ c->parent = g;
+ if (A[r + 2] == p)
+ A[r + 2] = c;
+ else
+ promote(c);
+ }
+
+ void good_sibling_transform(group* a, group* s)
+ {
+#if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
+ std::cerr << "- good sibling transform\n";
+#endif
+ rank_type r = a->rank;
+ group* c = s->children[s->rank - 1];
+ assert(c->rank == r);
+ if (A[r] == c)
+ {
+#if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
+ std::cerr << "- good sibling pair transform\n";
+#endif
+ A[r] = 0;
+ group* p = a->parent;
+
+ // Remove c from its parent
+ --s->rank;
+
+ // Make s the rank r child of p
+ s->parent = p;
+ p->children[r] = s;
+
+ // combine a, c and let the result by the rank r+1 child of p
+ assert(p->rank > r + 1);
+ group* x = combine(a, c);
+ x->parent = p;
+ p->children[r + 1] = x;
+
+ if (A[r + 1] == s)
+ A[r + 1] = x;
+ else
+ promote(x);
+
+#if defined(BOOST_RELAXED_HEAP_DEBUG) && BOOST_RELAXED_HEAP_DEBUG > 1
+ dump_tree(std::cerr);
+#endif
+ // pair_transform(a);
+ }
+ else
+ {
+ // Clean operation
+ group* p = a->parent;
+ s->children[r] = a;
+ a->parent = s;
+ p->children[r] = c;
+ c->parent = p;
+
+ promote(a);
+ }
+ }
+
+ static void do_swap(group*& x, group*& y)
+ {
+ group* tmp = x;
+ x = y;
+ y = tmp;
+ }
+
+ /// Function object that compares two values in the heap
+ Compare compare;
+
+ /// Mapping from values to indices in the range [0, n).
+ ID id;
+
+ /** The root group of the queue. This group is special because it will
+ * never store a value, but it acts as a parent to all of the
+ * roots. Thus, its list of children is the list of roots.
+ */
+ group root;
+
+ /** Mapping from the group index of a value to the group associated
+ * with that value. If a value is not in the queue, then the "value"
+ * field will be empty.
+ */
+ std::vector< group > index_to_group;
+
+ /** Flat data structure containing the values in each of the
+ * groups. It will be indexed via the id of the values. The groups
+ * are each log_n long, with the last group potentially being
+ * smaller.
+ */
+ std::vector< ::boost::optional< value_type > > groups;
+
+ /** The list of active groups, indexed by rank. When A[r] is null,
+ * there is no active group of rank r. Otherwise, A[r] is the active
+ * group of rank r.
+ */
+ std::vector< group* > A;
+
+ /** The group containing the smallest value in the queue, which must
+ * be either a root or an active group. If this group is null, then we
+ * will need to search for this group when it is needed.
+ */
+ mutable group* smallest_value;
+
+ /// Cached value log_base_2(n)
+ size_type log_n;
+};
+
+} // end namespace boost
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_RELAXED_HEAP_HEADER
diff --git a/contrib/restricted/boost/graph/include/boost/pending/stringtok.hpp b/contrib/restricted/boost/graph/include/boost/pending/stringtok.hpp
new file mode 100644
index 0000000000..f64a4c45dd
--- /dev/null
+++ b/contrib/restricted/boost/graph/include/boost/pending/stringtok.hpp
@@ -0,0 +1,116 @@
+// (C) Copyright Jeremy Siek 2004
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_STRINGTOK_HPP
+#define BOOST_STRINGTOK_HPP
+
+/*
+ * stringtok.hpp -- Breaks a string into tokens. This is an example for lib3.
+ *
+ * Template function looks like this:
+ *
+ * template <typename Container>
+ * void stringtok (Container &l,
+ * string const &s,
+ * char const * const ws = " \t\n");
+ *
+ * A nondestructive version of strtok() that handles its own memory and can
+ * be broken up by any character(s). Does all the work at once rather than
+ * in an invocation loop like strtok() requires.
+ *
+ * Container is any type that supports push_back(a_string), although using
+ * list<string> and deque<string> are indicated due to their O(1) push_back.
+ * (I prefer deque<> because op[]/at() is available as well.) The first
+ * parameter references an existing Container.
+ *
+ * s is the string to be tokenized. From the parameter declaration, it can
+ * be seen that s is not affected. Since references-to-const may refer to
+ * temporaries, you could use stringtok(some_container, readline("")) when
+ * using the GNU readline library.
+ *
+ * The final parameter is an array of characters that serve as whitespace.
+ * Whitespace characters default to one or more of tab, space, and newline,
+ * in any combination.
+ *
+ * 'l' need not be empty on entry. On return, 'l' will have the token
+ * strings appended.
+ *
+ *
+ * [Example:
+ * list<string> ls;
+ * stringtok (ls, " this \t is\t\n a test ");
+ * for (list<string>::const_iterator i = ls.begin();
+ * i != ls.end(); ++i)
+ * {
+ * cerr << ':' << (*i) << ":\n";
+ * }
+ *
+ * would print
+ * :this:
+ * :is:
+ * :a:
+ * :test:
+ * -end example]
+ *
+ * pedwards@jaj.com May 1999
+ */
+
+#include <string>
+#include <cstring> // for strchr
+
+/*****************************************************************
+ * This is the only part of the implementation that I don't like.
+ * It can probably be improved upon by the reader...
+ */
+
+inline bool isws(char c, char const* const wstr)
+{
+ using namespace std;
+ return (strchr(wstr, c) != NULL);
+}
+
+namespace boost
+{
+
+/*****************************************************************
+ * Simplistic and quite Standard, but a bit slow. This should be
+ * templatized on basic_string instead, or on a more generic StringT
+ * that just happens to support ::size_type, .substr(), and so on.
+ * I had hoped that "whitespace" would be a trait, but it isn't, so
+ * the user must supply it. Enh, this lets them break up strings on
+ * different things easier than traits would anyhow.
+ */
+template < typename Container >
+void stringtok(
+ Container& l, std::string const& s, char const* const ws = " \t\n")
+{
+ typedef std::string::size_type size_type;
+ const size_type S = s.size();
+ size_type i = 0;
+
+ while (i < S)
+ {
+ // eat leading whitespace
+ while ((i < S) && (isws(s[i], ws)))
+ ++i;
+ if (i == S)
+ return; // nothing left but WS
+
+ // find end of word
+ size_type j = i + 1;
+ while ((j < S) && (!isws(s[j], ws)))
+ ++j;
+
+ // add word
+ l.push_back(s.substr(i, j - i));
+
+ // set up for next loop
+ i = j + 1;
+ }
+}
+
+} // namespace boost
+
+#endif // BOOST_STRINGTOK_HPP