boost::dynamic_propertiesでもできそうでしたが、
今回はboost::label_writerに習って、重みを出力するためのPropertyWriterを用意してみました。
まず、重みのみを出力するPropertyWriter。
template <class Graph> struct weight_writer { weight_writer(const Graph& g) : graph_(g) {} template <class Edge> void operator()(std::ostream& out, Edge edge) const { out << "[weight=" << boost::get(boost::edge_weight, graph_, edge) << "]"; } private: const Graph& graph_; }; template <class Graph> inline weight_writer<Graph> make_weight_writer(const Graph& g) { return weight_writer<Graph>(g); }
これを使用してdotファイルを出力し、その後pngに変換します。
#include <fstream> #include <vector> #include <string> #include <boost/graph/adjacency_list.hpp> #include <boost/graph/graphviz.hpp> typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, int>> Graph; typedef std::pair<int, int> Edge; enum { A, B, C, D, E, N }; const std::string name = "ABCDE"; int main() { const std::vector<Edge> edges = { {A, B}, {A, C}, {A, D}, {B, E}, {C, E}, {D, E} }; const std::vector<int> weights = { 3, 1, 4, 5, 2, 6 }; const Graph g(edges.begin(), edges.end(), weights.begin(), N); std::ofstream file("test.dot"); boost::write_graphviz(file, g, boost::make_label_writer(name.c_str()), make_weight_writer(g)); }
digraph G { 0[label="A"]; 1[label="B"]; 2[label="C"]; 3[label="D"]; 4[label="E"]; 0->1 [weight=3]; 0->2 [weight=1]; 0->3 [weight=4]; 1->4 [weight=5]; 2->4 [weight=2]; 3->4 [weight=6]; }
以下のようになります。
辺の長さのみが変わり、重みは値としては出力されません。
次に、重みと、その値を出力するPropertyWriter。
template <class Graph> struct weight_label_writer { weight_label_writer(const Graph& g) : graph_(g) {} template <class Edge> void operator()(std::ostream& out, const Edge& edge) const { write(out, edge, boost::get(boost::edge_weight, graph_, edge)); } private: template <class Edge, class Weight> void write(std::ostream& out, const Edge& edge, const Weight& weight) const { out << "[weight=" << weight << ", label=" << weight << "]"; } const Graph& graph_; }; template <class Graph> inline weight_label_writer<Graph> make_weight_label_writer(const Graph& g) { return weight_label_writer<Graph>(g); }
これを使用してdotファイルを出力し、その後pngに変換します。
#include <fstream> #include <vector> #include <string> #include <boost/graph/adjacency_list.hpp> #include <boost/graph/graphviz.hpp> typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, int>> Graph; typedef std::pair<int, int> Edge; enum { A, B, C, D, E, N }; const std::string name = "ABCDE"; int main() { const std::vector<Edge> edges = { {A, B}, {A, C}, {A, D}, {B, E}, {C, E}, {D, E} }; const std::vector<int> weights = { 3, 1, 4, 5, 2, 6 }; const Graph g(edges.begin(), edges.end(), weights.begin(), N); std::ofstream file("test.dot"); boost::write_graphviz(file, g, boost::make_label_writer(name.c_str()), make_weight_label_writer(g)); }
digraph G { 0[label="A"]; 1[label="B"]; 2[label="C"]; 3[label="D"]; 4[label="E"]; 0->1 [weight=3, label=3]; 0->2 [weight=1, label=1]; 0->3 [weight=4, label=4]; 1->4 [weight=5, label=5]; 2->4 [weight=2, label=2]; 3->4 [weight=6, label=6]; }
以下のようになります。今度は重みが値としても出力されています。
これらのPropertyWriterは、用途に応じて使い分けてください。
C++0xの可変引数テンプレートやmpl::vectorを使用して、PropertyWriterの合成ができるとおもしろいかもしれません。