| 
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  | 
  | 
| 
athos@1540
 | 
   114  | 
The graph input and output is based on <em> reading and writing
  | 
| 
athos@1540
 | 
   115  | 
commands</em>. The user gives reading and writing commands to the reader or
  | 
| 
athos@1540
 | 
   116  | 
writer class, then he calls the \c run() method that executes all the given
  | 
| 
athos@1540
 | 
   117  | 
commands.
  | 
| 
deba@1114
 | 
   118  | 
  | 
| 
deba@1114
 | 
   119  | 
\subsection write Writing a graph
  | 
| 
deba@1114
 | 
   120  | 
  | 
| 
alpar@1631
 | 
   121  | 
The \ref lemon::GraphWriter "GraphWriter" template class
  | 
| 
alpar@1631
 | 
   122  | 
provides the graph output. To write a graph
  | 
| 
athos@1526
 | 
   123  | 
you should first give writing commands to the writer. You can declare
  | 
| 
athos@1540
 | 
   124  | 
writing command as \c NodeMap or \c EdgeMap writing and labeled Node and
  | 
| 
deba@1114
 | 
   125  | 
Edge writing.
  | 
| 
deba@1114
 | 
   126  | 
  | 
| 
deba@1114
 | 
   127  | 
\code
  | 
| 
deba@1333
 | 
   128  | 
GraphWriter<ListGraph> writer(std::cout, graph);
  | 
| 
deba@1114
 | 
   129  | 
\endcode
  | 
| 
deba@1114
 | 
   130  | 
  | 
| 
alpar@1631
 | 
   131  | 
The \ref lemon::GraphWriter::writeNodeMap() "writeNodeMap()"
  | 
| 
alpar@1631
 | 
   132  | 
function declares a \c NodeMap writing command in the
  | 
| 
alpar@1631
 | 
   133  | 
\ref lemon::GraphWriter "GraphWriter".
  | 
| 
alpar@1631
 | 
   134  | 
You should give a name to the map and the map
  | 
| 
athos@1522
 | 
   135  | 
object as parameters. The NodeMap writing command with name "id" should write a 
  | 
| 
athos@1540
 | 
   136  | 
unique map because it will be regarded as an ID map.
  | 
| 
deba@1114
 | 
   137  | 
  | 
| 
deba@1114
 | 
   138  | 
\see IdMap, DescriptorMap  
  | 
| 
deba@1114
 | 
   139  | 
  | 
| 
deba@1114
 | 
   140  | 
\code
  | 
| 
deba@1114
 | 
   141  | 
IdMap<ListGraph, Node> nodeIdMap;
  | 
| 
deba@1394
 | 
   142  | 
writer.writeNodeMap("id", nodeIdMap);
 | 
| 
deba@1114
 | 
   143  | 
  | 
| 
deba@1394
 | 
   144  | 
writer.writeNodeMap("x-coord", xCoordMap);
 | 
| 
deba@1394
 | 
   145  | 
writer.writeNodeMap("y-coord", yCoordMap);
 | 
| 
deba@1394
 | 
   146  | 
writer.writeNodeMap("color", colorMap);
 | 
| 
deba@1114
 | 
   147  | 
\endcode
  | 
| 
deba@1114
 | 
   148  | 
  | 
| 
alpar@1631
 | 
   149  | 
With the \ref lemon::GraphWriter::writeEdgeMap() "writeEdgeMap()"
  | 
| 
alpar@1631
 | 
   150  | 
member function you can give an edge map
  | 
| 
deba@1333
 | 
   151  | 
writing command similar to the NodeMaps.
  | 
| 
deba@1114
 | 
   152  | 
  | 
| 
deba@1114
 | 
   153  | 
\see IdMap, DescriptorMap  
  | 
| 
athos@1522
 | 
   154  | 
  | 
| 
deba@1114
 | 
   155  | 
\code
  | 
| 
deba@1114
 | 
   156  | 
DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > edgeDescMap(graph);
  | 
| 
deba@1394
 | 
   157  | 
writer.writeEdgeMap("descriptor", edgeDescMap);
 | 
| 
deba@1114
 | 
   158  | 
  | 
