问题
Probably a silly question, but I can't find any answer online. My application reads a topology from a custom file and builds a boost::graph out of it. I'm in the process of moving to a more standard graphml representation. I can read/write node properties using a vertex_descriptor as a key, and similarly I can use an edge_descriptor for edge attributes, but what about graph attributes? To which key type will they be associated when they are read in the graphml file?
To explain my doubt, here's the code I have to define the graph and read the graphml file:
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 [...]
Notice how I create new associative maps to store properties that are useful for the definition of the graph (e.g. when I build it) but not worth storing in every single node/edge for the entire graph lifetime. Now, some of these properties are related to the entire graph; for example I could define in the graphml file something like
<key id="name" for="graph" attr.name="graphName" attr.type="string" />
How do I define the required property_map and add it to dp so that this bit of information will be parsed correctly?
回答1:
You can setup bundled properties for the graph, just like you did with the vertices and edges.
Something like this:
struct graph_props {
std::string myName;
...
};
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
NetworkNode, NetworkEdge, graph_props > DGraph;
In order to convince boost::read_graphml to save graph properties you have to supply a property map ( which will have just one member ) Unfortunately, AFAIK you will have to extract the values read_graphml places into this map and set the bundled graph property attributes. Maybe someone can point out a neater way to do this.
Something like this:
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");
来源:https://stackoverflow.com/questions/17112477/how-to-read-graph-domain-attributes-with-boostread-graphml