Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77189 - in trunk: boost/graph libs/graph/test
From: jewillco_at_[hidden]
Date: 2012-03-03 16:19:39


Author: jewillco
Date: 2012-03-03 16:19:38 EST (Sat, 03 Mar 2012)
New Revision: 77189
URL: http://svn.boost.org/trac/boost/changeset/77189

Log:
Tried to do read_graphviz for CSR; does not work but some infrastructure changed so it is being committed
Text files modified:
   trunk/boost/graph/graphviz.hpp | 102 ++++++++++++++++++++++++++++++
   trunk/libs/graph/test/graphviz_test.cpp | 132 ++++++++++++++++++++++++++++++---------
   2 files changed, 202 insertions(+), 32 deletions(-)

Modified: trunk/boost/graph/graphviz.hpp
==============================================================================
--- trunk/boost/graph/graphviz.hpp (original)
+++ trunk/boost/graph/graphviz.hpp 2012-03-03 16:19:38 EST (Sat, 03 Mar 2012)
@@ -25,10 +25,14 @@
 #include <boost/property_map/dynamic_property_map.hpp>
 #include <boost/graph/overloading.hpp>
 #include <boost/graph/dll_import_export.hpp>
+#include <boost/graph/compressed_sparse_row_graph.hpp>
 #include <boost/spirit/include/classic_multi_pass.hpp>
 #include <boost/lexical_cast.hpp>
+#include <boost/static_assert.hpp>
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/xpressive/xpressive_static.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/foreach.hpp>
 
 namespace boost {
 
@@ -713,6 +717,9 @@
 
   virtual void // RG: need new second parameter to support BGL subgraphs
   set_graph_property(const id_t& key, const id_t& value) = 0;
+
+ virtual void
+ finish_building_graph() = 0;
 };
 
 template<typename MutableGraph>
@@ -781,6 +788,8 @@
     put(key, dp_, &graph_, value);
   }
 
+ void finish_building_graph() {}
+
 
  protected:
   MutableGraph& graph_;
@@ -790,6 +799,99 @@
   std::map<edge_t, bgl_edge_t> bgl_edges;
 };
 
+template<typename Directed,
+ typename VertexProperty,
+ typename EdgeProperty,
+ typename GraphProperty,
+ typename Vertex,
+ typename EdgeIndex>
+class mutate_graph_impl<compressed_sparse_row_graph<Directed, VertexProperty, EdgeProperty, GraphProperty, Vertex, EdgeIndex> >
+ : public mutate_graph
+{
+ // The first part of this is to make the code dependent on a template parameter.
+ BOOST_STATIC_ASSERT_MSG(sizeof(Directed) == 0,
+ "Graphviz loading for CSR graphs is broken");
+
+ typedef compressed_sparse_row_graph<Directed, VertexProperty, EdgeProperty, GraphProperty, Vertex, EdgeIndex> CSRGraph;
+ typedef typename graph_traits<CSRGraph>::vertices_size_type bgl_vertex_t;
+ typedef typename graph_traits<CSRGraph>::edges_size_type bgl_edge_t;
+
+ public:
+ mutate_graph_impl(CSRGraph& graph, dynamic_properties& dp,
+ std::string node_id_prop)
+ : graph_(graph), dp_(dp), vertex_count(0), node_id_prop_(node_id_prop) { }
+
+ ~mutate_graph_impl() {}
+
+ void finish_building_graph() {
+ CSRGraph temp(edges_are_unsorted, edges.begin(), edges.end(), vertex_count);
+ set_property(temp, graph_all, get_property(graph_, graph_all));
+ graph_ = temp;
+ typedef tuple<id_t, bgl_edge_t, id_t> ve_prop;
+ BOOST_FOREACH(const ve_prop& t, vertex_and_edge_props) {
+ put(get<0>(t), dp_, get<1>(t), get<2>(t));
+ }
+ }
+
+ bool is_directed() const
+ {
+ return
+ boost::is_convertible<
+ typename boost::graph_traits<CSRGraph>::directed_category,
+ boost::directed_tag>::value;
+ }
+
+ virtual void do_add_vertex(const node_t& node)
+ {
+ // Add the node to the graph.
+ bgl_vertex_t v = vertex_count++;
+
+ // Set up a mapping from name to BGL vertex.
+ bgl_nodes.insert(std::make_pair(node, v));
+
+ // node_id_prop_ allows the caller to see the real id names for nodes.
+ vertex_and_edge_props.push_back(make_tuple(node_id_prop_, v, node));
+ }
+
+ void
+ do_add_edge(const edge_t& edge, const node_t& source, const node_t& target)
+ {
+ bgl_edge_t result = edges.size();
+ edges.push_back(std::make_pair(bgl_nodes[source], bgl_nodes[target]));
+ bgl_edges.insert(std::make_pair(edge, result));
+ }
+
+ void
+ set_node_property(const id_t& key, const node_t& node, const id_t& value)
+ {
+ vertex_and_edge_props.push_back(make_tuple(key, bgl_nodes[node], value));
+ }
+
+ void
+ set_edge_property(const id_t& key, const edge_t& edge, const id_t& value)
+ {
+ vertex_and_edge_props.push_back(make_tuple(key, bgl_edges[edge], value));
+ }
+
+ void
+ set_graph_property(const id_t& key, const id_t& value)
+ {
+ /* RG: pointer to graph prevents copying */
+ put(key, dp_, &graph_, value);
+ }
+
+
+ protected:
+ CSRGraph& graph_;
+ dynamic_properties& dp_;
+ bgl_vertex_t vertex_count;
+ std::string node_id_prop_;
+ std::vector<tuple<id_t, bgl_edge_t, id_t> > vertex_and_edge_props;
+ std::vector<std::pair<bgl_vertex_t, bgl_vertex_t> > edges;
+ std::map<node_t, bgl_vertex_t> bgl_nodes;
+ std::map<edge_t, bgl_edge_t> bgl_edges;
+};
+
 } } } // end namespace boost::detail::graph
 
 #ifdef BOOST_GRAPH_USE_SPIRIT_PARSER