| 
deba@1394
 | 
   159  | 
writer.writeEdgeMap("weight", weightMap);
 | 
| 
deba@1394
 | 
   160  | 
writer.writeEdgeMap("label", labelMap);
 | 
| 
deba@1114
 | 
   161  | 
\endcode
  | 
| 
deba@1114
 | 
   162  | 
  | 
| 
alpar@1631
 | 
   163  | 
With \ref lemon::GraphWriter::writeNode() "writeNode()"
  | 
| 
alpar@1631
 | 
   164  | 
and \ref lemon::GraphWriter::writeEdge() "writeEdge()"
  | 
| 
alpar@1631
 | 
   165  | 
functions you can designate Nodes and
  | 
| 
athos@1522
 | 
   166  | 
Edges in the graph. For example, you can write out the source and target node
  | 
| 
athos@1522
 | 
   167  | 
of a maximum flow instance.
  | 
| 
deba@1114
 | 
   168  | 
  | 
| 
deba@1114
 | 
   169  | 
\code
  | 
| 
deba@1394
 | 
   170  | 
writer.writeNode("source", sourceNode);
 | 
| 
deba@1394
 | 
   171  | 
writer.writeNode("target", targetNode);
 | 
| 
deba@1114
 | 
   172  | 
  | 
| 
deba@1394
 | 
   173  | 
writer.writeEdge("observed", edge);
 | 
| 
deba@1114
 | 
   174  | 
\endcode
  | 
| 
deba@1114
 | 
   175  | 
  | 
| 
alpar@1631
 | 
   176  | 
With \ref lemon::GraphWriter::writeAttribute() "writeAttribute()"
  | 
| 
alpar@1631
 | 
   177  | 
function you can write an attribute to the file.
  | 
| 
deba@1532
 | 
   178  | 
  | 
| 
deba@1532
 | 
   179  | 
\code
  | 
| 
deba@1532
 | 
   180  | 
writer.writeAttribute("author", "Balazs DEZSO");
 | 
| 
deba@1532
 | 
   181  | 
writer.writeAttribute("version", 12);
 | 
| 
deba@1532
 | 
   182  | 
\endcode
  | 
| 
deba@1532
 | 
   183  | 
  | 
| 
alpar@1631
 | 
   184  | 
After you give all write commands you must call the
  | 
| 
alpar@1631
 | 
   185  | 
\ref lemon::GraphWriter::run() "run()" member
  | 
| 
athos@1522
 | 
   186  | 
function, which executes all the writing commands.
  | 
| 
deba@1114
 | 
   187  | 
  | 
| 
deba@1114
 | 
   188  | 
\code
  | 
| 
deba@1114
 | 
   189  | 
writer.run();
  | 
| 
deba@1114
 | 
   190  | 
\endcode
  | 
| 
deba@1114
 | 
   191  | 
  | 
| 
deba@1114
 | 
   192  | 
\subsection reading Reading a graph
  | 
| 
deba@1114
 | 
   193  | 
  | 
| 
athos@1540
 | 
   194  | 
The file to be read may contain several maps and labeled nodes or edges.
  | 
| 
deba@1114
 | 
   195  | 
If you read a graph you need not read all the maps and items just those
  | 
| 
alpar@1631
 | 
   196  | 
that you need. The interface of the \ref lemon::GraphReader "GraphReader"
  | 
| 
alpar@1631
 | 
   197  | 
is very similar to
  | 
| 
alpar@1631
 | 
   198  | 
the \ref lemon::GraphWriter "GraphWriter"
  | 
| 
alpar@1631
 | 
   199  | 
but the reading method does not depend on the order of the
  | 
| 
deba@1114
 | 
   200  | 
given commands.
  | 
| 
deba@1114
 | 
   201  | 
  | 
| 
athos@1522
 | 
   202  | 
The reader object assumes that each not readed value does not contain 
  | 
| 
alpar@1118
 | 
   203  | 
whitespaces, therefore it has some extra possibilities to control how
  | 
| 
alpar@1118
 | 
   204  | 
it should skip the values when the string representation contains spaces.
  | 
| 
deba@1114
 | 
   205  | 
  | 
| 
deba@1114
 | 
   206  | 
