2012-07-06 10 views
5

angezeigt drucken Meine Frage basiert weg: How to print a graph with a single property displayedWie ein Diagramm, in graphviz mit mehreren Eigenschaften

Ich bin gebündelt Eigenschaften mit:

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; 

ich in einer Schleife die folgenden genannt haben, dass sollte erstellen, um die Kanten:

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

Dieses Segment ist das, was die Grafik-Format Punkt druckt.

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

Der Fehler ist:

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

Mir ist es seltsam, weil dies funktioniert:

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

und gibt die folgenden:

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

Mein Ziel ist es, habe jeden Knoten und jedes Kantenlabor markiert mit seiner Kapazität und Gewicht.

Antwort

11

Sie können here die Liste aller Überladungen für write_graphviz finden. Der Grund für Ihren ersten Fehler ist, dass die Überladung, die Sie versucht haben zu verwenden, einen Graph Property Writer in seinem fünften Argument erwartet.

Die Hilfsfunktion make_label_writer erstellt einfach einen Eigenschaften-Writer, der einem GraphViz-Scheitelpunkt oder Kantenattribut mit dem Namen label eine einzelne Eigenschaft von einem Scheitelpunkt oder einer Kante des Diagramms zuweist.

Um das zu erreichen, was Sie wollen, müssen Sie eine benutzerdefinierte property writer erstellen, in der Sie jede Ihrer Kanteneigenschaften der graphviz attributes zuweisen, die Sie benötigen. Ich würde persönlich verwenden weight ->label und capacity -> oder 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); 
} 

Und schließlich Ihr write_graphviz Aufruf wäre einfach:

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

Danke, das wie ein Charme. – Jim

Verwandte Themen