Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::graph subgraph + write_graphviz()
From: Chris Cooper (rallycoops_at_[hidden])
Date: 2012-08-01 21:39:29


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.

Thanks,
Chris

#include <boost/graph/graphviz.hpp>
#include <boost/graph/subgraph.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <string>
#include <sstream>

using namespace boost;
using namespace std;

int main()
{
        // Vertex properties
        typedef property<vertex_name_t, std::string, property<vertex_color_t,
float> > vertex_p;
        // Edge properties
        //typedef property<edge_weight_t, double> edge_p;
        typedef property<edge_index_t, int> edge_p;
        // Graph properties
        typedef property<graph_name_t, std::string> graph_p;
        // adjacency_list-based type
        typedef subgraph< adjacency_list<vecS, vecS, directedS, vertex_p,
edge_p, graph_p> > graph_t;

        // Construct an empty graph and prepare the dynamic_property_maps.
        graph_t G0(6);
        enum {A, B, C, D, E, F};

        dynamic_properties dp;

        property_map<graph_t, vertex_name_t>::type name = get(vertex_name, G0);
        dp.property("node_id", name);

        name[A] = "A";
        name[B] = "B";
        name[C] = "C";
        name[D] = "D";
        name[E] = "E";
        name[F] = "F";

        graph_t& G1 = G0.create_subgraph();
        enum {A1, B1, C1};

        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

        property_map<graph_t, vertex_name_t>::type name1 = get(vertex_name_t(), G1);
        name1[A1] = "A1";
        name1[B1] = "B1";
        name1[C1] = "C1";

        graph_t& G2 = G0.create_subgraph();
        enum {A2, B2};

        add_vertex(A, G2); // global vertex A becomes local A2 for G2
        add_vertex(C, G2); // global vertex C becomes local B2 for G2

        property_map<graph_t, vertex_name_t>::type name2 = get(vertex_name_t(), G2);
        name2[A2] = "A2";
        name2[B2] = "B2";

        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);

        property_map<graph_t, vertex_color_t>::type mass = get(vertex_color, G0);
        dp.property("mass", mass);

        property_map<graph_t, edge_index_t>::type edgeid = get(edge_index, G0);
        dp.property("edgeid", edgeid);

#if 0
        get_property(G0, graph_name) = "G0";
        get_property(G1, graph_name) = "G1";
        get_property(G2, graph_name) = "G2";
#else
        // set up graph names
        {
                boost::ref_property_map<graph_t*, std::string>
gname0(get_property(G0, graph_name));
                dp.property("name", gname0);
                gname0[0] = "G0";

                boost::ref_property_map<graph_t*, std::string>
gname1(get_property(G1, graph_name));
                dp.property("name", gname1);
                gname1[0] = "G1";

                boost::ref_property_map<graph_t*, std::string>
gname2(get_property(G1, graph_name));
                dp.property("name", gname2);
                gname2[0] = "G2";
        }
#endif

        std::ofstream ofs("out.dot");
        write_graphviz_dp(ofs, G0, dp, std::string("node_id"));

        return 0;
}

On 2 August 2012 01:33, Jeremiah Willcock <jewillco_at_[hidden]> wrote:
> On Wed, 1 Aug 2012, Chris Cooper wrote:
>
>> Hi,
>>
>> I'm trying to output an image showing subgraphs [0] using
>> write_graphviz() in boost 1.48.0. I've tried to modify an example [1]
>> by adding a write_graphviz() call. eg...
>>
>> std::ofstream ofs("out.dot");
>> const char* names[] = { "A", "B", "C", "D", "E", "F" };
>> write_graphviz(ofs, G0.m_graph, make_label_writer(names));
>>
>> This works fine for displaying the underlying graph, but no subgraphs
>> are shown. When I do the following...
>>
>> write_graphviz(ofs, G0, make_label_writer(names));
>>
>> I get a host of errors including...
>>
>> include/boost/graph/graphviz.hpp:377: error: no matching function
>> for call to ‘get(boost::label_writer<const char**>&, Vertex&)’
>
>
> Can you please try using write_graphviz_dp instead of write_graphviz? That
> might work better, and allows you to specify properties to write more
> easily.
>
>
>> I notice a comment in graphviz.hpp [2] 'requires graph_name graph
>> property' so I had a look at the subgraph_properties.cpp example [3].
>> This seemed to only be showing vertex properties but didn't compile
>> out of the box. Is it possible for someone experienced in
>> boost::graph to post a modified version of [1] that can produce
>> something like image [0], or point me in the right direction?
>
>
> I just committed a fixed version of subgraph_properties.cpp to the trunk, so
> that one should compile now.
>
> -- Jeremiah Willcock
> _______________________________________________
> 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