\code
  | 
| 
deba@1333
 | 
   207  | 
GraphReader<ListGraph> reader(std::cin, graph);
  | 
| 
deba@1114
 | 
   208  | 
\endcode
  | 
| 
deba@1114
 | 
   209  | 
  | 
| 
alpar@1631
 | 
   210  | 
The \ref lemon::GraphReader::readNodeMap() "readNodeMap()"
  | 
| 
alpar@1631
 | 
   211  | 
function reads a map from the \c nodeset section.
  | 
| 
athos@1522
 | 
   212  | 
If there is a map that you do not want to read from the file and there are
  | 
| 
athos@1522
 | 
   213  | 
whitespaces in the string represenation of the values then you should
  | 
| 
alpar@1631
 | 
   214  | 
call the \ref lemon::GraphReader::skipNodeMap() "skipNodeMap()"
  | 
| 
alpar@1631
 | 
   215  | 
template member function with proper parameters.
  | 
| 
deba@1114
 | 
   216  | 
  | 
| 
deba@1114
 | 
   217  | 
\see QuotedStringReader
  | 
| 
athos@1522
 | 
   218  | 
  | 
| 
deba@1114
 | 
   219  | 
\code
  | 
| 
deba@1394
 | 
   220  | 
reader.readNodeMap("x-coord", xCoordMap);
 | 
| 
deba@1394
 | 
   221  | 
reader.readNodeMap("y-coord", yCoordMap);
 | 
| 
deba@1114
 | 
   222  | 
  | 
| 
deba@1394
 | 
   223  | 
reader.readNodeMap<QuotedStringReader>("label", labelMap);
 | 
| 
deba@1114
 | 
   224  | 
reader.skipNodeMap<QuotedStringReader>("description");
 | 
| 
deba@1114
 | 
   225  | 
  | 
| 
deba@1394
 | 
   226  | 
reader.readNodeMap("color", colorMap);
 | 
| 
deba@1114
 | 
   227  | 
\endcode
  | 
| 
deba@1114
 | 
   228  | 
  | 
| 
alpar@1631
 | 
   229  | 
With the \ref lemon::GraphReader::readEdgeMap() "readEdgeMap()"
  | 
| 
alpar@1631
 | 
   230  | 
member function you can give an edge map
  | 
| 
deba@1114
 | 
   231  | 
reading command similar to the NodeMaps. 
  | 
| 
deba@1114
 | 
   232  | 
  | 
| 
deba@1114
 | 
   233  | 
\code
  | 
| 
deba@1394
 | 
   234  | 
reader.readEdgeMap("weight", weightMap);
 | 
| 
deba@1394
 | 
   235  | 
reader.readEdgeMap("label", labelMap);
 | 
| 
deba@1114
 | 
   236  | 
\endcode
  | 
| 
deba@1114
 | 
   237  | 
  | 
| 
alpar@1631
 | 
   238  | 
With \ref lemon::GraphReader::readNode() "readNode()"
  | 
| 
alpar@1631
 | 
   239  | 
and \ref lemon::GraphReader::readEdge() "readEdge()"
  | 
| 
alpar@1631
 | 
   240  | 
functions you can read labeled Nodes and
  | 
| 
deba@1114
 | 
   241  | 
Edges.
  | 
| 
deba@1114
 | 
   242  | 
  | 
| 
deba@1114
 | 
   243  | 
\code
  | 
| 
deba@1394
 | 
   244  | 
reader.readNode("source", sourceNode);
 | 
| 
deba@1394
 | 
   245  | 
reader.readNode("target", targetNode);
 | 
| 
deba@1114
 | 
   246  | 
  | 
| 
deba@1394
 | 
   247  | 
reader.readEdge("observed", edge);
 | 
| 
deba@1114
 | 
   248  | 
\endcode
  | 
| 
deba@1114
 | 
   249  | 
  | 
| 
alpar@1631
 | 
   250  | 
With \ref lemon::GraphReader::readAttribute() "readAttribute()"
  | 
| 
alpar@1631
 | 
   251  | 
function you can read an attribute from the file.
  | 
| 
deba@1532
 | 
   252  | 
  | 
