问题描述
我使用 Boost 图来存储一组节点和边,然后将其写入 graphml 格式。无论我做什么,我都找不到访问或设置节点 id (n0,n1) 或边 id (e0) 属性的方法。 好像是自动设置的。
有没有办法手动访问和设置?
<?xml version="1.0" encoding="UTF-8"?>
<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="key0" for="node" attr.name="id" attr.type="int" />
<key id="key1" for="edge" attr.name="length" attr.type="double" />
<key id="key2" for="edge" attr.name="max_speed" attr.type="double" />
<key id="key3" for="node" attr.name="name" attr.type="string" />
<key id="key4" for="edge" attr.name="name" attr.type="string" />
<key id="key5" for="edge" attr.name="source" attr.type="int" />
<key id="key6" for="node" attr.name="station" attr.type="boolean" />
<key id="key7" for="edge" attr.name="target" attr.type="int" />
<key id="key8" for="node" attr.name="theta" attr.type="double" />
<key id="key9" for="node" attr.name="x" attr.type="double" />
<key id="key10" for="node" attr.name="y" attr.type="double" />
<graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
<node id="n0">
<data key="key0">10000</data>
<data key="key3">node1</data>
<data key="key6">0</data>
<data key="key8">0</data>
<data key="key9">6.95279e-310</data>
<data key="key10">0</data>
</node>
<node id="n1">
<data key="key0">10001</data>
<data key="key3">node1</data>
<data key="key6">0</data>
<data key="key8">0</data>
<data key="key9">6.95279e-310</data>
<data key="key10">0</data>
</node>
<edge id="e0" source="n0" target="n1">
<data key="key1">6.95279e-310</data>
<data key="key2">150</data>
<data key="key4"></data>
<data key="key5">-127787376</data>
<data key="key7">21994</data>
</edge>
</graph>
</graphml>
我的图表
typedef typename boost::adjacency_list<boost::vecS,boost::vecS,boost::directedS,GpNode,GpEdge>
DirectedGraph;
提前致谢
解决方法
write_graphml
需要一个 dynamic_properties
。让我们配置一下:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphml.hpp>
struct GpNode {
int id;
std::string name;
bool station;
double theta;
double x;
double y;
};
struct GpEdge {
double length;
double max_speed;
std::string name;
int source;
int target;
};
using DirectedGraph = boost::adjacency_list<boost::vecS,boost::vecS,boost::directedS,GpNode,GpEdge>;
int main() {
std::ifstream ifs("input.xml");
DirectedGraph g;
auto n0 = add_vertex(
GpNode{
10000,// id
"node1",// name
0,// station
0,// theta
6.95279e-310,// x
0,// y
},g);
auto n1 = add_vertex(
GpNode{
10001,g);
/*auto e0 = */add_edge(n0,n1,GpEdge{
6.95279e-310,// length
150,// max_speed
"",// name
-127787376,// source
21994,// target
},g);
auto vindex = get(&GpNode::id,g);
boost::dynamic_properties dp;
//dp.property("node_id",vindex);
dp.property("id",vindex);
dp.property("name",get(&GpNode::name,g));
dp.property("station",get(&GpNode::station,g));
dp.property("theta",get(&GpNode::theta,g));
dp.property("x",get(&GpNode::x,g));
dp.property("y",get(&GpNode::y,g));
dp.property("length",get(&GpEdge::length,g));
dp.property("max_speed",get(&GpEdge::max_speed,g));
dp.property("name",get(&GpEdge::name,g));
dp.property("source",get(&GpEdge::source,g));
dp.property("target",get(&GpEdge::target,g));
boost::write_graphml(std::cout,g,dp);
}
印刷品
<?xml version="1.0" encoding="UTF-8"?>
<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="key0" for="node" attr.name="id" attr.type="int" />
<key id="key1" for="edge" attr.name="length" attr.type="double" />
<key id="key2" for="edge" attr.name="max_speed" attr.type="double" />
<key id="key3" for="node" attr.name="name" attr.type="string" />
<key id="key4" for="edge" attr.name="name" attr.type="string" />
<key id="key5" for="edge" attr.name="source" attr.type="int" />
<key id="key6" for="node" attr.name="station" attr.type="boolean" />
<key id="key7" for="edge" attr.name="target" attr.type="int" />
<key id="key8" for="node" attr.name="theta" attr.type="double" />
<key id="key9" for="node" attr.name="x" attr.type="double" />
<key id="key10" for="node" attr.name="y" attr.type="double" />
<graph id="G" edgedefault="directed" parse.nodeids="free" parse.edgeids="canonical" parse.order="nodesfirst">
<node id="n0">
<data key="key0">10000</data>
<data key="key3">node1</data>
<data key="key6">0</data>
<data key="key8">0</data>
<data key="key9">6.95279e-310</data>
<data key="key10">0</data>
</node>
<node id="n1">
<data key="key0">10001</data>
<data key="key3">node1</data>
<data key="key6">0</data>
<data key="key8">0</data>
<data key="key9">6.95279e-310</data>
<data key="key10">0</data>
</node>
<edge id="e0" source="n0" target="n1">
<data key="key1">6.95279e-310</data>
<data key="key2">150</data>
<data key="key4"></data>
<data key="key5">-127787376</data>
<data key="key7">21994</data>
</edge>
</graph>
</graphml>
嗯。那花了一段时间。但现在我明白了。我知道 write_graphviz_dp
假定 node_id
是节点 id 属性,但正如您所看到的,我尝试过但没有帮助
拯救文档
但是,等等,文档显示了第二个也需要 VertexIndexMap 的重载。让我们……试试看?
boost::write_graphml(std::cout,vindex,dp);
现在打印
<?xml version="1.0" encoding="UTF-8"?>
<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="key0" for="node" attr.name="id" attr.type="int" />
<key id="key1" for="edge" attr.name="length" attr.type="double" />
<key id="key2" for="edge" attr.name="max_speed" attr.type="double" />
<key id="key3" for="node" attr.name="name" attr.type="string" />
<key id="key4" for="edge" attr.name="name" attr.type="string" />
<key id="key5" for="edge" attr.name="source" attr.type="int" />
<key id="key6" for="node" attr.name="station" attr.type="boolean" />
<key id="key7" for="edge" attr.name="target" attr.type="int" />
<key id="key8" for="node" attr.name="theta" attr.type="double" />
<key id="key9" for="node" attr.name="x" attr.type="double" />
<key id="key10" for="node" attr.name="y" attr.type="double" />
<graph id="G" edgedefault="directed" parse.nodeids="free" parse.edgeids="canonical" parse.order="nodesfirst">
<node id="n10000">
<data key="key0">10000</data>
<data key="key3">node1</data>
<data key="key6">0</data>
<data key="key8">0</data>
<data key="key9">6.95279e-310</data>
<data key="key10">0</data>
</node>
<node id="n10001">
<data key="key0">10001</data>
<data key="key3">node1</data>
<data key="key6">0</data>
<data key="key8">0</data>
<data key="key9">6.95279e-310</data>
<data key="key10">0</data>
</node>
<edge id="e0" source="n10000" target="n10001">
<data key="key1">6.95279e-310</data>
<data key="key2">150</data>
<data key="key4"></data>
<data key="key5">-127787376</data>
<data key="key7">21994</data>
</edge>
</graph>
</graphml>
这很可能与您接近。将 id
类型更改为 std::string
不会阻止 "n"
前缀。 (我想这是为了让边缘可以毫无问题地与节点碰撞?)