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

how to color a node of a graph using boost

本文关键字:节点 图形 何使用 Boost      更新时间:2023-10-16

我试图使用boost创建一个图表。我想更改节点和边缘的属性。我收到编译错误。很抱歉重复的问题

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

正如你在这里看到的,具有三个参数的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 而不是 Map 。这是进行这些更改后的代码:

在科利鲁上运行

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
using std::map;
template <typename 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;
};
template <typename Map>
my_node_writer<Map> node_writer(Map& map) { return my_node_writer<Map>(map); }
template <typename Map>
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;
};
template <typename Map>
my_edge_writer<Map> edge_writer(Map& map) { return my_edge_writer<Map>(map); }
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;
struct edge_prop
{
    int miles;
};
int main()
{
    using namespace boost;
    typedef adjacency_list<vecS, vecS, directedS, no_property, edge_prop> Graph;
    Graph g;
    add_edge(0, 1, edge_prop{123}, g);
    write_graphviz(std::cout,g,node_writer(g),edge_writer(g),myGraphWrite);
}