Modified: trunk/libs/graph/test/graphviz_test.cpp
==============================================================================
--- trunk/libs/graph/test/graphviz_test.cpp (original)
+++ trunk/libs/graph/test/graphviz_test.cpp 2012-03-03 16:19:38 EST (Sat, 03 Mar 2012)
@@ -17,6 +17,7 @@
 #include <boost/graph/graphviz.hpp>
 #include <boost/assign/std/map.hpp>
 #include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/compressed_sparse_row_graph.hpp>
 #include <boost/graph/graph_traits.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <boost/property_map/dynamic_property_map.hpp>
@@ -41,33 +42,49 @@
 typedef std::map<node_t,float> mass_map_t;
 typedef std::map<edge_t,double> weight_map_t;
 
-template <typename Directedness, typename OutEdgeList>
+template <typename graph_t, typename NameMapKey, typename MassMapKey, typename WeightMapKey>
+bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
+ mass_map_t const& masses,
+ weight_map_t const& weights,
+ std::string const& node_id = "node_id",
+ std::string const& g_name = std::string(),
+ NameMapKey name_map_key = boost::vertex_name,
+ MassMapKey mass_map_key = boost::vertex_color,
+ WeightMapKey weight_map_key = boost::edge_weight);
+
+template <typename graph_t>
 bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
                 mass_map_t const& masses,
                 weight_map_t const& weights,
                 std::string const& node_id = "node_id",
                 std::string const& g_name = std::string()) {
+ return test_graph<graph_t, boost::vertex_name_t, boost::vertex_color_t, boost::edge_weight_t>(dotfile, correct_num_vertices, masses, weights, node_id);
+}
+
+template <typename graph_t, typename NameMapKey, typename MassMapKey, typename WeightMapKey>
+bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
+ mass_map_t const& masses,
+ weight_map_t const& weights,
+ std::string const& node_id = "node_id",
+ std::string const& g_name = std::string(),
+ NameMapKey name_map_key = boost::vertex_name,
+ MassMapKey mass_map_key = boost::vertex_color,
+ WeightMapKey weight_map_key = boost::edge_weight) {
 
- typedef property < vertex_name_t, std::string,
- property < vertex_color_t, float > > vertex_p;
- typedef property < edge_weight_t, double > edge_p;
- typedef property < graph_name_t, std::string > graph_p;
- typedef adjacency_list < OutEdgeList, vecS, Directedness,
- vertex_p, edge_p, graph_p > graph_t;
   typedef typename graph_traits < graph_t >::edge_descriptor edge_t;
   typedef typename graph_traits < graph_t >::vertex_descriptor vertex_t;
 
   // Construct a graph and set up the dynamic_property_maps.
- graph_t graph(0);
+ graph_t graph;
   dynamic_properties dp(ignore_other_properties);
- typename property_map<graph_t, vertex_name_t>::type name =
- get(vertex_name, graph);
+ typename property_map<graph_t, NameMapKey>::type name =
+ get(name_map_key, graph);
   dp.property(node_id,name);
- typename property_map<graph_t, vertex_color_t>::type mass =
- get(vertex_color, graph);
+ typename property_map<graph_t, MassMapKey>::type mass =
+ get(mass_map_key, graph);
   dp.property("mass",mass);
- typename property_map<graph_t, edge_weight_t>::type weight =
- get(edge_weight, graph);
+ typename property_map<graph_t, WeightMapKey>::type weight =
+ get(weight_map_key, graph);
   dp.property("weight",weight);
 
   boost::ref_property_map<graph_t*,std::string> gname(
@@ -139,19 +156,31 @@
 
   typedef istringstream gs_t;
 
+ typedef property < vertex_name_t, std::string,
+ property < vertex_color_t, float > > vertex_p;
+ typedef property < edge_weight_t, double > edge_p;
+ typedef property < graph_name_t, std::string > graph_p;
+
+ struct vertex_p_bundled {std::string name; float color;};
+ struct edge_p_bundled {double weight;};
+
   // Basic directed graph tests
   BOOST_AUTO_TEST_CASE (basic_directed_graph_1) {
     mass_map_t masses;
     insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
     gs_t gs("digraph { a node [mass = 7.7] c e [mass = 6.66] }");
- BOOST_CHECK((test_graph<directedS,vecS>(gs,3,masses,weight_map_t())));
+ typedef adjacency_list < vecS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t())));
   }
 
   BOOST_AUTO_TEST_CASE (basic_directed_graph_2) {
     mass_map_t masses;
     insert ( masses ) ("a",0.0f) ("e", 6.66f);
     gs_t gs("digraph { a node [mass = 7.7] \"a\" e [mass = 6.66] }");
- BOOST_CHECK((test_graph<directedS,vecS>(gs,2,masses,weight_map_t())));
+ typedef adjacency_list < vecS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,2,masses,weight_map_t())));
   }
 
   BOOST_AUTO_TEST_CASE (basic_directed_graph_3) {
@@ -162,7 +191,9 @@
     gs_t gs("digraph { a -> b eDge [weight = 7.7] "
             "c -> d e-> f [weight = 6.66] "
             "d ->e->a [weight=.5]}");
- BOOST_CHECK((test_graph<directedS,vecS>(gs,6,mass_map_t(),weights)));
+ typedef adjacency_list < vecS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,6,mass_map_t(),weights)));
   }
 
   // undirected graph with alternate node_id property name
