如何使用boost为图形的节点着色

时间:2016-06-03 01:44:09

标签: c++ boost graph

我试图用boost创建一个图。我想改变node和edge的属性。我得到编译错误。重复问题

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
struct my_graph_writer {
    void operator()(std::ostream& out) const {
        out << "graph [bgcolor=lightgrey]" << std::endl;
        out << "node [shape=circle color=blue]" << std::endl;
        out << "edge [color=red]" << std::endl;
    }
} myGraphWrite;
int main()
{
    using namespace boost;
    typedef adjacency_list<vecS, vecS, directedS, no_property, int> Graph;
    Graph g;
    add_edge(0, 1, 123, g);
    std::ofstream gout;
    gout.open("graphname.dot");
    write_graphviz(gout,g,my_graph_writer);
}

我纠正如下。但是第一个节点没有改变。问题是什么?

#include <iostream>
#include <boost/graph/graphviz.hpp>
using namespace boost;

typedef adjacency_list< listS, vecS, directedS > digraph;

//  define a property writer to color the edges as required
class color_writer {
public:
      // constructor - needs reference to graph we are coloring
    color_writer( digraph& g ) : myGraph( g ) {}
      // functor that does the coloring

    template <class VertexOrEdge>
    void operator()(std::ostream& out, const VertexOrEdge& e) const {

        out << "graph [bgcolor=lightgrey]" << std::endl;
        out << "node [shape=Mrect color=blue]" << std::endl;
        out << "edge [color=red]" << std::endl;
    }
private:
    digraph& myGraph;
};

int main()
{
    using namespace std;

    // instantiate a digraph object with 8 vertices
    digraph g;

    // add some edges
    add_edge(0, 1, g);
    add_edge(1, 5, g);
    add_edge(5, 6, g);
    add_edge(2, 3, g);
    add_edge(2, 4, g);
    boost::write_graphviz(f, g,color_writer( g ));
    return 0;
}

1 个答案:

答案 0 :(得分:1)

正如您所看到的https://blogs.msdn.microsoft.com/visualstudioalm/2014/03/14/visual-studio-online-load-test-troubleshooting-guide/,带有三个参数的write_graphviz重载期望其第三个参数为VertexPropertyWriter,因此您需要使用(如您原来的话)五个参数超载。这是你的方法:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
using std::map;
struct my_node_writer {
    // my_node_writer() {}
    my_node_writer(Map& g_) : g (g_) {};
    template <class Vertex>
    void operator()(std::ostream& out, Vertex v) {
        out << " [label=\"" << v << "\"]" << std::endl;
    };
    Map g;
};

struct my_edge_writer {
    my_edge_writer(Map& g_) : g (g_) {};
    template <class Edge>
    void operator()(std::ostream& out, Edge e) {

        out << " [color=purple]" << std::endl;
        out << " [label=\"" << e  <<":" << g[e].miles << "\"]" << std::endl;
    };
    Map g;
};

struct my_graph_writer {
    void operator()(std::ostream& out) const {
        out << "graph [bgcolor=lightgrey]" << std::endl;
        out << "node [shape=circle color=blue]" << std::endl;

        out << "edge [color=red]" << std::endl;
    }
} myGraphWrite;

int main()
{
    using namespace boost;
    typedef adjacency_list<vecS, vecS, directedS, no_property, int> Graph;
    Graph g;
    add_edge(0, 1, 123, g);
    std::ofstream gout;
    gout.open("graphname.dot");
    write_graphviz(gout,map,my_node_writer(map),my_edge_writer(map),myGraphWrite);

}

您有两个问题:您无法使用g[e].miles定义图表,Map不会引用任何内容。

为了解决第一个问题,您需要创建一个名为miles的member_variable结构,并在图表定义中将其用作EdgeProperty。 解决Map问题的最简单方法可能是使其成为需要它的结构的模板参数(尽管您也可以在属性编写者之前定义图表,然后使用Graph代替{ {1}}。这是进行这些更改后的代码:

here

Map