Увеличить BGL read_graphviz с помощью связанных свойств

У меня есть график, определенный так:

struct EdgeInfoProperty{
int score;
//is the trans from v to u, where u<v
Trans trans;
};
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, boost::no_property, EdgeInfoProperty > Graph;
typedef Graph::edge_descriptor Edge;
typedef Graph::vertex_descriptor Vertex;

И я использовал write_graphviz записать ребра + партитуры в файл (я пишу Trans отдельно, поэтому я хотел бы читать партитуры только при чтении файла точек). Я написал это так:

auto w_map = boost::get(&EdgeInfoProperty::score, G); // <=== THIS IS THE TRICK!!!
boost::write_graphviz(myfile, G, boost::default_writer(), make_edge_writer(w_map));

Мой файл точек выглядит примерно так:

graph G {
0;
1;
2;
3;
4;
5;
6;
7;
8;
9;
10;
11;
12;
0--1 [label="-3"];
0--5 [label="-2"];
2--3 [label="-8"];
3--8 [label="-4"];
4--5 [label="-1"];
4--6 [label="-6"];
4--7 [label="-5"];
4--8 [label="-10"];
8--9 [label="-9"];
}

Итак, я в основном хочу загрузить G, так что есть грань между 0—1 и т. Д. С G[edge].score = -3 и т. д. G[edge].trans = //some default value or whatever,

То, что у меня есть сейчас, дает мне кучу ошибок компиляции, и я серьезно думаю о том, чтобы просто сделать текстовую копию моего графика вместо того, чтобы пытаться прочитать файл точек и затем воссоздать график оттуда …

Вот что у меня есть:

    std::string gn = loc + "MST.dot";
Graph G(0);
boost::dynamic_properties dp;
boost::property_map<Graph, boost::vertex_name_t>::type name = boost::get(boost::vertex_name, G);
dp.property("node_id",name);

auto score = boost::get(&EdgeInfoProperty::score, G);
dp.property("score",score);

std::filebuf fb;
fb.open (gn, std::ios::in);
std::istream isg(&fb);
bool status = boost::read_graphviz(isg,G,dp,"node_id");

Я почти уверен, что иметь только счет — проблема, но я попытался получить карту EdgeInfoProperty, просто все, что я пытался, выдает ошибку …

2

Решение

вопросы

В вашем коде есть несколько ошибок:

boost::get(boost::vertex_name,G) предполагает, что есть свойство с именем название в вашей вершине, что не так. Более того, read_graphviz() сохраняет идентификаторы узла в карте свойств под названием node_id, Но в вашем случае у вас нет свойства для вашей вершины. Это не может работать.

Бегущий пример

#include <iostream>
#include <sstream>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
using namespace std;

struct Trans {
int t;
};

struct EdgeInfoProperty {
int score;
//is the trans from v to u, where u<v
Trans trans;
};

struct NodeInfoProperty {
int index;
};

/* you cannot read a graph without node property. By default, read_graphviz() assume
* nodes have a "node_id" property map...
*/
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, NodeInfoProperty, EdgeInfoProperty > Graph;

template<class Index> class noeud_writer {
public:
noeud_writer(Index id) : idm(id){}
template<class Noeud> void operator()(std::ostream & out, const Noeud & n) {
out << "[index=" << idm[n] << "]"; }
private:
Index idm;
};

template< class IdMap> inline noeud_writer<IdMap> make_noeud_writer(IdMap idm) {
return noeud_writer<IdMap>(idm); }

template<class Score> class edge_writer {
public:
edge_writer(Score s) : score(s){}
template<class Noeud> void operator()(std::ostream & out, const Noeud & n) {
out << "[score=" << score[n] << "]"; }
private:
Score score;
};

template< class Score> inline edge_writer<Score> make_edge_writer(Score score) {
return edge_writer<Score>(score); }int main(int argc, char * argv[])
{
Graph G(0);
boost::dynamic_properties dp;
dp.property("index", boost::get(&NodeInfoProperty::index,G));

auto score = boost::get(&EdgeInfoProperty::score, G);
dp.property("score", score);

std::istringstream isg("graph G {0[index=0];1[index=1];0--1[score=-3];}");
bool status = boost::read_graphviz(isg, G, dp,"index");

write_graphviz(std::cout, G, make_noeud_writer(boost::get(&NodeInfoProperty::index, G)),
make_edge_writer(boost::get(&EdgeInfoProperty::score, G)));
return 0;
}
1

Другие решения