2012-07-06 3 views
5

La mia domanda è basata fuori di: How to print a graph with a single property displayedCome stampare un grafico in graphviz con più proprietà visualizzate

Sono utilizzando le proprietà in bundle:

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; 

Ho il seguente chiamato in un ciclo che dovrebbe creare i bordi:

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

Questo segmento è quello di stampare il grafico a puntino formato.

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

L'errore è:

/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> >&)’ 

E 'strano per me, perché questo funziona:

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

ed emette il seguente:

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 ; 
... 
... 
} 

Il mio obiettivo è quello di avere ogni nodo etichettato e ogni laboratorio di bordo elled con la sua capacità e peso.

risposta

11

È possibile trovare here l'elenco di tutti i sovraccarichi per write_graphviz. La ragione del tuo primo errore è che il sovraccarico che hai provato ad utilizzare si aspetta un writer di proprietà del grafico nel suo quinto argomento.

La funzione di supporto make_label_writer crea semplicemente un writer di proprietà che assegna una singola proprietà da un vertice o un bordo del grafico a un attributo di vertice o di bordo graphviz denominato label.

Per ottenere ciò che desideri, è necessario creare un numero personalizzato property writer in cui assegnare ciascuna delle proprietà del bordo allo graphviz attributes necessario. Personalmente utilizzerei weight ->label e capacity ->taillabel o 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); 
} 

E infine il vostro write_graphviz invocazione sarebbe semplicemente:

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

Grazie, che ha lavorato come un fascino. – Jim