Невозможно добавить именованную вершину (согласно учебнику) - PullRequest
1 голос
/ 08 апреля 2020

Я сейчас изучаю BGL и нашел учебник для него. Все работало нормально, пока я не достиг функции add_named_vertex. Вот фрагмент кода, который у меня есть, который не работает так, как я (и учебник) ожидаю:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <type_traits>
#include <iostream>
#include <sstream>
#include <string>

boost::adjacency_list<
    boost::vecS,
    boost::vecS,
    boost::directedS,
    boost::property<boost::vertex_name_t, std::string>
>
create_empty_graph() { return {}; }

template<typename graph, typename name_type>
typename boost::graph_traits<graph>::vertex_descriptor
add_named_vertex(const name_type& vertex_name, graph& g) noexcept {
    const auto vd = boost::add_vertex(g);
    auto vertex_name_map = get(boost::vertex_name, g);
    put(vertex_name_map, vd, vertex_name);
    return vd;
}

int main()
{
    auto g = create_empty_graph();
    const auto va = add_named_vertex("One", g);
    const auto vb = add_named_vertex("Two", g);
    boost::add_edge(va,vb, g);

    std::stringstream f;
    boost::write_graphviz(f, g);
    std::cout << f.str() << std::endl;

    return 0;
}

Я ожидаю:

digraph G {
0[label=One];
1[label=Two];
0->1;
}

Но вот что я получил:

digraph G {
0;
1;
0->1;
}

Как видите, в выводе этого кода нет меток. Не могли бы вы сказать мне, что я скучаю? Это ожидаемое поведение? Пробовал оба clang ++ и g cc и для диапазона версии Boost (1.69 - 1.71).

1 Ответ

0 голосов
/ 08 апреля 2020

Да, это ожидаемое поведение. Чтобы напечатать этикетки, добавьте автора свойства:

auto vlw = boost::make_label_writer(boost::get(boost::vertex_name, g));
boost::write_graphviz(f, g, vlw);

Посмотрите его Live on Coliru

Или, как я предпочитаю, используйте write_graphviz_dp для использования dynamic_properties:

boost::dynamic_properties dp;
dp.property("node_id", boost::get(boost::vertex_index, g));
dp.property("label", boost::get(boost::vertex_name, g));
boost::write_graphviz_dp(f, g, dp);

Посмотрите это Живите в Coliru

Может показаться, что это больше работы, но это легко и гибко со многими свойствами вершин / ребер. Вы можете найти мои ответы , чтобы найти хорошие примеры этого.

Оба вышеприведенных решения печатают

digraph G {
0[label=One];
1[label=Two];
0->1 ;
}

БОНУС

Вам не нужно add_named_vertex функция. Вы можете инициализировать свойство напрямую с помощью boost::add_vertex:

const auto va = add_vertex({"One"}, g);
const auto vb = add_vertex({"Two"}, g);
add_edge(va, vb, g);
...