| 
deba@1532
 | 
   253  | 
\code
  | 
| 
deba@1532
 | 
   254  | 
std::string author;
  | 
| 
deba@1532
 | 
   255  | 
writer.readAttribute("author", author);
 | 
| 
deba@1532
 | 
   256  | 
int version;
  | 
| 
deba@1532
 | 
   257  | 
writer.writeAttribute("version", version);
 | 
| 
deba@1532
 | 
   258  | 
\endcode
  | 
| 
deba@1532
 | 
   259  | 
  | 
| 
alpar@1631
 | 
   260  | 
After you give all read commands you must call the
  | 
| 
alpar@1631
 | 
   261  | 
\ref lemon::GraphReader::run() "run()" member
  | 
| 
athos@1522
 | 
   262  | 
function, which executes all the commands.
  | 
| 
deba@1114
 | 
   263  | 
  | 
| 
deba@1114
 | 
   264  | 
\code
  | 
| 
deba@1114
 | 
   265  | 
reader.run();
  | 
| 
deba@1114
 | 
   266  | 
\endcode
  | 
| 
deba@1114
 | 
   267  | 
  | 
| 
athos@1540
 | 
   268  | 
\anchor rwbackground
  | 
| 
athos@1527
 | 
   269  | 
\section types Background of Reading and Writing
  | 
| 
athos@1540
 | 
   270  | 
  | 
| 
athos@1540
 | 
   271  | 
  | 
| 
athos@1527
 | 
   272  | 
To read a map (on the nodes or edges)
  | 
| 
alpar@1631
 | 
   273  | 
the \ref lemon::GraphReader "GraphReader"
  | 
| 
alpar@1631
 | 
   274  | 
should know how to read a Value from the given map.
  | 
| 
deba@1114
 | 
   275  | 
By the default implementation the input operator reads a value from
  | 
| 
deba@1114
 | 
   276  | 
the stream and the type of the readed value is the value type of the given map.
  | 
| 
deba@1114
 | 
   277  | 
When the reader should skip a value in the stream, because you do not
  | 
| 
athos@1527
 | 
   278  | 
want to store it in a map, the reader skips a character sequence without 
  | 
| 
athos@1540
 | 
   279  | 
whitespaces. 
  | 
| 
deba@1114
 | 
   280  | 
  | 
| 
deba@1114
 | 
   281  | 
If you want to change the functionality of the reader, you can use
  | 
| 
deba@1114
 | 
   282  | 
template parameters to specialize it. When you give a reading
  | 
| 
deba@1114
 | 
   283  | 
command for a map you can give a Reader type as template parameter.
  | 
| 
deba@1333
 | 
   284  | 
With this template parameter you can control how the Reader reads
  | 
| 
deba@1114
 | 
   285  | 
a value from the stream.
  | 
| 
deba@1114
 | 
   286  | 
  | 
| 
deba@1114
 | 
   287  | 
The reader has the next structure: 
  | 
| 
deba@1114
 | 
   288  | 
\code
  | 
| 
deba@1114
 | 
   289  | 
struct TypeReader {
 | 
| 
deba@1114
 | 
   290  | 
  typedef TypeName Value;
  | 
| 
deba@1114
 | 
   291  | 
  | 
| 
deba@1114
 | 
   292  | 
  void read(std::istream& is, Value& value);
  | 
| 
deba@1114
 | 
   293  | 
};
  | 
| 
deba@1114
 | 
   294  | 
\endcode
  | 
| 
deba@1114
 | 
   295  | 
  | 
| 
athos@1527
 | 
   296  | 
For example, the \c "strings" nodemap contains strings and you do not need
  | 
| 
athos@1540
 | 
   297  | 
the value of the string just the length. Then you can implement an own Reader
  | 
| 
deba@1114
 | 
   298  | 
struct.
  | 
| 
deba@1114
 | 
   299  | 
  | 
| 
deba@1114
 | 
   300  | 
\code
  | 
| 
deba@1114
 | 
   301  | 
