alpar@1118: namespace lemon {
deba@1114: /*!
deba@1114:
deba@1114:
deba@1114: \page graph-io-page Graph Input-Output
deba@1114:
athos@1522: The standard graph IO enables to store graphs and additional maps
alpar@1118: in a flexible and efficient way.
deba@1114:
deba@1114: \section format The general file format
deba@1114:
athos@1522: The file contains at most four sections in the following order:
deba@1114:
deba@1114: \li nodeset
deba@1114: \li edgeset
deba@1114: \li nodes
deba@1114: \li edges
deba@1114:
athos@1522: The nodeset section starts with the following line:
athos@1522:
athos@1522: \@nodeset
athos@1522:
athos@1522: The next line contains the names of the nodemaps, separated by whitespaces. Each
athos@1522: following line describes a node in the graph: it contains the values of the
athos@1522: maps in the right order. The map named "id" should contain unique values
athos@1522: because it is regarded as an ID-map. For example:
deba@1114:
deba@1114: \code
deba@1114: @nodeset
deba@1114: id x-coord y-coord color
deba@1114: 3 1.0 4.0 blue
deba@1114: 5 2.3 5.7 red
deba@1114: 12 7.8 2.3 green
deba@1114: \endcode
deba@1114:
deba@1114: The edgeset section is very similar to the nodeset section, it has
athos@1522: the same coloumn oriented structure. It starts with the line
athos@1522:
athos@1522: \@edgeset
athos@1522:
athos@1522: The next line contains the whitespace separated list of names of the maps.
alpar@1118: Each of the next lines describes one edge. The first two elements in the line
athos@1522: are the IDs of the source and target (or tail and head) node of the edge as they occur in the ID node
athos@1522: map. You can also have an optional ID map on the edges for later reference.
deba@1114:
deba@1114: \code
deba@1114: @edgeset
deba@1114: id weight label
deba@1114: 3 5 a 4.3 a-edge
deba@1114: 5 12 c 2.6 c-edge
deba@1114: 3 12 g 3.4 g-edge
deba@1114: \endcode
deba@1114:
deba@1333: The next section contains labeled nodes (i.e. nodes having a special
alpar@1118: label on them). The section starts with
athos@1522:
athos@1522: \@nodes
athos@1522:
athos@1522: Each of the next lines contains a label for a node in the graph
athos@1522: and then the ID described in the nodeset section.
deba@1114:
deba@1114: \code
deba@1114: @nodes
deba@1114: source 3
deba@1114: target 12
deba@1114: \endcode
deba@1114:
deba@1333: The last section describes the labeled edges
deba@1333: (i.e. edges having a special label on them). It starts with \c \@edges
deba@1114: and then each line contains the name of the edge and the ID.
deba@1114:
deba@1114: \code
deba@1114: @nodes
deba@1114: observed c
deba@1114: \endcode
deba@1114:
deba@1114:
deba@1114: The file may contain empty lines and comment lines. The comment lines
deba@1114: start with an \c # character.
deba@1114:
athos@1522: The file ends with the
athos@1522:
athos@1522: \@end
athos@1522:
athos@1522: line.
athos@1522:
deba@1114:
deba@1114: \section use Using graph input-output
athos@1522: The graph input and output is based on reading and writing commands. The user
athos@1522: adds reading and writing commands to the reader or writer class, then he
alpar@1118: calls the \c run() method that executes all the given commands.
deba@1114:
deba@1114: \subsection write Writing a graph
deba@1114:
deba@1114: The \c GraphWriter class provides the graph output. To write a graph
athos@1526: you should first give writing commands to the writer. You can declare
alpar@1118: write command as \c NodeMap or \c EdgeMap writing and labeled Node and
deba@1114: Edge writing.
deba@1114:
deba@1114: \code
deba@1333: GraphWriter writer(std::cout, graph);
deba@1114: \endcode
deba@1114:
deba@1394: The \c writeNodeMap() function declares a \c NodeMap writing command in the
athos@1522: \c GraphWriter. You should give a name of the map and the map
athos@1522: object as parameters. The NodeMap writing command with name "id" should write a
deba@1333: unique map because it is regarded as ID map.
deba@1114:
deba@1114: \see IdMap, DescriptorMap
deba@1114:
deba@1114: \code
deba@1114: IdMap nodeIdMap;
deba@1394: writer.writeNodeMap("id", nodeIdMap);
deba@1114:
deba@1394: writer.writeNodeMap("x-coord", xCoordMap);
deba@1394: writer.writeNodeMap("y-coord", yCoordMap);
deba@1394: writer.writeNodeMap("color", colorMap);
deba@1114: \endcode
deba@1114:
deba@1394: With the \c writeEdgeMap() member function you can give an edge map
deba@1333: writing command similar to the NodeMaps.
deba@1114:
deba@1114: \see IdMap, DescriptorMap
athos@1522:
deba@1114: \code
deba@1114: DescriptorMap > edgeDescMap(graph);
deba@1394: writer.writeEdgeMap("descriptor", edgeDescMap);
deba@1114:
deba@1394: writer.writeEdgeMap("weight", weightMap);
deba@1394: writer.writeEdgeMap("label", labelMap);
deba@1114: \endcode
deba@1114:
athos@1522: With \c writeNode() and \c writeEdge() functions you can designate Nodes and
athos@1522: Edges in the graph. For example, you can write out the source and target node
athos@1522: of a maximum flow instance.
deba@1114:
deba@1114: \code
deba@1394: writer.writeNode("source", sourceNode);
deba@1394: writer.writeNode("target", targetNode);
deba@1114:
deba@1394: writer.writeEdge("observed", edge);
deba@1114: \endcode
deba@1114:
deba@1114: After you give all write commands you must call the \c run() member
athos@1522: function, which executes all the writing commands.
deba@1114:
deba@1114: \code
deba@1114: writer.run();
deba@1114: \endcode
deba@1114:
deba@1114: \subsection reading Reading a graph
deba@1114:
alpar@1118: The given file format may contain several maps and labeled nodes or edges.
deba@1114: If you read a graph you need not read all the maps and items just those
deba@1114: that you need. The interface of the \c GraphReader is very similar to
athos@1522: the GraphWriter but the reading method does not depend on the order of the
deba@1114: given commands.
deba@1114:
athos@1522: The reader object assumes that each not readed value does not contain
alpar@1118: whitespaces, therefore it has some extra possibilities to control how
alpar@1118: it should skip the values when the string representation contains spaces.
deba@1114:
deba@1114: \code
deba@1333: GraphReader reader(std::cin, graph);
deba@1114: \endcode
deba@1114:
deba@1394: The \c readNodeMap() function reads a map from the \c \@nodeset section.
athos@1522: If there is a map that you do not want to read from the file and there are
athos@1522: whitespaces in the string represenation of the values then you should
deba@1114: call the \c skipNodeMap() template member function with proper parameters.
deba@1114:
deba@1114: \see QuotedStringReader
athos@1522:
deba@1114: \code
deba@1394: reader.readNodeMap("x-coord", xCoordMap);
deba@1394: reader.readNodeMap("y-coord", yCoordMap);
deba@1114:
deba@1394: reader.readNodeMap("label", labelMap);
deba@1114: reader.skipNodeMap("description");
deba@1114:
deba@1394: reader.readNodeMap("color", colorMap);
deba@1114: \endcode
deba@1114:
deba@1394: With the \c readEdgeMap() member function you can give an edge map
deba@1114: reading command similar to the NodeMaps.
deba@1114:
deba@1114: \code
deba@1394: reader.readEdgeMap("weight", weightMap);
deba@1394: reader.readEdgeMap("label", labelMap);
deba@1114: \endcode
deba@1114:
deba@1394: With \c readNode() and \c readEdge() functions you can read labeled Nodes and
deba@1114: Edges.
deba@1114:
deba@1114: \code
deba@1394: reader.readNode("source", sourceNode);
deba@1394: reader.readNode("target", targetNode);
deba@1114:
deba@1394: reader.readEdge("observed", edge);
deba@1114: \endcode
deba@1114:
deba@1114: After you give all read commands you must call the \c run() member
athos@1522: function, which executes all the commands.
deba@1114:
deba@1114: \code
deba@1114: reader.run();
deba@1114: \endcode
deba@1114:
athos@1522: \section types The background of Reading and Writing
athos@1522: The \c GraphReader should know how to read a Value from the given map.
deba@1114: By the default implementation the input operator reads a value from
deba@1114: the stream and the type of the readed value is the value type of the given map.
deba@1114: When the reader should skip a value in the stream, because you do not
deba@1114: want to store it in map, the reader skips a character sequence without
deba@1114: whitespace.
deba@1114:
deba@1114: If you want to change the functionality of the reader, you can use
deba@1114: template parameters to specialize it. When you give a reading
deba@1114: command for a map you can give a Reader type as template parameter.
deba@1333: With this template parameter you can control how the Reader reads
deba@1114: a value from the stream.
deba@1114:
deba@1114: The reader has the next structure:
deba@1114: \code
deba@1114: struct TypeReader {
deba@1114: typedef TypeName Value;
deba@1114:
deba@1114: void read(std::istream& is, Value& value);
deba@1114: };
deba@1114: \endcode
deba@1114:
deba@1114: By example, the \c "strings" nodemap contains strings and you do not need
deba@1114: the value of the string just the length. Then you can implement own Reader
deba@1114: struct.
deba@1114:
deba@1114: \code
deba@1114: struct LengthReader {
deba@1114: typedef int Value;
deba@1114:
deba@1114: void read(std::istream& is, Value& value) {
deba@1114: std::string tmp;
deba@1114: is >> tmp;
deba@1114: value = tmp.length();
deba@1114: }
deba@1114: };
deba@1114: ...
deba@1394: reader.readNodeMap("strings", lengthMap);
deba@1114: \endcode
deba@1114:
deba@1114: The global functionality of the reader class can be changed by giving a
athos@1526: special template parameter to the GraphReader class. By default, the
alpar@1118: template parameter is \c DefaultReaderTraits. A reader traits class
deba@1114: should provide an inner template class Reader for each type, and an
deba@1114: DefaultReader for skipping a value.
deba@1114:
deba@1114: The specialization of the writing should be very similar to the reading.
deba@1114:
deba@1333: \author Balazs Dezso
deba@1114: */
deba@1333: }