Boost.Graph and Graphviz nested subgraphs

后端 未结 2 1715
北海茫月
北海茫月 2021-01-27 00:52

I expected the code

#include 
#include 
#include 
#include          


        
2条回答
  •  余生分开走
    2021-01-27 01:21

    The trouble was caused by supplying make_iterator_vertex_map(names), which returns chars from names ('A', 'B'). This is incompatible with the expected (and default) vertex_index properties (0, 1). After the fix, I get:

    digraph G0 {
    subgraph clusterG1 {
    subgraph clusterG2 {
    1;
    }
    0;
    }
    0 -> 1;
    }
    

    vertex_marker, which is std::vector of 2 elements in my case, not 67 and more was expected to be indexed by vertex indices. I was experiencing undefined behavior,
    and if ( vertex_marker[pos] ) was never fulfilled.

    The responsible portion of boost::detail::write_graphviz_subgraph:

    // Print out vertices and edges not in the subgraphs.
    
    typename graph_traits::vertex_iterator i, end;
    typename graph_traits::edge_iterator ei, edge_end;
    
    for(boost::tie(i,end) = vertices(g); i != end; ++i) {
      Vertex v = g.local_to_global(*i);
      int pos = get(vertex_id, v); // 66, 65, should be 1, 0
      if ( vertex_marker[pos] ) {  // out-of-bounds access
        vertex_marker[pos] = false;
        out << escape_dot_string(pos);
        make_vertex_attributes_writer(g.root())(out, v);
        out << ";" << std::endl;
      }
    }
    

    A static_assert/SFINAE of the vertex_id parameter type against Graph's vertex_id type (which can be done immediately in boost::write_graphviz) would be greatly welcome. On a side note, the hardcoded int pos = ... does not look too professional...

    And if we want to keep the custom names, we have to provide them via label attributes instead.

提交回复
热议问题