TuttleOFX  1
TuttleOFX/libraries/tuttle/tests/boostgraph/main.cpp
Go to the documentation of this file.
00001 // custom host
00002 #include <tuttle/common/utils/global.hpp>
00003 #include <tuttle/host/graph/InternalGraph.hpp>
00004 #include <tuttle/host/graph/GraphExporter.hpp>
00005 #include <tuttle/host/graph/Visitors.hpp>
00006 
00007 #include <boost/graph/graph_utility.hpp>
00008 //#include <boost/bind.hpp>
00009 
00010 #include <iostream>
00011 #include <vector>
00012 
00013 namespace tuttle {
00014 namespace host {
00015 namespace graph {
00016 
00017 class TestVertex
00018 {
00019 public:
00020         typedef std::string Key;
00021 public:
00022         TestVertex() {}
00023         TestVertex( const std::string& name ) : _name( name ) {}
00024         ~TestVertex() {}
00025         std::string _name;
00026         const std::string& getName() const { return _name; }
00027         const std::string& getKey() const { return getName(); }
00028         friend std::ostream& operator<<( std::ostream& os, const TestVertex& v );
00029 };
00030 inline std::ostream& operator<<( std::ostream& os, const TestVertex& v )
00031 {
00032         os /*<< " _name:"*/ << v._name;
00033         return os;
00034 }
00035 
00036 class TestEdge
00037 {
00038 public:
00039         TestEdge() {}
00040         TestEdge( const std::string& in, const std::string& out )
00041                 : _nameIn( in )
00042                 , _nameOut( out )
00043                 , _name( out + "->" + in )
00044         {}
00045 
00046         ~TestEdge() {}
00047         std::string _nameIn;
00048         std::string _nameOut;
00049         std::string _name;
00050         const std::string&           getName() const { return _name; }
00051         const std::string&           getInAttrName() const { return _nameIn; }
00052         friend std::ostream& operator<<( std::ostream& os, const TestEdge& v );
00053 };
00054 inline std::ostream& operator<<( std::ostream& os, const TestEdge& e )
00055 {
00056         os << e._name;
00057         return os;
00058 }
00059 
00060 template<class G>
00061 struct vertex_label_writer
00062 {
00063         vertex_label_writer( const G& g ) : _g( g ) {}
00064         template<class Vertex>
00065         void operator()( std::ostream& out, const Vertex& v ) const
00066         {
00067                 out << dotEntry( "type", "vertex" );
00068                 out << dotEntry( "label", _g[v].getName() );
00069         }
00070 
00071         private:
00072                 const G& _g;
00073 };
00074 
00075 template<class G>
00076 struct edge_label_writer
00077 {
00078         edge_label_writer( const G& g ) : _g( g ) {}
00079         template<class Edge>
00080         void operator()( std::ostream& out, const Edge& e ) const
00081         {
00082                 out << dotEntry( "type", "vertex" );
00083                 out << dotEntry( "label", _g[e].getName() );
00084         }
00085 
00086         private:
00087                 const G& _g;
00088 };
00089 
00090 template<template<typename> class T, class G>
00091 T<G> make( const G& g )
00092 {
00093         return T<G>( g );
00094 }
00095 
00096 template<>
00097 void exportAsDOT<TestVertex, TestEdge>( std::ostream& os, const InternalGraph<TestVertex, TestEdge >& g )
00098 {
00099         std::map<std::string, std::string> graph_attr, vertex_attr, edge_attr;
00100         graph_attr["size"]       = "6,6";
00101         graph_attr["rankdir"]    = "LR";
00102         graph_attr["ratio"]      = "fill";
00103         graph_attr["label"]      = "TuttleOFX";
00104         vertex_attr["shape"]     = "circle";
00105         vertex_attr["color"]     = "dodgerblue4";
00106         vertex_attr["fontcolor"] = "dodgerblue4";
00107         edge_attr["style"]       = "dashed";
00108         edge_attr["minlen"]      = "1";
00109         edge_attr["color"]       = "darkslategray";
00110         edge_attr["fontcolor"]   = "darkslategray";
00111 
00112         using namespace boost;
00113         boost::write_graphviz( os,
00114                                g.getGraph(),
00115                                make<vertex_label_writer>( g.getGraph() ),
00116                                make<edge_label_writer>( g.getGraph() ),
00117                                boost::make_graph_attributes_writer( graph_attr, vertex_attr, edge_attr ) );
00118 
00119 }
00120 
00121 }
00122 }
00123 }
00124 
00125 #define BOOST_TEST_MODULE tuttle_boostgraph
00126 #include <tuttle/test/unit_test.hpp>
00127 
00128 BOOST_AUTO_TEST_SUITE( tuttle_boostgraph_suite )
00129 
00130 using namespace boost::unit_test;
00131 
00132 BOOST_AUTO_TEST_CASE( test_export )
00133 {
00134         using namespace tuttle::host;
00135 
00136         typedef graph::InternalGraph<graph::TestVertex, graph::TestEdge> InternalGraph;
00137         typedef InternalGraph::vertex_descriptor Descriptor;
00138         typedef std::map<std::string, int> InstanceCountMap;
00139 
00140         std::string n1( "v1" );
00141         std::string n2( "v2" );
00142         std::string n3( "v3" );
00143 
00144         InternalGraph graph;
00145         std::map<std::string, Descriptor> nodesDescriptor;
00146         nodesDescriptor[n1] = graph.addVertex( graph::TestVertex( n1 ) );
00147         nodesDescriptor[n2] = graph.addVertex( graph::TestVertex( n2 ) );
00148         nodesDescriptor[n3] = graph.addVertex( graph::TestVertex( n3 ) );
00149 
00150         graph.addEdge( nodesDescriptor[n1], nodesDescriptor[n2], graph::TestEdge( n1, n2 ) );
00151         graph.addEdge( nodesDescriptor[n2], nodesDescriptor[n3], graph::TestEdge( n2, n3 ) );
00152 
00153         TUTTLE_TLOG( TUTTLE_TRACE, "graph:" );
00154         boost::print_graph( graph.getGraph() );
00155 
00156         InternalGraph graphT;
00157         graphT.copyTransposed( graph );
00158 
00159         TUTTLE_TLOG( TUTTLE_TRACE, "graphT:" );
00160         boost::print_graph( graphT.getGraph() );
00161 
00162         graph::exportAsDOT<graph::TestVertex, graph::TestEdge>( "boostgraphtest.dot", graph );
00163         graph::exportAsDOT<graph::TestVertex, graph::TestEdge>( "boostgraphTtest.dot", graphT );
00164 
00165         TUTTLE_TLOG( TUTTLE_TRACE, "__________________________________________________" );
00166         TUTTLE_TLOG( TUTTLE_TRACE, "graph:" );
00167         //      std::vector<boost::default_color_type > colormap(boost::num_vertices(graph.getGraph()));
00168         graph::visitor::Test_dfs<InternalGraph> testVisitorA( graph );
00169         //      boost::depth_first_search( graph.getGraph(), boost::root_vertex(nodesDescriptor[n1]), boost::visitor(testVisitorA) );//, colormap );
00170         graph.depthFirstVisit( testVisitorA, nodesDescriptor[n1] );
00171 
00172         TUTTLE_TLOG( TUTTLE_TRACE, "__________________________________________________" );
00173         TUTTLE_TLOG( TUTTLE_TRACE, "graphT:" );
00174 
00175         std::map<std::string, InternalGraph::vertex_descriptor> mmap;
00176         for( InternalGraph::vertex_iterator i = vertices( graphT.getGraph() ).first, iEnd = vertices( graphT.getGraph() ).second;
00177              i != iEnd;
00178              ++i )
00179         {
00180                 TUTTLE_TLOG( TUTTLE_TRACE, "pp: " << graphT.getGraph()[*i]._name );
00181                 mmap[graphT.getGraph()[*i]._name] = *i;
00182                 //              TUTTLE_TLOG( TUTTLE_TRACE, "pp: "<< graphT.getGraph()[*i]._name );
00183         }
00184 
00185         graph::visitor::Test_dfs<InternalGraph> testVisitorB( graph );
00186         //      boost::depth_first_search( graphT.getGraph(), boost::visitor(testVisitorB) );
00187 
00188         graphT.depthFirstVisit( testVisitorB, mmap["v3"] );
00189 
00190 //         graph_traits<graph_type>::out_edge_iterator ei, edge_end;
00191 //         for( boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei )
00192 //          std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << "  ";
00193 }
00194 
00195 BOOST_AUTO_TEST_CASE( check_cycle )
00196 {
00197         using namespace tuttle::host;
00198 
00199         typedef graph::InternalGraph<graph::TestVertex, graph::TestEdge> InternalGraph;
00200         typedef InternalGraph::vertex_descriptor Descriptor;
00201         typedef std::map<std::string, int> InstanceCountMap;
00202 
00203         std::string n1( "v1" );
00204         std::string n2( "v2" );
00205         std::string n3( "v3" );
00206 
00207         InternalGraph graph;
00208         std::map<std::string, Descriptor> nodesDescriptor;
00209         nodesDescriptor[n1] = graph.addVertex( graph::TestVertex( n1 ) );
00210         nodesDescriptor[n2] = graph.addVertex( graph::TestVertex( n2 ) );
00211         nodesDescriptor[n3] = graph.addVertex( graph::TestVertex( n3 ) );
00212 
00213         graph.addEdge( nodesDescriptor[n1], nodesDescriptor[n2], graph::TestEdge( n1, n2 ) );
00214         graph.addEdge( nodesDescriptor[n2], nodesDescriptor[n3], graph::TestEdge( n2, n3 ) );
00215         
00216         BOOST_CHECK_THROW(
00217                 graph.addEdge( nodesDescriptor[n3], nodesDescriptor[n2], graph::TestEdge( n3, n2 ) ),
00218                 exception::Logic );
00219         BOOST_CHECK_THROW(
00220                 graph.addEdge( nodesDescriptor[n3], nodesDescriptor[n1], graph::TestEdge( n3, n1 ) ),
00221                  exception::Logic );
00222         
00223         TUTTLE_TLOG( TUTTLE_TRACE, "graph:" );
00224         boost::print_graph( graph.getGraph() );
00225 }
00226 
00227 BOOST_AUTO_TEST_CASE( test_create_add_remove_simple )
00228 {
00229         typedef boost::adjacency_list< boost::setS, boost::vecS, boost::bidirectionalS > TestGraph;
00230         TestGraph graph;
00231         
00232         // add vertices
00233         TestGraph::vertex_descriptor vd1 = boost::add_vertex( graph );
00234         TestGraph::vertex_descriptor vd2 = boost::add_vertex( graph );
00235         TestGraph::vertex_descriptor vd3 = boost::add_vertex( graph );
00236         TestGraph::vertex_descriptor vd4 = boost::add_vertex( graph );
00237         
00238         BOOST_CHECK_EQUAL( boost::num_vertices( graph ), 4 );
00239         BOOST_CHECK_EQUAL( boost::num_edges( graph ), 0 );
00240         
00241         boost::add_edge( vd1, vd2, graph );
00242         boost::add_edge( vd2, vd3, graph );
00243         boost::add_edge( vd3, vd4, graph );
00244         
00245         BOOST_CHECK_EQUAL( boost::num_vertices( graph ), 4 );
00246         BOOST_CHECK_EQUAL( boost::num_edges( graph ), 3 );
00247         
00248         boost::clear_vertex( vd3, graph );
00249         boost::remove_vertex( vd3, graph );
00250         
00251         BOOST_CHECK_EQUAL( boost::num_vertices( graph ), 3 );
00252         BOOST_CHECK_EQUAL( boost::num_edges( graph ), 1 );
00253         
00254         boost::add_edge(
00255                 graph.vertex_set()[1],
00256                 graph.vertex_set()[2],
00257                 graph );
00258         
00259         BOOST_CHECK_EQUAL( boost::num_vertices( graph ), 3 );
00260         BOOST_CHECK_EQUAL( boost::num_edges( graph ), 2 );
00261 }
00262 
00263 /*
00264  * Stupid test to check insertion, remove of vertices and edges.
00265  */
00266 BOOST_AUTO_TEST_CASE( test_create_add_remove )
00267 {
00268         using namespace tuttle::host;
00269         typedef boost::adjacency_list< boost::listS, boost::vecS, boost::undirectedS, graph::TestVertex, graph::TestEdge > TestGraph;
00270         TestGraph graph;
00271 
00272         // add vertices
00273         for( std::size_t i = 0; i < 20; ++i )
00274         {
00275                 TestGraph::vertex_descriptor vd = boost::add_vertex( graph );
00276                 graph[vd]._name = "a" + boost::lexical_cast<std::string > ( i );
00277         }
00278         
00279         BOOST_CHECK_EQUAL( boost::num_vertices( graph ), 20 );
00280         BOOST_CHECK_EQUAL( boost::num_edges( graph ), 0 );
00281         
00282         // add edges
00283         for( std::size_t i = 5; i < 8; ++i )
00284         {
00285                 TestGraph::edge_descriptor ed = boost::add_edge(
00286                         graph.vertex_set()[i],
00287                         graph.vertex_set()[i+1],
00288                         graph ).first;
00289         }
00290         
00291         BOOST_CHECK_EQUAL( boost::num_vertices( graph ), 20 );
00292         BOOST_CHECK_EQUAL( boost::num_edges( graph ), 3 );
00293         
00294         // remove some vertices
00295         for( std::size_t i = 0; i < 5; ++i )
00296         {
00297                 TestGraph::vertex_descriptor vd = graph.vertex_set()[0];
00298                 boost::clear_vertex( vd, graph ); // remove in and out edges
00299                 boost::remove_vertex( vd, graph ); // finally remove the vertex from the boost graph
00300         }
00301         
00302         BOOST_CHECK_EQUAL( boost::num_vertices( graph ), 20-5 );
00303         BOOST_CHECK_EQUAL( boost::num_edges( graph ), 3 );
00304         
00305         // edges
00306         for( std::size_t i = 9; i < 14; ++i )
00307         {
00308                 TestGraph::edge_descriptor ed = boost::add_edge(
00309                         graph.vertex_set()[i],
00310                         graph.vertex_set()[i+1],
00311                         graph ).first;
00312         }
00313         
00314         BOOST_CHECK_EQUAL( boost::num_vertices( graph ), 20-5 );
00315         BOOST_CHECK_EQUAL( boost::num_edges( graph ), 8 );
00316         
00317         // add some vertices
00318         for( std::size_t i = 0; i < 7; ++i )
00319         {
00320                 TestGraph::vertex_descriptor vd = boost::add_vertex( graph );
00321                 graph[vd]._name = "b" + boost::lexical_cast<std::string > ( i );
00322         }
00323         
00324         BOOST_CHECK_EQUAL( boost::num_vertices( graph ), 20 - 5 + 7 );
00325         BOOST_CHECK_EQUAL( boost::num_edges( graph ), 8 );
00326                 
00327 //      //zero some_property for all vertices
00328 //      for( Graph::vertex_iterator i = vertices( graph ).first, iEnd = vertices( graph ).second;
00329 //               i != iEnd;
00330 //               ++i )
00331 //      {
00332 //              TUTTLE_TLOG( TUTTLE_TRACE, ": " << graph[*i]._name );
00333 //      }
00334 }
00335 
00336 
00337 BOOST_AUTO_TEST_SUITE_END()
00338