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

Posted

技术标签:

【中文标题】如何使用 boost 为图的节点着色【英文标题】:how to color a node of a graph using boost 【发布时间】:2016-06-03 01:44:08 【问题描述】:

我正在尝试使用 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;

【问题讨论】:

【参考方案1】:

正如您所看到的here,带有三个参数的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。这个是进行这些更改后的代码:

Running on Coliru:

#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_prop123, g);

    write_graphviz(std::cout,g,node_writer(g),edge_writer(g),myGraphWrite);


【讨论】:

我按照上面的方法更正了。但是第一个节点没有改变。什么问题? 还有如何改变被访问顶点的颜色

以上是关于如何使用 boost 为图的节点着色的主要内容,如果未能解决你的问题,请参考以下文章

图的着色算法

图的m着色问题

图的m着色问题 (回溯搜索)

回溯法——图的m着色问题

图论---图的m-点着色判定问题(深搜--迭代式)

洛谷 P2819 图的m着色问题