From f07d91397c5efb07016a10240b80389fed01dc44 Mon Sep 17 00:00:00 2001 From: Stefan Hammer Date: Wed, 2 Nov 2016 11:02:39 +0100 Subject: [PATCH 01/21] [subgraph.hpp] add_vertex(u_global, g) on a subgraph does not recursively add to parent subgraphs --- include/boost/graph/subgraph.hpp | 80 +++++---- test/Jamfile.v2 | 1 + test/subgraph_add.cpp | 272 +++++++++++++++++++++++++++++++ 3 files changed, 318 insertions(+), 35 deletions(-) create mode 100644 test/subgraph_add.cpp diff --git a/include/boost/graph/subgraph.hpp b/include/boost/graph/subgraph.hpp index 22706bc61..0afb2cabb 100644 --- a/include/boost/graph/subgraph.hpp +++ b/include/boost/graph/subgraph.hpp @@ -371,46 +371,56 @@ typename subgraph::vertex_descriptor add_vertex(typename subgraph::vertex_descriptor u_global, subgraph& g) { - BOOST_ASSERT(!g.is_root()); - typename subgraph::vertex_descriptor u_local, v_global; - typename subgraph::edge_descriptor e_global; - - u_local = add_vertex(g.m_graph); - g.m_global_vertex.push_back(u_global); - g.m_local_vertex[u_global] = u_local; - - subgraph& r = g.root(); + if (g.is_root()) { + return u_global; + } else { + typename subgraph::vertex_descriptor u_local; + bool exists_local; + boost::tie(u_local, exists_local) = g.find_vertex(u_global); + + if (!exists_local) { + typename subgraph::vertex_descriptor v_global; + typename subgraph::edge_descriptor e_global; + // call recursion for parent subgraph + add_vertex(u_global, g.parent()); + + u_local = add_vertex(g.m_graph); + g.m_global_vertex.push_back(u_global); + g.m_local_vertex[u_global] = u_local; + + subgraph& r = g.root(); - // remember edge global and local maps - { - typename subgraph::out_edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = out_edges(u_global, r); - ei != ei_end; ++ei) { - e_global = *ei; - v_global = target(e_global, r); - if (g.find_vertex(v_global).second == true) - g.local_add_edge(u_local, g.global_to_local(v_global), e_global); - } - } - if (is_directed(g)) { // not necessary for undirected graph - typename subgraph::vertex_iterator vi, vi_end; - typename subgraph::out_edge_iterator ei, ei_end; - for(boost::tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) { - v_global = *vi; - if (v_global == u_global) - continue; // don't insert self loops twice! - if (!g.find_vertex(v_global).second) - continue; // not a subgraph vertex => try next one - for(boost::tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) { - e_global = *ei; - if(target(e_global, r) == u_global) { - g.local_add_edge(g.global_to_local(v_global), u_local, e_global); + // remember edge global and local maps + { + typename subgraph::out_edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = out_edges(u_global, r); + ei != ei_end; ++ei) { + e_global = *ei; + v_global = target(e_global, r); + if (g.find_vertex(v_global).second == true) + g.local_add_edge(u_local, g.global_to_local(v_global), e_global); + } + } + if (is_directed(g)) { // not necessary for undirected graph + typename subgraph::vertex_iterator vi, vi_end; + typename subgraph::out_edge_iterator ei, ei_end; + for(boost::tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) { + v_global = *vi; + if (v_global == u_global) + continue; // don't insert self loops twice! + if (!g.find_vertex(v_global).second) + continue; // not a subgraph vertex => try next one + for(boost::tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) { + e_global = *ei; + if(target(e_global, r) == u_global) { + g.local_add_edge(g.global_to_local(v_global), u_local, e_global); + } + } } } } + return u_local; } - - return u_local; } // NOTE: Descriptors are local unless otherwise noted. diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 263365cb5..c5e94afdb 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -74,6 +74,7 @@ test-suite graph_test : # TODO: Merge these into a single test framework. [ run subgraph.cpp ../../test/build//boost_test_exec_monitor ] [ run subgraph_bundled.cpp ] + [ run subgraph_add.cpp ../../test/build//boost_unit_test_framework/static : $(TEST_DIR) ] [ run subgraph_props.cpp ] [ run isomorphism.cpp ../../test/build//boost_test_exec_monitor ] diff --git a/test/subgraph_add.cpp b/test/subgraph_add.cpp new file mode 100644 index 000000000..d3265d219 --- /dev/null +++ b/test/subgraph_add.cpp @@ -0,0 +1,272 @@ +/* This file is a boost.test unit test and provides tests the internal dependency graph + * + * Created on: 06.10.2015 + * Author: Stefan Hammer + * License: Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * + */ + +#define BOOST_TEST_MODULE subgraph_add + +// std lib includes +#include + +// include boost components +#include +#include +#include + +// include header +#include + +using namespace boost; + +BOOST_AUTO_TEST_CASE(simpleGraph) { + + BOOST_TEST_MESSAGE("simple subgraph"); + + typedef subgraph< adjacency_list< vecS, vecS, directedS, + no_property, property< edge_index_t, int > > > Graph; + + const int N = 6; + Graph G0(N); + + enum { A, B, C, D, E, F}; // for conveniently refering to vertices in G0 + + Graph& G1 = G0.create_subgraph(); + Graph& G2 = G1.create_subgraph(); + + BOOST_CHECK(&G1.parent() == &G0); + BOOST_CHECK(&G2.parent() == &G1); + + enum { A1, B1, C1 }; // for conveniently refering to vertices in G1 + enum { A2, B2, C2 }; // for conveniently refering to vertices in G2 + + add_vertex(C, G1); // global vertex C becomes local A1 for G1 + add_vertex(E, G1); // global vertex E becomes local B1 for G1 + add_vertex(F, G1); // global vertex F becomes local C1 for G1 + + add_vertex(C, G2); // global vertex C becomes local A2 for G2 + add_vertex(E, G2); // global vertex E becomes local B2 for G2 + + BOOST_CHECK(num_vertices(G0) == 6); + BOOST_CHECK(num_vertices(G1) == 3); + std::cerr << num_vertices(G1) << std::endl; + BOOST_CHECK(num_vertices(G2) == 2); + + // add edges to root graph + add_edge(A, B, G0); + add_edge(B, C, G0); + add_edge(B, D, G0); + add_edge(E, F, G0); + + BOOST_CHECK(num_edges(G0) == 4); + BOOST_CHECK(num_edges(G1) == 1); + BOOST_CHECK(num_edges(G2) == 0); + + // add edges to G1 + add_edge(A1, B1, G1); + BOOST_CHECK(num_edges(G0) == 5); + BOOST_CHECK(num_edges(G1) == 2); + BOOST_CHECK(num_edges(G2) == 1); + // num_vertices stays the same + BOOST_CHECK(num_vertices(G0) == 6); + BOOST_CHECK(num_vertices(G1) == 3); + BOOST_CHECK(num_vertices(G2) == 2); +} + +BOOST_AUTO_TEST_CASE(addVertices) { + + BOOST_TEST_MESSAGE("subgraph add edges"); + + typedef subgraph< adjacency_list< vecS, vecS, directedS, + no_property, property< edge_index_t, int > > > Graph; + typedef Graph::vertex_descriptor Vertex; + + const int N = 3; + Graph G0(N); + Graph& G1 = G0.create_subgraph(); + Graph& G2 = G1.create_subgraph(); + + BOOST_CHECK(&G1.parent() == &G0); + BOOST_CHECK(&G2.parent() == &G1); + + // add vertices to G2 + Vertex n1 = add_vertex(0, G2); + Vertex n2 = add_vertex(1, G2); + // check if the global vertex 2 is equal to the returned local vertex + if (G2.find_vertex(0).second) { + BOOST_CHECK(G2.find_vertex(0).first == n1); + } else { + BOOST_ERROR( "vertex not found!" ); + } + if (G2.find_vertex(1).second) { + BOOST_CHECK(G2.find_vertex(1).first == n2); + } else { + BOOST_ERROR( "vertex not found!" ); + } + // and check if this vertex is also present in G1 + if (G1.find_vertex(0).second) { + BOOST_CHECK(G1.local_to_global(G1.find_vertex(0).first) == 0); + } else { + BOOST_ERROR( "vertex not found!" ); + } + if (G1.find_vertex(0).second) { + BOOST_CHECK(G1.local_to_global(G1.find_vertex(1).first) == 1); + } else { + BOOST_ERROR( "vertex not found!" ); + } + + // num_vertices stays the same + BOOST_CHECK(num_vertices(G0) == 3); + BOOST_CHECK(num_vertices(G1) == 2); + BOOST_CHECK(num_vertices(G2) == 2); + + // add vertices to G1 + Vertex n3 = add_vertex(2, G1); + // check if the global vertex 2 is equal to the returned local vertex + if (G1.find_vertex(2).second) { + BOOST_CHECK(G1.find_vertex(2).first == n3); + } else { + BOOST_ERROR( "vertex not found!" ); + } + // num_vertices stays the same + BOOST_CHECK(num_vertices(G0) == 3); + BOOST_CHECK(num_vertices(G1) == 3); + BOOST_CHECK(num_vertices(G2) == 2); + + // add vertices to G1 + Vertex n4 = add_vertex(G1); + + // check if the new local vertex is also in the global graph + BOOST_CHECK(G0.find_vertex(G1.local_to_global(n4)).second); + // check if the new local vertex is not in the subgraphs + BOOST_CHECK(!G2.find_vertex(n4).second); + + // num_vertices stays the same + BOOST_CHECK(num_vertices(G0) == 4); + BOOST_CHECK(num_vertices(G1) == 4); + BOOST_CHECK(num_vertices(G2) == 2); + + // add vertices to G0 + Vertex n5 = add_vertex(G0); + + // check if the new local vertex is not in the subgraphs + BOOST_CHECK(!G1.find_vertex(n5).second); + BOOST_CHECK(!G2.find_vertex(n5).second); + + // num_vertices stays the same + BOOST_CHECK(num_vertices(G0) == 5); + BOOST_CHECK(num_vertices(G1) == 4); + BOOST_CHECK(num_vertices(G2) == 2); + + std::cerr << "All G0 vertices: " << std::endl; + BGL_FORALL_VERTICES_T(v, G0, Graph) { + std::cerr << G0.local_to_global(v) << std::endl; + } + std::cerr << "All G1 vertices: " << std::endl; + BGL_FORALL_VERTICES_T(v, G1, Graph) { + std::cerr << G1.local_to_global(v) << std::endl; + } + std::cerr << "All G2 vertices: " << std::endl; + BGL_FORALL_VERTICES_T(v, G2, Graph) { + std::cerr << G2.local_to_global(v) << std::endl; + } +} + +BOOST_AUTO_TEST_CASE(addEdge) { + + BOOST_TEST_MESSAGE("subgraph add edges"); + + typedef subgraph< adjacency_list< vecS, vecS, directedS, + no_property, property< edge_index_t, int > > > Graph; + typedef Graph::vertex_descriptor Vertex; + + const int N = 3; + Graph G0(N); + Graph& G1 = G0.create_subgraph(); + Graph& G2 = G1.create_subgraph(); + + BOOST_CHECK(&G1.parent() == &G0); + BOOST_CHECK(&G2.parent() == &G1); + + // add vertices + add_vertex(0, G2); + add_vertex(1, G2); + BOOST_CHECK(num_vertices(G1) == 2); + BOOST_CHECK(num_vertices(G2) == 2); + + // add edge to G0 which needs propagation + add_edge(0, 1, G0); + + BOOST_CHECK(num_edges(G0) == 1); + BOOST_CHECK(num_edges(G1) == 1); + BOOST_CHECK(num_edges(G2) == 1); + // num_vertices stays the same + BOOST_CHECK(num_vertices(G0) == 3); + BOOST_CHECK(num_vertices(G1) == 2); + BOOST_CHECK(num_vertices(G2) == 2); + + // add edge to G0 without propagation + add_edge(1, 2, G0); + + BOOST_CHECK(num_edges(G0) == 2); + BOOST_CHECK(num_edges(G1) == 1); + BOOST_CHECK(num_edges(G2) == 1); + // num_vertices stays the same + BOOST_CHECK(num_vertices(G0) == 3); + BOOST_CHECK(num_vertices(G1) == 2); + BOOST_CHECK(num_vertices(G2) == 2); + + // add vertex 2 to G2/G1 with edge propagation + Vertex n = add_vertex(2, G2); + BOOST_CHECK(G2.local_to_global(n) == 2); + + BOOST_CHECK(num_edges(G0) == 2); + BOOST_CHECK(num_edges(G1) == 2); + BOOST_CHECK(num_edges(G2) == 2); + // num_vertices stays the same + BOOST_CHECK(num_vertices(G0) == 3); + BOOST_CHECK(num_vertices(G1) == 3); + BOOST_CHECK(num_vertices(G2) == 3); + + // add edge to G2 with propagation upwards + add_edge(0, 2, G2); + + BOOST_CHECK(num_edges(G0) == 3); + BOOST_CHECK(num_edges(G1) == 3); + BOOST_CHECK(num_edges(G2) == 3); + // num_vertices stays the same + BOOST_CHECK(num_vertices(G0) == 3); + BOOST_CHECK(num_vertices(G1) == 3); + BOOST_CHECK(num_vertices(G2) == 3); + + std::cerr << "All G0 vertices: " << std::endl; + BGL_FORALL_VERTICES_T(v, G0, Graph) { + std::cerr << G0.local_to_global(v) << std::endl; + } + std::cerr << "All G1 vertices: " << std::endl; + BGL_FORALL_VERTICES_T(v, G1, Graph) { + std::cerr << G1.local_to_global(v) << std::endl; + } + std::cerr << "All G2 vertices: " << std::endl; + BGL_FORALL_VERTICES_T(v, G2, Graph) { + std::cerr << G2.local_to_global(v) << std::endl; + } + std::cerr << "All G0 edges: " << std::endl; + BGL_FORALL_EDGES_T(e, G0, Graph) { + std::cerr << source(e, G0) << "->" << target(e, G0) << std::endl; + } + std::cerr << "All G1 edges: " << std::endl; + BGL_FORALL_EDGES_T(e, G1, Graph) { + std::cerr << source(e, G1) << "->" << target(e, G1) << std::endl; + } + std::cerr << "All G2 edges: " << std::endl; + BGL_FORALL_EDGES_T(e, G2, Graph) { + std::cerr << source(e, G2) << "->" << target(e, G2) << std::endl; + } +} + From faef224193090d2ce57ce7da8e3fd390f3f966df Mon Sep 17 00:00:00 2001 From: Mateusz Polnik Date: Tue, 4 Jul 2017 23:20:09 +0100 Subject: [PATCH 02/21] Reproduce memory issue with resource constrained shortest paths. Valgrind confirms reads/writes outside allocated memory. --- test/r_c_shortest_paths_test.cpp | 158 +++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/test/r_c_shortest_paths_test.cpp b/test/r_c_shortest_paths_test.cpp index cf6d57e16..7d0864a29 100644 --- a/test/r_c_shortest_paths_test.cpp +++ b/test/r_c_shortest_paths_test.cpp @@ -199,6 +199,89 @@ class dominance_spptw }; // end data structures for shortest path problem with time windows (spptw) +struct spp_spptw_marked_res_cont { + spp_spptw_marked_res_cont(SPPRC_Example_Graph::vertex_descriptor v, int c = 0, int t = 0 ) : cost( c ), time( t ), marked() { + marked.insert(v); + } + spp_spptw_marked_res_cont& operator=( const spp_spptw_marked_res_cont& other ) + { + if( this == &other ) + return *this; + this->~spp_spptw_marked_res_cont(); + new( this ) spp_spptw_marked_res_cont( other ); + return *this; + } + int cost; + int time; + std::set marked; +}; + +bool operator==( const spp_spptw_marked_res_cont& res_cont_1, + const spp_spptw_marked_res_cont& res_cont_2 ) +{ + return res_cont_1.cost == res_cont_2.cost + && res_cont_1.time == res_cont_2.time + && res_cont_1.marked == res_cont_2.marked; +} + +bool operator<( const spp_spptw_marked_res_cont& res_cont_1, + const spp_spptw_marked_res_cont& res_cont_2 ) +{ + if( res_cont_1.cost > res_cont_2.cost || res_cont_1.time > res_cont_2.time) { + return false; + } + + if( !std::includes( res_cont_2.marked.begin(), + res_cont_2.marked.end(), + res_cont_1.marked.begin(), + res_cont_1.marked.end() ) ) { + return false; + } + + if( res_cont_1.cost == res_cont_2.cost ) { + return res_cont_1.time < res_cont_2.time; + } + return true; +} + +class ref_spptw_marked { +public: + inline bool operator()(const SPPRC_Example_Graph &g, + spp_spptw_marked_res_cont &new_cont, + const spp_spptw_marked_res_cont &old_cont, + graph_traits + ::edge_descriptor ed) const { + const graph_traits ::vertex_descriptor dest = target(ed, g); + + if(old_cont.marked.find(dest) != old_cont.marked.end()) { + return false; + } + + const SPPRC_Example_Graph_Arc_Prop& arc_prop = get( edge_bundle, g )[ed]; + const SPPRC_Example_Graph_Vert_Prop& vert_prop = get( vertex_bundle, g )[dest]; + new_cont.cost = old_cont.cost + arc_prop.cost; + new_cont.marked = old_cont.marked; + new_cont.marked.insert(dest); + int& i_time = new_cont.time; + i_time = old_cont.time + arc_prop.time; + i_time < vert_prop.eat ? i_time = vert_prop.eat : 0; + return i_time <= vert_prop.lat; +} +}; + +class dominance_spptw_marked { +public: + inline bool operator()( const spp_spptw_marked_res_cont& res_cont_1, + const spp_spptw_marked_res_cont& res_cont_2 ) const { + return res_cont_1.time <= res_cont_2.time + && res_cont_1.cost <= res_cont_2.cost + && std::includes( res_cont_1.marked.begin(), + res_cont_1.marked.end(), + res_cont_2.marked.begin(), + res_cont_2.marked.end() ); + } +}; + int test_main(int, char*[]) { SPPRC_Example_Graph g; @@ -637,5 +720,80 @@ int test_main(int, char*[]) BOOST_CHECK(pareto_opt_rc.cost == 3); + SPPRC_Example_Graph g3; + add_vertex( SPPRC_Example_Graph_Vert_Prop( 0, 0, 1000 ), g3 ); + add_vertex( SPPRC_Example_Graph_Vert_Prop( 1, 0, 1000 ), g3 ); + add_vertex( SPPRC_Example_Graph_Vert_Prop( 2, 0, 974 ), g3 ); + add_vertex( SPPRC_Example_Graph_Vert_Prop( 3, 0, 972 ), g3 ); + add_vertex( SPPRC_Example_Graph_Vert_Prop( 4, 0, 967 ), g3 ); + add_vertex( SPPRC_Example_Graph_Vert_Prop( 5, 678, 801 ), g3 ); + add_edge( 0, 2, SPPRC_Example_Graph_Arc_Prop( 0, 0, 16 ), g3 ); + add_edge( 0, 3, SPPRC_Example_Graph_Arc_Prop( 1, 0, 18 ), g3 ); + add_edge( 0, 4, SPPRC_Example_Graph_Arc_Prop( 2, 0, 23 ), g3 ); + add_edge( 0, 5, SPPRC_Example_Graph_Arc_Prop( 3, 0, 25 ), g3 ); + add_edge( 2, 3, SPPRC_Example_Graph_Arc_Prop( 4, 0, 33 ), g3 ); + add_edge( 2, 4, SPPRC_Example_Graph_Arc_Prop( 5, 0, 15 ), g3 ); + add_edge( 2, 5, SPPRC_Example_Graph_Arc_Prop( 6, 0, 33 ), g3 ); + add_edge( 2, 1, SPPRC_Example_Graph_Arc_Prop( 7, 0, 16 ), g3 ); + add_edge( 3, 2, SPPRC_Example_Graph_Arc_Prop( 8, 0, 33 ), g3 ); + add_edge( 3, 4, SPPRC_Example_Graph_Arc_Prop( 9, 0, 35 ), g3 ); + add_edge( 3, 5, SPPRC_Example_Graph_Arc_Prop( 10, 0, 21 ), g3 ); + add_edge( 3, 1, SPPRC_Example_Graph_Arc_Prop( 11, 0, 18 ), g3 ); + add_edge( 4, 2, SPPRC_Example_Graph_Arc_Prop( 12, 0, 15 ), g3 ); + add_edge( 4, 3, SPPRC_Example_Graph_Arc_Prop( 13, 0, 35 ), g3 ); + add_edge( 4, 5, SPPRC_Example_Graph_Arc_Prop( 14, 0, 25 ), g3 ); + add_edge( 4, 1, SPPRC_Example_Graph_Arc_Prop( 15, 0, 23 ), g3 ); + add_edge( 5, 2, SPPRC_Example_Graph_Arc_Prop( 16, 0, 33 ), g3 ); + add_edge( 5, 3, SPPRC_Example_Graph_Arc_Prop( 17, 0, 21 ), g3 ); + add_edge( 5, 4, SPPRC_Example_Graph_Arc_Prop( 18, 0, 25 ), g3 ); + add_edge( 5, 1, SPPRC_Example_Graph_Arc_Prop( 19, 0, 25 ), g3 ); + + std::vector::edge_descriptor> > + pareto_opt_marked_solutions; + std::vector pareto_opt_marked_resource_containers; + + typename graph_traits::vertex_descriptor g3_source = 0, g3_target = 1; + r_c_shortest_paths( g3, + get( &SPPRC_Example_Graph_Vert_Prop::num, g3 ), + get( &SPPRC_Example_Graph_Arc_Prop::num, g3 ), + g3_source, + g3_target, + pareto_opt_marked_solutions, + pareto_opt_marked_resource_containers, + spp_spptw_marked_res_cont( 0, 0, 0 ), + ref_spptw_marked(), + dominance_spptw_marked(), + std::allocator + >(), + default_r_c_shortest_paths_visitor() ); + + BOOST_CHECK(!pareto_opt_marked_solutions.empty()); + std::vector::edge_descriptor> >::const_iterator path_it, path_end_it; + for (path_it = pareto_opt_marked_solutions.begin(), path_end_it = pareto_opt_marked_solutions.end(); path_it != path_end_it; ++path_it) { + const std::vector::edge_descriptor> &path = *path_it; + BOOST_CHECK(!path.empty()); + + const typename graph_traits::edge_descriptor front = path.front(); + BOOST_CHECK(boost::target(front, g3) == g3_target); + + std::vector::edge_descriptor>::const_iterator edge_it, edge_it_end; + typename graph_traits::edge_descriptor prev_edge = front; + + for(edge_it = path.begin() + 1, edge_it_end = path.end(); edge_it != edge_it_end; ++edge_it) { + typename graph_traits::edge_descriptor edge = *edge_it; + + typename graph_traits::vertex_descriptor prev_end, current_end; + prev_end = boost::source(prev_edge, g3); + current_end = boost::target(edge, g3); + BOOST_CHECK(prev_end == current_end); + + prev_edge = edge; + } + + const typename graph_traits::edge_descriptor back = path.back(); + BOOST_CHECK(boost::source(back, g3) == g3_source); + } + return 0; } From 67a32c26b25a55c72c13fe96c89c9ec0f7b284c1 Mon Sep 17 00:00:00 2001 From: Mateusz Polnik Date: Tue, 4 Jul 2017 23:21:27 +0100 Subject: [PATCH 03/21] Fix read/writes outside allocated memory. Remove is_valid assertions - explain a scenario where they do not work correctly. --- include/boost/graph/r_c_shortest_paths.hpp | 210 +++++++++------------ 1 file changed, 85 insertions(+), 125 deletions(-) diff --git a/include/boost/graph/r_c_shortest_paths.hpp b/include/boost/graph/r_c_shortest_paths.hpp index 7e490fc7d..ab34c9328 100644 --- a/include/boost/graph/r_c_shortest_paths.hpp +++ b/include/boost/graph/r_c_shortest_paths.hpp @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include #include @@ -21,12 +23,12 @@ namespace boost { // r_c_shortest_paths_label struct template -struct r_c_shortest_paths_label +struct r_c_shortest_paths_label : public boost::enable_shared_from_this > { r_c_shortest_paths_label ( const unsigned long n, const Resource_Container& rc = Resource_Container(), - const r_c_shortest_paths_label* const pl = 0, + const boost::shared_ptr > pl = nullptr, const typename graph_traits::edge_descriptor& ed = graph_traits::edge_descriptor(), const typename graph_traits::vertex_descriptor& vd = @@ -37,8 +39,7 @@ struct r_c_shortest_paths_label pred_edge( ed ), resident_vertex( vd ), b_is_dominated( false ), - b_is_processed( false ), - b_is_valid( true ) + b_is_processed( false ) {} r_c_shortest_paths_label& operator=( const r_c_shortest_paths_label& other ) { @@ -50,12 +51,11 @@ struct r_c_shortest_paths_label } const unsigned long num; Resource_Container cumulated_resource_consumption; - const r_c_shortest_paths_label* const p_pred_label; + const boost::shared_ptr > p_pred_label; const typename graph_traits::edge_descriptor pred_edge; const typename graph_traits::vertex_descriptor resident_vertex; bool b_is_dominated; bool b_is_processed; - bool b_is_valid; }; // r_c_shortest_paths_label template @@ -63,7 +63,6 @@ inline bool operator== ( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - assert (l1.b_is_valid && l2.b_is_valid); return l1.cumulated_resource_consumption == l2.cumulated_resource_consumption; } @@ -73,17 +72,15 @@ inline bool operator!= ( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - assert (l1.b_is_valid && l2.b_is_valid); return !( l1 == l2 ); } template inline bool operator< -( const r_c_shortest_paths_label& l1, +( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - assert (l1.b_is_valid && l2.b_is_valid); return l1.cumulated_resource_consumption < l2.cumulated_resource_consumption; } @@ -93,7 +90,6 @@ inline bool operator> ( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - assert (l1.b_is_valid && l2.b_is_valid); return l2.cumulated_resource_consumption < l1.cumulated_resource_consumption; } @@ -103,7 +99,6 @@ inline bool operator<= ( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - assert (l1.b_is_valid && l2.b_is_valid); return l1 < l2 || l1 == l2; } @@ -113,53 +108,39 @@ inline bool operator>= ( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - assert (l1.b_is_valid && l2.b_is_valid); return l2 < l1 || l1 == l2; } -namespace detail { +template +inline bool operator< + ( const boost::shared_ptr > &t, + const boost::shared_ptr > &u) { + return *t < *u; +} -// ks_smart_pointer class -// from: -// Kuhlins, S.; Schader, M. (1999): -// Die C++-Standardbibliothek -// Springer, Berlin -// p. 333 f. -template -class ks_smart_pointer -{ -public: - ks_smart_pointer( T* ptt = 0 ) : pt( ptt ) {} - ks_smart_pointer( const ks_smart_pointer& other ) : pt( other.pt ) {} - ks_smart_pointer& operator=( const ks_smart_pointer& other ) - { pt = other.pt; return *this; } - ~ks_smart_pointer() {} - T& operator*() const { return *pt; } - T* operator->() const { return pt; } - T* get() const { return pt; } - operator T*() const { return pt; } - friend bool operator==( const ks_smart_pointer& t, - const ks_smart_pointer& u ) - { return *t.pt == *u.pt; } - friend bool operator!=( const ks_smart_pointer& t, - const ks_smart_pointer& u ) - { return *t.pt != *u.pt; } - friend bool operator<( const ks_smart_pointer& t, - const ks_smart_pointer& u ) - { return *t.pt < *u.pt; } - friend bool operator>( const ks_smart_pointer& t, - const ks_smart_pointer& u ) - { return *t.pt > *u.pt; } - friend bool operator<=( const ks_smart_pointer& t, - const ks_smart_pointer& u ) - { return *t.pt <= *u.pt; } - friend bool operator>=( const ks_smart_pointer& t, - const ks_smart_pointer& u ) - { return *t.pt >= *u.pt; } -private: - T* pt; -}; // ks_smart_pointer +template +inline bool operator<=( const boost::shared_ptr > &t, + const boost::shared_ptr > &u ) { + return *t <= *u; +} +template +inline bool operator> + ( + const boost::shared_ptr > &t, + const boost::shared_ptr > &u ) { + return *t > *u; +} + +template +inline bool operator>= + ( + const boost::shared_ptr > &t, + const boost::shared_ptr > &u) { + return *t >= *u; +} + +namespace detail { // r_c_shortest_paths_dispatch function (body/implementation) template >::other LAlloc; LAlloc l_alloc; - typedef - ks_smart_pointer - > Splabel; - std::priority_queue, std::greater > + typedef + boost::shared_ptr > Splabel; + std::priority_queue, std::greater > unprocessed_labels; bool b_feasible = true; - r_c_shortest_paths_label* first_label = - l_alloc.allocate( 1 ); - l_alloc.construct - ( first_label, - r_c_shortest_paths_label - ( i_label_num++, - rc, - 0, - typename graph_traits:: - edge_descriptor(), - s ) ); - - Splabel splabel_first_label = Splabel( first_label ); + Splabel splabel_first_label = boost::allocate_shared >( + l_alloc, + i_label_num++, + rc, + nullptr, + typename graph_traits::edge_descriptor(), + s ); + unprocessed_labels.push( splabel_first_label ); std::vector > vec_vertex_labels_data( num_vertices( g ) ); iterator_property_map >::iterator, @@ -257,7 +232,6 @@ void r_c_shortest_paths_dispatch while( !unprocessed_labels.empty() && vis.on_enter_loop(unprocessed_labels, g) ) { Splabel cur_label = unprocessed_labels.top(); - assert (cur_label->b_is_valid); unprocessed_labels.pop(); vis.on_label_popped( *cur_label, g ); // an Splabel object in unprocessed_labels and the respective Splabel @@ -272,7 +246,6 @@ void r_c_shortest_paths_dispatch // 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 - assert (cur_label->b_is_valid); if( !cur_label->b_is_dominated ) { typename boost::graph_traits::vertex_descriptor @@ -289,7 +262,6 @@ void r_c_shortest_paths_dispatch while( outer_iter != list_labels_cur_vertex.end() ) { Splabel cur_outer_splabel = *outer_iter; - assert (cur_outer_splabel->b_is_valid); typename std::list::iterator inner_iter = outer_iter; if( !b_outer_iter_at_or_beyond_last_valid_pos_for_dominance && outer_iter == @@ -312,7 +284,6 @@ void r_c_shortest_paths_dispatch while( inner_iter != list_labels_cur_vertex.end() ) { Splabel cur_inner_splabel = *inner_iter; - assert (cur_inner_splabel->b_is_valid); if( dominance( cur_outer_splabel-> cumulated_resource_consumption, cur_inner_splabel-> @@ -323,9 +294,7 @@ void r_c_shortest_paths_dispatch list_labels_cur_vertex.erase( buf ); if( cur_inner_splabel->b_is_processed ) { - cur_inner_splabel->b_is_valid = false; - l_alloc.destroy( cur_inner_splabel.get() ); - l_alloc.deallocate( cur_inner_splabel.get(), 1 ); + cur_inner_splabel.reset(); } else cur_inner_splabel->b_is_dominated = true; @@ -342,12 +311,9 @@ void r_c_shortest_paths_dispatch ++outer_iter; list_labels_cur_vertex.erase( buf ); b_outer_iter_erased = true; - assert (cur_outer_splabel->b_is_valid); if( cur_outer_splabel->b_is_processed ) { - cur_outer_splabel->b_is_valid = false; - l_alloc.destroy( cur_outer_splabel.get() ); - l_alloc.deallocate( cur_outer_splabel.get(), 1 ); + cur_outer_splabel.reset(); } else cur_outer_splabel->b_is_dominated = true; @@ -369,28 +335,22 @@ void r_c_shortest_paths_dispatch list_labels_cur_vertex.size() - 1); } } - assert (b_all_pareto_optimal_solutions || cur_label->b_is_valid); if( !b_all_pareto_optimal_solutions && cur_label->resident_vertex == t ) { // the devil don't sleep if( cur_label->b_is_dominated ) { - cur_label->b_is_valid = false; - l_alloc.destroy( cur_label.get() ); - l_alloc.deallocate( cur_label.get(), 1 ); + cur_label.reset(); } while( unprocessed_labels.size() ) { Splabel l = unprocessed_labels.top(); - assert (l->b_is_valid); unprocessed_labels.pop(); // delete only dominated labels, because nondominated labels are // deleted at the end of the function if( l->b_is_dominated ) { - l->b_is_valid = false; - l_alloc.destroy( l.get() ); - l_alloc.deallocate( l.get(), 1 ); + l.reset(); } } break; @@ -407,16 +367,13 @@ void r_c_shortest_paths_dispatch ++oei ) { b_feasible = true; - r_c_shortest_paths_label* new_label = - l_alloc.allocate( 1 ); - l_alloc.construct( new_label, - r_c_shortest_paths_label - - ( i_label_num++, - cur_label->cumulated_resource_consumption, - cur_label.get(), - *oei, - target( *oei, g ) ) ); + Splabel new_label = boost::allocate_shared >( + 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, @@ -426,29 +383,21 @@ void r_c_shortest_paths_dispatch if( !b_feasible ) { vis.on_label_not_feasible( *new_label, g ); - new_label->b_is_valid = false; - l_alloc.destroy( new_label ); - l_alloc.deallocate( new_label, 1 ); + new_label.reset(); } else { - const r_c_shortest_paths_label& - ref_new_label = *new_label; - vis.on_label_feasible( ref_new_label, g ); - Splabel new_sp_label( new_label ); - vec_vertex_labels[new_sp_label->resident_vertex]. - push_back( new_sp_label ); - unprocessed_labels.push( new_sp_label ); + vis.on_label_feasible( *new_label, g ); + vec_vertex_labels[new_label->resident_vertex]. + push_back( new_label ); + unprocessed_labels.push( new_label ); } } } else { - assert (cur_label->b_is_valid); vis.on_label_dominated( *cur_label, g ); - cur_label->b_is_valid = false; - l_alloc.destroy( cur_label.get() ); - l_alloc.deallocate( cur_label.get(), 1 ); + cur_label.reset(); } } std::list dsplabels = get(vec_vertex_labels, t); @@ -461,16 +410,29 @@ void r_c_shortest_paths_dispatch { std::vector::edge_descriptor> cur_pareto_optimal_path; - const r_c_shortest_paths_label* p_cur_label = - (*csi).get(); - assert (p_cur_label->b_is_valid); + boost::shared_ptr > 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; - assert (p_cur_label->b_is_valid); + + // 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 ) @@ -479,14 +441,12 @@ void r_c_shortest_paths_dispatch } BGL_FORALL_VERTICES_T(i, g, Graph) { - const std::list& list_labels_cur_vertex = vec_vertex_labels[i]; - csi_end = list_labels_cur_vertex.end(); - for( csi = list_labels_cur_vertex.begin(); csi != csi_end; ++csi ) + std::list& list_labels_cur_vertex = vec_vertex_labels[i]; + typename std::list::iterator si = list_labels_cur_vertex.begin(); + const typename std::list::iterator si_end = list_labels_cur_vertex.end(); + for(; si != si_end; ++si ) { - assert ((*csi)->b_is_valid); - (*csi)->b_is_valid = false; - l_alloc.destroy( (*csi).get() ); - l_alloc.deallocate( (*csi).get(), 1 ); + (*si).reset(); } } } // r_c_shortest_paths_dispatch From 726e9530d6c484d59de44b8fa59e89409e37994b Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Thu, 27 Jul 2017 14:34:07 -0600 Subject: [PATCH 04/21] Replace /bin/bash with /bin/sh /bin/bash is a Linuxism. /bin/sh is portable, and this script isn't using any bash-specific features. --- doc/grid_graph_export_svg.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/grid_graph_export_svg.sh b/doc/grid_graph_export_svg.sh index 03e7cb9c6..d12ea2169 100755 --- a/doc/grid_graph_export_svg.sh +++ b/doc/grid_graph_export_svg.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh #======================================================================= # Copyright 2009 Trustees of Indiana University. @@ -16,4 +16,4 @@ inkscape --export-png grid_graph_unwrapped.png --export-id g3150 --export-id-onl inkscape --export-png grid_graph_wrapped.png grid_graph_unindexed.svg # Indexed, unwrapped -inkscape --export-png grid_graph_indexed.png grid_graph_indexed.svg \ No newline at end of file +inkscape --export-png grid_graph_indexed.png grid_graph_indexed.svg From e2db737d1b01327bdb9d3154ce7bfa3331dada34 Mon Sep 17 00:00:00 2001 From: Rasmus Ahlberg Date: Mon, 30 Jul 2018 12:15:25 +0200 Subject: [PATCH 05/21] Don't copy value if not needed, as source's m_property will be set to null when copied. See https://svn.boost.org/trac10/ticket/13544. --- include/boost/graph/detail/adjacency_list.hpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index 6fb497d7e..a8c92df1d 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -2058,13 +2058,17 @@ namespace boost { { typename EdgeList::iterator ei = el.begin(), e_end = el.end(); while (ei != e_end) { - typename EdgeList::value_type ce = *ei; - ++ei; - if (ce.get_target() > u) { + if (ei->get_target() > u) { + typename EdgeList::value_type ce = *ei; + ++ei; el.erase(ce); --ce.get_target(); el.insert(ce); } + else + { + ++ei; + } } } } // namespace detail From e8d7c9fe9bc548ebcd59a5fcc659e216c8c23cd8 Mon Sep 17 00:00:00 2001 From: Rasmus Ahlberg Date: Thu, 23 Aug 2018 16:22:06 +0200 Subject: [PATCH 06/21] Added test case for removing edges bug from previous commit. --- test/Jamfile.v2 | 1 + test/delete_edge.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 test/delete_edge.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 263365cb5..f0c54d146 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -137,6 +137,7 @@ test-suite graph_test : [ run strong_components_test.cpp ] [ run find_flow_cost_bundled_properties_and_named_params_test.cpp ../../test/build//boost_unit_test_framework/static ] [ run max_flow_algorithms_bundled_properties_and_named_params.cpp ../../test/build//boost_unit_test_framework/static ] + [ run remove_edge.cpp ] ; # Run SDB tests only when -sSDB= is set. diff --git a/test/delete_edge.cpp b/test/delete_edge.cpp new file mode 100644 index 000000000..342796b6e --- /dev/null +++ b/test/delete_edge.cpp @@ -0,0 +1,57 @@ +//======================================================================= +// Copyright 2018 +// Authors: Rasmus Ahlberg +// +// 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) +//======================================================================= + +#include + +#include + +#include + +int test_main(int argc, char* argv[]) +{ + typedef int Vertex; + typedef int Edge; + + typedef boost::adjacency_list Graph_t; + + typedef Graph_t::edge_descriptor EdgeDesc; + + + Graph_t m_graph; + + auto v1 = boost::add_vertex(m_graph); + auto v2 = boost::add_vertex(m_graph); + auto v3 = boost::add_vertex(m_graph); + + EdgeDesc ed1; + bool inserted1; + + boost::tie(ed1, inserted1) = boost::add_edge(v3, v1, m_graph); + + BOOST_REQUIRE(inserted1); + + static const int EDGE_VAL = 1234; + + m_graph[ed1] = EDGE_VAL; + + boost::remove_vertex(v2, m_graph); + + std::cout << "ed1 " << m_graph[ed1] << std::endl; + + BOOST_REQUIRE(m_graph[ed1] == EDGE_VAL); + + return 0; +} From 84122c804998c78632b887c1abfd82503f478848 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Fri, 31 Aug 2018 23:53:45 -0400 Subject: [PATCH 07/21] Fixed an incorrect file name in tests and added a git ignore for generated testing files. --- .gitignore | 8 ++++++++ test/Jamfile.v2 | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..36e77b53c --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +cube-fr.dot +cube.dot +disconnected-fr.dot +graphml_test_out.xml +kevin-bacon2.dat +random.dot +triangular-fr.dot +triangular-kk.dot diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index b75673543..15a8a4777 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -138,7 +138,7 @@ test-suite graph_test : [ run strong_components_test.cpp ] [ run find_flow_cost_bundled_properties_and_named_params_test.cpp ../../test/build//boost_unit_test_framework/static ] [ run max_flow_algorithms_bundled_properties_and_named_params.cpp ../../test/build//boost_unit_test_framework/static ] - [ run remove_edge.cpp ] + [ run delete_edge.cpp ] ; # Run SDB tests only when -sSDB= is set. From 19c23ca2555040915660918cc8a6ff2b0d49bf80 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Sat, 1 Sep 2018 14:51:42 -0400 Subject: [PATCH 08/21] Removing references and testing to relaxed heap; relaxed heap is now marked as depreciated. This is due to some testing failures and a lack of use of relaxed_heap. --- include/boost/graph/cycle_canceling.hpp | 44 ++- .../boost/graph/dijkstra_shortest_paths.hpp | 35 +-- .../dijkstra_shortest_paths_no_color_map.hpp | 55 ++-- ...sive_shortest_path_nonnegative_weights.hpp | 76 +++-- include/boost/pending/relaxed_heap.hpp | 1 + test/Jamfile.v2 | 1 - test/dijkstra_heap_performance.cpp | 31 +- test/relaxed_heap_test.cpp | 265 ------------------ 8 files changed, 93 insertions(+), 415 deletions(-) delete mode 100644 test/relaxed_heap_test.cpp diff --git a/include/boost/graph/cycle_canceling.hpp b/include/boost/graph/cycle_canceling.hpp index 46a4b864c..bc7e69099 100644 --- a/include/boost/graph/cycle_canceling.hpp +++ b/include/boost/graph/cycle_canceling.hpp @@ -1,6 +1,6 @@ //======================================================================= // Copyright 2013 University of Warsaw. -// Authors: Piotr Wygocki +// Authors: Piotr Wygocki // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,7 +12,7 @@ // by Ahuja, Magnanti, Orlin. #ifndef BOOST_GRAPH_CYCLE_CANCELING_HPP -#define BOOST_GRAPH_CYCLE_CANCELING_HPP +#define BOOST_GRAPH_CYCLE_CANCELING_HPP #include @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -32,11 +31,11 @@ namespace boost { namespace detail { template -class RecordEdgeMapAndCycleVertex +class RecordEdgeMapAndCycleVertex : public bellman_visitor > { typedef edge_predecessor_recorder PredRec; public: - RecordEdgeMapAndCycleVertex(PredEdgeMap pred, Vertex & v) : + RecordEdgeMapAndCycleVertex(PredEdgeMap pred, Vertex & v) : bellman_visitor(PredRec(pred)), m_v(v), m_pred(pred) {} template @@ -63,27 +62,27 @@ template > ResGraph; ResGraph gres = detail::residual_graph(g, residual_capacity); - + typedef graph_traits ResGTraits; typedef graph_traits 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, + while(!bellman_ford_shortest_paths(gres, N, weight_map(weight). distance_map(distance). visitor(detail::RecordEdgeMapAndCycleVertex(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); @@ -97,7 +96,7 @@ namespace detail { template void cycle_canceling_dispatch2( - const Graph &g, + const Graph &g, Weight weight, Reversed rev, ResidualCapacity residual_capacity, @@ -110,7 +109,7 @@ void cycle_canceling_dispatch2( //setting default distance map template void cycle_canceling_dispatch2( - Graph &g, + Graph &g, Weight weight, Reversed rev, ResidualCapacity residual_capacity, @@ -121,27 +120,27 @@ void cycle_canceling_dispatch2( std::vector d_map(num_vertices(g)); - cycle_canceling(g, weight, rev, residual_capacity, pred, + 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 void cycle_canceling_dispatch1( - Graph &g, - Weight weight, + Graph &g, + Weight weight, Reversed rev, ResidualCapacity residual_capacity, Pred pred, const bgl_named_params& params) { - cycle_canceling_dispatch2(g, weight, rev,residual_capacity, pred, + cycle_canceling_dispatch2(g, weight, rev,residual_capacity, pred, get_param(params, vertex_distance), params); } //setting default predecessors map template void cycle_canceling_dispatch1( - Graph &g, - Weight weight, + Graph &g, + Weight weight, Reversed rev, ResidualCapacity residual_capacity, param_not_found, @@ -151,7 +150,7 @@ void cycle_canceling_dispatch1( 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); + get_param(params, vertex_distance), params); } }//detail @@ -159,12 +158,12 @@ void cycle_canceling_dispatch1( template void cycle_canceling(Graph &g, const bgl_named_params& params) { - cycle_canceling_dispatch1(g, + 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), + choose_pmap(get_param(params, edge_residual_capacity), g, edge_residual_capacity), - get_param(params, vertex_predecessor), + get_param(params, vertex_predecessor), params); } @@ -178,4 +177,3 @@ void cycle_canceling(Graph &g) { } #endif /* BOOST_GRAPH_CYCLE_CANCELING_HPP */ - diff --git a/include/boost/graph/dijkstra_shortest_paths.hpp b/include/boost/graph/dijkstra_shortest_paths.hpp index 10e40f828..f6833f6e1 100644 --- a/include/boost/graph/dijkstra_shortest_paths.hpp +++ b/include/boost/graph/dijkstra_shortest_paths.hpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -53,18 +52,13 @@ namespace boost { * @param old_distance the previous distance to @p vertex */ template - inline void + inline void dijkstra_queue_update(Buffer& Q, Vertex vertex, DistanceType old_distance) { (void)old_distance; Q.update(vertex); } -#ifdef BOOST_GRAPH_DIJKSTRA_TESTING - // This is a misnomer now: it now just refers to the "default heap", which is - // currently d-ary (d=4) but can be changed by a #define. - static bool dijkstra_relaxed_heap = true; -#endif template struct DijkstraVisitorConcept { @@ -187,7 +181,7 @@ namespace boost { // The test here is equivalent to e_weight < 0 if m_combine has a // cancellation law, but always returns false when m_combine is a // projection operator. - if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero)) + if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero)) boost::throw_exception(negative_edge()); // End of test for negative-weight edges. @@ -345,25 +339,7 @@ namespace boost { typedef typename graph_traits::vertex_descriptor Vertex; -#ifdef BOOST_GRAPH_DIJKSTRA_TESTING - if (!dijkstra_relaxed_heap) { - typedef mutable_queue, IndirectCmp, IndexMap> - MutableQueue; - - MutableQueue Q(num_vertices(g), icmp, index_map); - detail::dijkstra_bfs_visitor - bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero); - - breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color); - return; - } -#endif // BOOST_GRAPH_DIJKSTRA_TESTING - -#ifdef BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP - typedef relaxed_heap MutableQueue; - MutableQueue Q(num_vertices(g), icmp, index_map); -#else // Now the default: use a d-ary heap + // Now the default: use a d-ary heap boost::scoped_array index_in_heap_map_holder; typedef detail::vertex_property_map_generator @@ -374,7 +350,6 @@ namespace boost { typedef d_ary_heap_indirect MutableQueue; MutableQueue Q(distance, index_in_heap, compare); -#endif // Relaxed heap detail::dijkstra_bfs_visitor @@ -406,7 +381,7 @@ namespace boost { template inline void dijkstra_shortest_paths @@ -429,7 +404,7 @@ namespace boost { template inline void dijkstra_shortest_paths diff --git a/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp b/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp index b1a9ef589..eb96c0d88 100644 --- a/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp +++ b/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -41,19 +40,12 @@ namespace boost { { typedef typename graph_traits::vertex_descriptor Vertex; typedef typename property_traits::value_type Distance; - + typedef indirect_cmp DistanceIndirectCompare; DistanceIndirectCompare distance_indirect_compare(distance_map, distance_compare); - - // Choose vertex queue type -#if BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP - typedef relaxed_heap - VertexQueue; - VertexQueue vertex_queue(num_vertices(graph), - distance_indirect_compare, - index_map); -#else + + // Default - use d-ary heap (d = 4) typedef detail::vertex_property_map_generator @@ -62,54 +54,53 @@ namespace boost { typedef d_ary_heap_indirect VertexQueue; - + boost::scoped_array index_in_heap_map_holder; IndexInHeapMap index_in_heap = IndexInHeapMapHelper::build(graph, index_map, - index_in_heap_map_holder); + index_in_heap_map_holder); VertexQueue vertex_queue(distance_map, index_in_heap, distance_compare); -#endif - + // 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 = + bool is_neighbor_undiscovered = !distance_compare(neighbor_vertex_distance, distance_infinity); // Attempt to relax the edge bool was_edge_relaxed = relax(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) { @@ -121,9 +112,9 @@ namespace boost { } else { visitor.edge_not_relaxed(current_edge, graph); } - + } // end out edge iteration - + visitor.finish_vertex(min_vertex, graph); } // end while queue not empty } @@ -150,17 +141,17 @@ namespace boost { // 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, @@ -216,7 +207,7 @@ namespace boost { typedef typename property_traits::value_type DistanceType; typename std::vector::size_type vertex_count = is_default_param(distance_map) ? num_vertices(graph) : 1; - + std::vector default_distance_map(vertex_count); detail::dijkstra_no_color_map_dispatch2 diff --git a/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp b/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp index 72b1512c1..6a3aeb168 100644 --- a/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp +++ b/include/boost/graph/successive_shortest_path_nonnegative_weights.hpp @@ -1,6 +1,6 @@ //======================================================================= // Copyright 2013 University of Warsaw. -// Authors: Piotr Wygocki +// Authors: Piotr Wygocki // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,7 +11,7 @@ // by Ahuja, Magnanti, Orlin. #ifndef BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP -#define BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP +#define BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP #include @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -29,9 +28,9 @@ namespace boost { namespace detail { - + template -class MapReducedWeight : +class MapReducedWeight : public put_get_helper::value_type, MapReducedWeight > { typedef graph_traits gtraits; public: @@ -39,11 +38,11 @@ class MapReducedWeight : typedef typename property_traits::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) : + 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); + return get(distance_, source(v, g_)) - get(distance_,target(v, g_)) + get(weight_, v); } private: const Graph & g_; @@ -53,7 +52,7 @@ class MapReducedWeight : }; template -MapReducedWeight +MapReducedWeight make_mapReducedWeight(const Graph & g, Weight w, Distance d, Reversed r) { return MapReducedWeight(g, w, d, r); } @@ -63,21 +62,21 @@ make_mapReducedWeight(const Graph & g, Weight w, Distance d, Reversed r) { template void successive_shortest_path_nonnegative_weights( - const Graph &g, - typename graph_traits::vertex_descriptor s, + const Graph &g, + typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, - Weight weight, + Weight weight, Reversed rev, VertexIndex index, - Pred pred, + Pred pred, Distance distance, Distance2 distance_prev) { filtered_graph > gres = detail::residual_graph(g, residual_capacity); typedef typename graph_traits::edge_descriptor edge_descriptor; - + BGL_FORALL_EDGES_T(e, g, Graph) { put(residual_capacity, e, get(capacity, e)); } @@ -90,7 +89,7 @@ void successive_shortest_path_nonnegative_weights( BGL_FORALL_VERTICES_T(v, g, Graph) { put(pred, v, edge_descriptor()); } - dijkstra_shortest_paths(gres, s, + dijkstra_shortest_paths(gres, s, weight_map(detail::make_mapReducedWeight(gres, weight, distance_prev, rev)). distance_map(distance). vertex_index_map(index). @@ -113,8 +112,8 @@ namespace detail { template void successive_shortest_path_nonnegative_weights_dispatch3( - const Graph &g, - typename graph_traits::vertex_descriptor s, + const Graph &g, + typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, @@ -130,8 +129,8 @@ void successive_shortest_path_nonnegative_weights_dispatch3( //setting default distance map template void successive_shortest_path_nonnegative_weights_dispatch3( - Graph &g, - typename graph_traits::vertex_descriptor s, + Graph &g, + typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, @@ -151,8 +150,8 @@ void successive_shortest_path_nonnegative_weights_dispatch3( template void successive_shortest_path_nonnegative_weights_dispatch2( - Graph &g, - typename graph_traits::vertex_descriptor s, + Graph &g, + typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, @@ -168,8 +167,8 @@ void successive_shortest_path_nonnegative_weights_dispatch2( //setting default distance map template void successive_shortest_path_nonnegative_weights_dispatch2( - Graph &g, - typename graph_traits::vertex_descriptor s, + Graph &g, + typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, @@ -177,7 +176,7 @@ void successive_shortest_path_nonnegative_weights_dispatch2( Reversed rev, VertexIndex index, Pred pred, - param_not_found, + param_not_found, const bgl_named_params& params) { typedef typename property_traits::value_type D; @@ -190,12 +189,12 @@ void successive_shortest_path_nonnegative_weights_dispatch2( template void successive_shortest_path_nonnegative_weights_dispatch1( - Graph &g, - typename graph_traits::vertex_descriptor s, + Graph &g, + typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, - Weight weight, + Weight weight, Reversed rev, VertexIndex index, Pred pred, @@ -207,12 +206,12 @@ void successive_shortest_path_nonnegative_weights_dispatch1( //setting default predecessors map template void successive_shortest_path_nonnegative_weights_dispatch1( - Graph &g, - typename graph_traits::vertex_descriptor s, + Graph &g, + typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, - Weight weight, + Weight weight, Reversed rev, VertexIndex index, param_not_found, @@ -220,9 +219,9 @@ void successive_shortest_path_nonnegative_weights_dispatch1( typedef typename graph_traits::edge_descriptor edge_descriptor; std::vector pred_vec(num_vertices(g)); - successive_shortest_path_nonnegative_weights_dispatch2(g, s, t, capacity, residual_capacity, weight, rev, index, + 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); + get_param(params, vertex_distance), params); } }//detail @@ -230,26 +229,26 @@ void successive_shortest_path_nonnegative_weights_dispatch1( template void successive_shortest_path_nonnegative_weights( - Graph &g, - typename graph_traits::vertex_descriptor s, + Graph &g, + typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, const bgl_named_params& params) { - - return detail::successive_shortest_path_nonnegative_weights_dispatch1(g, s, t, + + 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), + 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), + get_param(params, vertex_predecessor), params); } template void successive_shortest_path_nonnegative_weights( Graph &g, - typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t) { bgl_named_params params(0); successive_shortest_path_nonnegative_weights(g, s, t, params); @@ -258,4 +257,3 @@ void successive_shortest_path_nonnegative_weights( }//boost #endif /* BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP */ - diff --git a/include/boost/pending/relaxed_heap.hpp b/include/boost/pending/relaxed_heap.hpp index 8be448473..d2c492e9d 100644 --- a/include/boost/pending/relaxed_heap.hpp +++ b/include/boost/pending/relaxed_heap.hpp @@ -6,6 +6,7 @@ // Authors: Douglas Gregor // Andrew Lumsdaine +#warning "Use of relaxed_heap is depreciated; please use the standard heap functions." #ifndef BOOST_RELAXED_HEAP_HEADER #define BOOST_RELAXED_HEAP_HEADER diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 15a8a4777..5ea4da3b7 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -50,7 +50,6 @@ test-suite graph_test : [ run dijkstra_heap_performance.cpp : 10000 ] [ run dijkstra_no_color_map_compare.cpp : 10000 ] [ run dominator_tree_test.cpp ] - [ run relaxed_heap_test.cpp : 5000 15000 ] [ compile edge_list_cc.cpp ] [ compile filtered_graph_cc.cpp ] [ run generator_test.cpp ] diff --git a/test/dijkstra_heap_performance.cpp b/test/dijkstra_heap_performance.cpp index 2cab3fbf2..8e290224b 100644 --- a/test/dijkstra_heap_performance.cpp +++ b/test/dijkstra_heap_performance.cpp @@ -50,7 +50,7 @@ struct show_events_visitor : dijkstra_visitor<> template -void run_test(const Graph& g, const char* name, Kind kind, +void run_test(const Graph& g, const char* name, Kind kind, const std::vector& correct_distances) { std::vector distances(num_vertices(g)); @@ -111,11 +111,7 @@ int main(int argc, char* argv[]) std::cout << "Running Dijkstra's with binary heap..."; std::cout.flush(); timer t; -#ifdef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR - dijkstra_heap_kind = dijkstra_binary_heap; -#else - dijkstra_relaxed_heap = false; -#endif + dijkstra_shortest_paths(g, vertex(0, g), distance_map( boost::make_iterator_property_map( @@ -123,19 +119,11 @@ int main(int argc, char* argv[]) double binary_heap_time = t.elapsed(); std::cout << binary_heap_time << " seconds.\n"; - // Run relaxed heap version -#ifdef BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP - std::cout << "Running Dijkstra's with relaxed heap..."; -#else + std::cout << "Running Dijkstra's with d-ary heap (d=4)..."; -#endif std::cout.flush(); t.restart(); -#ifdef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR - dijkstra_heap_kind = dijkstra_relaxed_heap; -#else - dijkstra_relaxed_heap = true; -#endif + dijkstra_shortest_paths(g, vertex(0, g), distance_map( boost::make_iterator_property_map( @@ -148,18 +136,11 @@ int main(int argc, char* argv[]) BOOST_TEST(binary_heap_distances == relaxed_heap_distances); // Run Michael's no-color-map version -#ifdef BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP - std::cout << "Running Dijkstra's (no color map) with relaxed heap..."; -#else + std::cout << "Running Dijkstra's (no color map) with d-ary heap (d=4)..."; -#endif std::cout.flush(); t.restart(); -#ifdef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR - dijkstra_heap_kind = dijkstra_relaxed_heap; -#else - dijkstra_relaxed_heap = true; -#endif + dijkstra_shortest_paths_no_color_map (g, vertex(0, g), boost::dummy_property_map(), diff --git a/test/relaxed_heap_test.cpp b/test/relaxed_heap_test.cpp deleted file mode 100644 index 3bad264a7..000000000 --- a/test/relaxed_heap_test.cpp +++ /dev/null @@ -1,265 +0,0 @@ -// 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_DEBUG -# define BOOST_RELAXED_HEAP_DEBUG 0 -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef std::vector > values_type; -values_type values; - -struct less_extvalue -{ - typedef bool result_type; - - bool operator()(unsigned x, unsigned y) const - { - assert(values[x] && values[y]); - return values[x] < values[y]; - } -}; - -using namespace std; - -boost::optional get_min_value() -{ - boost::optional min_value; - for (unsigned i = 0; i < values.size(); ++i) { - if (values[i]) { - if (!min_value || *values[i] < *min_value) min_value = values[i]; - } - } - return min_value; -} - -void interactive_test() -{ - unsigned max_values; - cout << "Enter max number of values in the heap> "; - cin >> max_values; - - values.resize(max_values); - boost::relaxed_heap heap(max_values); - - char option; - do { - cout << "Enter command> "; - if (cin >> option) { - switch (option) { - case 'i': case 'I': - { - unsigned index; - double value; - if (cin >> index >> value) { - if (index >= values.size()) cout << "Index out of range.\n"; - else if (values[index]) cout << "Already in queue.\n"; - else { - values[index] = value; - heap.push(index); - heap.dump_tree(); - } - } - } - break; - - case 'u': case 'U': - { - unsigned index; - double value; - if (cin >> index >> value) { - if (index >= values.size()) cout << "Index out of range.\n"; - else if (!values[index]) cout << "Not in queue.\n"; - else { - values[index] = value; - heap.update(index); - heap.dump_tree(); - } - } - } - break; - - case 'r': case 'R': - { - unsigned index; - if (cin >> index) { - if (index >= values.size()) cout << "Index out of range.\n"; - else if (!values[index]) cout << "Not in queue.\n"; - else { - heap.remove(index); - heap.dump_tree(); - } - } - } - break; - - case 't': case 'T': - { - if (boost::optional min_value = get_min_value()) { - cout << "Top value is (" << heap.top() << ", " - << *values[heap.top()] << ").\n"; - BOOST_CHECK(*min_value == *values[heap.top()]); - } else { - cout << "Queue is empty.\n"; - BOOST_CHECK(heap.empty()); - } - } - break; - - case 'd': case 'D': - { - if (boost::optional min_value = get_min_value()) { - unsigned victim = heap.top(); - double value = *values[victim]; - cout << "Removed top value (" << victim << ", " << value << ")\n"; - BOOST_CHECK(*min_value == value); - - heap.pop(); - heap.dump_tree(); - values[victim].reset(); - } else { - cout << "Queue is empty.\n"; - BOOST_CHECK(heap.empty()); - } - } - break; - - case 'q': case 'Q': - break; - - default: - cout << "Unknown command '" << option << "'.\n"; - } - } - } while (cin && option != 'q' && option != 'Q'); -} - -void random_test(int n, int iterations, int seed) -{ - values.resize(n); - boost::relaxed_heap heap(n); - boost::minstd_rand gen(seed); - boost::uniform_int rand_index(0, n-1); - boost::uniform_real<> rand_value(-1000.0, 1000.0); - boost::uniform_int which_option(0, 3); - - cout << n << std::endl; - -#if BOOST_RELAXED_HEAP_DEBUG > 1 - heap.dump_tree(); -#endif - - BOOST_REQUIRE(heap.valid()); - -#if BOOST_RELAXED_HEAP_DEBUG == 0 - boost::progress_display progress(iterations); -#endif - - for (int iteration = 0; iteration < iterations; ++iteration) { -#if BOOST_RELAXED_HEAP_DEBUG > 1 - std::cout << "Iteration #" << iteration << std::endl; -#endif - unsigned victim = rand_index(gen); - if (values[victim]) { - switch (which_option(gen)) { - case 0: case 3: - { - // Update with a smaller weight - boost::uniform_real<> rand_smaller((rand_value.min)(), *values[victim]); - values[victim] = rand_smaller(gen); - assert(*values[victim] >= (rand_smaller.min)()); - assert(*values[victim] <= (rand_smaller.max)()); - -#if BOOST_RELAXED_HEAP_DEBUG > 0 - cout << "u " << victim << " " << *values[victim] << std::endl; - cout.flush(); -#endif - heap.update(victim); - } - break; - - case 1: - { - // Delete minimum value in the queue. - victim = heap.top(); - double top_value = *values[victim]; - BOOST_CHECK(*get_min_value() == top_value); - if (*get_min_value() != top_value) return; -#if BOOST_RELAXED_HEAP_DEBUG > 0 - cout << "d" << std::endl; - cout.flush(); -#endif - heap.pop(); - values[victim].reset(); -#if BOOST_RELAXED_HEAP_DEBUG > 1 - cout << "(Removed " << victim << ")\n"; -#endif // BOOST_RELAXED_HEAP_DEBUG > 1 - } - break; - - case 2: - { - // Just remove this value from the queue completely - values[victim].reset(); -#if BOOST_RELAXED_HEAP_DEBUG > 0 - cout << "r " << victim << std::endl; - cout.flush(); -#endif - heap.remove(victim); - } - break; - - default: - cout << "Random number generator failed." << endl; - BOOST_CHECK(false); - return; - break; - } - } else { - values[victim] = rand_value(gen); - assert(*values[victim] >= (rand_value.min)()); - assert(*values[victim] <= (rand_value.max)()); - -#if BOOST_RELAXED_HEAP_DEBUG > 0 - cout << "i " << victim << " " << *values[victim] << std::endl; - cout.flush(); -#endif - heap.push(victim); - } - -#if BOOST_RELAXED_HEAP_DEBUG > 1 - heap.dump_tree(); -#endif // BOOST_RELAXED_HEAP_DEBUG > 1 - - BOOST_REQUIRE(heap.valid()); - -#if BOOST_RELAXED_HEAP_DEBUG == 0 - ++progress; -#endif - } -} - -int test_main(int argc, char* argv[]) -{ - if (argc >= 3) { - int n = boost::lexical_cast(argv[1]); - int iterations = boost::lexical_cast(argv[2]); - int seed = (argc >= 4? boost::lexical_cast(argv[3]) : 1); - random_test(n, iterations, seed); - } else interactive_test(); - return 0; -} From 98164bf937e5c10a9ddf6d484db9963e8b418bbf Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Sat, 1 Sep 2018 17:59:02 -0400 Subject: [PATCH 09/21] Removed dead code/comment block from iteration macros. --- include/boost/graph/iteration_macros.hpp | 39 ------------------------ 1 file changed, 39 deletions(-) diff --git a/include/boost/graph/iteration_macros.hpp b/include/boost/graph/iteration_macros.hpp index 2bf40f958..80845aeb0 100644 --- a/include/boost/graph/iteration_macros.hpp +++ b/include/boost/graph/iteration_macros.hpp @@ -17,45 +17,6 @@ #define BGL_FIRST(linenum) (BGL_RANGE(linenum).first) #define BGL_LAST(linenum) (BGL_RANGE(linenum).second) -/* - BGL_FORALL_VERTICES_T(v, g, graph_t) // This is on line 9 - expands to the following, but all on the same line - - for (typename boost::graph_traits::vertex_iterator - bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second; - bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) - for (typename boost::graph_traits::vertex_descriptor v; - bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false; - ++bgl_first_9) - - The purpose of having two for-loops is just to provide a place to - declare both the iterator and value variables. There is really only - one loop. The stopping condition gets executed two more times than it - usually would be, oh well. The reason for the bgl_first_9 = bgl_last_9 - in the outer for-loop is in case the user puts a break statement - in the inner for-loop. - - The other macros work in a similar fashion. - - Use the _T versions when the graph type is a template parameter or - dependent on a template parameter. Otherwise use the non _T versions. - - ----------------------- - 6/9/09 THK - - The above contains two calls to the vertices function. I modified these - macros to expand to - - for (std::pair::vertex_iterator, - typename boost::graph_traits::vertex_iterator> bgl_range_9 = vertices(g); - bgl_range_9.first != bgl_range_9.second; - bgl_range_9.first = bgl_range_9.second) - for (typename boost::graph_traits::vertex_descriptor v; - bgl_range_9.first != bgl_range_9.second ? (v = *bgl_range_9.first, true) : false; - ++bgl_range_9.first) - - */ - #define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \ for (std::pair::vertex_iterator, \ From 283675d7928dfb215237d645a583c853639849c5 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Wed, 5 Sep 2018 14:33:43 -0400 Subject: [PATCH 10/21] Use of nullptr when it is too soon to include that feature. --- include/boost/graph/r_c_shortest_paths.hpp | 458 ++++++++++----------- 1 file changed, 229 insertions(+), 229 deletions(-) diff --git a/include/boost/graph/r_c_shortest_paths.hpp b/include/boost/graph/r_c_shortest_paths.hpp index ab34c9328..918b7e492 100644 --- a/include/boost/graph/r_c_shortest_paths.hpp +++ b/include/boost/graph/r_c_shortest_paths.hpp @@ -2,7 +2,7 @@ // Copyright Michael Drexl 2005, 2006. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at +// (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 @@ -26,19 +26,19 @@ template struct r_c_shortest_paths_label : public boost::enable_shared_from_this > { r_c_shortest_paths_label - ( const unsigned long n, - const Resource_Container& rc = Resource_Container(), - const boost::shared_ptr > pl = nullptr, - const typename graph_traits::edge_descriptor& ed = - graph_traits::edge_descriptor(), - const typename graph_traits::vertex_descriptor& vd = + ( const unsigned long n, + const Resource_Container& rc = Resource_Container(), + const boost::shared_ptr > pl = NULL, + const typename graph_traits::edge_descriptor& ed = + graph_traits::edge_descriptor(), + const typename graph_traits::vertex_descriptor& vd = graph_traits::vertex_descriptor() ) - : num( n ), - cumulated_resource_consumption( rc ), - p_pred_label( pl ), - pred_edge( ed ), - resident_vertex( vd ), - b_is_dominated( false ), + : 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 ) @@ -60,19 +60,19 @@ struct r_c_shortest_paths_label : public boost::enable_shared_from_this inline bool operator== -( const r_c_shortest_paths_label& l1, +( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - return + return l1.cumulated_resource_consumption == l2.cumulated_resource_consumption; } template inline bool operator!= -( const r_c_shortest_paths_label& l1, +( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - return + return !( l1 == l2 ); } @@ -81,31 +81,31 @@ inline bool operator< ( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - return + return l1.cumulated_resource_consumption < l2.cumulated_resource_consumption; } template inline bool operator> -( const r_c_shortest_paths_label& l1, +( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - return + return l2.cumulated_resource_consumption < l1.cumulated_resource_consumption; } template inline bool operator<= -( const r_c_shortest_paths_label& l1, +( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { - return + return l1 < l2 || l1 == l2; } template inline bool operator>= -( const r_c_shortest_paths_label& l1, +( const r_c_shortest_paths_label& l1, const r_c_shortest_paths_label& l2 ) { return l2 < l1 || l1 == l2; @@ -143,43 +143,43 @@ inline bool operator>= namespace detail { // r_c_shortest_paths_dispatch function (body/implementation) -template void r_c_shortest_paths_dispatch -( const Graph& g, - const VertexIndexMap& vertex_index_map, - const EdgeIndexMap& /*edge_index_map*/, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, +( const Graph& g, + const VertexIndexMap& vertex_index_map, + const EdgeIndexMap& /*edge_index_map*/, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, // each inner vector corresponds to a pareto-optimal path std::vector ::edge_descriptor> >& pareto_optimal_solutions, + ::edge_descriptor> >& pareto_optimal_solutions, std::vector - & pareto_optimal_resource_containers, - bool b_all_pareto_optimal_solutions, - // to initialize the first label/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, + const Resource_Container& rc, + Resource_Extension_Function& ref, + Dominance_Function& dominance, // to specify the memory management strategy for the labels - Label_Allocator /*la*/, + Label_Allocator /*la*/, Visitor vis ) { pareto_optimal_resource_containers.clear(); pareto_optimal_solutions.clear(); size_t i_label_num = 0; - typedef - typename + typedef + typename Label_Allocator::template rebind >::other LAlloc; @@ -192,10 +192,10 @@ void r_c_shortest_paths_dispatch bool b_feasible = true; Splabel splabel_first_label = boost::allocate_shared >( l_alloc, - i_label_num++, - rc, - nullptr, - typename graph_traits::edge_descriptor(), + i_label_num++, + rc, + NULL, + typename graph_traits::edge_descriptor(), s ); unprocessed_labels.push( splabel_first_label ); @@ -205,7 +205,7 @@ void r_c_shortest_paths_dispatch vec_vertex_labels(vec_vertex_labels_data.begin(), vertex_index_map); vec_vertex_labels[s].push_back( splabel_first_label ); typedef - std::vector::iterator> + std::vector::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 ) ); @@ -222,7 +222,7 @@ void r_c_shortest_paths_dispatch iterator_property_map::iterator, VertexIndexMap> vec_last_valid_index_for_dominance (vec_last_valid_index_for_dominance_data.begin(), vertex_index_map); - std::vector + std::vector b_vec_vertex_already_checked_for_dominance_data( num_vertices( g ), false ); iterator_property_map::iterator, VertexIndexMap> b_vec_vertex_already_checked_for_dominance @@ -234,37 +234,37 @@ void r_c_shortest_paths_dispatch 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 of vec_vertex_labels share their + // an Splabel object in unprocessed_labels and the respective Splabel + // object in the respective list 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 + // 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 + // 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::vertex_descriptor i_cur_resident_vertex = cur_label->resident_vertex; - std::list& list_labels_cur_vertex = + std::list& 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] + 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::iterator outer_iter = + typename std::list::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::iterator inner_iter = outer_iter; - if( !b_outer_iter_at_or_beyond_last_valid_pos_for_dominance - && 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; @@ -275,7 +275,7 @@ void r_c_shortest_paths_dispatch } else { - inner_iter = + inner_iter = get(vec_last_valid_positions_for_dominance, i_cur_resident_vertex); ++inner_iter; @@ -285,7 +285,7 @@ void r_c_shortest_paths_dispatch { Splabel cur_inner_splabel = *inner_iter; if( dominance( cur_outer_splabel-> - cumulated_resource_consumption, + cumulated_resource_consumption, cur_inner_splabel-> cumulated_resource_consumption ) ) { @@ -303,7 +303,7 @@ void r_c_shortest_paths_dispatch else ++inner_iter; if( dominance( cur_inner_splabel-> - cumulated_resource_consumption, + cumulated_resource_consumption, cur_outer_splabel-> cumulated_resource_consumption ) ) { @@ -346,7 +346,7 @@ void r_c_shortest_paths_dispatch { Splabel l = unprocessed_labels.top(); unprocessed_labels.pop(); - // delete only dominated labels, because nondominated labels are + // delete only dominated labels, because nondominated labels are // deleted at the end of the function if( l->b_is_dominated ) { @@ -359,25 +359,25 @@ void r_c_shortest_paths_dispatch { cur_label->b_is_processed = true; vis.on_label_not_dominated( *cur_label, g ); - typename graph_traits::vertex_descriptor cur_vertex = + typename graph_traits::vertex_descriptor cur_vertex = cur_label->resident_vertex; typename graph_traits::out_edge_iterator oei, oei_end; - for( boost::tie( oei, oei_end ) = out_edges( cur_vertex, g ); - 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 >( - l_alloc, - i_label_num++, - cur_label->cumulated_resource_consumption, - cur_label, - *oei, + 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, + b_feasible = + ref( g, + new_label->cumulated_resource_consumption, + new_label->p_pred_label->cumulated_resource_consumption, new_label->pred_edge ); if( !b_feasible ) @@ -408,7 +408,7 @@ void r_c_shortest_paths_dispatch { for( ; csi != csi_end; ++csi ) { - std::vector::edge_descriptor> + std::vector::edge_descriptor> cur_pareto_optimal_path; boost::shared_ptr > p_cur_label = *csi; pareto_optimal_resource_containers. @@ -466,13 +466,13 @@ struct default_r_c_shortest_paths_visitor void on_label_dominated( const Label&, const Graph& ) {} template void on_label_not_dominated( const Label&, const Graph& ) {} - template + template 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 +typedef std::allocator default_r_c_shortest_paths_allocator; // default_r_c_shortest_paths_allocator @@ -481,93 +481,93 @@ typedef // first overload: // - return all pareto-optimal solutions // - specify Label_Allocator and Visitor arguments -template void r_c_shortest_paths -( const Graph& g, - const VertexIndexMap& vertex_index_map, - const EdgeIndexMap& edge_index_map, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, +( const Graph& g, + const VertexIndexMap& vertex_index_map, + const EdgeIndexMap& edge_index_map, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, // each inner vector corresponds to a pareto-optimal path - std::vector::edge_descriptor> >& - pareto_optimal_solutions, - std::vector& pareto_optimal_resource_containers, - // to initialize the first label/resource container + std::vector::edge_descriptor> >& + pareto_optimal_solutions, + std::vector& 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, + 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, + 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, + 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 void r_c_shortest_paths -( const Graph& g, - const VertexIndexMap& vertex_index_map, - const EdgeIndexMap& edge_index_map, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - std::vector::edge_descriptor>& - pareto_optimal_solution, - Resource_Container& pareto_optimal_resource_container, - // to initialize the first label/resource container +( const Graph& g, + const VertexIndexMap& vertex_index_map, + const EdgeIndexMap& edge_index_map, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + std::vector::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, + 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, + Label_Allocator la, Visitor vis ) { // each inner vector corresponds to a pareto-optimal path - std::vector::edge_descriptor> > + std::vector::edge_descriptor> > pareto_optimal_solutions; std::vector 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, + 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]; @@ -578,83 +578,83 @@ void r_c_shortest_paths // third overload: // - return all pareto-optimal solutions // - use default Label_Allocator and Visitor -template void r_c_shortest_paths -( const Graph& g, - const VertexIndexMap& vertex_index_map, - const EdgeIndexMap& edge_index_map, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, +( const Graph& g, + const VertexIndexMap& vertex_index_map, + const EdgeIndexMap& edge_index_map, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, // each inner vector corresponds to a pareto-optimal path - std::vector::edge_descriptor> >& - pareto_optimal_solutions, - std::vector& pareto_optimal_resource_containers, - // to initialize the first label/resource container + std::vector::edge_descriptor> >& + pareto_optimal_solutions, + std::vector& 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 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(), + 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 void r_c_shortest_paths -( const Graph& g, - const VertexIndexMap& vertex_index_map, - const EdgeIndexMap& edge_index_map, - typename graph_traits::vertex_descriptor s, - typename graph_traits::vertex_descriptor t, - std::vector::edge_descriptor>& - pareto_optimal_solution, - Resource_Container& pareto_optimal_resource_container, - // to initialize the first label/resource container +( const Graph& g, + const VertexIndexMap& vertex_index_map, + const EdgeIndexMap& edge_index_map, + typename graph_traits::vertex_descriptor s, + typename graph_traits::vertex_descriptor t, + std::vector::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 Resource_Container& rc, + const Resource_Extension_Function& ref, const Dominance_Function& dominance ) { // each inner vector corresponds to a pareto-optimal path - std::vector::edge_descriptor> > + std::vector::edge_descriptor> > pareto_optimal_solutions; std::vector 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(), + 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]; @@ -665,26 +665,26 @@ void r_c_shortest_paths // check_r_c_path function -template -void check_r_c_path( const Graph& g, +void check_r_c_path( const Graph& g, const std::vector ::edge_descriptor>& ed_vec_path, - const Resource_Container& initial_resource_levels, - // if true, computed accumulated final resource levels must + ::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 + // 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::edge_descriptor& + 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::edge_descriptor& ed_last_extended_arc ) { size_t i_size_ed_vec_path = ed_vec_path.size(); @@ -693,7 +693,7 @@ void check_r_c_path( const Graph& g, b_feasible = true; else { - if( i_size_ed_vec_path == 1 + 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 @@ -718,21 +718,21 @@ void check_r_c_path( const Graph& g, 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, + 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 ? + b_correctly_extended = + actual_final_resource_levels == desired_final_resource_levels ? true : false; else { - if( actual_final_resource_levels < desired_final_resource_levels + if( actual_final_resource_levels < desired_final_resource_levels || actual_final_resource_levels == desired_final_resource_levels ) b_correctly_extended = true; } From 82fa79e783e197c92c3bac2b0b7ff2e0696d86b8 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Wed, 5 Sep 2018 14:35:26 -0400 Subject: [PATCH 11/21] Inappropriate overuse of 'typename' removed. --- test/r_c_shortest_paths_test.cpp | 242 +++++++++++++++---------------- 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/test/r_c_shortest_paths_test.cpp b/test/r_c_shortest_paths_test.cpp index 7d0864a29..246271780 100644 --- a/test/r_c_shortest_paths_test.cpp +++ b/test/r_c_shortest_paths_test.cpp @@ -1,6 +1,6 @@ // Copyright Michael Drexl 2005, 2006. // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at +// (See accompanying file LICENSE_1_0.txt or copy at // http://boost.org/LICENSE_1_0.txt) #include @@ -20,7 +20,7 @@ using namespace boost; struct SPPRC_Example_Graph_Vert_Prop { - SPPRC_Example_Graph_Vert_Prop( int n = 0, int e = 0, int l = 0 ) + SPPRC_Example_Graph_Vert_Prop( int n = 0, int e = 0, int l = 0 ) : num( n ), eat( e ), lat( l ) {} int num; // earliest arrival time @@ -31,7 +31,7 @@ struct SPPRC_Example_Graph_Vert_Prop struct SPPRC_Example_Graph_Arc_Prop { - SPPRC_Example_Graph_Arc_Prop( int n = 0, int c = 0, int t = 0 ) + SPPRC_Example_Graph_Arc_Prop( int n = 0, int c = 0, int t = 0 ) : num( n ), cost( c ), time( t ) {} int num; // traversal cost @@ -40,11 +40,11 @@ struct SPPRC_Example_Graph_Arc_Prop int time; }; -typedef adjacency_list +typedef adjacency_list SPPRC_Example_Graph; // data structures for spp without resource constraints: @@ -63,13 +63,13 @@ struct spp_no_rc_res_cont int cost; }; -bool operator==( const spp_no_rc_res_cont& res_cont_1, +bool operator==( const spp_no_rc_res_cont& res_cont_1, const spp_no_rc_res_cont& res_cont_2 ) { return ( res_cont_1.cost == res_cont_2.cost ); } -bool operator<( const spp_no_rc_res_cont& res_cont_1, +bool operator<( const spp_no_rc_res_cont& res_cont_1, const spp_no_rc_res_cont& res_cont_2 ) { return ( res_cont_1.cost < res_cont_2.cost ); @@ -79,9 +79,9 @@ bool operator<( const spp_no_rc_res_cont& res_cont_1, class ref_no_res_cont { public: - inline bool operator()( const SPPRC_Example_Graph& g, - spp_no_rc_res_cont& new_cont, - const spp_no_rc_res_cont& old_cont, + inline bool operator()( const SPPRC_Example_Graph& g, + spp_no_rc_res_cont& new_cont, + const spp_no_rc_res_cont& old_cont, graph_traits ::edge_descriptor ed ) const { @@ -94,7 +94,7 @@ class ref_no_res_cont class dominance_no_res_cont { public: - inline bool operator()( const spp_no_rc_res_cont& res_cont_1, + inline bool operator()( const spp_no_rc_res_cont& res_cont_1, const spp_no_rc_res_cont& res_cont_2 ) const { // must be "<=" here!!! @@ -102,15 +102,15 @@ class dominance_no_res_cont return res_cont_1.cost <= res_cont_2.cost; // this is not a contradiction to the documentation // the documentation says: - // "A label $l_1$ dominates a label $l_2$ if and only if both are resident - // at the same vertex, and if, for each resource, the resource consumption - // of $l_1$ is less than or equal to the resource consumption of $l_2$, - // and if there is at least one resource where $l_1$ has a lower resource + // "A label $l_1$ dominates a label $l_2$ if and only if both are resident + // at the same vertex, and if, for each resource, the resource consumption + // of $l_1$ is less than or equal to the resource consumption of $l_2$, + // and if there is at least one resource where $l_1$ has a lower resource // consumption than $l_2$." - // one can think of a new label with a resource consumption equal to that - // of an old label as being dominated by that old label, because the new - // one will have a higher number and is created at a later point in time, - // so one can implicitly use the number or the creation time as a resource + // one can think of a new label with a resource consumption equal to that + // of an old label as being dominated by that old label, because the new + // one will have a higher number and is created at a later point in time, + // so one can implicitly use the number or the creation time as a resource // for tie-breaking } }; @@ -133,14 +133,14 @@ struct spp_spptw_res_cont int time; }; -bool operator==( const spp_spptw_res_cont& res_cont_1, +bool operator==( const spp_spptw_res_cont& res_cont_1, const spp_spptw_res_cont& res_cont_2 ) { - return ( res_cont_1.cost == res_cont_2.cost + return ( res_cont_1.cost == res_cont_2.cost && res_cont_1.time == res_cont_2.time ); } -bool operator<( const spp_spptw_res_cont& res_cont_1, +bool operator<( const spp_spptw_res_cont& res_cont_1, const spp_spptw_res_cont& res_cont_2 ) { if( res_cont_1.cost > res_cont_2.cost ) @@ -154,15 +154,15 @@ bool operator<( const spp_spptw_res_cont& res_cont_1, class ref_spptw { public: - inline bool operator()( const SPPRC_Example_Graph& g, - spp_spptw_res_cont& new_cont, - const spp_spptw_res_cont& old_cont, + inline bool operator()( const SPPRC_Example_Graph& g, + spp_spptw_res_cont& new_cont, + const spp_spptw_res_cont& old_cont, graph_traits ::edge_descriptor ed ) const { - const SPPRC_Example_Graph_Arc_Prop& arc_prop = + const SPPRC_Example_Graph_Arc_Prop& arc_prop = get( edge_bundle, g )[ed]; - const SPPRC_Example_Graph_Vert_Prop& vert_prop = + const SPPRC_Example_Graph_Vert_Prop& vert_prop = get( vertex_bundle, g )[target( ed, g )]; new_cont.cost = old_cont.cost + arc_prop.cost; int& i_time = new_cont.time; @@ -176,24 +176,24 @@ class ref_spptw class dominance_spptw { public: - inline bool operator()( const spp_spptw_res_cont& res_cont_1, + inline bool operator()( const spp_spptw_res_cont& res_cont_1, const spp_spptw_res_cont& res_cont_2 ) const { // must be "<=" here!!! // must NOT be "<"!!! - return res_cont_1.cost <= res_cont_2.cost + return res_cont_1.cost <= res_cont_2.cost && res_cont_1.time <= res_cont_2.time; // this is not a contradiction to the documentation // the documentation says: - // "A label $l_1$ dominates a label $l_2$ if and only if both are resident - // at the same vertex, and if, for each resource, the resource consumption - // of $l_1$ is less than or equal to the resource consumption of $l_2$, - // and if there is at least one resource where $l_1$ has a lower resource + // "A label $l_1$ dominates a label $l_2$ if and only if both are resident + // at the same vertex, and if, for each resource, the resource consumption + // of $l_1$ is less than or equal to the resource consumption of $l_2$, + // and if there is at least one resource where $l_1$ has a lower resource // consumption than $l_2$." - // one can think of a new label with a resource consumption equal to that - // of an old label as being dominated by that old label, because the new - // one will have a higher number and is created at a later point in time, - // so one can implicitly use the number or the creation time as a resource + // one can think of a new label with a resource consumption equal to that + // of an old label as being dominated by that old label, because the new + // one will have a higher number and is created at a later point in time, + // so one can implicitly use the number or the creation time as a resource // for tie-breaking } }; @@ -345,12 +345,12 @@ int test_main(int, char*[]) add_edge( 8, 3, SPPRC_Example_Graph_Arc_Prop( 45, 11, 9 ), g ); add_edge( 9, 0, SPPRC_Example_Graph_Arc_Prop( 48, 41, 5 ), g ); add_edge( 9, 1, SPPRC_Example_Graph_Arc_Prop( 49, 44, 7 ), g ); - + // spp without resource constraints std::vector ::edge_descriptor> > + ::edge_descriptor> > opt_solutions; std::vector pareto_opt_rcs_no_rc; std::vector i_vec_opt_solutions_spp_no_rc; @@ -360,19 +360,19 @@ int test_main(int, char*[]) for( int t = 0; t < 10; ++t ) { r_c_shortest_paths - ( g, - get( &SPPRC_Example_Graph_Vert_Prop::num, g ), - get( &SPPRC_Example_Graph_Arc_Prop::num, g ), - s, - t, - opt_solutions, - pareto_opt_rcs_no_rc, - spp_no_rc_res_cont( 0 ), - ref_no_res_cont(), - dominance_no_res_cont(), + ( g, + get( &SPPRC_Example_Graph_Vert_Prop::num, g ), + get( &SPPRC_Example_Graph_Arc_Prop::num, g ), + s, + t, + opt_solutions, + pareto_opt_rcs_no_rc, + spp_no_rc_res_cont( 0 ), + ref_no_res_cont(), + dominance_no_res_cont(), std::allocator >(), + >(), default_r_c_shortest_paths_visitor() ); i_vec_opt_solutions_spp_no_rc.push_back( pareto_opt_rcs_no_rc[0].cost ); //std::cout << "From " << s << " to " << t << ": "; @@ -380,23 +380,23 @@ int test_main(int, char*[]) } } - //std::vector::vertex_descriptor> + //std::vector::vertex_descriptor> // p( num_vertices( g ) ); //std::vector d( num_vertices( g ) ); //std::vector i_vec_dijkstra_distances; //std::cout << "Dijkstra:" << std::endl; //for( int s = 0; s < 10; ++s ) //{ - // dijkstra_shortest_paths( g, - // s, - // &p[0], - // &d[0], - // get( &SPPRC_Example_Graph_Arc_Prop::cost, g ), - // get( &SPPRC_Example_Graph_Vert_Prop::num, g ), - // std::less(), - // closed_plus(), - // (std::numeric_limits::max)(), - // 0, + // dijkstra_shortest_paths( g, + // s, + // &p[0], + // &d[0], + // get( &SPPRC_Example_Graph_Arc_Prop::cost, g ), + // get( &SPPRC_Example_Graph_Vert_Prop::num, g ), + // std::less(), + // closed_plus(), + // (std::numeric_limits::max)(), + // 0, // default_dijkstra_visitor() ); // for( int t = 0; t < 10; ++t ) // { @@ -513,14 +513,14 @@ int test_main(int, char*[]) // spptw std::vector ::edge_descriptor> > + ::edge_descriptor> > opt_solutions_spptw; std::vector pareto_opt_rcs_spptw; std::vector ::edge_descriptor> > > > + ::edge_descriptor> > > > vec_vec_vec_vec_opt_solutions_spptw( 10 ); for( int s = 0; s < 10; ++s ) @@ -528,56 +528,56 @@ int test_main(int, char*[]) for( int t = 0; t < 10; ++t ) { r_c_shortest_paths - ( g, - get( &SPPRC_Example_Graph_Vert_Prop::num, g ), - get( &SPPRC_Example_Graph_Arc_Prop::num, g ), - s, - t, - opt_solutions_spptw, - pareto_opt_rcs_spptw, + ( g, + get( &SPPRC_Example_Graph_Vert_Prop::num, g ), + get( &SPPRC_Example_Graph_Arc_Prop::num, g ), + s, + t, + opt_solutions_spptw, + pareto_opt_rcs_spptw, // be careful, do not simply take 0 as initial value for time - spp_spptw_res_cont( 0, g[s].eat ), - ref_spptw(), - dominance_spptw(), + spp_spptw_res_cont( 0, g[s].eat ), + ref_spptw(), + dominance_spptw(), std::allocator >(), + >(), default_r_c_shortest_paths_visitor() ); vec_vec_vec_vec_opt_solutions_spptw[s].push_back( opt_solutions_spptw ); if( opt_solutions_spptw.size() ) { bool b_is_a_path_at_all = false; - bool b_feasible = false; + bool b_feasible = false; bool b_correctly_extended = false; spp_spptw_res_cont actual_final_resource_levels( 0, 0 ); graph_traits::edge_descriptor ed_last_extended_arc; - check_r_c_path( g, - opt_solutions_spptw[0], - spp_spptw_res_cont( 0, g[s].eat ), - true, - pareto_opt_rcs_spptw[0], - actual_final_resource_levels, - ref_spptw(), - b_is_a_path_at_all, - b_feasible, - b_correctly_extended, + check_r_c_path( g, + opt_solutions_spptw[0], + spp_spptw_res_cont( 0, g[s].eat ), + true, + pareto_opt_rcs_spptw[0], + actual_final_resource_levels, + ref_spptw(), + b_is_a_path_at_all, + b_feasible, + b_correctly_extended, ed_last_extended_arc ); BOOST_CHECK(b_is_a_path_at_all && b_feasible && b_correctly_extended); b_is_a_path_at_all = false; - b_feasible = false; + b_feasible = false; b_correctly_extended = false; spp_spptw_res_cont actual_final_resource_levels2( 0, 0 ); graph_traits::edge_descriptor ed_last_extended_arc2; - check_r_c_path( g, - opt_solutions_spptw[0], - spp_spptw_res_cont( 0, g[s].eat ), - false, - pareto_opt_rcs_spptw[0], - actual_final_resource_levels2, - ref_spptw(), - b_is_a_path_at_all, - b_feasible, - b_correctly_extended, + check_r_c_path( g, + opt_solutions_spptw[0], + spp_spptw_res_cont( 0, g[s].eat ), + false, + pareto_opt_rcs_spptw[0], + actual_final_resource_levels2, + ref_spptw(), + b_is_a_path_at_all, + b_feasible, + b_correctly_extended, ed_last_extended_arc2 ); BOOST_CHECK(b_is_a_path_at_all && b_feasible && b_correctly_extended); } @@ -688,7 +688,7 @@ int test_main(int, char*[]) for( int s = 0; s < 10; ++s ) for( int t = 0; t < 10; ++t ) BOOST_CHECK( static_cast - ( vec_vec_vec_vec_opt_solutions_spptw[s][t].size() ) == + ( vec_vec_vec_vec_opt_solutions_spptw[s][t].size() ) == i_vec_correct_num_solutions_spptw[10 * s + t] ); // one pareto-optimal solution @@ -703,19 +703,19 @@ int test_main(int, char*[]) add_edge( 2, 3, SPPRC_Example_Graph_Arc_Prop( 3, 1, 1 ), g2 ); std::vector::edge_descriptor> opt_solution; spp_spptw_res_cont pareto_opt_rc; - r_c_shortest_paths( g2, - get( &SPPRC_Example_Graph_Vert_Prop::num, g2 ), - get( &SPPRC_Example_Graph_Arc_Prop::num, g2 ), - 0, - 3, - opt_solution, - pareto_opt_rc, - spp_spptw_res_cont( 0, 0 ), - ref_spptw(), - dominance_spptw(), + r_c_shortest_paths( g2, + get( &SPPRC_Example_Graph_Vert_Prop::num, g2 ), + get( &SPPRC_Example_Graph_Arc_Prop::num, g2 ), + 0, + 3, + opt_solution, + pareto_opt_rc, + spp_spptw_res_cont( 0, 0 ), + ref_spptw(), + dominance_spptw(), std::allocator >(), + >(), default_r_c_shortest_paths_visitor() ); BOOST_CHECK(pareto_opt_rc.cost == 3); @@ -748,11 +748,11 @@ int test_main(int, char*[]) add_edge( 5, 4, SPPRC_Example_Graph_Arc_Prop( 18, 0, 25 ), g3 ); add_edge( 5, 1, SPPRC_Example_Graph_Arc_Prop( 19, 0, 25 ), g3 ); - std::vector::edge_descriptor> > + std::vector::edge_descriptor> > pareto_opt_marked_solutions; std::vector pareto_opt_marked_resource_containers; - typename graph_traits::vertex_descriptor g3_source = 0, g3_target = 1; + graph_traits::vertex_descriptor g3_source = 0, g3_target = 1; r_c_shortest_paths( g3, get( &SPPRC_Example_Graph_Vert_Prop::num, g3 ), get( &SPPRC_Example_Graph_Arc_Prop::num, g3 ), @@ -769,21 +769,21 @@ int test_main(int, char*[]) default_r_c_shortest_paths_visitor() ); BOOST_CHECK(!pareto_opt_marked_solutions.empty()); - std::vector::edge_descriptor> >::const_iterator path_it, path_end_it; + std::vector::edge_descriptor> >::const_iterator path_it, path_end_it; for (path_it = pareto_opt_marked_solutions.begin(), path_end_it = pareto_opt_marked_solutions.end(); path_it != path_end_it; ++path_it) { - const std::vector::edge_descriptor> &path = *path_it; + const std::vector::edge_descriptor> &path = *path_it; BOOST_CHECK(!path.empty()); - const typename graph_traits::edge_descriptor front = path.front(); + const graph_traits::edge_descriptor front = path.front(); BOOST_CHECK(boost::target(front, g3) == g3_target); - std::vector::edge_descriptor>::const_iterator edge_it, edge_it_end; - typename graph_traits::edge_descriptor prev_edge = front; + std::vector::edge_descriptor>::const_iterator edge_it, edge_it_end; + graph_traits::edge_descriptor prev_edge = front; for(edge_it = path.begin() + 1, edge_it_end = path.end(); edge_it != edge_it_end; ++edge_it) { - typename graph_traits::edge_descriptor edge = *edge_it; + graph_traits::edge_descriptor edge = *edge_it; - typename graph_traits::vertex_descriptor prev_end, current_end; + graph_traits::vertex_descriptor prev_end, current_end; prev_end = boost::source(prev_edge, g3); current_end = boost::target(edge, g3); BOOST_CHECK(prev_end == current_end); @@ -791,7 +791,7 @@ int test_main(int, char*[]) prev_edge = edge; } - const typename graph_traits::edge_descriptor back = path.back(); + const graph_traits::edge_descriptor back = path.back(); BOOST_CHECK(boost::source(back, g3) == g3_source); } From 037af4db54da701325413a7a534e607bcc46f2ad Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Thu, 6 Sep 2018 10:06:07 -0400 Subject: [PATCH 12/21] Fixing incorrect use of typedef's via macro. --- test/subgraph_add.cpp | 85 +++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/test/subgraph_add.cpp b/test/subgraph_add.cpp index d3265d219..99d2dbbd2 100644 --- a/test/subgraph_add.cpp +++ b/test/subgraph_add.cpp @@ -6,7 +6,7 @@ * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * + * */ #define BOOST_TEST_MODULE subgraph_add @@ -38,35 +38,35 @@ BOOST_AUTO_TEST_CASE(simpleGraph) { Graph& G1 = G0.create_subgraph(); Graph& G2 = G1.create_subgraph(); - + BOOST_CHECK(&G1.parent() == &G0); BOOST_CHECK(&G2.parent() == &G1); - + enum { A1, B1, C1 }; // for conveniently refering to vertices in G1 enum { A2, B2, C2 }; // for conveniently refering to vertices in G2 - + add_vertex(C, G1); // global vertex C becomes local A1 for G1 add_vertex(E, G1); // global vertex E becomes local B1 for G1 add_vertex(F, G1); // global vertex F becomes local C1 for G1 add_vertex(C, G2); // global vertex C becomes local A2 for G2 add_vertex(E, G2); // global vertex E becomes local B2 for G2 - + BOOST_CHECK(num_vertices(G0) == 6); BOOST_CHECK(num_vertices(G1) == 3); std::cerr << num_vertices(G1) << std::endl; BOOST_CHECK(num_vertices(G2) == 2); - + // add edges to root graph add_edge(A, B, G0); add_edge(B, C, G0); add_edge(B, D, G0); add_edge(E, F, G0); - + BOOST_CHECK(num_edges(G0) == 4); BOOST_CHECK(num_edges(G1) == 1); BOOST_CHECK(num_edges(G2) == 0); - + // add edges to G1 add_edge(A1, B1, G1); BOOST_CHECK(num_edges(G0) == 5); @@ -90,10 +90,10 @@ BOOST_AUTO_TEST_CASE(addVertices) { Graph G0(N); Graph& G1 = G0.create_subgraph(); Graph& G2 = G1.create_subgraph(); - + BOOST_CHECK(&G1.parent() == &G0); BOOST_CHECK(&G2.parent() == &G1); - + // add vertices to G2 Vertex n1 = add_vertex(0, G2); Vertex n2 = add_vertex(1, G2); @@ -119,12 +119,12 @@ BOOST_AUTO_TEST_CASE(addVertices) { } else { BOOST_ERROR( "vertex not found!" ); } - + // num_vertices stays the same BOOST_CHECK(num_vertices(G0) == 3); BOOST_CHECK(num_vertices(G1) == 2); BOOST_CHECK(num_vertices(G2) == 2); - + // add vertices to G1 Vertex n3 = add_vertex(2, G1); // check if the global vertex 2 is equal to the returned local vertex @@ -137,43 +137,43 @@ BOOST_AUTO_TEST_CASE(addVertices) { BOOST_CHECK(num_vertices(G0) == 3); BOOST_CHECK(num_vertices(G1) == 3); BOOST_CHECK(num_vertices(G2) == 2); - + // add vertices to G1 Vertex n4 = add_vertex(G1); - + // check if the new local vertex is also in the global graph BOOST_CHECK(G0.find_vertex(G1.local_to_global(n4)).second); // check if the new local vertex is not in the subgraphs BOOST_CHECK(!G2.find_vertex(n4).second); - + // num_vertices stays the same BOOST_CHECK(num_vertices(G0) == 4); BOOST_CHECK(num_vertices(G1) == 4); BOOST_CHECK(num_vertices(G2) == 2); - + // add vertices to G0 Vertex n5 = add_vertex(G0); - + // check if the new local vertex is not in the subgraphs BOOST_CHECK(!G1.find_vertex(n5).second); BOOST_CHECK(!G2.find_vertex(n5).second); - + // num_vertices stays the same BOOST_CHECK(num_vertices(G0) == 5); BOOST_CHECK(num_vertices(G1) == 4); BOOST_CHECK(num_vertices(G2) == 2); - + std::cerr << "All G0 vertices: " << std::endl; - BGL_FORALL_VERTICES_T(v, G0, Graph) { - std::cerr << G0.local_to_global(v) << std::endl; + for(auto v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { + std::cerr << G0.local_to_global(v->first) << std::endl; } std::cerr << "All G1 vertices: " << std::endl; - BGL_FORALL_VERTICES_T(v, G1, Graph) { - std::cerr << G1.local_to_global(v) << std::endl; + for(auto v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { + std::cerr << G1.local_to_global(v->first) << std::endl; } std::cerr << "All G2 vertices: " << std::endl; - BGL_FORALL_VERTICES_T(v, G2, Graph) { - std::cerr << G2.local_to_global(v) << std::endl; + for(auto v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { + std::cerr << G2.local_to_global(v->first) << std::endl; } } @@ -189,19 +189,19 @@ BOOST_AUTO_TEST_CASE(addEdge) { Graph G0(N); Graph& G1 = G0.create_subgraph(); Graph& G2 = G1.create_subgraph(); - + BOOST_CHECK(&G1.parent() == &G0); BOOST_CHECK(&G2.parent() == &G1); - + // add vertices add_vertex(0, G2); add_vertex(1, G2); BOOST_CHECK(num_vertices(G1) == 2); BOOST_CHECK(num_vertices(G2) == 2); - + // add edge to G0 which needs propagation add_edge(0, 1, G0); - + BOOST_CHECK(num_edges(G0) == 1); BOOST_CHECK(num_edges(G1) == 1); BOOST_CHECK(num_edges(G2) == 1); @@ -209,10 +209,10 @@ BOOST_AUTO_TEST_CASE(addEdge) { BOOST_CHECK(num_vertices(G0) == 3); BOOST_CHECK(num_vertices(G1) == 2); BOOST_CHECK(num_vertices(G2) == 2); - + // add edge to G0 without propagation add_edge(1, 2, G0); - + BOOST_CHECK(num_edges(G0) == 2); BOOST_CHECK(num_edges(G1) == 1); BOOST_CHECK(num_edges(G2) == 1); @@ -220,11 +220,11 @@ BOOST_AUTO_TEST_CASE(addEdge) { BOOST_CHECK(num_vertices(G0) == 3); BOOST_CHECK(num_vertices(G1) == 2); BOOST_CHECK(num_vertices(G2) == 2); - + // add vertex 2 to G2/G1 with edge propagation Vertex n = add_vertex(2, G2); BOOST_CHECK(G2.local_to_global(n) == 2); - + BOOST_CHECK(num_edges(G0) == 2); BOOST_CHECK(num_edges(G1) == 2); BOOST_CHECK(num_edges(G2) == 2); @@ -232,10 +232,10 @@ BOOST_AUTO_TEST_CASE(addEdge) { BOOST_CHECK(num_vertices(G0) == 3); BOOST_CHECK(num_vertices(G1) == 3); BOOST_CHECK(num_vertices(G2) == 3); - + // add edge to G2 with propagation upwards add_edge(0, 2, G2); - + BOOST_CHECK(num_edges(G0) == 3); BOOST_CHECK(num_edges(G1) == 3); BOOST_CHECK(num_edges(G2) == 3); @@ -243,18 +243,18 @@ BOOST_AUTO_TEST_CASE(addEdge) { BOOST_CHECK(num_vertices(G0) == 3); BOOST_CHECK(num_vertices(G1) == 3); BOOST_CHECK(num_vertices(G2) == 3); - + std::cerr << "All G0 vertices: " << std::endl; - BGL_FORALL_VERTICES_T(v, G0, Graph) { - std::cerr << G0.local_to_global(v) << std::endl; + for(auto v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { + std::cerr << G0.local_to_global(v->first) << std::endl; } std::cerr << "All G1 vertices: " << std::endl; - BGL_FORALL_VERTICES_T(v, G1, Graph) { - std::cerr << G1.local_to_global(v) << std::endl; + for(auto v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { + std::cerr << G1.local_to_global(v->first) << std::endl; } std::cerr << "All G2 vertices: " << std::endl; - BGL_FORALL_VERTICES_T(v, G2, Graph) { - std::cerr << G2.local_to_global(v) << std::endl; + for(auto v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { + std::cerr << G2.local_to_global(v->first) << std::endl; } std::cerr << "All G0 edges: " << std::endl; BGL_FORALL_EDGES_T(e, G0, Graph) { @@ -269,4 +269,3 @@ BOOST_AUTO_TEST_CASE(addEdge) { std::cerr << source(e, G2) << "->" << target(e, G2) << std::endl; } } - From 3cc890e8543fbced1421d1c8190785ac349050fb Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Fri, 7 Sep 2018 00:03:57 -0400 Subject: [PATCH 13/21] Changing c++11 auto type usage to delctype() boilerplate in order to allow compatability with C++03. This has only been tested locally, and this is being uploaded to test aginst the automated test suite. --- test/subgraph_add.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/subgraph_add.cpp b/test/subgraph_add.cpp index 99d2dbbd2..c3e2c57a1 100644 --- a/test/subgraph_add.cpp +++ b/test/subgraph_add.cpp @@ -245,15 +245,15 @@ BOOST_AUTO_TEST_CASE(addEdge) { BOOST_CHECK(num_vertices(G2) == 3); std::cerr << "All G0 vertices: " << std::endl; - for(auto v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { + for(decltype(G0.m_local_vertex.begin()) v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { std::cerr << G0.local_to_global(v->first) << std::endl; } std::cerr << "All G1 vertices: " << std::endl; - for(auto v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { + for(decltype(G1.m_local_vertex.begin()) v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { std::cerr << G1.local_to_global(v->first) << std::endl; } std::cerr << "All G2 vertices: " << std::endl; - for(auto v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { + for(decltype(G2.m_local_vertex.begin()) v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { std::cerr << G2.local_to_global(v->first) << std::endl; } std::cerr << "All G0 edges: " << std::endl; From 8551039ae31e8fa87bdac745f81795cc6a2f0174 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Sat, 8 Sep 2018 03:02:13 -0400 Subject: [PATCH 14/21] Learned more of how typename works, changed to using that. --- test/subgraph_add.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/subgraph_add.cpp b/test/subgraph_add.cpp index c3e2c57a1..6b8834446 100644 --- a/test/subgraph_add.cpp +++ b/test/subgraph_add.cpp @@ -244,16 +244,18 @@ BOOST_AUTO_TEST_CASE(addEdge) { BOOST_CHECK(num_vertices(G1) == 3); BOOST_CHECK(num_vertices(G2) == 3); + typedef typename std::map::vertex_descriptor, graph_traits::vertex_descriptor>::iterator v_itr; + std::cerr << "All G0 vertices: " << std::endl; - for(decltype(G0.m_local_vertex.begin()) v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { + for(v_itr v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { std::cerr << G0.local_to_global(v->first) << std::endl; } std::cerr << "All G1 vertices: " << std::endl; - for(decltype(G1.m_local_vertex.begin()) v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { + for(v_itr v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { std::cerr << G1.local_to_global(v->first) << std::endl; } std::cerr << "All G2 vertices: " << std::endl; - for(decltype(G2.m_local_vertex.begin()) v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { + for(v_itr v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { std::cerr << G2.local_to_global(v->first) << std::endl; } std::cerr << "All G0 edges: " << std::endl; From a10f17eb99f3d55e42ddab18a94ecfe6dea1d079 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Tue, 11 Sep 2018 17:00:05 -0400 Subject: [PATCH 15/21] Made typename fixes more broad and complete. --- test/subgraph_add.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/subgraph_add.cpp b/test/subgraph_add.cpp index 6b8834446..da14b6e04 100644 --- a/test/subgraph_add.cpp +++ b/test/subgraph_add.cpp @@ -163,16 +163,18 @@ BOOST_AUTO_TEST_CASE(addVertices) { BOOST_CHECK(num_vertices(G1) == 4); BOOST_CHECK(num_vertices(G2) == 2); + typedef typename std::map::vertex_descriptor, graph_traits::vertex_descriptor>::iterator v_itr; + std::cerr << "All G0 vertices: " << std::endl; - for(auto v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { + for(v_itr v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { std::cerr << G0.local_to_global(v->first) << std::endl; } std::cerr << "All G1 vertices: " << std::endl; - for(auto v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { + for(v_itr v = G1.m_local_vertex.begin(); v != G1.m_local_vertex.end(); ++v) { std::cerr << G1.local_to_global(v->first) << std::endl; } std::cerr << "All G2 vertices: " << std::endl; - for(auto v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { + for(v_itr v = G2.m_local_vertex.begin(); v != G2.m_local_vertex.end(); ++v) { std::cerr << G2.local_to_global(v->first) << std::endl; } } From 6808062c07be7e394223819ea703ccb2c98e84a1 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Tue, 11 Sep 2018 17:00:43 -0400 Subject: [PATCH 16/21] First possible complete fixes for r_c_shortest_paths. --- include/boost/graph/r_c_shortest_paths.hpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/include/boost/graph/r_c_shortest_paths.hpp b/include/boost/graph/r_c_shortest_paths.hpp index 918b7e492..f047e0f7c 100644 --- a/include/boost/graph/r_c_shortest_paths.hpp +++ b/include/boost/graph/r_c_shortest_paths.hpp @@ -28,11 +28,9 @@ struct r_c_shortest_paths_label : public boost::enable_shared_from_this > pl = NULL, - const typename graph_traits::edge_descriptor& ed = - graph_traits::edge_descriptor(), - const typename graph_traits::vertex_descriptor& vd = - graph_traits::vertex_descriptor() ) + const boost::shared_ptr > pl = boost::shared_ptr >(), + const typename graph_traits::edge_descriptor& ed = graph_traits::edge_descriptor(), + const typename graph_traits::vertex_descriptor& vd = graph_traits::vertex_descriptor() ) : num( n ), cumulated_resource_consumption( rc ), p_pred_label( pl ), @@ -41,6 +39,7 @@ struct r_c_shortest_paths_label : public boost::enable_shared_from_this >(), typename graph_traits::edge_descriptor(), s ); From 21bdac5709507394a0e215077b472d2128e2244b Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Fri, 14 Sep 2018 14:45:11 -0400 Subject: [PATCH 17/21] Silencing some build warnings about a trivial faux pas --- include/boost/graph/maximum_adjacency_search.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/boost/graph/maximum_adjacency_search.hpp b/include/boost/graph/maximum_adjacency_search.hpp index e27a7a048..558c89161 100644 --- a/include/boost/graph/maximum_adjacency_search.hpp +++ b/include/boost/graph/maximum_adjacency_search.hpp @@ -146,10 +146,10 @@ namespace boost { // start traversing the graph //vertex_descriptor s, t; - weight_type w; + //weight_type w; while (!pq.empty()) { // while PQ \neq {} do const vertex_descriptor u = pq.top(); // u = extractmax(PQ) - w = get(keys, u); vis.start_vertex(u, g); + 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 @@ -218,9 +218,9 @@ maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis, cons struct mas_dispatch { typedef void result_type; template - static result_type apply(const Graph& g, - //const bgl_named_params& params, - const ArgPack& params, + static result_type apply(const Graph& g, + //const bgl_named_params& params, + const ArgPack& params, WeightMap w) { using namespace boost::graph::keywords; @@ -249,8 +249,8 @@ maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis, cons typedef void result_type; template - static result_type apply(const Graph& g, - const ArgPack& params, + static result_type apply(const Graph& g, + const ArgPack& params, param_not_found) { using namespace boost::graph::keywords; From 9cfddda9cf6f74795991cf40d8f50a6b03bf76da Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Sat, 22 Sep 2018 21:25:21 -0400 Subject: [PATCH 18/21] I don't recall messing with these to make them auto, but they were auto. I've still been unable to reproduce the TravisCI errors, but this should still bring this branch closer to merging. --- test/delete_edge.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/delete_edge.cpp b/test/delete_edge.cpp index 342796b6e..ebc11228c 100644 --- a/test/delete_edge.cpp +++ b/test/delete_edge.cpp @@ -10,6 +10,7 @@ #include #include +#include #include @@ -28,13 +29,13 @@ int test_main(int argc, char* argv[]) > Graph_t; typedef Graph_t::edge_descriptor EdgeDesc; - + typedef Graph_t::vertex_descriptor VertexType; Graph_t m_graph; - auto v1 = boost::add_vertex(m_graph); - auto v2 = boost::add_vertex(m_graph); - auto v3 = boost::add_vertex(m_graph); + VertexType v1 = boost::add_vertex(m_graph); + VertexType v2 = boost::add_vertex(m_graph); + VertexType v3 = boost::add_vertex(m_graph); EdgeDesc ed1; bool inserted1; From 5d0f5a6b03c5284b573ad8bbb4379fa27ea31b08 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Sat, 22 Sep 2018 22:03:15 -0400 Subject: [PATCH 19/21] Clang had some helpful warnings about typename usage which were applied. --- test/subgraph_add.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/subgraph_add.cpp b/test/subgraph_add.cpp index da14b6e04..a6a3d3644 100644 --- a/test/subgraph_add.cpp +++ b/test/subgraph_add.cpp @@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(addVertices) { BOOST_CHECK(num_vertices(G1) == 4); BOOST_CHECK(num_vertices(G2) == 2); - typedef typename std::map::vertex_descriptor, graph_traits::vertex_descriptor>::iterator v_itr; + typedef std::map::vertex_descriptor, graph_traits::vertex_descriptor>::iterator v_itr; std::cerr << "All G0 vertices: " << std::endl; for(v_itr v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { @@ -246,7 +246,7 @@ BOOST_AUTO_TEST_CASE(addEdge) { BOOST_CHECK(num_vertices(G1) == 3); BOOST_CHECK(num_vertices(G2) == 3); - typedef typename std::map::vertex_descriptor, graph_traits::vertex_descriptor>::iterator v_itr; + typedef std::map::vertex_descriptor, graph_traits::vertex_descriptor>::iterator v_itr; std::cerr << "All G0 vertices: " << std::endl; for(v_itr v = G0.m_local_vertex.begin(); v != G0.m_local_vertex.end(); ++v) { @@ -261,15 +261,15 @@ BOOST_AUTO_TEST_CASE(addEdge) { std::cerr << G2.local_to_global(v->first) << std::endl; } std::cerr << "All G0 edges: " << std::endl; - BGL_FORALL_EDGES_T(e, G0, Graph) { + BGL_FORALL_EDGES(e, G0, Graph) { std::cerr << source(e, G0) << "->" << target(e, G0) << std::endl; } std::cerr << "All G1 edges: " << std::endl; - BGL_FORALL_EDGES_T(e, G1, Graph) { + BGL_FORALL_EDGES(e, G1, Graph) { std::cerr << source(e, G1) << "->" << target(e, G1) << std::endl; } std::cerr << "All G2 edges: " << std::endl; - BGL_FORALL_EDGES_T(e, G2, Graph) { + BGL_FORALL_EDGES(e, G2, Graph) { std::cerr << source(e, G2) << "->" << target(e, G2) << std::endl; } } From 5d6c7f669575961b42017e750e7511d30d59ef62 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Tue, 25 Sep 2018 09:59:16 -0400 Subject: [PATCH 20/21] Reverting a block comment removal at jzmaddock's request. --- include/boost/graph/iteration_macros.hpp | 39 ++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/include/boost/graph/iteration_macros.hpp b/include/boost/graph/iteration_macros.hpp index 80845aeb0..2bf40f958 100644 --- a/include/boost/graph/iteration_macros.hpp +++ b/include/boost/graph/iteration_macros.hpp @@ -17,6 +17,45 @@ #define BGL_FIRST(linenum) (BGL_RANGE(linenum).first) #define BGL_LAST(linenum) (BGL_RANGE(linenum).second) +/* + BGL_FORALL_VERTICES_T(v, g, graph_t) // This is on line 9 + expands to the following, but all on the same line + + for (typename boost::graph_traits::vertex_iterator + bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second; + bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9) + for (typename boost::graph_traits::vertex_descriptor v; + bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false; + ++bgl_first_9) + + The purpose of having two for-loops is just to provide a place to + declare both the iterator and value variables. There is really only + one loop. The stopping condition gets executed two more times than it + usually would be, oh well. The reason for the bgl_first_9 = bgl_last_9 + in the outer for-loop is in case the user puts a break statement + in the inner for-loop. + + The other macros work in a similar fashion. + + Use the _T versions when the graph type is a template parameter or + dependent on a template parameter. Otherwise use the non _T versions. + + ----------------------- + 6/9/09 THK + + The above contains two calls to the vertices function. I modified these + macros to expand to + + for (std::pair::vertex_iterator, + typename boost::graph_traits::vertex_iterator> bgl_range_9 = vertices(g); + bgl_range_9.first != bgl_range_9.second; + bgl_range_9.first = bgl_range_9.second) + for (typename boost::graph_traits::vertex_descriptor v; + bgl_range_9.first != bgl_range_9.second ? (v = *bgl_range_9.first, true) : false; + ++bgl_range_9.first) + + */ + #define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \ for (std::pair::vertex_iterator, \ From 5dd748307cc35e8ee1e7045902ba08adedbe8646 Mon Sep 17 00:00:00 2001 From: Josh Marshall Date: Fri, 28 Sep 2018 09:47:26 -0400 Subject: [PATCH 21/21] Realized the while loop in reindex_edge_list(), and so changed this. --- include/boost/graph/detail/adjacency_list.hpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index a8c92df1d..01d400ffd 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -267,7 +267,7 @@ namespace boost { : Base(static_cast< Base const& >(x)), m_property(const_cast(x).m_property) { } self& operator=(const self& x) { // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). - static_cast(*this) = static_cast< Base const& >(x); + static_cast(*this) = static_cast< Base const& >(x); m_property = const_cast(x).m_property; return *this; } @@ -277,7 +277,7 @@ namespace boost { : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property)) { } self& operator=(self&& x) { // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). - static_cast(*this) = static_cast< Base&& >(x); + static_cast(*this) = static_cast< Base&& >(x); m_property = std::move(x.m_property); return *this; } @@ -2051,24 +2051,19 @@ namespace boost { if ((*ei).get_target() > u) --(*ei).get_target(); } + template inline void reindex_edge_list(EdgeList& el, vertex_descriptor u, boost::disallow_parallel_edge_tag) { - typename EdgeList::iterator ei = el.begin(), e_end = el.end(); - while (ei != e_end) { + for(typename EdgeList::iterator ei = el.begin(); ei != el.end(); ++ei) { if (ei->get_target() > u) { typename EdgeList::value_type ce = *ei; - ++ei; el.erase(ce); --ce.get_target(); el.insert(ce); } - else - { - ++ei; - } } } } // namespace detail