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