@@ -170,8 +201,10 @@
     mass_map_t masses;
     insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
     gs_t gs("graph { a node [mass = 7.7] c e [mass = 6.66] }");
- BOOST_CHECK((test_graph<undirectedS,vecS>(gs,3,masses,weight_map_t(),
- "nodenames")));
+ typedef adjacency_list < vecS, vecS, undirectedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t(),
+ "nodenames")));
   }
 
   // Basic undirected graph tests
@@ -179,7 +212,9 @@
     mass_map_t masses;
     insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
     gs_t gs("graph { a node [mass = 7.7] c e [mass =\\\n6.66] }");
- BOOST_CHECK((test_graph<undirectedS,vecS>(gs,3,masses,weight_map_t())));
+ typedef adjacency_list < vecS, vecS, undirectedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t())));
   }
 
   BOOST_AUTO_TEST_CASE (basic_undirected_graph_2) {
@@ -188,7 +223,9 @@
       (make_pair("c","d"),7.7)(make_pair("e","f"),6.66);
     gs_t gs("graph { a -- b eDge [weight = 7.7] "
             "c -- d e -- f [weight = 6.66] }");
- BOOST_CHECK((test_graph<undirectedS,vecS>(gs,6,mass_map_t(),weights)));
+ typedef adjacency_list < vecS, vecS, undirectedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,6,mass_map_t(),weights)));
   }
 
   // Mismatch directed graph test
@@ -197,7 +234,9 @@
     insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
     gs_t gs("graph { a nodE [mass = 7.7] c e [mass = 6.66] }");
     try {
- test_graph<directedS,vecS>(gs,3,masses,weight_map_t());
+ typedef adjacency_list < vecS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ test_graph<graph_t>(gs,3,masses,weight_map_t());
       BOOST_ERROR("Failed to throw boost::undirected_graph_error.");
     } catch (boost::undirected_graph_error&) {
     } catch (boost::directed_graph_error&) {
@@ -211,7 +250,9 @@
     insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
     gs_t gs("digraph { a node [mass = 7.7] c e [mass = 6.66] }");
     try {
- test_graph<undirectedS,vecS>(gs,3,masses,weight_map_t());
+ typedef adjacency_list < vecS, vecS, undirectedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ test_graph<graph_t>(gs,3,masses,weight_map_t());
       BOOST_ERROR("Failed to throw boost::directed_graph_error.");
     } catch (boost::directed_graph_error&) {}
   }
