alpar@1118
|
1 |
namespace lemon {
|
deba@1114
|
2 |
/*!
|
deba@1114
|
3 |
|
deba@1114
|
4 |
|
deba@1114
|
5 |
\page graph-io-page Graph Input-Output
|
deba@1114
|
6 |
|
athos@1540
|
7 |
The standard graph IO enables one to store graphs and additional maps
|
athos@1540
|
8 |
(i.e. functions on the nodes or edges) in a flexible and efficient way.
|
athos@1540
|
9 |
Before you read this page you should be familiar with LEMON
|
athos@1540
|
10 |
\ref graphs "graphs" and \ref maps-page "maps".
|
deba@1114
|
11 |
|
deba@1114
|
12 |
\section format The general file format
|
deba@1114
|
13 |
|
deba@1532
|
14 |
The file contains sections in the following order:
|
deba@1114
|
15 |
|
deba@1114
|
16 |
\li nodeset
|
deba@1114
|
17 |
\li edgeset
|
deba@1114
|
18 |
\li nodes
|
deba@1114
|
19 |
\li edges
|
deba@1532
|
20 |
\li attributes
|
deba@1114
|
21 |
|
athos@1540
|
22 |
Some of these sections can be omitted, but you will basicly need the nodeset
|
athos@1540
|
23 |
section (unless your graph has no nodes at all) and the edgeset section
|
athos@1540
|
24 |
(unless your graph has no edges at all).
|
athos@1540
|
25 |
|
athos@1540
|
26 |
The nodeset section describes the nodes of your graph: it identifies the nodes
|
athos@1540
|
27 |
and gives the maps defined on them, if any. It starts with the
|
athos@1540
|
28 |
following line:
|
athos@1522
|
29 |
|
athos@1522
|
30 |
<tt>\@nodeset</tt>
|
athos@1522
|
31 |
|
athos@1522
|
32 |
The next line contains the names of the nodemaps, separated by whitespaces. Each
|
athos@1522
|
33 |
following line describes a node in the graph: it contains the values of the
|
athos@1522
|
34 |
maps in the right order. The map named "id" should contain unique values
|
athos@1540
|
35 |
because it is regarded as an ID-map. These ids need not be numbers but they
|
athos@1540
|
36 |
must identify the nodes uniquely for later reference. For example:
|
deba@1114
|
37 |
|
deba@1114
|
38 |
\code
|
deba@1114
|
39 |
@nodeset
|
deba@1114
|
40 |
id x-coord y-coord color
|
deba@1114
|
41 |
3 1.0 4.0 blue
|
deba@1114
|
42 |
5 2.3 5.7 red
|
deba@1114
|
43 |
12 7.8 2.3 green
|
deba@1114
|
44 |
\endcode
|
deba@1114
|
45 |
|
deba@1114
|
46 |
The edgeset section is very similar to the nodeset section, it has
|
athos@1522
|
47 |
the same coloumn oriented structure. It starts with the line
|
athos@1522
|
48 |
|
athos@1522
|
49 |
<tt>\@edgeset</tt>
|
athos@1522
|
50 |
|
athos@1540
|
51 |
The next line contains the whitespace separated list of names of the edge
|
athos@1540
|
52 |
maps. Each of the next lines describes one edge. The first two elements in
|
athos@1540
|
53 |
the line are the IDs of the source and target (or tail and head) nodes of the
|
athos@1540
|
54 |
edge as they occur in the ID node map of the nodeset section. You can also
|
athos@1540
|
55 |
have an optional ID map on the edges for later reference (which has to be
|
athos@1540
|
56 |
unique in this case).
|
deba@1114
|
57 |
|
deba@1114
|
58 |
\code
|
deba@1114
|
59 |
@edgeset
|
deba@1114
|
60 |
id weight label
|
deba@1114
|
61 |
3 5 a 4.3 a-edge
|
deba@1114
|
62 |
5 12 c 2.6 c-edge
|
deba@1114
|
63 |
3 12 g 3.4 g-edge
|
deba@1114
|
64 |
\endcode
|
deba@1114
|
65 |
|
athos@1540
|
66 |
The \e nodes section contains <em>labeled (distinguished) nodes</em>
|
athos@1540
|
67 |
(i.e. nodes having a special
|
alpar@1118
|
68 |
label on them). The section starts with
|
athos@1522
|
69 |
|
athos@1522
|
70 |
<tt> \@nodes </tt>
|
athos@1522
|
71 |
|
athos@1522
|
72 |
Each of the next lines contains a label for a node in the graph
|
athos@1540
|
73 |
and then the ID as described in the \e nodeset section.
|
deba@1114
|
74 |
|
deba@1114
|
75 |
\code
|
deba@1114
|
76 |
@nodes
|
deba@1114
|
77 |
source 3
|
deba@1114
|
78 |
target 12
|
deba@1114
|
79 |
\endcode
|
deba@1114
|
80 |
|
athos@1540
|
81 |
The last section describes the <em>labeled (distinguished) edges</em>
|
deba@1333
|
82 |
(i.e. edges having a special label on them). It starts with \c \@edges
|
deba@1114
|
83 |
and then each line contains the name of the edge and the ID.
|
deba@1114
|
84 |
|
deba@1114
|
85 |
\code
|
athos@1540
|
86 |
@edges
|
deba@1114
|
87 |
observed c
|
deba@1114
|
88 |
\endcode
|
deba@1114
|
89 |
|
deba@1114
|
90 |
|
deba@1114
|
91 |
The file may contain empty lines and comment lines. The comment lines
|
deba@1114
|
92 |
start with an \c # character.
|
deba@1114
|
93 |
|
deba@1532
|
94 |
The attributes section can handle some information about the graph. It
|
athos@1540
|
95 |
contains key-value pairs in each line (a key and the mapped value to key). The
|
athos@1540
|
96 |
key should be a string without whitespaces, the value can be of various types.
|
deba@1532
|
97 |
|
deba@1532
|
98 |
\code
|
deba@1532
|
99 |
@attributes
|
deba@1532
|
100 |
title "Four colored plan graph"
|
deba@1532
|
101 |
author "Balazs DEZSO"
|
deba@1532
|
102 |
copyright "Lemon Library"
|
deba@1532
|
103 |
version 12
|
deba@1532
|
104 |
\endcode
|
deba@1532
|
105 |
|
athos@1522
|
106 |
<tt> \@end </tt>
|
athos@1522
|
107 |
|
athos@1522
|
108 |
line.
|
athos@1522
|
109 |
|
deba@1114
|
110 |
|
deba@1114
|
111 |
\section use Using graph input-output
|
athos@1540
|
112 |
|
athos@1540
|
113 |
The easiest way of using graph input and output is using the versions of the
|
athos@1540
|
114 |
public \ref readGraph() and \ref writeGraph() functions; if you don't need
|
athos@1540
|
115 |
very sophisticated behaviour then you might be satisfied with
|
athos@1540
|
116 |
those. Otherwise go on reading this page.
|
athos@1540
|
117 |
|
athos@1540
|
118 |
The graph input and output is based on <em> reading and writing
|
athos@1540
|
119 |
commands</em>. The user gives reading and writing commands to the reader or
|
athos@1540
|
120 |
writer class, then he calls the \c run() method that executes all the given
|
athos@1540
|
121 |
commands.
|
deba@1114
|
122 |
|
deba@1114
|
123 |
\subsection write Writing a graph
|
deba@1114
|
124 |
|
alpar@1631
|
125 |
The \ref lemon::GraphWriter "GraphWriter" template class
|
alpar@1631
|
126 |
provides the graph output. To write a graph
|
athos@1526
|
127 |
you should first give writing commands to the writer. You can declare
|
athos@1540
|
128 |
writing command as \c NodeMap or \c EdgeMap writing and labeled Node and
|
deba@1114
|
129 |
Edge writing.
|
deba@1114
|
130 |
|
deba@1114
|
131 |
\code
|
deba@1333
|
132 |
GraphWriter<ListGraph> writer(std::cout, graph);
|
deba@1114
|
133 |
\endcode
|
deba@1114
|
134 |
|
alpar@1631
|
135 |
The \ref lemon::GraphWriter::writeNodeMap() "writeNodeMap()"
|
alpar@1631
|
136 |
function declares a \c NodeMap writing command in the
|
alpar@1631
|
137 |
\ref lemon::GraphWriter "GraphWriter".
|
alpar@1631
|
138 |
You should give a name to the map and the map
|
athos@1522
|
139 |
object as parameters. The NodeMap writing command with name "id" should write a
|
athos@1540
|
140 |
unique map because it will be regarded as an ID map.
|
deba@1114
|
141 |
|
deba@1114
|
142 |
\see IdMap, DescriptorMap
|
deba@1114
|
143 |
|
deba@1114
|
144 |
\code
|
deba@1114
|
145 |
IdMap<ListGraph, Node> nodeIdMap;
|
deba@1394
|
146 |
writer.writeNodeMap("id", nodeIdMap);
|
deba@1114
|
147 |
|
deba@1394
|
148 |
writer.writeNodeMap("x-coord", xCoordMap);
|
deba@1394
|
149 |
writer.writeNodeMap("y-coord", yCoordMap);
|
deba@1394
|
150 |
writer.writeNodeMap("color", colorMap);
|
deba@1114
|
151 |
\endcode
|
deba@1114
|
152 |
|
alpar@1631
|
153 |
With the \ref lemon::GraphWriter::writeEdgeMap() "writeEdgeMap()"
|
alpar@1631
|
154 |
member function you can give an edge map
|
deba@1333
|
155 |
writing command similar to the NodeMaps.
|
deba@1114
|
156 |
|
deba@1114
|
157 |
\see IdMap, DescriptorMap
|
athos@1522
|
158 |
|
deba@1114
|
159 |
\code
|
deba@1114
|
160 |
DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > edgeDescMap(graph);
|
deba@1394
|
161 |
writer.writeEdgeMap("descriptor", edgeDescMap);
|
deba@1114
|
162 |
|
deba@1394
|
163 |
writer.writeEdgeMap("weight", weightMap);
|
deba@1394
|
164 |
writer.writeEdgeMap("label", labelMap);
|
deba@1114
|
165 |
\endcode
|
deba@1114
|
166 |
|
alpar@1631
|
167 |
With \ref lemon::GraphWriter::writeNode() "writeNode()"
|
alpar@1631
|
168 |
and \ref lemon::GraphWriter::writeEdge() "writeEdge()"
|
alpar@1631
|
169 |
functions you can designate Nodes and
|
athos@1522
|
170 |
Edges in the graph. For example, you can write out the source and target node
|
athos@1522
|
171 |
of a maximum flow instance.
|
deba@1114
|
172 |
|
deba@1114
|
173 |
\code
|
deba@1394
|
174 |
writer.writeNode("source", sourceNode);
|
deba@1394
|
175 |
writer.writeNode("target", targetNode);
|
deba@1114
|
176 |
|
deba@1394
|
177 |
writer.writeEdge("observed", edge);
|
deba@1114
|
178 |
\endcode
|
deba@1114
|
179 |
|
alpar@1631
|
180 |
With \ref lemon::GraphWriter::writeAttribute() "writeAttribute()"
|
alpar@1631
|
181 |
function you can write an attribute to the file.
|
deba@1532
|
182 |
|
deba@1532
|
183 |
\code
|
deba@1532
|
184 |
writer.writeAttribute("author", "Balazs DEZSO");
|
deba@1532
|
185 |
writer.writeAttribute("version", 12);
|
deba@1532
|
186 |
\endcode
|
deba@1532
|
187 |
|
alpar@1631
|
188 |
After you give all write commands you must call the
|
alpar@1631
|
189 |
\ref lemon::GraphWriter::run() "run()" member
|
athos@1522
|
190 |
function, which executes all the writing commands.
|
deba@1114
|
191 |
|
deba@1114
|
192 |
\code
|
deba@1114
|
193 |
writer.run();
|
deba@1114
|
194 |
\endcode
|
deba@1114
|
195 |
|
deba@1114
|
196 |
\subsection reading Reading a graph
|
deba@1114
|
197 |
|
athos@1540
|
198 |
The file to be read may contain several maps and labeled nodes or edges.
|
deba@1114
|
199 |
If you read a graph you need not read all the maps and items just those
|
alpar@1631
|
200 |
that you need. The interface of the \ref lemon::GraphReader "GraphReader"
|
alpar@1631
|
201 |
is very similar to
|
alpar@1631
|
202 |
the \ref lemon::GraphWriter "GraphWriter"
|
alpar@1631
|
203 |
but the reading method does not depend on the order of the
|
deba@1114
|
204 |
given commands.
|
deba@1114
|
205 |
|
athos@1522
|
206 |
The reader object assumes that each not readed value does not contain
|
alpar@1118
|
207 |
whitespaces, therefore it has some extra possibilities to control how
|
alpar@1118
|
208 |
it should skip the values when the string representation contains spaces.
|
deba@1114
|
209 |
|
deba@1114
|
210 |
\code
|
deba@1333
|
211 |
GraphReader<ListGraph> reader(std::cin, graph);
|
deba@1114
|
212 |
\endcode
|
deba@1114
|
213 |
|
alpar@1631
|
214 |
The \ref lemon::GraphReader::readNodeMap() "readNodeMap()"
|
alpar@1631
|
215 |
function reads a map from the \c nodeset section.
|
athos@1522
|
216 |
If there is a map that you do not want to read from the file and there are
|
athos@1522
|
217 |
whitespaces in the string represenation of the values then you should
|
alpar@1631
|
218 |
call the \ref lemon::GraphReader::skipNodeMap() "skipNodeMap()"
|
alpar@1631
|
219 |
template member function with proper parameters.
|
deba@1114
|
220 |
|
deba@1114
|
221 |
\see QuotedStringReader
|
athos@1522
|
222 |
|
deba@1114
|
223 |
\code
|
deba@1394
|
224 |
reader.readNodeMap("x-coord", xCoordMap);
|
deba@1394
|
225 |
reader.readNodeMap("y-coord", yCoordMap);
|
deba@1114
|
226 |
|
deba@1394
|
227 |
reader.readNodeMap<QuotedStringReader>("label", labelMap);
|
deba@1114
|
228 |
reader.skipNodeMap<QuotedStringReader>("description");
|
deba@1114
|
229 |
|
deba@1394
|
230 |
reader.readNodeMap("color", colorMap);
|
deba@1114
|
231 |
\endcode
|
deba@1114
|
232 |
|
alpar@1631
|
233 |
With the \ref lemon::GraphReader::readEdgeMap() "readEdgeMap()"
|
alpar@1631
|
234 |
member function you can give an edge map
|
deba@1114
|
235 |
reading command similar to the NodeMaps.
|
deba@1114
|
236 |
|
deba@1114
|
237 |
\code
|
deba@1394
|
238 |
reader.readEdgeMap("weight", weightMap);
|
deba@1394
|
239 |
reader.readEdgeMap("label", labelMap);
|
deba@1114
|
240 |
\endcode
|
deba@1114
|
241 |
|
alpar@1631
|
242 |
With \ref lemon::GraphReader::readNode() "readNode()"
|
alpar@1631
|
243 |
and \ref lemon::GraphReader::readEdge() "readEdge()"
|
alpar@1631
|
244 |
functions you can read labeled Nodes and
|
deba@1114
|
245 |
Edges.
|
deba@1114
|
246 |
|
deba@1114
|
247 |
\code
|
deba@1394
|
248 |
reader.readNode("source", sourceNode);
|
deba@1394
|
249 |
reader.readNode("target", targetNode);
|
deba@1114
|
250 |
|
deba@1394
|
251 |
reader.readEdge("observed", edge);
|
deba@1114
|
252 |
\endcode
|
deba@1114
|
253 |
|
alpar@1631
|
254 |
With \ref lemon::GraphReader::readAttribute() "readAttribute()"
|
alpar@1631
|
255 |
function you can read an attribute from the file.
|
deba@1532
|
256 |
|
deba@1532
|
257 |
\code
|
deba@1532
|
258 |
std::string author;
|
deba@1532
|
259 |
writer.readAttribute("author", author);
|
deba@1532
|
260 |
int version;
|
deba@1532
|
261 |
writer.writeAttribute("version", version);
|
deba@1532
|
262 |
\endcode
|
deba@1532
|
263 |
|
alpar@1631
|
264 |
After you give all read commands you must call the
|
alpar@1631
|
265 |
\ref lemon::GraphReader::run() "run()" member
|
athos@1522
|
266 |
function, which executes all the commands.
|
deba@1114
|
267 |
|
deba@1114
|
268 |
\code
|
deba@1114
|
269 |
reader.run();
|
deba@1114
|
270 |
\endcode
|
deba@1114
|
271 |
|
athos@1540
|
272 |
\anchor rwbackground
|
athos@1527
|
273 |
\section types Background of Reading and Writing
|
athos@1540
|
274 |
|
athos@1540
|
275 |
|
athos@1527
|
276 |
To read a map (on the nodes or edges)
|
alpar@1631
|
277 |
the \ref lemon::GraphReader "GraphReader"
|
alpar@1631
|
278 |
should know how to read a Value from the given map.
|
deba@1114
|
279 |
By the default implementation the input operator reads a value from
|
deba@1114
|
280 |
the stream and the type of the readed value is the value type of the given map.
|
deba@1114
|
281 |
When the reader should skip a value in the stream, because you do not
|
athos@1527
|
282 |
want to store it in a map, the reader skips a character sequence without
|
athos@1540
|
283 |
whitespaces.
|
deba@1114
|
284 |
|
deba@1114
|
285 |
If you want to change the functionality of the reader, you can use
|
deba@1114
|
286 |
template parameters to specialize it. When you give a reading
|
deba@1114
|
287 |
command for a map you can give a Reader type as template parameter.
|
deba@1333
|
288 |
With this template parameter you can control how the Reader reads
|
deba@1114
|
289 |
a value from the stream.
|
deba@1114
|
290 |
|
deba@1114
|
291 |
The reader has the next structure:
|
deba@1114
|
292 |
\code
|
deba@1114
|
293 |
struct TypeReader {
|
deba@1114
|
294 |
typedef TypeName Value;
|
deba@1114
|
295 |
|
deba@1114
|
296 |
void read(std::istream& is, Value& value);
|
deba@1114
|
297 |
};
|
deba@1114
|
298 |
\endcode
|
deba@1114
|
299 |
|
athos@1527
|
300 |
For example, the \c "strings" nodemap contains strings and you do not need
|
athos@1540
|
301 |
the value of the string just the length. Then you can implement an own Reader
|
deba@1114
|
302 |
struct.
|
deba@1114
|
303 |
|
deba@1114
|
304 |
\code
|
deba@1114
|
305 |
struct LengthReader {
|
deba@1114
|
306 |
typedef int Value;
|
deba@1114
|
307 |
|
deba@1114
|
308 |
void read(std::istream& is, Value& value) {
|
deba@1114
|
309 |
std::string tmp;
|
deba@1114
|
310 |
is >> tmp;
|
deba@1114
|
311 |
value = tmp.length();
|
deba@1114
|
312 |
}
|
deba@1114
|
313 |
};
|
deba@1114
|
314 |
...
|
deba@1394
|
315 |
reader.readNodeMap<LengthReader>("strings", lengthMap);
|
deba@1114
|
316 |
\endcode
|
deba@1114
|
317 |
|
deba@1114
|
318 |
The global functionality of the reader class can be changed by giving a
|
athos@1526
|
319 |
special template parameter to the GraphReader class. By default, the
|
alpar@1118
|
320 |
template parameter is \c DefaultReaderTraits. A reader traits class
|
athos@1540
|
321 |
should provide an inner template class Reader for each type, and a
|
deba@1114
|
322 |
DefaultReader for skipping a value.
|
deba@1114
|
323 |
|
athos@1540
|
324 |
The specialization of writing is very similar to that of reading.
|
deba@1114
|
325 |
|
athos@1540
|
326 |
\section undir Undirected graphs
|
deba@1532
|
327 |
|
athos@1540
|
328 |
In a file describing an undirected graph (undir graph, for short) you find an
|
athos@1540
|
329 |
\c undiredgeset section instead of the \c edgeset section. The first line of
|
athos@1540
|
330 |
the section describes the names of the maps on the undirected egdes and all
|
athos@1540
|
331 |
next lines describe one undirected edge with the the incident nodes and the
|
athos@1540
|
332 |
values of the map.
|
deba@1532
|
333 |
|
athos@1540
|
334 |
The format handles directed edge maps as a syntactical sugar???, if there
|
athos@1540
|
335 |
are two maps with names being the same with a \c '+' and a \c '-' prefix
|
athos@1540
|
336 |
then this will be read as a directed map.
|
deba@1532
|
337 |
|
deba@1532
|
338 |
\code
|
deba@1532
|
339 |
@undiredgeset
|
deba@1532
|
340 |
id capacity +flow -flow
|
deba@1532
|
341 |
32 2 1 4.3 2.0 0.0
|
deba@1532
|
342 |
21 21 5 2.6 0.0 2.6
|
deba@1532
|
343 |
21 12 8 3.4 0.0 0.0
|
deba@1532
|
344 |
\endcode
|
deba@1532
|
345 |
|
athos@1540
|
346 |
The \c edges section is changed to \c undiredges section. This section
|
deba@1532
|
347 |
describes labeled edges and undirected edges. The directed edge label
|
athos@1540
|
348 |
should start with a \c '+' or a \c '-' prefix to decide the direction
|
deba@1532
|
349 |
of the edge.
|
deba@1532
|
350 |
|
deba@1532
|
351 |
\code
|
deba@1532
|
352 |
@undiredges
|
deba@1532
|
353 |
undiredge 1
|
deba@1532
|
354 |
+edge 5
|
deba@1532
|
355 |
-back 5
|
deba@1532
|
356 |
\endcode
|
deba@1532
|
357 |
|
alpar@1631
|
358 |
There are similar classes to the \ref lemon::GraphReader "GraphReader" and
|
alpar@1631
|
359 |
\ref lemon::GraphWriter "GraphWriter" which
|
alpar@1631
|
360 |
handle the undirected graphs. These classes are
|
alpar@1631
|
361 |
the \ref lemon::UndirGraphReader "UndirGraphReader"
|
alpar@1631
|
362 |
and \ref lemon::UndirGraphWriter "UndirGraphWriter".
|
deba@1532
|
363 |
|
alpar@1631
|
364 |
The \ref lemon::UndirGraphReader::readUndirMap() "readUndirMap()"
|
alpar@1631
|
365 |
function reads an undirected map and the
|
alpar@1631
|
366 |
\ref lemon::UndirGraphReader::readUndirEdge() "readUndirEdge()"
|
alpar@1631
|
367 |
reads an undirected edge from the file,
|
deba@1532
|
368 |
|
deba@1532
|
369 |
\code
|
deba@1532
|
370 |
reader.readUndirEdgeMap("capacity", capacityMap);
|
deba@1532
|
371 |
reader.readEdgeMap("flow", flowMap);
|
deba@1532
|
372 |
...
|
deba@1532
|
373 |
reader.readUndirEdge("undir_edge", undir_edge);
|
deba@1532
|
374 |
reader.readEdge("edge", edge);
|
deba@1532
|
375 |
\endcode
|
deba@1532
|
376 |
|
deba@1532
|
377 |
\section advanced Advanced features
|
deba@1532
|
378 |
|
athos@1540
|
379 |
The graph reader and writer classes give an easy way to read and write
|
athos@1540
|
380 |
graphs. But sometimes we want more advanced features. In this case we can
|
athos@1540
|
381 |
use the more general <tt>lemon reader and writer</tt> interface.
|
deba@1532
|
382 |
|
athos@1540
|
383 |
The LEMON file format is a section oriented file format. It contains one or
|
athos@1540
|
384 |
more sections, each starting with a line identifying its type
|
athos@1540
|
385 |
(the word starting with the \c \@ character).
|
deba@1532
|
386 |
The content of the section this way cannot contain line with \c \@ first
|
deba@1532
|
387 |
character. The file may contains comment lines with \c # first character.
|
deba@1532
|
388 |
|
alpar@1631
|
389 |
The \ref lemon::LemonReader "LemonReader"
|
alpar@1631
|
390 |
and \ref lemon::LemonWriter "LemonWriter"
|
alpar@1631
|
391 |
gives a framework to read and
|
deba@1532
|
392 |
write sections. There are various section reader and section writer
|
alpar@1631
|
393 |
classes which can be attached to a \ref lemon::LemonReader "LemonReader"
|
alpar@1631
|
394 |
or a \ref lemon::LemonWriter "LemonWriter".
|
deba@1532
|
395 |
|
deba@1532
|
396 |
There are default section readers and writers for reading and writing
|
athos@1540
|
397 |
item sets, and labeled items in the graph. These read and write
|
deba@1532
|
398 |
the format described above. Other type of data can be handled with own
|
deba@1532
|
399 |
section reader and writer classes which are inherited from the
|
alpar@1631
|
400 |
\c LemonReader::SectionReader or the
|
alpar@1631
|
401 |
\ref lemon::LemonWriter::SectionWriter "LemonWriter::SectionWriter"
|
alpar@1631
|
402 |
classes.
|
deba@1532
|
403 |
|
deba@1532
|
404 |
The next example defines a special section reader which reads the
|
deba@1532
|
405 |
\c \@description sections into a string:
|
deba@1532
|
406 |
|
deba@1532
|
407 |
\code
|
deba@1532
|
408 |
class DescriptionReader : LemonReader::SectionReader {
|
deba@1532
|
409 |
protected:
|
deba@1532
|
410 |
virtual bool header(const std::string& line) {
|
deba@1532
|
411 |
std::istringstream ls(line);
|
deba@1532
|
412 |
std::string head;
|
deba@1532
|
413 |
ls >> head;
|
deba@1532
|
414 |
return head == "@description";
|
deba@1532
|
415 |
}
|
deba@1532
|
416 |
|
deba@1532
|
417 |
virtual void read(std::istream& is) {
|
deba@1532
|
418 |
std::string line;
|
deba@1532
|
419 |
while (getline(is, line)) {
|
deba@1532
|
420 |
desc += line;
|
deba@1532
|
421 |
}
|
deba@1532
|
422 |
}
|
deba@1532
|
423 |
public:
|
deba@1532
|
424 |
|
deba@1532
|
425 |
typedef LemonReader::SectionReader Parent;
|
deba@1532
|
426 |
|
deba@1532
|
427 |
DescriptionReader(LemonReader& reader) : Parent(reader) {}
|
deba@1532
|
428 |
|
deba@1532
|
429 |
const std::string& description() const {
|
deba@1532
|
430 |
return description;
|
deba@1532
|
431 |
}
|
deba@1532
|
432 |
|
deba@1532
|
433 |
private:
|
deba@1532
|
434 |
std::string desc;
|
deba@1532
|
435 |
};
|
deba@1532
|
436 |
\endcode
|
deba@1532
|
437 |
|
deba@1532
|
438 |
The other advanced stuff of the generalized file format is that
|
deba@1532
|
439 |
multiple edgesets can be stored to the same nodeset. It can be used
|
athos@1540
|
440 |
for example as a network traffic matrix.
|
deba@1532
|
441 |
|
athos@1540
|
442 |
In our example there is a network with symmetric links and there are assymetric
|
deba@1532
|
443 |
traffic request on the network. This construction can be stored in an
|
alpar@1631
|
444 |
undirected graph and in a directed \c NewEdgeSetAdaptor class. The example
|
alpar@1631
|
445 |
shows the input with the \ref lemon::LemonReader "LemonReader" class:
|
deba@1532
|
446 |
|
deba@1532
|
447 |
\code
|
deba@1532
|
448 |
UndirListGraph network;
|
deba@1532
|
449 |
UndirListGraph::UndirEdgeSet<double> capacity;
|
deba@1532
|
450 |
NewEdgeSetAdaptor<UndirListGraph> traffic(network);
|
deba@1532
|
451 |
NewEdgeSetAdaptor<UndirListGraph>::EdgeSet<double> request(network);
|
deba@1532
|
452 |
|
deba@1532
|
453 |
LemonReader reader(std::cin);
|
deba@1532
|
454 |
NodeSetReader nodesetReader(reader, network);
|
deba@1532
|
455 |
UndirEdgeSetReader undirEdgesetReader(reader, network, nodesetReader);
|
deba@1532
|
456 |
undirEdgesetReader.readEdgeMap("capacity", capacity);
|
deba@1532
|
457 |
EdgeSetReader edgesetReader(reader, traffic, nodesetReader);
|
deba@1532
|
458 |
edgesetReader.readEdgeMap("request", request);
|
deba@1532
|
459 |
|
deba@1532
|
460 |
reader.run();
|
deba@1532
|
461 |
\endcode
|
deba@1532
|
462 |
|
alpar@1631
|
463 |
Because both the \ref lemon::GraphReader "GraphReader"
|
alpar@1631
|
464 |
and the \ref lemon::UndirGraphReader "UndirGraphReader" can be converted
|
alpar@1631
|
465 |
to \ref lemon::LemonReader "LemonReader"
|
alpar@1631
|
466 |
and it can resolve the ID's of the items, the previous
|
alpar@1631
|
467 |
result can be achived with the \ref lemon::UndirGraphReader "UndirGraphReader"
|
alpar@1631
|
468 |
class, too.
|
deba@1532
|
469 |
|
deba@1532
|
470 |
|
deba@1532
|
471 |
\code
|
deba@1532
|
472 |
UndirListGraph network;
|
deba@1532
|
473 |
UndirListGraph::UndirEdgeSet<double> capacity;
|
deba@1532
|
474 |
NewEdgeSetAdaptor<UndirListGraph> traffic(network);
|
deba@1532
|
475 |
NewEdgeSetAdaptor<UndirListGraph>::EdgeSet<double> request(network);
|
deba@1532
|
476 |
|
deba@1532
|
477 |
UndirGraphReader reader(std::cin, network);
|
deba@1532
|
478 |
reader.readEdgeMap("capacity", capacity);
|
deba@1532
|
479 |
EdgeSetReader edgesetReader(reader, traffic, reader);
|
deba@1532
|
480 |
edgesetReader.readEdgeMap("request", request);
|
deba@1532
|
481 |
|
deba@1532
|
482 |
reader.run();
|
deba@1532
|
483 |
\endcode
|
deba@1532
|
484 |
|
deba@1333
|
485 |
\author Balazs Dezso
|
deba@1114
|
486 |
*/
|
alpar@1631
|
487 |
} |