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