struct LengthReader {
 | 
| 
deba@1114
 | 
   302  | 
  typedef int Value;
  | 
| 
deba@1114
 | 
   303  | 
  | 
| 
deba@1114
 | 
   304  | 
  void read(std::istream& is, Value& value) {
 | 
| 
deba@1114
 | 
   305  | 
    std::string tmp;
  | 
| 
deba@1114
 | 
   306  | 
    is >> tmp;
  | 
| 
deba@1114
 | 
   307  | 
    value = tmp.length();
  | 
| 
deba@1114
 | 
   308  | 
  }
  | 
| 
deba@1114
 | 
   309  | 
};
  | 
| 
deba@1114
 | 
   310  | 
...
  | 
| 
deba@1394
 | 
   311  | 
reader.readNodeMap<LengthReader>("strings", lengthMap);
 | 
| 
deba@1114
 | 
   312  | 
\endcode  
  | 
| 
deba@1114
 | 
   313  | 
  | 
| 
deba@1114
 | 
   314  | 
The global functionality of the reader class can be changed by giving a
  | 
| 
athos@1526
 | 
   315  | 
special template parameter to the GraphReader class. By default, the
  | 
| 
alpar@1118
 | 
   316  | 
template parameter is \c DefaultReaderTraits. A reader traits class 
  | 
| 
athos@1540
 | 
   317  | 
should provide an inner template class Reader for each type, and a 
  | 
| 
deba@1114
 | 
   318  | 
DefaultReader for skipping a value.
  | 
| 
deba@1114
 | 
   319  | 
  | 
| 
athos@1540
 | 
   320  | 
The specialization of  writing is very similar to that of reading.
  | 
| 
deba@1114
 | 
   321  | 
  | 
| 
athos@1540
 | 
   322  | 
\section undir Undirected graphs
  | 
| 
deba@1532
 | 
   323  | 
  | 
| 
athos@1540
 | 
   324  | 
In a file describing an undirected graph (undir graph, for short) you find an
  | 
| 
athos@1540
 | 
   325  | 
\c undiredgeset section instead of the \c edgeset section. The first line of
  | 
| 
athos@1540
 | 
   326  | 
the section describes the names of the maps on the undirected egdes and all
  | 
| 
athos@1540
 | 
   327  | 
next lines describe one undirected edge with the the incident nodes and the
  | 
| 
athos@1540
 | 
   328  | 
values of the map.
  | 
| 
deba@1532
 | 
   329  | 
  | 
| 
athos@1540
 | 
   330  | 
The format handles directed edge maps as a syntactical sugar???, if there
  | 
| 
athos@1540
 | 
   331  | 
are two maps with names being the same with a \c '+' and a \c '-' prefix
  | 
| 
athos@1540
 | 
   332  | 
then this will be read as a directed map.
  | 
| 
deba@1532
 | 
   333  | 
  | 
| 
deba@1532
 | 
   334  | 
\code
  | 
| 
deba@1532
 | 
   335  | 
@undiredgeset
  | 
| 
deba@1532
 | 
   336  | 
             id    capacity +flow -flow
  | 
| 
deba@1532
 | 
   337  | 
32   2       1     4.3      2.0	  0.0
  | 
| 
deba@1532
 | 
   338  | 
21   21      5     2.6      0.0   2.6
  | 
| 
deba@1532
 | 
   339  | 
21   12      8     3.4      0.0   0.0
  | 
| 
deba@1532
 | 
   340  | 
\endcode
  | 
| 
deba@1532
 | 
   341  | 
  | 
| 
athos@1540
 | 
   342  | 
The \c edges section is changed to \c undiredges section. This section
  | 
| 
deba@1532
 | 
   343  | 
describes labeled edges and undirected edges. The directed edge label
  | 
| 
athos@1540
 | 
   344  | 
should start with a \c '+' or a \c '-' prefix to decide the direction
  | 
| 
deba@1532
 | 
   345  | 
of the edge. 
  | 
| 
deba@1532
 | 
   346  | 
  | 
| 
deba@1532
 | 
   347  | 
\code
  | 
| 
deba@1532
 | 
   348  | 
@undiredges
  | 
| 
deba@1532
 | 
   349  | 
undiredge 1
  | 
| 
deba@1532
 | 
   350  | 
+edge 5
  | 
| 
deba@1532
 | 
   351  | 
