1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/doc/read_write_bg.dox Thu Sep 14 19:11:24 2006 +0000
1.3 @@ -0,0 +1,219 @@
1.4 +namespace lemon {
1.5 +/*!
1.6 +\page read_write_bg Background of Reading and Writing
1.7 +
1.8 +To read a map (on the nodes or edges)
1.9 +the \ref lemon::GraphReader "GraphReader"
1.10 +should know how to read a Value from the given map.
1.11 +By the default implementation the input operator reads a value from
1.12 +the stream and the type of the read value is the value type of the given map.
1.13 +When the reader should skip a value in the stream, because you do not
1.14 +want to store it in a map, the reader skips a character sequence without
1.15 +whitespaces.
1.16 +
1.17 +If you want to change the functionality of the reader, you can use
1.18 +template parameters to specialize it. When you give a reading
1.19 +command for a map you can give a Reader type as template parameter.
1.20 +With this template parameter you can control how the Reader reads
1.21 +a value from the stream.
1.22 +
1.23 +The reader has the next structure:
1.24 +\code
1.25 +struct TypeReader {
1.26 + typedef TypeName Value;
1.27 +
1.28 + void read(std::istream& is, Value& value);
1.29 +};
1.30 +\endcode
1.31 +
1.32 +For example, the \c "strings" nodemap contains strings and you do not need
1.33 +the value of the string just the length. Then you can implement an own Reader
1.34 +struct.
1.35 +
1.36 +\code
1.37 +struct LengthReader {
1.38 + typedef int Value;
1.39 +
1.40 + void read(std::istream& is, Value& value) {
1.41 + std::string tmp;
1.42 + is >> tmp;
1.43 + value = tmp.length();
1.44 + }
1.45 +};
1.46 +...
1.47 +reader.readNodeMap<LengthReader>("strings", lengthMap);
1.48 +\endcode
1.49 +
1.50 +The global functionality of the reader class can be changed by giving a
1.51 +special template parameter to the GraphReader class. By default, the
1.52 +template parameter is \c DefaultReaderTraits. A reader traits class
1.53 +should provide a nested template class Reader for each type, and a
1.54 +DefaultReader for skipping a value.
1.55 +
1.56 +The specialization of writing is very similar to that of reading.
1.57 +
1.58 +\section u Undirected graphs
1.59 +
1.60 +In a file describing an undirected graph (ugraph, for short) you find an
1.61 +\c uedgeset section instead of the \c edgeset section. The first line of
1.62 +the section describes the names of the maps on the undirected egdes and all
1.63 +next lines describe one undirected edge with the the incident nodes and the
1.64 +values of the map.
1.65 +
1.66 +The format handles directed edge maps as a syntactical sugar???, if there
1.67 +are two maps with names being the same with a \c '+' and a \c '-' prefix
1.68 +then this will be read as a directed map.
1.69 +
1.70 +\code
1.71 +@uedgeset
1.72 + label capacity +flow -flow
1.73 +32 2 1 4.3 2.0 0.0
1.74 +21 21 5 2.6 0.0 2.6
1.75 +21 12 8 3.4 0.0 0.0
1.76 +\endcode
1.77 +
1.78 +The \c edges section is changed to \c uedges section. This section
1.79 +describes labeled edges and undirected edges. The directed edge label
1.80 +should start with a \c '+' or a \c '-' prefix to decide the direction
1.81 +of the edge.
1.82 +
1.83 +\code
1.84 +@uedges
1.85 +uedge 1
1.86 ++edge 5
1.87 +-back 5
1.88 +\endcode
1.89 +
1.90 +There are similar classes to the \ref lemon::GraphReader "GraphReader" and
1.91 +\ref lemon::GraphWriter "GraphWriter" which
1.92 +handle the undirected graphs. These classes are
1.93 +the \ref lemon::UGraphReader "UGraphReader"
1.94 +and \ref lemon::UGraphWriter "UGraphWriter".
1.95 +
1.96 +The \ref lemon::UGraphReader::readUEdgeMap() "readUEdgeMap()"
1.97 +function reads an undirected map and the
1.98 +\ref lemon::UGraphReader::readUEdge() "readUEdge()"
1.99 +reads an undirected edge from the file,
1.100 +
1.101 +\code
1.102 +reader.readUEdgeMap("capacity", capacityMap);
1.103 +reader.readEdgeMap("flow", flowMap);
1.104 +...
1.105 +reader.readUEdge("u_edge", u_edge);
1.106 +reader.readEdge("edge", edge);
1.107 +\endcode
1.108 +
1.109 +\section advanced Advanced features
1.110 +
1.111 +The graph reader and writer classes give an easy way to read and write
1.112 +graphs. But sometimes we want more advanced features. In this case we can
1.113 +use the more general <tt>lemon reader and writer</tt> interface.
1.114 +
1.115 +The LEMON file format is a section oriented file format. It contains one or
1.116 +more sections, each starting with a line identifying its type
1.117 +(the word starting with the \c \@ character).
1.118 +The content of the section this way cannot contain line with \c \@ first
1.119 +character. The file may contains comment lines with \c # first character.
1.120 +
1.121 +The \ref lemon::LemonReader "LemonReader"
1.122 +and \ref lemon::LemonWriter "LemonWriter"
1.123 +gives a framework to read and
1.124 +write sections. There are various section reader and section writer
1.125 +classes which can be attached to a \ref lemon::LemonReader "LemonReader"
1.126 +or a \ref lemon::LemonWriter "LemonWriter".
1.127 +
1.128 +There are default section readers and writers for reading and writing
1.129 +item sets, and labeled items in the graph. These read and write
1.130 +the format described above. Other type of data can be handled with own
1.131 +section reader and writer classes which are inherited from the
1.132 +\c LemonReader::SectionReader or the
1.133 +\ref lemon::LemonWriter::SectionWriter "LemonWriter::SectionWriter"
1.134 +classes.
1.135 +
1.136 +The next example defines a special section reader which reads the
1.137 +\c \@description sections into a string:
1.138 +
1.139 +\code
1.140 +class DescriptionReader : LemonReader::SectionReader {
1.141 +protected:
1.142 + virtual bool header(const std::string& line) {
1.143 + std::istringstream ls(line);
1.144 + std::string head;
1.145 + ls >> head;
1.146 + return head == "@description";
1.147 + }
1.148 +
1.149 + virtual void read(std::istream& is) {
1.150 + std::string line;
1.151 + while (getline(is, line)) {
1.152 + desc += line;
1.153 + }
1.154 + }
1.155 +public:
1.156 +
1.157 + typedef LemonReader::SectionReader Parent;
1.158 +
1.159 + DescriptionReader(LemonReader& reader) : Parent(reader) {}
1.160 +
1.161 + const std::string& description() const {
1.162 + return description;
1.163 + }
1.164 +
1.165 +private:
1.166 + std::string desc;
1.167 +};
1.168 +\endcode
1.169 +
1.170 +The other advanced stuff of the generalized file format is that
1.171 +multiple edgesets can be stored to the same nodeset. It can be used
1.172 +for example as a network traffic matrix.
1.173 +
1.174 +In our example there is a network with symmetric links and there are assymetric
1.175 +traffic request on the network. This construction can be stored in an
1.176 +undirected graph and in a directed \c ListEdgeSet class. The example
1.177 +shows the input with the \ref lemon::LemonReader "LemonReader" class:
1.178 +
1.179 +\code
1.180 +ListUGraph network;
1.181 +ListUGraph::UEdgeMap<double> capacity;
1.182 +ListEdgeSet<ListUGraph> traffic(network);
1.183 +ListEdgeSet<ListUGraph>::EdgeMap<double> request(network);
1.184 +
1.185 +LemonReader reader(std::cin);
1.186 +NodeSetReader<ListUGraph> nodesetReader(reader, network);
1.187 +UEdgeSetReader<ListUGraph>
1.188 + uEdgesetReader(reader, network, nodesetReader);
1.189 +uEdgesetReader.readEdgeMap("capacity", capacity);
1.190 +EdgeSetReader<ListEdgeSet<ListUGraph> >
1.191 + edgesetReader(reader, traffic, nodesetReader, "traffic");
1.192 +edgesetReader.readEdgeMap("request", request);
1.193 +
1.194 +reader.run();
1.195 +\endcode
1.196 +
1.197 +Because both the \ref lemon::GraphReader "GraphReader"
1.198 +and the \ref lemon::UGraphReader "UGraphReader" can be converted
1.199 +to \ref lemon::LemonReader "LemonReader"
1.200 +and it can resolve the label's of the items, the previous
1.201 +result can be achived with the \ref lemon::UGraphReader "UGraphReader"
1.202 +class, too.
1.203 +
1.204 +
1.205 +\code
1.206 +ListUGraph network;
1.207 +ListUGraph::UEdgeSet<double> capacity;
1.208 +ListEdgeSet<ListUGraph> traffic(network);
1.209 +ListEdgeSet<ListUGraph>::EdgeMap<double> request(network);
1.210 +
1.211 +UGraphReader<ListUGraph> reader(std::cin, network);
1.212 +reader.readEdgeMap("capacity", capacity);
1.213 +EdgeSetReader<ListEdgeSet<ListUGraph> >
1.214 + edgesetReader(reader, traffic, reader, "traffic");
1.215 +edgesetReader.readEdgeMap("request", request);
1.216 +
1.217 +reader.run();
1.218 +\endcode
1.219 +
1.220 +\author Balazs Dezso
1.221 +*/
1.222 +}