2012-07-06 11 views
5

Moje pytanie jest oparty off: How to print a graph with a single property displayedJak wydrukować wykres w graphviz z wielu właściwości wyświetlane

Używam dołączonych właściwości:

typedef struct vert{ 
    std::string name; 
}; 

typedef struct edge{ 
    int capacity; 
    int weight; 
}; 

typedef adjacency_list<listS, vecS, undirectedS, vert, edge> Graph; 
Graph g; 
vector<int,int> ele; 

Mam następujący zwane w pętli że powinien tworzyć krawędzie:

edge prop; 
    prop.weight = 5; 
    prop.capacity = 4; 
    add_edge(ele.first,ele.second, prop, g); 

Ten segment jest to, co drukuje wykres do kropki formatu.

ofstream dot("graph.dot"); 
write_graphviz(dot, g, 
    boost::make_label_writer(boost::get(&vert::name, g)), 
    boost::make_label_writer(boost::get(&edge::weight, g)), 
    boost::make_label_writer(boost::get(&edge::capacity, g))); 

Błąd jest:

/usr/include/boost/graph/graphviz.hpp: In function ‘void boost::write_graphviz(std::ostream&, const Graph&, VertexPropertiesWriter, EdgePropertiesWriter, GraphPropertiesWriter, VertexID) [with Graph = boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, vert, edge, boost::no_property, boost::listS>, VertexPropertiesWriter = boost::label_writer<boost::bundle_property_map<boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, vert, edge, boost::no_property, boost::listS>, long unsigned int, vert, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, EdgePropertiesWriter = boost::label_writer<boost::bundle_property_map<boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, vert, edge, boost::no_property, boost::listS>, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, edge, int> >, GraphPropertiesWriter = boost::label_writer<boost::bundle_property_map<boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, vert, edge, boost::no_property, boost::listS>, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, edge, int> >, VertexID = boost::vec_adj_list_vertex_id_map<boost::property<boost::vertex_bundle_t, vert, boost::no_property>, long unsigned int>]’: 
/usr/include/boost/graph/graphviz.hpp:260: instantiated from ‘void boost::write_graphviz(std::ostream&, const Graph&, VertexPropertiesWriter, EdgePropertiesWriter, GraphPropertiesWriter) [with Graph = Graph, VertexPropertiesWriter = boost::label_writer<boost::bundle_property_map<boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, vert, edge, boost::no_property, boost::listS>, long unsigned int, vert, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, EdgePropertiesWriter = boost::label_writer<boost::bundle_property_map<boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, vert, edge, boost::no_property, boost::listS>, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, edge, int> >, GraphPropertiesWriter = boost::label_writer<boost::bundle_property_map<boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, vert, edge, boost::no_property, boost::listS>, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, edge, int> >]’ 
file_format.cc:194: instantiated from here 
/usr/include/boost/graph/graphviz.hpp:236: error: no match for call to ‘(boost::label_writer<boost::bundle_property_map<boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, vert, edge, boost::no_property, boost::listS>, boost::detail::edge_desc_impl<boost::undirected_tag, long unsigned int>, edge, int> >) (std::basic_ostream<char, std::char_traits<char> >&)’ 

Jest to dla mnie dziwne, bo to działa:

write_graphviz(dot, g, 
    boost::make_label_writer(boost::get(&vert_info::name, g))); 

i wyprowadza następujące:

graph G { 
0[label="0"]; 
1[label="1"]; 
2[label="2"]; 
3[label="3"]; 
4[label="4"]; 
5[label="5"]; 
6[label="6"]; 
7[label="7"]; 
8[label="8"]; 
9[label=""]; // this is another problem that I will have to fix but beside the point 
0--9 ; 
0--5 ; 
0--2 ; 
0--1 ; 
... 
... 
} 

Moim celem jest każdy oznaczony węzeł i każde laboratorium krawędzi zważywszy na jego pojemność i wagę.

Odpowiedz

11

Możesz znaleźć here listę wszystkich przeciążeń dla write_graphviz. Powodem pierwszego błędu jest to, że przeciążenie, którego próbowałeś użyć, oczekuje od twórcy wykresu właściwości w piątym argumencie.

Funkcja pomocnika make_label_writer po prostu tworzy program piszący właściwości, który przypisuje pojedynczą właściwość z wierzchołka lub krawędzi wykresu do atrybutu wierzchołka lub krawędzi grafviz o nazwie label.

Aby osiągnąć to, co chcesz, musisz utworzyć niestandardową property writer, w której przypiszesz każdą z właściwości krawędzi do potrzebnej graphviz attributes. Osobiście używam weight ->label i capacity ->taillabel lub headlabel.

template <class WeightMap,class CapacityMap> 
class edge_writer { 
public: 
    edge_writer(WeightMap w, CapacityMap c) : wm(w),cm(c) {} 
    template <class Edge> 
    void operator()(ostream &out, const Edge& e) const { 
    out << "[label=\"" << wm[e] << "\", taillabel=\"" << cm[e] << "\"]"; 
    } 
private: 
    WeightMap wm; 
    CapacityMap cm; 
}; 

template <class WeightMap, class CapacityMap> 
inline edge_writer<WeightMap,CapacityMap> 
make_edge_writer(WeightMap w,CapacityMap c) { 
    return edge_writer<WeightMap,CapacityMap>(w,c); 
} 

I wreszcie swoją write_graphviz inwokacja byłoby po prostu:

ofstream dot("graph.dot"); 
write_graphviz(dot, g, 
    boost::make_label_writer(boost::get(&vert::name, g)), 
    make_edge_writer(boost::get(&edge::weight,g),boost::get(&edge::capacity,g))); 
+0

Dziękuję, że pracował jak czar. – Jim

Powiązane problemy