-back 5
  | 
| 
deba@1532
 | 
   352  | 
\endcode
  | 
| 
deba@1532
 | 
   353  | 
  | 
| 
alpar@1631
 | 
   354  | 
There are similar classes to the \ref lemon::GraphReader "GraphReader" and
  | 
| 
alpar@1631
 | 
   355  | 
\ref lemon::GraphWriter "GraphWriter" which
  | 
| 
alpar@1631
 | 
   356  | 
handle the undirected graphs. These classes are
  | 
| 
alpar@1631
 | 
   357  | 
the \ref lemon::UndirGraphReader "UndirGraphReader"
  | 
| 
alpar@1631
 | 
   358  | 
and \ref lemon::UndirGraphWriter "UndirGraphWriter".
  | 
| 
deba@1532
 | 
   359  | 
  | 
| 
deba@1788
 | 
   360  | 
The \ref lemon::UndirGraphReader::readUndirEdgeMap() "readUndirEdgeMap()"
  | 
| 
alpar@1631
 | 
   361  | 
function reads an undirected map and the
  | 
| 
alpar@1631
 | 
   362  | 
\ref lemon::UndirGraphReader::readUndirEdge() "readUndirEdge()"
  | 
| 
alpar@1631
 | 
   363  | 
reads an undirected edge from the file, 
  | 
| 
deba@1532
 | 
   364  | 
  | 
| 
deba@1532
 | 
   365  | 
\code
  | 
| 
deba@1532
 | 
   366  | 
reader.readUndirEdgeMap("capacity", capacityMap);
 | 
| 
deba@1532
 | 
   367  | 
reader.readEdgeMap("flow", flowMap);
 | 
| 
deba@1532
 | 
   368  | 
...
  | 
| 
deba@1532
 | 
   369  | 
reader.readUndirEdge("undir_edge", undir_edge);
 | 
| 
deba@1532
 | 
   370  | 
reader.readEdge("edge", edge);
 | 
| 
deba@1532
 | 
   371  | 
\endcode
  | 
| 
deba@1532
 | 
   372  | 
  | 
| 
deba@1532
 | 
   373  | 
\section advanced Advanced features
  | 
| 
deba@1532
 | 
   374  | 
  | 
| 
athos@1540
 | 
   375  | 
The graph reader and writer classes give an easy way to read and write
  | 
| 
athos@1540
 | 
   376  | 
graphs. But sometimes we want more advanced features. In this case we can
  | 
| 
athos@1540
 | 
   377  | 
use the more general <tt>lemon reader and writer</tt> interface.
  | 
| 
deba@1532
 | 
   378  | 
  | 
| 
athos@1540
 | 
   379  | 
The LEMON file format is a section oriented file format. It contains one or
  | 
| 
athos@1540
 | 
   380  | 
more sections, each starting with a line identifying its type 
  | 
| 
athos@1540
 | 
   381  | 
(the word starting with the \c \@  character).
  | 
| 
deba@1532
 | 
   382  | 
The content of the section this way cannot contain line with \c \@ first
  | 
| 
deba@1532
 | 
   383  | 
character. The file may contains comment lines with \c # first character.
  | 
| 
deba@1532
 | 
   384  | 
  | 
| 
alpar@1631
 | 
   385  | 
The \ref lemon::LemonReader "LemonReader"
  | 
| 
alpar@1631
 | 
   386  | 
and \ref lemon::LemonWriter "LemonWriter"
  | 
| 
alpar@1631
 | 
   387  | 
gives a framework to read and
  | 
| 
deba@1532
 | 
   388  | 
write sections. There are various section reader and section writer
  | 
| 
alpar@1631
 | 
   389  | 
classes which can be attached to a \ref lemon::LemonReader "LemonReader"
  | 
| 
alpar@1631
 | 
   390  | 
or a \ref lemon::LemonWriter "LemonWriter".
  | 
| 
deba@1532
 | 
   391  | 
  | 
| 
deba@1532
 | 
   392  | 
There are default section readers and writers for reading and writing
  | 
| 
athos@1540
 | 
   393  | 
item sets, and labeled items in the graph. These read and write
  | 
