how to read graph-domain attributes with boost::read_graphml?

人走茶凉 提交于 2020-01-07 00:54:50

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!