5 \page graph-io-page Graph Input-Output
7 The standard graph IO enables to store graphs and additional maps
8 in a flexible and efficient way.
10 \section format The general file format
12 The file contains sections in the following order:
20 The nodeset section starts with the following line:
24 The next line contains the names of the nodemaps, separated by whitespaces. Each
25 following line describes a node in the graph: it contains the values of the
26 maps in the right order. The map named "id" should contain unique values
27 because it is regarded as an ID-map. For example:
31 id x-coord y-coord color
37 The edgeset section is very similar to the nodeset section, it has
38 the same coloumn oriented structure. It starts with the line
42 The next line contains the whitespace separated list of names of the maps.
43 Each of the next lines describes one edge. The first two elements in the line
44 are the IDs of the source and target (or tail and head) node of the edge as they occur in the ID node
45 map. You can also have an optional ID map on the edges for later reference.
55 The next section contains <em>labeled nodes</em> (i.e. nodes having a special
56 label on them). The section starts with
60 Each of the next lines contains a label for a node in the graph
61 and then the ID described in the nodeset section.
69 The last section describes the <em>labeled edges</em>
70 (i.e. edges having a special label on them). It starts with \c \@edges
71 and then each line contains the name of the edge and the ID.
79 The file may contain empty lines and comment lines. The comment lines
80 start with an \c # character.
82 The attributes section can handle some information about the graph. It
83 contains in each line an key and the mapped value to key. The key should
84 be a string without whitespace, the value can be from various type.
88 title "Four colored plan graph"
90 copyright "Lemon Library"
98 The file ends with the
105 \section use Using graph input-output
106 The graph input and output is based on reading and writing commands. The user
107 adds reading and writing commands to the reader or writer class, then he
108 calls the \c run() method that executes all the given commands.
110 \subsection write Writing a graph
112 The \c GraphWriter class provides the graph output. To write a graph
113 you should first give writing commands to the writer. You can declare
114 write command as \c NodeMap or \c EdgeMap writing and labeled Node and
118 GraphWriter<ListGraph> writer(std::cout, graph);
121 The \c writeNodeMap() function declares a \c NodeMap writing command in the
122 \c GraphWriter. You should give a name of the map and the map
123 object as parameters. The NodeMap writing command with name "id" should write a
124 unique map because it is regarded as ID map.
126 \see IdMap, DescriptorMap
129 IdMap<ListGraph, Node> nodeIdMap;
130 writer.writeNodeMap("id", nodeIdMap);
132 writer.writeNodeMap("x-coord", xCoordMap);
133 writer.writeNodeMap("y-coord", yCoordMap);
134 writer.writeNodeMap("color", colorMap);
137 With the \c writeEdgeMap() member function you can give an edge map
138 writing command similar to the NodeMaps.
140 \see IdMap, DescriptorMap
143 DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > edgeDescMap(graph);
144 writer.writeEdgeMap("descriptor", edgeDescMap);
146 writer.writeEdgeMap("weight", weightMap);
147 writer.writeEdgeMap("label", labelMap);
150 With \c writeNode() and \c writeEdge() functions you can designate Nodes and
151 Edges in the graph. For example, you can write out the source and target node
152 of a maximum flow instance.
155 writer.writeNode("source", sourceNode);
156 writer.writeNode("target", targetNode);
158 writer.writeEdge("observed", edge);
161 With \c writeAttribute() function you can write an attribute to the file.
164 writer.writeAttribute("author", "Balazs DEZSO");
165 writer.writeAttribute("version", 12);
168 After you give all write commands you must call the \c run() member
169 function, which executes all the writing commands.
175 \subsection reading Reading a graph
177 The given file format may contain several maps and labeled nodes or edges.
178 If you read a graph you need not read all the maps and items just those
179 that you need. The interface of the \c GraphReader is very similar to
180 the GraphWriter but the reading method does not depend on the order of the
183 The reader object assumes that each not readed value does not contain
184 whitespaces, therefore it has some extra possibilities to control how
185 it should skip the values when the string representation contains spaces.
188 GraphReader<ListGraph> reader(std::cin, graph);
191 The \c readNodeMap() function reads a map from the \c \@nodeset section.
192 If there is a map that you do not want to read from the file and there are
193 whitespaces in the string represenation of the values then you should
194 call the \c skipNodeMap() template member function with proper parameters.
196 \see QuotedStringReader
199 reader.readNodeMap("x-coord", xCoordMap);
200 reader.readNodeMap("y-coord", yCoordMap);
202 reader.readNodeMap<QuotedStringReader>("label", labelMap);
203 reader.skipNodeMap<QuotedStringReader>("description");
205 reader.readNodeMap("color", colorMap);
208 With the \c readEdgeMap() member function you can give an edge map
209 reading command similar to the NodeMaps.
212 reader.readEdgeMap("weight", weightMap);
213 reader.readEdgeMap("label", labelMap);
216 With \c readNode() and \c readEdge() functions you can read labeled Nodes and
220 reader.readNode("source", sourceNode);
221 reader.readNode("target", targetNode);
223 reader.readEdge("observed", edge);
226 With \c readAttribute() function you can read an attribute from the file.
230 writer.readAttribute("author", author);
232 writer.writeAttribute("version", version);
235 After you give all read commands you must call the \c run() member
236 function, which executes all the commands.
242 \section types Background of Reading and Writing
243 To read a map (on the nodes or edges)
244 the \c GraphReader should know how to read a Value from the given map.
245 By the default implementation the input operator reads a value from
246 the stream and the type of the readed value is the value type of the given map.
247 When the reader should skip a value in the stream, because you do not
248 want to store it in a map, the reader skips a character sequence without
251 If you want to change the functionality of the reader, you can use
252 template parameters to specialize it. When you give a reading
253 command for a map you can give a Reader type as template parameter.
254 With this template parameter you can control how the Reader reads
255 a value from the stream.
257 The reader has the next structure:
260 typedef TypeName Value;
262 void read(std::istream& is, Value& value);
266 For example, the \c "strings" nodemap contains strings and you do not need
267 the value of the string just the length. Then you can implement own Reader
271 struct LengthReader {
274 void read(std::istream& is, Value& value) {
277 value = tmp.length();
281 reader.readNodeMap<LengthReader>("strings", lengthMap);
284 The global functionality of the reader class can be changed by giving a
285 special template parameter to the GraphReader class. By default, the
286 template parameter is \c DefaultReaderTraits. A reader traits class
287 should provide an inner template class Reader for each type, and an
288 DefaultReader for skipping a value.
290 The specialization of writing should be very similar to that of reading.
292 \section undir Undir graphs
294 In the undir graph format there is an \c undiredgeset section instead of
295 the \c edgeset section. The first line of the section describes the
296 undirected egdes' names and all next lines describes one undirected edge
297 with the the incident nodes and the values of the map.
299 The format handles the directed edge maps as a syntactical sugar, if there
300 is two map which names are the same with a \c '+' and a \c '-' prefix
301 then it can be read as an directed map.
305 id capacity +flow -flow
311 The \c edges section changed to \c undiredges section. This section
312 describes labeled edges and undirected edges. The directed edge label
313 should start with a \c '+' and a \c '-' prefix what decide the direction
323 There are similar classes to the \c GraphReader ans \c GraphWriter
324 which handle the undirected graphs. These classes are the
325 \c UndirGraphReader and \UndirGraphWriter.
327 The \c readUndirMap() function reads an undirected map and the
328 \c readUndirEdge() reads an undirected edge from the file,
331 reader.readUndirEdgeMap("capacity", capacityMap);
332 reader.readEdgeMap("flow", flowMap);
334 reader.readUndirEdge("undir_edge", undir_edge);
335 reader.readEdge("edge", edge);
338 \section advanced Advanced features
340 The graph reader and writer classes gives an easy way to read and write
341 graphs. But sometimes we want more advanced features. This way we can
342 use the more general lemon reader and writer interface.
344 The lemon format is an section oriented file format. It contains one or
345 more section, each starts with a line with \c \@ first character.
346 The content of the section this way cannot contain line with \c \@ first
347 character. The file may contains comment lines with \c # first character.
349 The \c LemonReader and \c LemonWriter gives a framework to read and
350 write sections. There are various section reader and section writer
351 classes which can be attached to a \c LemonReader or a \c LemonWriter.
353 There are default section readers and writers for reading and writing
354 item sets, and labeled items in the graph. These reads and writes
355 the format described above. Other type of data can be handled with own
356 section reader and writer classes which are inherited from the
357 \c LemonReader::SectionReader or the \c LemonWriter::SectionWriter classes.
359 The next example defines a special section reader which reads the
360 \c \@description sections into a string:
363 class DescriptionReader : LemonReader::SectionReader {
365 virtual bool header(const std::string& line) {
366 std::istringstream ls(line);
369 return head == "@description";
372 virtual void read(std::istream& is) {
374 while (getline(is, line)) {
380 typedef LemonReader::SectionReader Parent;
382 DescriptionReader(LemonReader& reader) : Parent(reader) {}
384 const std::string& description() const {
393 The other advanced stuff of the generalized file format is that
394 multiple edgesets can be stored to the same nodeset. It can be used
395 by example as a network traffic matrix.
397 In example there is a network with symmetric links and there are assymetric
398 traffic request on the network. This construction can be stored in an
399 undirected graph and in an directed NewEdgeSetAdaptor class. The example
400 shows the input with the LemonReader class:
403 UndirListGraph network;
404 UndirListGraph::UndirEdgeSet<double> capacity;
405 NewEdgeSetAdaptor<UndirListGraph> traffic(network);
406 NewEdgeSetAdaptor<UndirListGraph>::EdgeSet<double> request(network);
408 LemonReader reader(std::cin);
409 NodeSetReader nodesetReader(reader, network);
410 UndirEdgeSetReader undirEdgesetReader(reader, network, nodesetReader);
411 undirEdgesetReader.readEdgeMap("capacity", capacity);
412 EdgeSetReader edgesetReader(reader, traffic, nodesetReader);
413 edgesetReader.readEdgeMap("request", request);
418 Because the GraphReader and the UndirGraphReader can be converted
419 to LemonReader and it can resolve the ID's of the items, the previous
420 result can be achived with the UndirGraphReader class also.
424 UndirListGraph network;
425 UndirListGraph::UndirEdgeSet<double> capacity;
426 NewEdgeSetAdaptor<UndirListGraph> traffic(network);
427 NewEdgeSetAdaptor<UndirListGraph>::EdgeSet<double> request(network);
429 UndirGraphReader reader(std::cin, network);
430 reader.readEdgeMap("capacity", capacity);
431 EdgeSetReader edgesetReader(reader, traffic, reader);
432 edgesetReader.readEdgeMap("request", request);