使用Boost Graph库read_graphml函数读取GraphML属性时遇报错
问题
使用Boost库的read_graphml函数读取.graphml文件时,遇到属性找不到的错误。报错信息如下:
terminate called after throwing an instance of 'boost::wrapexcept<boost::property_not_found>' what(): Property not found: betti. Aborted (core dumped)
最小可复现代码:
#include <iostream> #include <fstream> #include <boost/graph/graphml.hpp> #include <boost/property_map/dynamic_property_map.hpp> using namespace boost; int main(int, char**){ typedef adjacency_list<vecS, setS, undirectedS> Graph; std::ifstream graph_file; graph_file.open("more_exampleHoles_8.graphml", std::ifstream::in); Graph g; boost::dynamic_properties dp; boost::read_graphml(graph_file, g, dp); }
目标GraphML文件内容:
<?xml version='1.0' encoding='UTF-8'?> <!-- created by IGraph/M, http://szhorvat.net/mathematica/IGraphM --> <graphml xmlns='http://graphml.graphdrawing.org/xmlns' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd'> <key id="v_betti" for="node" attr.name="betti" attr.type="long" /> <key for='node' id='v_dimk' attr.name='dimk' attr.type='long' /> <key for='node' id='v_gap' attr.name='gap' attr.type='double' /> <graph id='Graph' edgedefault='undirected'> <node id="1"> <data key="v_betti">5</data> <data key='v_dimk'>1</data> <data key='v_gap'>0.12405641442417092</data> </node> <node id='2' /> <node id='3' /> <node id='4' /> <node id='5' /> <node id='6' /> <node id='7' /> <node id='8' /> <node id='9' /> <node id='10' /> <node id='11' /> <node id='12' /> <edge source='1' target='2' /> <edge source='1' target='3' /> <edge source='1' target='4' /> <edge source='1' target='8' /> <edge source='2' target='7' /> <edge source='2' target='9' /> <edge source='2' target='11' /> <edge source='3' target='5' /> <edge source='3' target='10' /> <edge source='4' target='5' /> <edge source='4' target='6' /> <edge source='4' target='7' /> <edge source='4' target='8' /> <edge source='4' target='9' /> <edge source='4' target='11' /> <edge source='5' target='9' /> <edge source='5' target='10' /> <edge source='6' target='8' /> <edge source='7' target='10' /> <edge source='8' target='10' /> <edge source='9' target='11' /> </graph> </graphml>
解决方法
报错原因是read_graphml尝试读取GraphML中的节点属性,但未在dynamic_properties对象中为这些属性注册对应的属性映射。需要修改代码,定义包含节点属性的图类型,并将属性映射添加到dynamic_properties中。
修改后的代码
#include <iostream> #include <fstream> #include <boost/graph/graphml.hpp> #include <boost/property_map/dynamic_property_map.hpp> #include <boost/graph/adjacency_list.hpp> using namespace boost; // 定义节点属性结构体 struct NodeProperties { long betti; long dimk; double gap; }; // 定义包含节点属性的图类型 typedef adjacency_list<vecS, setS, undirectedS, NodeProperties> Graph; int main(int, char**){ std::ifstream graph_file("more_exampleHoles_8.graphml", std::ifstream::in); Graph g; boost::dynamic_properties dp; // 将节点属性映射到dynamic_properties dp.property("betti", get(&NodeProperties::betti, g)); dp.property("dimk", get(&NodeProperties::dimk, g)); dp.property("gap", get(&NodeProperties::gap, g)); // 读取GraphML文件,允许部分节点没有属性(使用默认值) boost::read_graphml(graph_file, g, dp, true); // 示例:输出第一个节点的属性 auto v = *vertices(g).first; std::cout << "Node betti: " << g[v].betti << std::endl; std::cout << "Node dimk: " << g[v].dimk << std::endl; std::cout << "Node gap: " << g[v].gap << std::endl; return 0; }
关键说明
- 定义
NodeProperties结构体,对应GraphML中所有节点属性的类型和名称; - 在
adjacency_list的第四个模板参数中指定节点属性类型,让图结构能存储这些属性; - 用
dp.property()将GraphML中的属性名(对应attr.name)绑定到图的属性映射上; - 调用
read_graphml时最后一个参数设为true,允许部分节点无属性值,此时会使用属性类型的默认构造值(如long默认0,double默认0.0)。
内容的提问来源于stack exchange,提问作者ibnyusuf
相关产品推荐
相关产品推荐

