Возможно глупый вопрос, но я не могу найти никакого ответа онлайн. Мое приложение считывает топологию из пользовательского файла и создает из него boost :: graph. Я нахожусь в процессе перехода к более стандартному представлению graphml. Я могу читать / записывать свойства узла, используя vertex_descriptor в качестве ключа, и аналогичным образом я могу использовать edge_descriptor для атрибутов ребер, но как насчет атрибутов графа? С каким типом ключа они будут связаны, когда будут прочитаны в файле graphml?
Чтобы объяснить мои сомнения, вот код, который я должен определить в графе и прочитать файл graphml:
struct NetworkNode {
int ponCustomers;
int asid;
}; //bundled property map for nodes
struct NetworkEdge {
int length;
Capacity maxCapacity;
Capacity spareCapacity;
std::set<Flow*> activeFlows;
Capacity peakCapacity;
}; //bundled property map for edges
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
NetworkNode, NetworkEdge> DGraph;
typedef DGraph::vertex_descriptor Vertex;
[...]
DGraph topology;
boost::dynamic_properties dp;
dp.property("asid", boost::get(&NetworkNode::asid, topology));
dp.property("ponCustomers", boost::get(&NetworkNode::ponCustomers, topology));
dp.property("length", boost::get(&NetworkEdge::length, topology));
dp.property("maxCapacity", boost::get(&NetworkEdge::maxCapacity, topology));
dp.property("spareCapacity", boost::get(&NetworkEdge::spareCapacity, topology));
dp.property("peakCapacity", boost::get(&NetworkEdge::peakCapacity, topology));
std::map<Vertex, int> avgUsersMap;
boost::associative_property_map<std::map<Vertex, int> >
avgUsersPMap(avgUsersMap);
dp.property("avgUsers", avgUsersPMap);
[...]
try {
boost::read_graphml(stream, this->topology, dp);
} catch [...]
Обратите внимание, как я создаю новые ассоциативные карты для хранения свойств, которые полезны для определения графа (например, когда я его строю), но не стоит хранить в каждом отдельном узле / ребре в течение всего времени жизни графа. Теперь некоторые из этих свойств относятся ко всему графу; например, я мог бы определить в файле GraphML что-то вроде
<key id="name" for="graph" attr.name="graphName" attr.type="string" />
Как мне определить требуемое property_map и добавить его в dp, чтобы этот бит информации был правильно проанализирован?
Вы можете настроить связанные свойства для графа, как вы это сделали с вершинами и ребрами.
Что-то вроде этого:
struct graph_props {
std::string myName;
...
};
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
NetworkNode, NetworkEdge, graph_props > DGraph;
Чтобы убедить boost :: read_graphml в сохранении свойств графа, вы должны предоставить карту свойств (в которой будет только один элемент). К сожалению, AFAIK вам придется извлечь значения read_graphml, помещенные в эту карту, и установить атрибуты связанного свойства графа. Может быть, кто-то может указать более аккуратный способ сделать это.
Что-то вроде этого:
std::map< std::string, std::string > attribute_name2name;
boost::associative_property_map< std::map< std::string, std::string > >
graphname_map( attribute_name2name );
dp.property("graphname", graphname_map );
boost::read_graphml(stream, this->topology, dp);
topology[boost::graph_bundle].myName = get(graphname_map,"graphname");
Других решений пока нет …