Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::graph subgraph + write_graphviz()
From: Jeremiah Willcock (jewillco_at_[hidden])
Date: 2012-08-02 11:38:32


On Thu, 2 Aug 2012, Chris Cooper wrote:

> With the dynamic property code I posted previously you should be able
> to just change that write_graphviz_dp call to write_graphviz(ofs, G0).
> Here's some code as per my original post. With boost trunk it's
> currently failing with...
>
> include/boost/pending/property.hpp:126:5: error: no type named ‘type’
> in ‘struct boost::lookup_one_property_internal<boost::no_property,
> boost::graph_graph_attribute_t>’

It looks like some of the property map defaults in write_graphviz got lost
when I changed how property lookup works, and write_graphviz on subgraphs
isn't using the default property writers like the normal version of
write_graphviz does. The workaround is to change your property
declarations to:

   typedef std::map<std::string, std::string> smap;
   typedef property<vertex_color_t, int,
             property<vertex_attribute_t, smap> > vertex_p;
   typedef property<edge_index_t, int,
             property<edge_attribute_t, smap> > edge_p;
   typedef property<graph_name_t, std::string,
             property<graph_graph_attribute_t, smap,
               property<graph_vertex_attribute_t, smap,
                 property<graph_edge_attribute_t, smap> > > >
     graph_p;

You don't need to initialize the new properties added here; the
default-constructed empty versions are fine. If you want to save storage,
you can create a dummy class that acts like an empty std::map<string,
string> and use that instead of smap in the code.

-- Jeremiah Willcock

>
>
>
> #include <boost/config.hpp>
> #include <iostream>
> #include <fstream>
> #include <boost/graph/subgraph.hpp>
> #include <boost/graph/adjacency_list.hpp>
> #include <boost/graph/graph_utility.hpp>
> #include <boost/graph/graphviz.hpp>
>
> int main(int,char*[])
> {
> using namespace boost;
> typedef adjacency_list_traits<vecS, vecS, directedS> Traits;
> typedef property<vertex_color_t, int> vertex_p;
> typedef property<edge_index_t, int> edge_p;
> typedef property<graph_name_t, std::string> graph_p;
> typedef subgraph< adjacency_list<vecS, vecS, directedS, vertex_p,
> edge_p, graph_p > > 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 = G0.create_subgraph();
> enum { A1, B1, C1 }; // for conveniently refering to vertices in G1
> enum { A2, B2 }; // 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(A, G2); // global vertex A becomes local A1 for G2
> add_vertex(B, G2); // global vertex B becomes local B1 for G2
>
> add_edge(A, B, G0);
> add_edge(B, C, G0);
> add_edge(B, D, G0);
> add_edge(E, B, G0);
> add_edge(E, F, G0);
> add_edge(F, D, G0);
>
> add_edge(A1, C1, G1); // (A1,C1) is subgraph G1 local indices for (C,F).
>
> const char* names[] = { "A", "B", "C", "D", "E", "F" };
> const char* enames[] = { "0", "1", "2", "3", "4", "5" };
> const char* gnames[] = { "G0", "G1", "G2" };
>
> std::ofstream ofs("out.dot");
>
> #if 0
> // works
> write_graphviz(ofs, G0.m_graph, make_label_writer(names));
> #else
> write_graphviz(ofs, G0);
> //write_graphviz(ofs, G0, make_label_writer(names),
> make_label_writer(enames), make_label_writer(gnames));
> #endif
>
> return 0;
> }
>
>
>
> On 2 August 2012 11:58, Jeremiah Willcock <jewillco_at_[hidden]> wrote:
>> On Thu, 2 Aug 2012, Chris Cooper wrote:
>>
>>> Thanks Jeremiah,
>>>
>>> I've now got something that compiles and runs, but still doesn't
>>> include 'subgraph' clauses in the dot output and corresponding
>>> rectangles when rendered. Interestingly if I now change back to
>>> write_graphviz(ofs, G0) I do get some subgraph clauses, but the names
>>> are messed up presumably since they're now being set up using dynamic
>>> properties. Also the subgraphs still don't render in this case.
>>
>>
>> It looks like you do need to use write_graphviz (without _dp) to get
>> subgraphs in the output. Could you please try your original code with the
>> Boost trunk and see what happens? That will allow your line numbers to
>> match up with mine. Also, a full code example using write_graphviz would be
>> helpful. Thank you.
>>
>>
>> -- Jeremiah Willcock
>> _______________________________________________
>> Boost-users mailing list
>> Boost-users_at_[hidden]
>> http://lists.boost.org/mailman/listinfo.cgi/boost-users
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net