COIN-OR::LEMON - Graph Library

source: lemon-0.x/doc/graph_io.dox @ 1903:f3d24016dad5

Last change on this file since 1903:f3d24016dad5 was 1901:723b2b81d900, checked in by Balazs Dezso, 14 years ago

Lemon Graph Format uses label instead of id named map.

File size: 14.8 KB
RevLine 
[1118]1namespace lemon {
[1114]2/*!
3
4
5\page graph-io-page Graph Input-Output
6
[1540]7The standard graph IO enables one to store graphs and additional maps
8(i.e. functions on the nodes or edges) in a flexible and efficient way.
9Before you read this page you should be familiar with LEMON
10\ref graphs "graphs" and \ref maps-page "maps".
[1114]11
12\section format The general file format
13
[1532]14The file contains sections in the following order:
[1114]15
16\li nodeset
17\li edgeset
18\li nodes
19\li edges
[1532]20\li attributes
[1114]21
[1540]22Some of these sections can be omitted, but you will basicly need the nodeset
23section (unless your graph has no nodes at all) and the edgeset section
24(unless your graph has no edges at all).
25
26The nodeset section describes the nodes of your graph: it identifies the nodes
27and gives the maps defined on them, if any. It starts with the
28following line:
[1522]29
30<tt>\@nodeset</tt>
31
32The next line contains the names of the nodemaps, separated by whitespaces.  Each
33following line describes a node in the graph: it contains the values of the
[1901]34maps in the right order. The map named "label" should contain unique values
35because it is regarded as a label map. These labels need not be numbers but they
[1540]36must identify the nodes uniquely for later reference. For example:
[1114]37
38\code
39@nodeset
[1901]40label  x-coord  y-coord  color
[1114]413   1.0      4.0      blue
425   2.3      5.7      red
4312  7.8      2.3      green
44\endcode
45
46The edgeset section is very similar to the nodeset section, it has
[1522]47the same coloumn oriented structure. It starts with the line
48
49<tt>\@edgeset</tt>
50
[1540]51The next line contains the whitespace separated list of names of the edge
52maps.  Each of the next lines describes one edge. The first two elements in
[1901]53the line are the labels of the source and target (or tail and head) nodes of the
54edge as they occur in the label node map of the nodeset section. You can also
55have an optional label map on the edges for later reference (which has to be
[1540]56unique in this case).
[1114]57
58\code
59@edgeset
[1901]60             label      weight   note
613   5        a          4.3      a-edge
625   12       c          2.6      c-edge
633   12       g          3.4      g-edge
[1114]64\endcode
65
[1540]66The \e nodes section contains <em>labeled (distinguished) nodes</em>
67(i.e. nodes having a special
[1118]68label on them). The section starts with
[1522]69
70<tt> \@nodes </tt>
71
72Each of the next lines contains a label for a node in the graph
[1901]73and then the label as described in the \e nodeset section.
[1114]74
75\code
76@nodes
77source 3
78target 12
79\endcode
80
[1540]81The last section describes the <em>labeled (distinguished) edges</em>
[1333]82(i.e. edges having a special label on them). It starts with \c \@edges
[1901]83and then each line contains the name of the edge and the label.
[1114]84
85\code
[1540]86@edges
[1114]87observed c
88\endcode
89
90
91The file may contain empty lines and comment lines. The comment lines
92start with an \c # character.
93
[1532]94The attributes section can handle some information about the graph. It
[1540]95contains key-value pairs in each line (a key and the mapped value to key). The
96key should be a string without whitespaces, the value can be of various types.
[1532]97
98\code
99@attributes
100title "Four colored plan graph"
101author "Balazs DEZSO"
102copyright "Lemon Library"
103version 12
104\endcode
105
[1901]106Finally, the file should be closed with \c \@end line.
[1522]107
[1114]108
109\section use Using graph input-output
[1540]110
111
112The graph input and output is based on <em> reading and writing
113commands</em>. The user gives reading and writing commands to the reader or
114writer class, then he calls the \c run() method that executes all the given
115commands.
[1114]116
117\subsection write Writing a graph
118
[1631]119The \ref lemon::GraphWriter "GraphWriter" template class
120provides the graph output. To write a graph
[1526]121you should first give writing commands to the writer. You can declare
[1540]122writing command as \c NodeMap or \c EdgeMap writing and labeled Node and
[1114]123Edge writing.
124
125\code
[1333]126GraphWriter<ListGraph> writer(std::cout, graph);
[1114]127\endcode
128
[1631]129The \ref lemon::GraphWriter::writeNodeMap() "writeNodeMap()"
130function declares a \c NodeMap writing command in the
131\ref lemon::GraphWriter "GraphWriter".
132You should give a name to the map and the map
[1901]133object as parameters. The NodeMap writing command with name "label" should write a
134unique map because it will be regarded as a label map.
[1114]135
136\see IdMap, DescriptorMap 
137
138\code
[1901]139IdMap<ListGraph, Node> nodeLabelMap;
140writer.writeNodeMap("label", nodeLabelMap);
[1114]141
[1394]142writer.writeNodeMap("x-coord", xCoordMap);
143writer.writeNodeMap("y-coord", yCoordMap);
144writer.writeNodeMap("color", colorMap);
[1114]145\endcode
146
[1631]147With the \ref lemon::GraphWriter::writeEdgeMap() "writeEdgeMap()"
148member function you can give an edge map
[1333]149writing command similar to the NodeMaps.
[1114]150
151\see IdMap, DescriptorMap 
[1522]152
[1114]153\code
154DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > edgeDescMap(graph);
[1394]155writer.writeEdgeMap("descriptor", edgeDescMap);
[1114]156
[1394]157writer.writeEdgeMap("weight", weightMap);
[1901]158writer.writeEdgeMap("note", noteMap);
[1114]159\endcode
160
[1631]161With \ref lemon::GraphWriter::writeNode() "writeNode()"
162and \ref lemon::GraphWriter::writeEdge() "writeEdge()"
163functions you can designate Nodes and
[1522]164Edges in the graph. For example, you can write out the source and target node
165of a maximum flow instance.
[1114]166
167\code
[1394]168writer.writeNode("source", sourceNode);
169writer.writeNode("target", targetNode);
[1114]170
[1394]171writer.writeEdge("observed", edge);
[1114]172\endcode
173
[1631]174With \ref lemon::GraphWriter::writeAttribute() "writeAttribute()"
175function you can write an attribute to the file.
[1532]176
177\code
178writer.writeAttribute("author", "Balazs DEZSO");
179writer.writeAttribute("version", 12);
180\endcode
181
[1631]182After you give all write commands you must call the
183\ref lemon::GraphWriter::run() "run()" member
[1522]184function, which executes all the writing commands.
[1114]185
186\code
187writer.run();
188\endcode
189
190\subsection reading Reading a graph
191
[1540]192The file to be read may contain several maps and labeled nodes or edges.
[1114]193If you read a graph you need not read all the maps and items just those
[1631]194that you need. The interface of the \ref lemon::GraphReader "GraphReader"
195is very similar to
196the \ref lemon::GraphWriter "GraphWriter"
197but the reading method does not depend on the order of the
[1114]198given commands.
199
[1522]200The reader object assumes that each not readed value does not contain
[1118]201whitespaces, therefore it has some extra possibilities to control how
202it should skip the values when the string representation contains spaces.
[1114]203
204\code
[1333]205GraphReader<ListGraph> reader(std::cin, graph);
[1114]206\endcode
207
[1631]208The \ref lemon::GraphReader::readNodeMap() "readNodeMap()"
209function reads a map from the \c nodeset section.
[1522]210If there is a map that you do not want to read from the file and there are
211whitespaces in the string represenation of the values then you should
[1631]212call the \ref lemon::GraphReader::skipNodeMap() "skipNodeMap()"
213template member function with proper parameters.
[1114]214
215\see QuotedStringReader
[1522]216
[1114]217\code
[1394]218reader.readNodeMap("x-coord", xCoordMap);
219reader.readNodeMap("y-coord", yCoordMap);
[1114]220
[1394]221reader.readNodeMap<QuotedStringReader>("label", labelMap);
[1114]222reader.skipNodeMap<QuotedStringReader>("description");
223
[1394]224reader.readNodeMap("color", colorMap);
[1114]225\endcode
226
[1631]227With the \ref lemon::GraphReader::readEdgeMap() "readEdgeMap()"
228member function you can give an edge map
[1114]229reading command similar to the NodeMaps.
230
231\code
[1394]232reader.readEdgeMap("weight", weightMap);
233reader.readEdgeMap("label", labelMap);
[1114]234\endcode
235
[1631]236With \ref lemon::GraphReader::readNode() "readNode()"
237and \ref lemon::GraphReader::readEdge() "readEdge()"
238functions you can read labeled Nodes and
[1114]239Edges.
240
241\code
[1394]242reader.readNode("source", sourceNode);
243reader.readNode("target", targetNode);
[1114]244
[1394]245reader.readEdge("observed", edge);
[1114]246\endcode
247
[1631]248With \ref lemon::GraphReader::readAttribute() "readAttribute()"
249function you can read an attribute from the file.
[1532]250
251\code
252std::string author;
253writer.readAttribute("author", author);
254int version;
255writer.writeAttribute("version", version);
256\endcode
257
[1631]258After you give all read commands you must call the
259\ref lemon::GraphReader::run() "run()" member
[1522]260function, which executes all the commands.
[1114]261
262\code
263reader.run();
264\endcode
265
[1540]266\anchor rwbackground
[1527]267\section types Background of Reading and Writing
[1540]268
269
[1527]270To read a map (on the nodes or edges)
[1631]271the \ref lemon::GraphReader "GraphReader"
272should know how to read a Value from the given map.
[1114]273By the default implementation the input operator reads a value from
274the stream and the type of the readed value is the value type of the given map.
275When the reader should skip a value in the stream, because you do not
[1527]276want to store it in a map, the reader skips a character sequence without
[1540]277whitespaces.
[1114]278
279If you want to change the functionality of the reader, you can use
280template parameters to specialize it. When you give a reading
281command for a map you can give a Reader type as template parameter.
[1333]282With this template parameter you can control how the Reader reads
[1114]283a value from the stream.
284
285The reader has the next structure:
286\code
287struct TypeReader {
288  typedef TypeName Value;
289
290  void read(std::istream& is, Value& value);
291};
292\endcode
293
[1527]294For example, the \c "strings" nodemap contains strings and you do not need
[1540]295the value of the string just the length. Then you can implement an own Reader
[1114]296struct.
297
298\code
299struct LengthReader {
300  typedef int Value;
301
302  void read(std::istream& is, Value& value) {
303    std::string tmp;
304    is >> tmp;
305    value = tmp.length();
306  }
307};
308...
[1394]309reader.readNodeMap<LengthReader>("strings", lengthMap);
[1114]310\endcode 
311
312The global functionality of the reader class can be changed by giving a
[1526]313special template parameter to the GraphReader class. By default, the
[1118]314template parameter is \c DefaultReaderTraits. A reader traits class
[1901]315should provide a nested template class Reader for each type, and a
[1114]316DefaultReader for skipping a value.
317
[1901]318The specialization of writing is very similar to that of reading.
[1114]319
[1540]320\section undir Undirected graphs
[1532]321
[1540]322In a file describing an undirected graph (undir graph, for short) you find an
323\c undiredgeset section instead of the \c edgeset section. The first line of
324the section describes the names of the maps on the undirected egdes and all
325next lines describe one undirected edge with the the incident nodes and the
326values of the map.
[1532]327
[1540]328The format handles directed edge maps as a syntactical sugar???, if there
329are two maps with names being the same with a \c '+' and a \c '-' prefix
330then this will be read as a directed map.
[1532]331
332\code
333@undiredgeset
[1901]334             label      capacity        +flow   -flow
33532   2       1          4.3             2.0     0.0
33621   21      5          2.6             0.0     2.6
33721   12      8          3.4             0.0     0.0
[1532]338\endcode
339
[1540]340The \c edges section is changed to \c undiredges section. This section
[1532]341describes labeled edges and undirected edges. The directed edge label
[1540]342should start with a \c '+' or a \c '-' prefix to decide the direction
[1532]343of the edge.
344
345\code
346@undiredges
347undiredge 1
348+edge 5
349-back 5
350\endcode
351
[1631]352There are similar classes to the \ref lemon::GraphReader "GraphReader" and
353\ref lemon::GraphWriter "GraphWriter" which
354handle the undirected graphs. These classes are
355the \ref lemon::UndirGraphReader "UndirGraphReader"
356and \ref lemon::UndirGraphWriter "UndirGraphWriter".
[1532]357
[1788]358The \ref lemon::UndirGraphReader::readUndirEdgeMap() "readUndirEdgeMap()"
[1631]359function reads an undirected map and the
360\ref lemon::UndirGraphReader::readUndirEdge() "readUndirEdge()"
361reads an undirected edge from the file,
[1532]362
363\code
364reader.readUndirEdgeMap("capacity", capacityMap);
365reader.readEdgeMap("flow", flowMap);
366...
367reader.readUndirEdge("undir_edge", undir_edge);
368reader.readEdge("edge", edge);
369\endcode
370
371\section advanced Advanced features
372
[1540]373The graph reader and writer classes give an easy way to read and write
374graphs. But sometimes we want more advanced features. In this case we can
375use the more general <tt>lemon reader and writer</tt> interface.
[1532]376
[1540]377The LEMON file format is a section oriented file format. It contains one or
378more sections, each starting with a line identifying its type
379(the word starting with the \c \@  character).
[1532]380The content of the section this way cannot contain line with \c \@ first
381character. The file may contains comment lines with \c # first character.
382
[1631]383The \ref lemon::LemonReader "LemonReader"
384and \ref lemon::LemonWriter "LemonWriter"
385gives a framework to read and
[1532]386write sections. There are various section reader and section writer
[1631]387classes which can be attached to a \ref lemon::LemonReader "LemonReader"
388or a \ref lemon::LemonWriter "LemonWriter".
[1532]389
390There are default section readers and writers for reading and writing
[1540]391item sets, and labeled items in the graph. These read and write
[1532]392the format described above. Other type of data can be handled with own
393section reader and writer classes which are inherited from the
[1631]394\c LemonReader::SectionReader or the
395\ref lemon::LemonWriter::SectionWriter "LemonWriter::SectionWriter"
396classes.
[1532]397
398The next example defines a special section reader which reads the
399\c \@description sections into a string:
400
401\code
402class DescriptionReader : LemonReader::SectionReader {
403protected:
404  virtual bool header(const std::string& line) {
405    std::istringstream ls(line);
406    std::string head;
407    ls >> head;
408    return head == "@description";
409  }
410
411  virtual void read(std::istream& is) {
412    std::string line;
413    while (getline(is, line)) {
414      desc += line;
415    }
416  }
417public:
418
419  typedef LemonReader::SectionReader Parent;
420 
421  DescriptionReader(LemonReader& reader) : Parent(reader) {}
422
423  const std::string& description() const {
424    return description;
425  }
426
427private:
428  std::string desc;
429};
430\endcode
431
432The other advanced stuff of the generalized file format is that
433multiple edgesets can be stored to the same nodeset. It can be used
[1540]434for example as a network traffic matrix.
[1532]435
[1540]436In our example there is a network with symmetric links and there are assymetric
[1532]437traffic request on the network. This construction can be stored in an
[1842]438undirected graph and in a directed \c ListEdgeSet class. The example
[1631]439shows the input with the \ref lemon::LemonReader "LemonReader" class:
[1532]440
441\code
442UndirListGraph network;
[1839]443UndirListGraph::UndirEdgeMap<double> capacity;
[1842]444ListEdgeSet<UndirListGraph> traffic(network);
445ListEdgeSet<UndirListGraph>::EdgeMap<double> request(network);
[1532]446
447LemonReader reader(std::cin);
[1839]448NodeSetReader<UndirListGraph> nodesetReader(reader, network);
449UndirEdgeSetReader<UndirListGraph>
450  undirEdgesetReader(reader, network, nodesetReader);
[1532]451undirEdgesetReader.readEdgeMap("capacity", capacity);
[1842]452EdgeSetReader<ListEdgeSet<UndirListGraph> >
[1848]453  edgesetReader(reader, traffic, nodesetReader, "traffic");
[1532]454edgesetReader.readEdgeMap("request", request);
455
456reader.run();
457\endcode
458
[1631]459Because both the \ref lemon::GraphReader "GraphReader"
460and the \ref lemon::UndirGraphReader "UndirGraphReader" can be converted
461to \ref lemon::LemonReader "LemonReader"
[1901]462and it can resolve the label's of the items, the previous
[1631]463result can be achived with the \ref lemon::UndirGraphReader "UndirGraphReader"
464class, too.
[1532]465
466
467\code
468UndirListGraph network;
469UndirListGraph::UndirEdgeSet<double> capacity;
[1842]470ListEdgeSet<UndirListGraph> traffic(network);
471ListEdgeSet<UndirListGraph>::EdgeMap<double> request(network);
[1532]472
[1842]473UndirGraphReader<UndirListGraph> reader(std::cin, network);
[1532]474reader.readEdgeMap("capacity", capacity);
[1842]475EdgeSetReader<ListEdgeSet<UndirListGraph> >
[1848]476  edgesetReader(reader, traffic, reader, "traffic");
[1532]477edgesetReader.readEdgeMap("request", request);
478
479reader.run();
480\endcode
481
[1333]482\author Balazs Dezso
[1114]483*/
[1631]484}
Note: See TracBrowser for help on using the repository browser.