Как использовать boost make_label_writer для записи свойств ребер? - PullRequest
0 голосов
/ 02 июля 2018

У меня есть простой график, мне удалось записать свойства с вершиной, но когда я использую make_label_writer для записи свойств по краям, компилятор всегда жалуется. Может ли кто-нибудь помочь с этим?

Мой код выглядит следующим образом:

int main (int argc, char * argv[]) {
    typedef std::pair<int ,int> Edge;
    std::vector<Edge> used_by = {Edge(1, 0), Edge(2, 1),
            Edge(1,2), Edge(2, 0)};
    using namespace boost;
    typedef adjacency_list<vecS, vecS, directedS
             > Graph;
    Graph g(used_by.begin(), used_by.end(), 3);
    std::ofstream dmp;
    dmp.open("dmp.dot");
    //name for vertex
    std::vector<std::string> name{"one", "two", "three"};
    //name for edge
    std::vector<std::string> name1{"e1", "e2", "e3", "e4"};
    write_graphviz(std::cout, g, make_label_writer(&name[0]) 
                                   ,make_label_writer(&name1[0]));
}

write_graphviz() будет называться шаблоном, что прекрасно:

  template <typename Graph, typename VertexWriter, typename 
  EdgeWriter>
  inline void
  write_graphviz(std::ostream& out, const Graph& g,
             VertexWriter vw, EdgeWriter ew
       BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,vertex_list_graph_tag))
  {
    default_writer gw;
    write_graphviz(out, g, vw, ew, gw);
  }

Итак, проблема в том, что когда я пишу свойства вершин только с помощью make_label_writer(&name[0]]]), код работает отлично. Но когда я добавляю make_label_writer(&name1[0]), возникает ошибка.

1 Ответ

0 голосов
/ 02 июля 2018

Индекс вершины по умолчанию является целым, поэтому вы можете использовать адрес имени первой вершины в качестве карты подразумеваемых ассоциативных свойств.

Дескриптор края это другой зверь и требует от вас либо

  • создать явную карту свойств итератора (используя дополнительную карту свойств индекса для отображения из дескриптора ребра в интегральный индекс в вектор name1)
  • или используйте модель концепции Associative PropertyMap.

В этом случае вы должны сделать это позже, используя std::map<edge_descriptor, std::string>.

Также рассмотрите возможность упрощения своей жизни со свойствами, используя Связанные свойства .

Карта ассоциативной собственности

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> Graph;

int main() {
    Graph g(3);
    auto e1 = add_edge(1, 0, g).first;
    auto e2 = add_edge(2, 1, g).first;
    auto e3 = add_edge(1, 2, g).first;
    auto e4 = add_edge(2, 0, g).first;

    std::vector<std::string>                      vname{ "one", "two", "three" };
    std::map<Graph::edge_descriptor, std::string> ename{ 
        { e1, "e1" },
        { e2, "e2" },
        { e3, "e3" },
        { e4, "e4" },
    };

    write_graphviz(std::cout, g,
            boost::make_label_writer(&vname[0]),
            make_label_writer(boost::make_assoc_property_map(ename)));
}

печать

Связанные свойства вместо

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>

struct VertexProps { std::string name; };
struct EdgeProps   { std::string name; };
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProps, EdgeProps> Graph;

int main() {
    Graph g(3);
    g[0].name = "one";
    g[1].name = "two";
    g[2].name = "three";
    add_edge(1, 0, {"e1"}, g);
    add_edge(2, 1, {"e2"}, g);
    add_edge(1, 2, {"e3"}, g);
    add_edge(2, 0, {"e4"}, g);

    write_graphviz(std::cout, g,
            make_label_writer(get(&VertexProps::name, g)),
            make_label_writer(get(&EdgeProps::name, g)));
}

Печатает так же

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...