|
1 namespace lemon { |
|
2 /*! |
|
3 \page read_write_bg Background of Reading and Writing |
|
4 |
|
5 To read a map (on the nodes or edges) |
|
6 the \ref lemon::GraphReader "GraphReader" |
|
7 should know how to read a Value from the given map. |
|
8 By the default implementation the input operator reads a value from |
|
9 the stream and the type of the read value is the value type of the given map. |
|
10 When the reader should skip a value in the stream, because you do not |
|
11 want to store it in a map, the reader skips a character sequence without |
|
12 whitespaces. |
|
13 |
|
14 If you want to change the functionality of the reader, you can use |
|
15 template parameters to specialize it. When you give a reading |
|
16 command for a map you can give a Reader type as template parameter. |
|
17 With this template parameter you can control how the Reader reads |
|
18 a value from the stream. |
|
19 |
|
20 The reader has the next structure: |
|
21 \code |
|
22 struct TypeReader { |
|
23 typedef TypeName Value; |
|
24 |
|
25 void read(std::istream& is, Value& value); |
|
26 }; |
|
27 \endcode |
|
28 |
|
29 For example, the \c "strings" nodemap contains strings and you do not need |
|
30 the value of the string just the length. Then you can implement an own Reader |
|
31 struct. |
|
32 |
|
33 \code |
|
34 struct LengthReader { |
|
35 typedef int Value; |
|
36 |
|
37 void read(std::istream& is, Value& value) { |
|
38 std::string tmp; |
|
39 is >> tmp; |
|
40 value = tmp.length(); |
|
41 } |
|
42 }; |
|
43 ... |
|
44 reader.readNodeMap<LengthReader>("strings", lengthMap); |
|
45 \endcode |
|
46 |
|
47 The global functionality of the reader class can be changed by giving a |
|
48 special template parameter to the GraphReader class. By default, the |
|
49 template parameter is \c DefaultReaderTraits. A reader traits class |
|
50 should provide a nested template class Reader for each type, and a |
|
51 DefaultReader for skipping a value. |
|
52 |
|
53 The specialization of writing is very similar to that of reading. |
|
54 |
|
55 \section u Undirected graphs |
|
56 |
|
57 In a file describing an undirected graph (ugraph, for short) you find an |
|
58 \c uedgeset section instead of the \c edgeset section. The first line of |
|
59 the section describes the names of the maps on the undirected egdes and all |
|
60 next lines describe one undirected edge with the the incident nodes and the |
|
61 values of the map. |
|
62 |
|
63 The format handles directed edge maps as a syntactical sugar???, if there |
|
64 are two maps with names being the same with a \c '+' and a \c '-' prefix |
|
65 then this will be read as a directed map. |
|
66 |
|
67 \code |
|
68 @uedgeset |
|
69 label capacity +flow -flow |
|
70 32 2 1 4.3 2.0 0.0 |
|
71 21 21 5 2.6 0.0 2.6 |
|
72 21 12 8 3.4 0.0 0.0 |
|
73 \endcode |
|
74 |
|
75 The \c edges section is changed to \c uedges section. This section |
|
76 describes labeled edges and undirected edges. The directed edge label |
|
77 should start with a \c '+' or a \c '-' prefix to decide the direction |
|
78 of the edge. |
|
79 |
|
80 \code |
|
81 @uedges |
|
82 uedge 1 |
|
83 +edge 5 |
|
84 -back 5 |
|
85 \endcode |
|
86 |
|
87 There are similar classes to the \ref lemon::GraphReader "GraphReader" and |
|
88 \ref lemon::GraphWriter "GraphWriter" which |
|
89 handle the undirected graphs. These classes are |
|
90 the \ref lemon::UGraphReader "UGraphReader" |
|
91 and \ref lemon::UGraphWriter "UGraphWriter". |
|
92 |
|
93 The \ref lemon::UGraphReader::readUEdgeMap() "readUEdgeMap()" |
|
94 function reads an undirected map and the |
|
95 \ref lemon::UGraphReader::readUEdge() "readUEdge()" |
|
96 reads an undirected edge from the file, |
|
97 |
|
98 \code |
|
99 reader.readUEdgeMap("capacity", capacityMap); |
|
100 reader.readEdgeMap("flow", flowMap); |
|
101 ... |
|
102 reader.readUEdge("u_edge", u_edge); |
|
103 reader.readEdge("edge", edge); |
|
104 \endcode |
|
105 |
|
106 \section advanced Advanced features |
|
107 |
|
108 The graph reader and writer classes give an easy way to read and write |
|
109 graphs. But sometimes we want more advanced features. In this case we can |
|
110 use the more general <tt>lemon reader and writer</tt> interface. |
|
111 |
|
112 The LEMON file format is a section oriented file format. It contains one or |
|
113 more sections, each starting with a line identifying its type |
|
114 (the word starting with the \c \@ character). |
|
115 The content of the section this way cannot contain line with \c \@ first |
|
116 character. The file may contains comment lines with \c # first character. |
|
117 |
|
118 The \ref lemon::LemonReader "LemonReader" |
|
119 and \ref lemon::LemonWriter "LemonWriter" |
|
120 gives a framework to read and |
|
121 write sections. There are various section reader and section writer |
|
122 classes which can be attached to a \ref lemon::LemonReader "LemonReader" |
|
123 or a \ref lemon::LemonWriter "LemonWriter". |
|
124 |
|
125 There are default section readers and writers for reading and writing |
|
126 item sets, and labeled items in the graph. These read and write |
|
127 the format described above. Other type of data can be handled with own |
|
128 section reader and writer classes which are inherited from the |
|
129 \c LemonReader::SectionReader or the |
|
130 \ref lemon::LemonWriter::SectionWriter "LemonWriter::SectionWriter" |
|
131 classes. |
|
132 |
|
133 The next example defines a special section reader which reads the |
|
134 \c \@description sections into a string: |
|
135 |
|
136 \code |
|
137 class DescriptionReader : LemonReader::SectionReader { |
|
138 protected: |
|
139 virtual bool header(const std::string& line) { |
|
140 std::istringstream ls(line); |
|
141 std::string head; |
|
142 ls >> head; |
|
143 return head == "@description"; |
|
144 } |
|
145 |
|
146 virtual void read(std::istream& is) { |
|
147 std::string line; |
|
148 while (getline(is, line)) { |
|
149 desc += line; |
|
150 } |
|
151 } |
|
152 public: |
|
153 |
|
154 typedef LemonReader::SectionReader Parent; |
|
155 |
|
156 DescriptionReader(LemonReader& reader) : Parent(reader) {} |
|
157 |
|
158 const std::string& description() const { |
|
159 return description; |
|
160 } |
|
161 |
|
162 private: |
|
163 std::string desc; |
|
164 }; |
|
165 \endcode |
|
166 |
|
167 The other advanced stuff of the generalized file format is that |
|
168 multiple edgesets can be stored to the same nodeset. It can be used |
|
169 for example as a network traffic matrix. |
|
170 |
|
171 In our example there is a network with symmetric links and there are assymetric |
|
172 traffic request on the network. This construction can be stored in an |
|
173 undirected graph and in a directed \c ListEdgeSet class. The example |
|
174 shows the input with the \ref lemon::LemonReader "LemonReader" class: |
|
175 |
|
176 \code |
|
177 ListUGraph network; |
|
178 ListUGraph::UEdgeMap<double> capacity; |
|
179 ListEdgeSet<ListUGraph> traffic(network); |
|
180 ListEdgeSet<ListUGraph>::EdgeMap<double> request(network); |
|
181 |
|
182 LemonReader reader(std::cin); |
|
183 NodeSetReader<ListUGraph> nodesetReader(reader, network); |
|
184 UEdgeSetReader<ListUGraph> |
|
185 uEdgesetReader(reader, network, nodesetReader); |
|
186 uEdgesetReader.readEdgeMap("capacity", capacity); |
|
187 EdgeSetReader<ListEdgeSet<ListUGraph> > |
|
188 edgesetReader(reader, traffic, nodesetReader, "traffic"); |
|
189 edgesetReader.readEdgeMap("request", request); |
|
190 |
|
191 reader.run(); |
|
192 \endcode |
|
193 |
|
194 Because both the \ref lemon::GraphReader "GraphReader" |
|
195 and the \ref lemon::UGraphReader "UGraphReader" can be converted |
|
196 to \ref lemon::LemonReader "LemonReader" |
|
197 and it can resolve the label's of the items, the previous |
|
198 result can be achived with the \ref lemon::UGraphReader "UGraphReader" |
|
199 class, too. |
|
200 |
|
201 |
|
202 \code |
|
203 ListUGraph network; |
|
204 ListUGraph::UEdgeSet<double> capacity; |
|
205 ListEdgeSet<ListUGraph> traffic(network); |
|
206 ListEdgeSet<ListUGraph>::EdgeMap<double> request(network); |
|
207 |
|
208 UGraphReader<ListUGraph> reader(std::cin, network); |
|
209 reader.readEdgeMap("capacity", capacity); |
|
210 EdgeSetReader<ListEdgeSet<ListUGraph> > |
|
211 edgesetReader(reader, traffic, reader, "traffic"); |
|
212 edgesetReader.readEdgeMap("request", request); |
|
213 |
|
214 reader.run(); |
|
215 \endcode |
|
216 |
|
217 \author Balazs Dezso |
|
218 */ |
|
219 } |