可能是一个愚蠢的问题,但我在网上找不到任何答案。我的应用程序从自定义文件中读取拓扑并从中构建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,以便正确解析这些信息?
答案 0 :(得分:2)
您可以为图表设置捆绑属性,就像使用顶点和边缘一样。
这样的事情:
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");