| 
deba@1532
 | 
   394  | 
the format described above. Other type of data can be handled with own
  | 
| 
deba@1532
 | 
   395  | 
section reader and writer classes which are inherited from the
  | 
| 
alpar@1631
 | 
   396  | 
\c LemonReader::SectionReader or the
  | 
| 
alpar@1631
 | 
   397  | 
\ref lemon::LemonWriter::SectionWriter "LemonWriter::SectionWriter"
  | 
| 
alpar@1631
 | 
   398  | 
classes.
  | 
| 
deba@1532
 | 
   399  | 
  | 
| 
deba@1532
 | 
   400  | 
The next example defines a special section reader which reads the
  | 
| 
deba@1532
 | 
   401  | 
\c \@description sections into a string:
  | 
| 
deba@1532
 | 
   402  | 
  | 
| 
deba@1532
 | 
   403  | 
\code 
  | 
| 
deba@1532
 | 
   404  | 
class DescriptionReader : LemonReader::SectionReader {
 | 
| 
deba@1532
 | 
   405  | 
protected:
  | 
| 
deba@1532
 | 
   406  | 
  virtual bool header(const std::string& line) {
 | 
| 
deba@1532
 | 
   407  | 
    std::istringstream ls(line);
  | 
| 
deba@1532
 | 
   408  | 
    std::string head;
  | 
| 
deba@1532
 | 
   409  | 
    ls >> head;
  | 
| 
deba@1532
 | 
   410  | 
    return head == "@description";
  | 
| 
deba@1532
 | 
   411  | 
  }
  | 
| 
deba@1532
 | 
   412  | 
  | 
| 
deba@1532
 | 
   413  | 
  virtual void read(std::istream& is) {
 | 
| 
deba@1532
 | 
   414  | 
    std::string line;
  | 
| 
deba@1532
 | 
   415  | 
    while (getline(is, line)) {
 | 
| 
deba@1532
 | 
   416  | 
      desc += line;
  | 
| 
deba@1532
 | 
   417  | 
    }
  | 
| 
deba@1532
 | 
   418  | 
  }
  | 
| 
deba@1532
 | 
   419  | 
public:
  | 
| 
deba@1532
 | 
   420  | 
  | 
| 
deba@1532
 | 
   421  | 
  typedef LemonReader::SectionReader Parent;
  | 
| 
deba@1532
 | 
   422  | 
  
  | 
| 
deba@1532
 | 
   423  | 
  DescriptionReader(LemonReader& reader) : Parent(reader) {}
 | 
| 
deba@1532
 | 
   424  | 
  | 
| 
deba@1532
 | 
   425  | 
  const std::string& description() const {
 | 
| 
deba@1532
 | 
   426  | 
    return description;
  | 
| 
deba@1532
 | 
   427  | 
  }
  | 
| 
deba@1532
 | 
   428  | 
  | 
| 
deba@1532
 | 
   429  | 
private:
  | 
| 
deba@1532
 | 
   430  | 
  std::string desc;
  | 
| 
deba@1532
 | 
   431  | 
};
  | 
| 
deba@1532
 | 
   432  | 
\endcode
  | 
| 
deba@1532
 | 
   433  | 
  | 
| 
deba@1532
 | 
   434  | 
The other advanced stuff of the generalized file format is that 
  | 
| 
deba@1532
 | 
   435  | 
multiple edgesets can be stored to the same nodeset. It can be used 
  | 
| 
athos@1540
 | 
   436  | 
for example as a network traffic matrix.
  | 
| 
deba@1532
 | 
   437  | 
  | 
| 
athos@1540
 | 
   438  | 
In our example there is a network with symmetric links and there are assymetric
  | 
| 
deba@1532
 | 
   439  | 
traffic request on the network. This construction can be stored in an
  | 
| 
deba@1842
 | 
   440  | 
undirected graph and in a directed \c ListEdgeSet class. The example
  | 
| 
alpar@1631
 | 
   441  | 
shows the input with the \ref lemon::LemonReader "LemonReader" class:
  | 
| 
deba@1532
 | 
   442  | 
  | 
| 
deba@1532
 | 
   443  | 
\code
  | 
| 
deba@1532
 | 
   444  | 