@@ -223,7 +264,9 @@
     insert( weights )(make_pair("a","b"),7.7);
     gs_t gs("diGraph { a -> b [weight = 7.7] a -> b [weight = 7.7] }");
     try {
- test_graph<directedS,setS>(gs,2,mass_map_t(),weights);
+ typedef adjacency_list < setS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ test_graph<graph_t>(gs,2,mass_map_t(),weights);
       BOOST_ERROR("Failed to throw boost::bad_parallel_edge.");
     } catch (boost::bad_parallel_edge&) {}
   }
@@ -233,7 +276,9 @@
     weight_map_t weights;
     insert( weights )(make_pair("a","b"),7.7);
     gs_t gs("digraph { a -> b [weight = 7.7] a -> b [weight = 7.7] }");
- BOOST_CHECK((test_graph<directedS,vecS>(gs,2,mass_map_t(),weights)));
+ typedef adjacency_list < vecS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,2,mass_map_t(),weights)));
   }
 
   // Graph Property Test 1
@@ -242,8 +287,10 @@
     insert ( masses ) ("a",0.0f) ("c",0.0f) ("e", 6.66f);
     gs_t gs("digraph { graph [name=\"foo \\\"escaped\\\"\"] a c e [mass = 6.66] }");
     std::string graph_name("foo \"escaped\"");
- BOOST_CHECK((test_graph<directedS,vecS>(gs,3,masses,weight_map_t(),"",
- graph_name)));
+ typedef adjacency_list < vecS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t(),"",
+ graph_name)));
   }
 
   // Graph Property Test 2
@@ -252,8 +299,10 @@
     insert ( masses ) ("a",0.0f) ("c",0.0f) ("e", 6.66f);
     gs_t gs("digraph { name=\"fo\"+ \"\\\no\" a c e [mass = 6.66] }");
     std::string graph_name("foo");
- BOOST_CHECK((test_graph<directedS,vecS>(gs,3,masses,weight_map_t(),"",
- graph_name)));
+ typedef adjacency_list < vecS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t(),"",
+ graph_name)));
   }
 
   // Graph Property Test 3 (HTML)
@@ -262,8 +311,10 @@
     insert ( masses ) ("a",0.0f) ("c",0.0f) ("e", 6.66f);
     std::string graph_name = "<html title=\"x'\" title2='y\"'>foo<b><![CDATA[><bad tag&>]]>bar</b>\n<br/>\nbaz</html>";
     gs_t gs("digraph { name=" + graph_name + " a c e [mass = 6.66] }");
- BOOST_CHECK((test_graph<directedS,vecS>(gs,3,masses,weight_map_t(),"",
- graph_name)));
+ typedef adjacency_list < vecS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t(),"",
+ graph_name)));
   }
 
   // Comments embedded in strings
@@ -274,7 +325,24 @@
       "a1 [ label = \"//depot/path/to/file_29#9\" ];"
       "a0 -> a1 [ color=gray ];"
       "}");
- BOOST_CHECK((test_graph<directedS,vecS>(gs,2,mass_map_t(),weight_map_t())));
+ typedef adjacency_list < vecS, vecS, directedS,
+ vertex_p, edge_p, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,2,mass_map_t(),weight_map_t())));
   }
+
+#if 0 // Currently broken
+ BOOST_AUTO_TEST_CASE (basic_csr_directed_graph) {
+ weight_map_t weights;
+ insert( weights )(make_pair("a","b"),0.0)
+ (make_pair("c","d"),7.7)(make_pair("e","f"),6.66)
+ (make_pair("d","e"),0.5)(make_pair("e","a"),0.5);
+ gs_t gs("digraph { a -> b eDge [weight = 7.7] "
+ "c -> d e-> f [weight = 6.66] "
+ "d ->e->a [weight=.5]}");
+ typedef compressed_sparse_row_graph<directedS, vertex_p_bundled, edge_p_bundled, graph_p > graph_t;
+ BOOST_CHECK((test_graph<graph_t>(gs,6,mass_map_t(),weights,"node_id","",&vertex_p_bundled::name,&vertex_p_bundled::color,&edge_p_bundled::weight)));
+ }
+#endif
+
 // return 0;
 // }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk