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