UndirListGraph network;
  | 
| 
deba@1839
 | 
   445  | 
UndirListGraph::UndirEdgeMap<double> capacity;
  | 
| 
deba@1842
 | 
   446  | 
ListEdgeSet<UndirListGraph> traffic(network);
  | 
| 
deba@1842
 | 
   447  | 
ListEdgeSet<UndirListGraph>::EdgeMap<double> request(network);
  | 
| 
deba@1532
 | 
   448  | 
  | 
| 
deba@1532
 | 
   449  | 
LemonReader reader(std::cin);
  | 
| 
deba@1839
 | 
   450  | 
NodeSetReader<UndirListGraph> nodesetReader(reader, network);
  | 
| 
deba@1839
 | 
   451  | 
UndirEdgeSetReader<UndirListGraph> 
  | 
| 
deba@1839
 | 
   452  | 
  undirEdgesetReader(reader, network, nodesetReader);
  | 
| 
deba@1532
 | 
   453  | 
undirEdgesetReader.readEdgeMap("capacity", capacity);
 | 
| 
deba@1842
 | 
   454  | 
EdgeSetReader<ListEdgeSet<UndirListGraph> > 
  | 
| 
deba@1848
 | 
   455  | 
  edgesetReader(reader, traffic, nodesetReader, "traffic");
  | 
| 
deba@1532
 | 
   456  | 
edgesetReader.readEdgeMap("request", request);
 | 
| 
deba@1532
 | 
   457  | 
  | 
| 
deba@1532
 | 
   458  | 
reader.run();
  | 
| 
deba@1532
 | 
   459  | 
\endcode
  | 
| 
deba@1532
 | 
   460  | 
  | 
| 
alpar@1631
 | 
   461  | 
Because both the \ref lemon::GraphReader "GraphReader"
  | 
| 
alpar@1631
 | 
   462  | 
and the \ref lemon::UndirGraphReader "UndirGraphReader" can be converted
  | 
| 
alpar@1631
 | 
   463  | 
to \ref lemon::LemonReader "LemonReader"
  | 
| 
alpar@1631
 | 
   464  | 
and it can resolve the ID's of the items, the previous
  | 
| 
alpar@1631
 | 
   465  | 
result can be achived with the \ref lemon::UndirGraphReader "UndirGraphReader"
  | 
| 
alpar@1631
 | 
   466  | 
class, too.
  | 
| 
deba@1532
 | 
   467  | 
  | 
| 
deba@1532
 | 
   468  | 
  | 
| 
deba@1532
 | 
   469  | 
\code
  | 
| 
deba@1532
 | 
   470  | 
UndirListGraph network;
  | 
| 
deba@1532
 | 
   471  | 
UndirListGraph::UndirEdgeSet<double> capacity;
  | 
| 
deba@1842
 | 
   472  | 
ListEdgeSet<UndirListGraph> traffic(network);
  | 
| 
deba@1842
 | 
   473  | 
ListEdgeSet<UndirListGraph>::EdgeMap<double> request(network);
  | 
| 
deba@1532
 | 
   474  | 
  | 
| 
deba@1842
 | 
   475  | 
UndirGraphReader<UndirListGraph> reader(std::cin, network);
  | 
| 
deba@1532
 | 
   476  | 
reader.readEdgeMap("capacity", capacity);
 | 
| 
deba@1842
 | 
   477  | 
EdgeSetReader<ListEdgeSet<UndirListGraph> > 
  | 
| 
deba@1848
 | 
   478  | 
  edgesetReader(reader, traffic, reader, "traffic");
  | 
| 
deba@1532
 | 
   479  | 
edgesetReader.readEdgeMap("request", request);
 | 
| 
deba@1532
 | 
   480  | 
  | 
| 
deba@1532
 | 
   481  | 
reader.run();
  | 
| 
deba@1532
 | 
   482  | 
\endcode
  | 
| 
deba@1532
 | 
   483  | 
  | 
| 
deba@1333
 | 
   484  | 
\author Balazs Dezso
  | 
| 
deba@1114
 | 
   485  | 
*/
  | 
| 
alpar@1631
 | 
   486  | 
}  |