2012-07-06 17 views
5

Mi pregunta se basa apagado de: How to print a graph with a single property displayedCómo imprimir un gráfico en graphviz con múltiples propiedades que se muestran

estoy usando las propiedades de paquetes:

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; 

Tengo las siguientes llamadas en un bucle que debe crear los bordes:

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

Este segmento es lo que imprime el gráfico de poner los puntos 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))); 

El error es:

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

Es extraño para mí, porque esto funciona:

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

y emite la siguiente:

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

Mi objetivo es marcar cada nodo y cada laboratorio de borde elled con su capacidad y peso.

Respuesta

11

Puede encontrar here la lista de todas las sobrecargas para write_graphviz. El motivo de su primer error es que la sobrecarga que intentó usar espera un escritor de propiedad de gráfico en su quinto argumento.

La función auxiliar make_label_writer simplemente crea un escritor de propiedad que asigna una sola propiedad desde un vértice o un borde de su gráfica a un vértice graphviz o atributo de borde llamado label.

Para lograr lo que necesita, necesita crear un property writer personalizado en el que asigne cada una de sus propiedades de borde al graphviz attributes que necesite. Utilizaría personalmente weight ->label y 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); 
} 

Y finalmente su write_graphviz invocación sería simplemente:

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

Gracias, que funcionó como un encanto. – Jim

Cuestiones relacionadas